LCOV - code coverage report
Current view: top level - drivers/net/zxdh - zxdh_flow.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 0 963 0.0 %
Date: 2025-10-01 17:51:42 Functions: 0 49 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 560 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  * Copyright(c) 2025 ZTE 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 <stdlib.h>
      13                 :            : 
      14                 :            : #include <rte_debug.h>
      15                 :            : #include <rte_ether.h>
      16                 :            : #include <ethdev_driver.h>
      17                 :            : #include <rte_log.h>
      18                 :            : #include <rte_malloc.h>
      19                 :            : #include <rte_tailq.h>
      20                 :            : #include <rte_flow.h>
      21                 :            : #include <rte_bitmap.h>
      22                 :            : 
      23                 :            : #include "zxdh_ethdev.h"
      24                 :            : #include "zxdh_logs.h"
      25                 :            : #include "zxdh_flow.h"
      26                 :            : #include "zxdh_tables.h"
      27                 :            : #include "zxdh_ethdev_ops.h"
      28                 :            : #include "zxdh_np.h"
      29                 :            : #include "zxdh_msg.h"
      30                 :            : 
      31                 :            : #define ZXDH_IPV6_FRAG_HEADER    44
      32                 :            : #define ZXDH_TENANT_ARRAY_NUM    3
      33                 :            : #define ZXDH_VLAN_TCI_MASK       0xFFFF
      34                 :            : #define ZXDH_VLAN_PRI_MASK       0xE000
      35                 :            : #define ZXDH_VLAN_CFI_MASK       0x1000
      36                 :            : #define ZXDH_VLAN_VID_MASK       0x0FFF
      37                 :            : #define MAX_STRING_LEN           8192
      38                 :            : #define FLOW_INGRESS             0
      39                 :            : #define FLOW_EGRESS              1
      40                 :            : #define MAX_ENCAP1_NUM           (256)
      41                 :            : #define INVALID_HANDLEIDX        0xffff
      42                 :            : #define ACTION_VXLAN_ENCAP_ITEMS_NUM (6)
      43                 :            : static struct dh_engine_list flow_engine_list = TAILQ_HEAD_INITIALIZER(flow_engine_list);
      44                 :            : static struct count_res flow_count_ref[MAX_FLOW_COUNT_NUM];
      45                 :            : static rte_spinlock_t fd_hw_res_lock = RTE_SPINLOCK_INITIALIZER;
      46                 :            : static uint8_t fd_hwres_bitmap[ZXDH_MAX_FLOW_NUM] = {0};
      47                 :            : 
      48                 :            : #define MKDUMPSTR(buf, buf_size, cur_len, ...) \
      49                 :            : do { \
      50                 :            :         if ((cur_len) >= (buf_size)) \
      51                 :            :                 break; \
      52                 :            :         (cur_len) += snprintf((buf) + (cur_len), (buf_size) - (cur_len), __VA_ARGS__); \
      53                 :            : } while (0)
      54                 :            : 
      55                 :            : static inline void
      56                 :          0 : print_ether_addr(const char *what, const struct rte_ether_addr *eth_addr,
      57                 :            :                  char print_buf[], uint32_t buf_size, uint32_t *cur_len)
      58                 :            : {
      59                 :            :         char buf[RTE_ETHER_ADDR_FMT_SIZE];
      60                 :            : 
      61                 :          0 :         rte_ether_format_addr(buf, RTE_ETHER_ADDR_FMT_SIZE, eth_addr);
      62         [ #  # ]:          0 :         MKDUMPSTR(print_buf, buf_size, *cur_len, "%s%s", what, buf);
      63                 :          0 : }
      64                 :            : 
      65                 :            : static inline void
      66                 :            : zxdh_fd_flow_free_dtbentry(ZXDH_DTB_USER_ENTRY_T *dtb_entry)
      67                 :            : {
      68                 :          0 :         rte_free(dtb_entry->p_entry_data);
      69                 :          0 :         dtb_entry->p_entry_data = NULL;
      70                 :          0 :         dtb_entry->sdt_no = 0;
      71                 :            : }
      72                 :            : 
      73                 :            : static void
      74                 :            : data_bitwise(void *data, int bytecnt)
      75                 :            : {
      76                 :            :         int i;
      77                 :            :         uint32_t *temp = (uint32_t *)data;
      78                 :            :         int remain = bytecnt % 4;
      79         [ #  # ]:          0 :         for (i = 0; i < (bytecnt >> 2); i++)   {
      80                 :          0 :                 *(temp) = ~*(temp);
      81                 :          0 :                 temp++;
      82                 :            :         }
      83                 :            : 
      84                 :            :         if (remain) {
      85                 :            :                 for (i = 0; i < remain; i++) {
      86                 :            :                         uint8_t *tmp = (uint8_t *)temp;
      87                 :            :                         *(uint8_t *)tmp = ~*(uint8_t *)tmp;
      88                 :            :                         tmp++;
      89                 :            :                 }
      90                 :            :         }
      91                 :            : }
      92                 :            : 
      93                 :            : static void
      94         [ #  # ]:          0 : zxdh_adjust_flow_op_rsp_memory_layout(void *old_data,
      95                 :            :                 size_t old_size, void *new_data)
      96                 :            : {
      97                 :            :         rte_memcpy(new_data, old_data, sizeof(struct zxdh_flow));
      98         [ #  # ]:          0 :         memset((char *)new_data + sizeof(struct zxdh_flow), 0, 4);
      99         [ #  # ]:          0 :         rte_memcpy((char *)new_data + sizeof(struct zxdh_flow) + 4,
     100                 :            :                 (char *)old_data + sizeof(struct zxdh_flow),
     101                 :            :                 old_size - sizeof(struct zxdh_flow));
     102                 :          0 : }
     103                 :            : 
     104                 :          0 : void zxdh_flow_global_init(void)
     105                 :            : {
     106                 :            :         int i;
     107         [ #  # ]:          0 :         for (i = 0; i < MAX_FLOW_COUNT_NUM; i++) {
     108                 :            :                 rte_spinlock_init(&flow_count_ref[i].count_lock);
     109                 :          0 :                 flow_count_ref[i].count_ref = 0;
     110                 :            :         }
     111                 :          0 : }
     112                 :            : 
     113                 :            : static void
     114                 :          0 : __entry_dump(char *print_buf, uint32_t buf_size,
     115                 :            :                 uint32_t *cur_len, struct fd_flow_key *key)
     116                 :            : {
     117                 :          0 :         print_ether_addr("\nL2\t  dst=", &key->mac_dst, print_buf, buf_size, cur_len);
     118                 :          0 :         print_ether_addr(" - src=", &key->mac_src, print_buf, buf_size, cur_len);
     119         [ #  # ]:          0 :         MKDUMPSTR(print_buf, buf_size, *cur_len, " -eth type=0x%04x", key->ether_type);
     120         [ #  # ]:          0 :         MKDUMPSTR(print_buf, buf_size, *cur_len,
     121                 :            :                 " -vlan_pri=0x%02x -vlan_vlanid=0x%04x  -vlan_tci=0x%04x ",
     122                 :            :                 key->cvlan_pri, key->cvlan_vlanid, key->vlan_tci);
     123         [ #  # ]:          0 :         MKDUMPSTR(print_buf, buf_size, *cur_len,
     124                 :            :                 " -vni=0x%02x 0x%02x 0x%02x\n", key->vni[0], key->vni[1], key->vni[2]);
     125         [ #  # ]:          0 :         MKDUMPSTR(print_buf, buf_size, *cur_len,
     126                 :            :                 "L3\t  dstip=0x%08x 0x%08x 0x%08x 0x%08x("IPv6_BYTES_FMT")\n",
     127                 :            :                 *(uint32_t *)key->dst_ip, *((uint32_t *)key->dst_ip + 1),
     128                 :            :                 *((uint32_t *)key->dst_ip + 2),
     129                 :            :                 *((uint32_t *)key->dst_ip + 3),
     130                 :            :                 IPv6_BYTES(key->dst_ip));
     131         [ #  # ]:          0 :         MKDUMPSTR(print_buf, buf_size, *cur_len,
     132                 :            :                 "\t  srcip=0x%08x 0x%08x 0x%08x 0x%08x("IPv6_BYTES_FMT")\n",
     133                 :            :                 *((uint32_t *)key->src_ip), *((uint32_t *)key->src_ip + 1),
     134                 :            :                 *((uint32_t *)key->src_ip + 2),
     135                 :            :                 *((uint32_t *)key->src_ip + 3),
     136                 :            :                 IPv6_BYTES(key->src_ip));
     137         [ #  # ]:          0 :         MKDUMPSTR(print_buf, buf_size, *cur_len,
     138                 :            :                 "  \t  tos=0x%02x -nw-proto=0x%02x -frag-flag %u\n",
     139                 :            :                 key->tos, key->nw_proto, key->frag_flag);
     140         [ #  # ]:          0 :         MKDUMPSTR(print_buf, buf_size, *cur_len,
     141                 :            :                 "L4\t  dstport=0x%04x -srcport=0x%04x", key->tp_dst, key->tp_src);
     142                 :          0 : }
     143                 :            : 
     144                 :            : static void
     145                 :          0 : __result_dump(char *print_buf, uint32_t buf_size,
     146                 :            :                 uint32_t *cur_len, struct fd_flow_result *res)
     147                 :            : {
     148         [ #  # ]:          0 :         MKDUMPSTR(print_buf, buf_size, *cur_len, " -hit_flag = 0x%04x", res->hit_flag);
     149         [ #  # ]:          0 :         MKDUMPSTR(print_buf, buf_size, *cur_len, " -action_idx = 0x%02x", res->action_idx);
     150         [ #  # ]:          0 :         MKDUMPSTR(print_buf, buf_size, *cur_len, " -qid = 0x%04x", res->qid);
     151         [ #  # ]:          0 :         MKDUMPSTR(print_buf, buf_size, *cur_len, " -mark_id = 0x%08x", res->mark_fd_id);
     152         [ #  # ]:          0 :         MKDUMPSTR(print_buf, buf_size, *cur_len, " -count_id = 0x%02x", res->countid);
     153                 :          0 : }
     154                 :            : 
     155                 :          0 : static void offlow_key_dump(struct fd_flow_key *key, struct fd_flow_key *key_mask, FILE *file)
     156                 :            : {
     157                 :            :         char print_buf[MAX_STRING_LEN];
     158                 :            :         uint32_t buf_size = MAX_STRING_LEN;
     159                 :            :         uint32_t cur_len = 0;
     160                 :            : 
     161                 :          0 :         MKDUMPSTR(print_buf, buf_size, cur_len, "offload key:\n\t");
     162                 :          0 :         __entry_dump(print_buf, buf_size, &cur_len, key);
     163                 :            : 
     164         [ #  # ]:          0 :         MKDUMPSTR(print_buf, buf_size, cur_len, "\noffload key_mask:\n\t");
     165                 :          0 :         __entry_dump(print_buf, buf_size, &cur_len, key_mask);
     166                 :            : 
     167                 :          0 :         PMD_DRV_LOG(INFO, "%s", print_buf);
     168         [ #  # ]:          0 :         MKDUMPSTR(print_buf, buf_size, cur_len, "\n");
     169         [ #  # ]:          0 :         if (file)
     170                 :          0 :                 fputs(print_buf, file);
     171                 :          0 : }
     172                 :            : 
     173                 :          0 : static void offlow_result_dump(struct fd_flow_result *res, FILE *file)
     174                 :            : {
     175                 :            :         char print_buf[MAX_STRING_LEN];
     176                 :            :         uint32_t buf_size = MAX_STRING_LEN;
     177                 :            :         uint32_t cur_len = 0;
     178                 :            : 
     179                 :          0 :         MKDUMPSTR(print_buf, buf_size, cur_len, "offload result:\n");
     180                 :          0 :         __result_dump(print_buf, buf_size, &cur_len, res);
     181                 :          0 :         PMD_DRV_LOG(INFO, "%s", print_buf);
     182                 :          0 :         PMD_DRV_LOG(INFO, "memdump : ===result ===");
     183         [ #  # ]:          0 :         MKDUMPSTR(print_buf, buf_size, cur_len, "\n");
     184         [ #  # ]:          0 :         if (file)
     185                 :          0 :                 fputs(print_buf, file);
     186                 :          0 : }
     187                 :            : 
     188                 :            : static int
     189                 :          0 : set_flow_enable(struct rte_eth_dev *dev, uint8_t dir,
     190                 :            :                 bool enable, struct rte_flow_error *error)
     191                 :            : {
     192                 :          0 :         struct zxdh_hw *priv = dev->data->dev_private;
     193                 :          0 :         struct zxdh_port_attr_table port_attr = {0};
     194                 :            :         int ret = 0;
     195                 :            : 
     196         [ #  # ]:          0 :         if (priv->is_pf) {
     197                 :          0 :                 ret = zxdh_get_port_attr(priv, priv->vport.vport, &port_attr);
     198         [ #  # ]:          0 :                 if (ret)
     199                 :          0 :                         return -rte_flow_error_set(error, EINVAL,
     200                 :            :                                         RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
     201                 :            :                                         "get port attr failed.");
     202                 :          0 :                 port_attr.fd_enable = enable;
     203                 :            : 
     204                 :          0 :                 ret = zxdh_set_port_attr(priv, priv->vport.vport, &port_attr);
     205         [ #  # ]:          0 :                 if (ret)
     206                 :          0 :                         return -rte_flow_error_set(error, EINVAL,
     207                 :            :                                         RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
     208                 :            :                                         "set port attr fd_enable failed.");
     209                 :            :         } else {
     210                 :          0 :                 struct zxdh_msg_info msg_info = {0};
     211                 :            :                 struct zxdh_port_attr_set_msg *attr_msg = &msg_info.data.port_attr_msg;
     212                 :            : 
     213                 :          0 :                 attr_msg->mode  = ZXDH_PORT_FD_EN_OFF_FLAG;
     214                 :          0 :                 attr_msg->value = enable;
     215                 :          0 :                 zxdh_msg_head_build(priv, ZXDH_PORT_ATTRS_SET, &msg_info);
     216                 :          0 :                 ret = zxdh_vf_send_msg_to_pf(dev, &msg_info, sizeof(msg_info), NULL, 0);
     217         [ #  # ]:          0 :                 if (ret) {
     218                 :          0 :                         PMD_DRV_LOG(ERR, "port %d flow enable failed", priv->port_id);
     219                 :          0 :                         return -rte_flow_error_set(error, EINVAL,
     220                 :            :                                                 RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
     221                 :            :                                                 "flow enable failed.");
     222                 :            :                 }
     223                 :            :         }
     224         [ #  # ]:          0 :         if (dir == FLOW_INGRESS)
     225                 :          0 :                 priv->i_flow_en = !!enable;
     226                 :            :         else
     227                 :          0 :                 priv->e_flow_en = !!enable;
     228                 :            : 
     229                 :            :         return ret;
     230                 :            : }
     231                 :            : 
     232                 :            : static int
     233                 :          0 : set_vxlan_enable(struct rte_eth_dev *dev, bool enable, struct rte_flow_error *error)
     234                 :            : {
     235                 :          0 :         struct zxdh_hw *priv = dev->data->dev_private;
     236                 :          0 :         struct zxdh_port_attr_table port_attr = {0};
     237                 :            :         int ret = 0;
     238                 :            : 
     239         [ #  # ]:          0 :         if (priv->vxlan_flow_en == !!enable)
     240                 :            :                 return 0;
     241         [ #  # ]:          0 :         if (priv->is_pf) {
     242                 :          0 :                 ret = zxdh_get_port_attr(priv, priv->vport.vport, &port_attr);
     243         [ #  # ]:          0 :                 if (ret)
     244                 :          0 :                         return -rte_flow_error_set(error, EINVAL,
     245                 :            :                                         RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
     246                 :            :                                         "get port attr failed.");
     247                 :          0 :                 port_attr.fd_vxlan_offload_en = enable;
     248                 :            : 
     249                 :          0 :                 ret = zxdh_set_port_attr(priv, priv->vport.vport, &port_attr);
     250         [ #  # ]:          0 :                 if (ret)
     251                 :          0 :                         return -rte_flow_error_set(error, EINVAL,
     252                 :            :                                         RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
     253                 :            :                                         "set port attr fd_enable failed.");
     254                 :            :         } else {
     255                 :          0 :                 struct zxdh_msg_info msg_info = {0};
     256                 :            :                 struct zxdh_port_attr_set_msg *attr_msg = &msg_info.data.port_attr_msg;
     257                 :            : 
     258                 :          0 :                 attr_msg->mode  = ZXDH_PORT_VXLAN_OFFLOAD_EN_OFF;
     259                 :          0 :                 attr_msg->value = enable;
     260                 :            : 
     261                 :          0 :                 zxdh_msg_head_build(priv, ZXDH_PORT_ATTRS_SET, &msg_info);
     262                 :          0 :                 ret = zxdh_vf_send_msg_to_pf(dev, &msg_info, sizeof(msg_info), NULL, 0);
     263         [ #  # ]:          0 :                 if (ret) {
     264                 :          0 :                         PMD_DRV_LOG(ERR, "port %d vxlan flow enable failed", priv->port_id);
     265                 :          0 :                         return -rte_flow_error_set(error, EINVAL,
     266                 :            :                                                 RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
     267                 :            :                                                 "vxlan offload enable failed.");
     268                 :            :                 }
     269                 :            :         }
     270                 :            : 
     271                 :          0 :         priv->vxlan_flow_en = !!enable;
     272                 :          0 :         return ret;
     273                 :            : }
     274                 :            : 
     275                 :          0 : void zxdh_register_flow_engine(struct dh_flow_engine *engine)
     276                 :            : {
     277                 :          0 :         TAILQ_INSERT_TAIL(&flow_engine_list, engine, node);
     278                 :          0 : }
     279                 :            : 
     280                 :          0 : static void zxdh_flow_free(struct zxdh_flow *dh_flow)
     281                 :            : {
     282         [ #  # ]:          0 :         if (dh_flow)
     283         [ #  # ]:          0 :                 rte_mempool_put(zxdh_shared_data->flow_mp, dh_flow);
     284                 :          0 : }
     285                 :            : 
     286                 :            : static struct dh_flow_engine *zxdh_get_flow_engine(struct rte_eth_dev *dev __rte_unused)
     287                 :            : {
     288                 :            :         struct dh_flow_engine *engine = NULL;
     289                 :            :         void *temp;
     290                 :            : 
     291   [ #  #  #  #  :          0 :         RTE_TAILQ_FOREACH_SAFE(engine, &flow_engine_list, node, temp) {
          #  #  #  #  #  
                      # ]
     292   [ #  #  #  #  :          0 :                 if (engine->type  == FLOW_TYPE_FD_TCAM)
          #  #  #  #  #  
                      # ]
     293                 :            :                         break;
     294                 :            :         }
     295                 :            :         return engine;
     296                 :            : }
     297                 :            : 
     298                 :            : static int
     299                 :          0 : zxdh_flow_validate(struct rte_eth_dev *dev,
     300                 :            :                          const struct rte_flow_attr *attr,
     301                 :            :                          const struct rte_flow_item  *pattern,
     302                 :            :                          const struct rte_flow_action *actions,
     303                 :            :                          struct rte_flow_error *error)
     304                 :            : {
     305                 :            :         struct dh_flow_engine *flow_engine = NULL;
     306                 :            : 
     307         [ #  # ]:          0 :         if (!pattern) {
     308                 :          0 :                 rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM_NUM,
     309                 :            :                                    NULL, "NULL pattern.");
     310                 :          0 :                 return -rte_errno;
     311                 :            :         }
     312                 :            : 
     313         [ #  # ]:          0 :         if (!actions) {
     314                 :          0 :                 rte_flow_error_set(error, EINVAL,
     315                 :            :                                    RTE_FLOW_ERROR_TYPE_ACTION_NUM,
     316                 :            :                                    NULL, "NULL action.");
     317                 :          0 :                 return -rte_errno;
     318                 :            :         }
     319                 :            : 
     320         [ #  # ]:          0 :         if (!attr) {
     321                 :          0 :                 rte_flow_error_set(error, EINVAL,
     322                 :            :                                    RTE_FLOW_ERROR_TYPE_ATTR,
     323                 :            :                                    NULL, "NULL attribute.");
     324                 :          0 :                 return -rte_errno;
     325                 :            :         }
     326                 :            :         flow_engine = zxdh_get_flow_engine(dev);
     327   [ #  #  #  # ]:          0 :         if (flow_engine == NULL || flow_engine->parse_pattern_action == NULL) {
     328                 :          0 :                 rte_flow_error_set(error, EINVAL,
     329                 :            :                                    RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
     330                 :            :                                    NULL, "cannot find valid flow engine.");
     331                 :          0 :                 return -rte_errno;
     332                 :            :         }
     333         [ #  # ]:          0 :         if (flow_engine->parse_pattern_action(dev, attr, pattern, actions, error, NULL) != 0)
     334                 :          0 :                 return -rte_errno;
     335                 :            :         return 0;
     336                 :            : }
     337                 :            : 
     338                 :          0 : static struct zxdh_flow *flow_exist_check(struct rte_eth_dev *dev, struct zxdh_flow *dh_flow)
     339                 :            : {
     340                 :          0 :         struct zxdh_hw *hw = dev->data->dev_private;
     341                 :            :         struct rte_flow *entry;
     342                 :            :         struct zxdh_flow *entry_flow;
     343                 :            : 
     344         [ #  # ]:          0 :         TAILQ_FOREACH(entry, &hw->dh_flow_list, next) {
     345                 :          0 :                 entry_flow = (struct zxdh_flow *)entry->driver_flow;
     346         [ #  # ]:          0 :                 if ((memcmp(&entry_flow->flowentry.fd_flow.key, &dh_flow->flowentry.fd_flow.key,
     347                 :          0 :                                  sizeof(struct fd_flow_key)) == 0)  &&
     348                 :          0 :                         (memcmp(&entry_flow->flowentry.fd_flow.key_mask,
     349         [ #  # ]:          0 :                                 &dh_flow->flowentry.fd_flow.key_mask,
     350                 :            :                                  sizeof(struct fd_flow_key)) == 0)) {
     351                 :          0 :                         return entry_flow;
     352                 :            :                 }
     353                 :            :         }
     354                 :            :         return NULL;
     355                 :            : }
     356                 :            : 
     357                 :            : static struct rte_flow *
     358                 :          0 : zxdh_flow_create(struct rte_eth_dev *dev,
     359                 :            :                  const struct rte_flow_attr *attr,
     360                 :            :                  const struct rte_flow_item pattern[],
     361                 :            :                  const struct rte_flow_action actions[],
     362                 :            :                  struct rte_flow_error *error)
     363                 :            : {
     364                 :          0 :         struct zxdh_hw *hw = dev->data->dev_private;
     365                 :            :         struct rte_flow *flow = NULL;
     366                 :          0 :         struct zxdh_flow *dh_flow = NULL;
     367                 :            :         int ret = 0;
     368                 :            :         struct dh_flow_engine *flow_engine = NULL;
     369                 :            : 
     370                 :            :         flow_engine = zxdh_get_flow_engine(dev);
     371                 :            : 
     372         [ #  # ]:          0 :         if (flow_engine == NULL ||
     373         [ #  # ]:          0 :                 flow_engine->parse_pattern_action == NULL ||
     374         [ #  # ]:          0 :                 flow_engine->apply == NULL) {
     375                 :          0 :                 rte_flow_error_set(error, EINVAL,
     376                 :            :                                    RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
     377                 :            :                                    NULL, "cannot find valid flow engine.");
     378                 :          0 :                 return NULL;
     379                 :            :         }
     380                 :            : 
     381                 :          0 :         flow = rte_zmalloc("rte_flow", sizeof(struct rte_flow), 0);
     382         [ #  # ]:          0 :         if (!flow) {
     383                 :          0 :                 rte_flow_error_set(error, ENOMEM, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, "flow malloc failed");
     384                 :          0 :                 return NULL;
     385                 :            :         }
     386         [ #  # ]:          0 :         ret = rte_mempool_get(zxdh_shared_data->flow_mp, (void **)&dh_flow);
     387         [ #  # ]:          0 :         if (ret) {
     388                 :          0 :                 rte_flow_error_set(error, ENOMEM,
     389                 :            :                                    RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
     390                 :            :                                         "Failed to allocate memory from flowmp");
     391                 :          0 :                 goto free_flow;
     392                 :            :         }
     393                 :          0 :         memset(dh_flow, 0, sizeof(struct zxdh_flow));
     394         [ #  # ]:          0 :         if (flow_engine->parse_pattern_action(dev, attr, pattern, actions, error, dh_flow) != 0) {
     395                 :          0 :                 PMD_DRV_LOG(ERR, "parse_pattern_action failed zxdh_created failed");
     396                 :          0 :                 goto free_flow;
     397                 :            :         }
     398                 :            : 
     399         [ #  # ]:          0 :         if (flow_exist_check(dev, dh_flow) != NULL) {
     400                 :          0 :                 rte_flow_error_set(error, EINVAL,
     401                 :            :                                    RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
     402                 :            :                                         "duplicate entry: will not add");
     403                 :          0 :                 goto free_flow;
     404                 :            :         }
     405                 :            : 
     406                 :          0 :         ret = flow_engine->apply(dev, dh_flow, error, hw->vport.vport, hw->pcie_id);
     407         [ #  # ]:          0 :         if (ret) {
     408                 :          0 :                 PMD_DRV_LOG(ERR, "flow creation failed: failed to apply");
     409                 :          0 :                 goto free_flow;
     410                 :            :         }
     411                 :            : 
     412         [ #  # ]:          0 :         if (hw->i_flow_en == 0) {
     413                 :          0 :                 ret = set_flow_enable(dev, FLOW_INGRESS, 1, error);
     414         [ #  # ]:          0 :                 if (ret < 0) {
     415                 :          0 :                         PMD_DRV_LOG(ERR, "set flow enable failed");
     416                 :          0 :                         goto free_flow;
     417                 :            :                 }
     418                 :            :         }
     419                 :            : 
     420                 :          0 :         flow->driver_flow = dh_flow;
     421                 :          0 :         flow->port_id = dev->data->port_id;
     422                 :          0 :         flow->type = ZXDH_FLOW_GROUP_TCAM;
     423                 :          0 :         TAILQ_INSERT_TAIL(&hw->dh_flow_list, flow, next);
     424                 :            : 
     425                 :          0 :         return flow;
     426                 :          0 : free_flow:
     427                 :          0 :         zxdh_flow_free(dh_flow);
     428                 :          0 :         rte_free(flow);
     429                 :          0 :         return NULL;
     430                 :            : }
     431                 :            : 
     432                 :            : static int
     433                 :          0 : zxdh_flow_destroy(struct rte_eth_dev *dev,
     434                 :            :                   struct rte_flow *flow,
     435                 :            :                   struct rte_flow_error *error)
     436                 :            : {
     437                 :          0 :         struct zxdh_hw *priv = dev->data->dev_private;
     438                 :            :         struct zxdh_flow *dh_flow = NULL;
     439                 :            :         int ret = 0;
     440                 :            :         struct dh_flow_engine *flow_engine = NULL;
     441                 :            : 
     442                 :            :         flow_engine = zxdh_get_flow_engine(dev);
     443         [ #  # ]:          0 :         if (flow_engine == NULL ||
     444         [ #  # ]:          0 :                 flow_engine->destroy == NULL) {
     445                 :          0 :                 rte_flow_error_set(error, EINVAL,
     446                 :            :                                  RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
     447                 :            :                                  NULL, "cannot find valid flow engine.");
     448                 :          0 :                 return -rte_errno;
     449                 :            :         }
     450         [ #  # ]:          0 :         if (flow->driver_flow)
     451                 :            :                 dh_flow = (struct zxdh_flow *)flow->driver_flow;
     452                 :            : 
     453                 :            :         if (dh_flow == NULL) {
     454                 :          0 :                 PMD_DRV_LOG(ERR, "invalid flow");
     455                 :          0 :                 rte_flow_error_set(error, EINVAL,
     456                 :            :                                  RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
     457                 :            :                                  NULL, "invalid flow");
     458                 :          0 :                 return -1;
     459                 :            :         }
     460                 :          0 :         ret = flow_engine->destroy(dev, dh_flow, error, priv->vport.vport, priv->pcie_id);
     461         [ #  # ]:          0 :         if (ret) {
     462                 :          0 :                 rte_flow_error_set(error, -ret,
     463                 :            :                                    RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
     464                 :            :                                    "Failed to destroy flow.");
     465                 :          0 :                 return -rte_errno;
     466                 :            :         }
     467         [ #  # ]:          0 :         TAILQ_REMOVE(&priv->dh_flow_list, flow, next);
     468                 :          0 :         zxdh_flow_free(dh_flow);
     469                 :          0 :         rte_free(flow);
     470                 :            : 
     471         [ #  # ]:          0 :         if (TAILQ_EMPTY(&priv->dh_flow_list)) {
     472                 :          0 :                 ret = set_flow_enable(dev, FLOW_INGRESS, 0, error);
     473         [ #  # ]:          0 :                 if (ret) {
     474                 :          0 :                         PMD_DRV_LOG(ERR, "clear flow enable failed");
     475                 :          0 :                         return -rte_errno;
     476                 :            :                 }
     477                 :            :         }
     478                 :            :         return ret;
     479                 :            : }
     480                 :            : 
     481                 :            : 
     482                 :            : static int
     483                 :          0 : zxdh_flow_query(struct rte_eth_dev *dev,
     484                 :            :                 struct rte_flow *flow,
     485                 :            :                 const struct rte_flow_action *actions,
     486                 :            :                 void *data, struct rte_flow_error *error)
     487                 :            : {
     488                 :            :         struct zxdh_flow *dh_flow = NULL;
     489                 :            :         struct dh_flow_engine *flow_engine = NULL;
     490                 :            :         int ret = 0;
     491                 :            : 
     492                 :            :         flow_engine = zxdh_get_flow_engine(dev);
     493                 :            : 
     494         [ #  # ]:          0 :         if (flow_engine == NULL ||
     495         [ #  # ]:          0 :                 flow_engine->query_count == NULL) {
     496                 :          0 :                 rte_flow_error_set(error, EINVAL,
     497                 :            :                                    RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
     498                 :            :                                    NULL, "cannot find valid flow engine.");
     499                 :          0 :                 return -rte_errno;
     500                 :            :         }
     501                 :            : 
     502         [ #  # ]:          0 :         if (flow->driver_flow) {
     503                 :            :                 dh_flow = (struct zxdh_flow *)flow->driver_flow;
     504                 :            :                 if (dh_flow == NULL) {
     505                 :            :                         PMD_DRV_LOG(ERR, "flow does not exist");
     506                 :            :                         return -1;
     507                 :            :                 }
     508                 :            :         }
     509                 :            : 
     510         [ #  # ]:          0 :         for (; actions->type != RTE_FLOW_ACTION_TYPE_END; actions++) {
     511      [ #  #  # ]:          0 :                 switch (actions->type) {
     512                 :            :                 case RTE_FLOW_ACTION_TYPE_VOID:
     513                 :            :                         break;
     514                 :          0 :                 case RTE_FLOW_ACTION_TYPE_COUNT:
     515                 :          0 :                         ret = flow_engine->query_count(dev, dh_flow,
     516                 :            :                                                  (struct rte_flow_query_count *)data, error);
     517                 :          0 :                         break;
     518                 :          0 :                 default:
     519                 :          0 :                         ret = rte_flow_error_set(error, ENOTSUP,
     520                 :            :                                         RTE_FLOW_ERROR_TYPE_ACTION,
     521                 :            :                                         actions,
     522                 :            :                                         "action does not support QUERY");
     523                 :          0 :                         goto out;
     524                 :            :                 }
     525                 :            :         }
     526                 :          0 : out:
     527         [ #  # ]:          0 :         if (ret)
     528                 :          0 :                 PMD_DRV_LOG(ERR, "flow query failed");
     529                 :            :         return ret;
     530                 :            : }
     531                 :            : 
     532                 :          0 : static int zxdh_flow_flush(struct rte_eth_dev *dev, struct rte_flow_error *error)
     533                 :            : {
     534                 :            :         struct rte_flow *flow;
     535                 :            :         struct zxdh_flow *dh_flow = NULL;
     536                 :          0 :         struct zxdh_hw *hw = dev->data->dev_private;
     537                 :          0 :         struct zxdh_dtb_shared_data *dtb_data = &hw->dev_sd->dtb_sd;
     538                 :            :         struct dh_flow_engine *flow_engine = NULL;
     539                 :          0 :         struct zxdh_msg_info msg_info = {0};
     540                 :          0 :         uint8_t zxdh_msg_reply_info[ZXDH_ST_SZ_BYTES(msg_reply_info)] = {0};
     541                 :            :         int ret = 0;
     542                 :            : 
     543                 :            :         flow_engine = zxdh_get_flow_engine(dev);
     544         [ #  # ]:          0 :         if (flow_engine == NULL) {
     545                 :          0 :                 PMD_DRV_LOG(ERR, "get flow engine failed");
     546                 :          0 :                 return -1;
     547                 :            :         }
     548                 :          0 :         ret = set_flow_enable(dev, FLOW_INGRESS, 0, error);
     549         [ #  # ]:          0 :         if (ret) {
     550                 :          0 :                 PMD_DRV_LOG(ERR, "clear flow enable failed");
     551                 :          0 :                 return ret;
     552                 :            :         }
     553                 :            : 
     554                 :          0 :         ret = set_vxlan_enable(dev, 0, error);
     555         [ #  # ]:          0 :         if (ret)
     556                 :          0 :                 PMD_DRV_LOG(ERR, "clear vxlan enable failed");
     557                 :          0 :         hw->vxlan_fd_num = 0;
     558                 :            : 
     559         [ #  # ]:          0 :         if (hw->is_pf) {
     560                 :          0 :                 ret = zxdh_np_dtb_acl_offline_delete(hw->dev_id, dtb_data->queueid,
     561                 :          0 :                                         ZXDH_SDT_FD_TABLE, hw->vport.vport,
     562                 :            :                                         ZXDH_FLOW_STATS_INGRESS_BASE, 1);
     563         [ #  # ]:          0 :                 if (ret)
     564                 :          0 :                         PMD_DRV_LOG(ERR, "%s flush failed. code:%d", dev->data->name, ret);
     565                 :            :         } else {
     566                 :          0 :                 zxdh_msg_head_build(hw, ZXDH_FLOW_HW_FLUSH, &msg_info);
     567                 :          0 :                 ret = zxdh_vf_send_msg_to_pf(dev, &msg_info, sizeof(struct zxdh_msg_info),
     568                 :            :                         (void *)zxdh_msg_reply_info, ZXDH_ST_SZ_BYTES(msg_reply_info));
     569         [ #  # ]:          0 :                 if (ret) {
     570                 :          0 :                         PMD_DRV_LOG(ERR, "port %d flow op %d flush failed ret %d",
     571                 :            :                                 hw->port_id, ZXDH_FLOW_HW_FLUSH, ret);
     572                 :          0 :                         return -1;
     573                 :            :                 }
     574                 :            :         }
     575                 :            : 
     576                 :            :         /* Remove all flows */
     577         [ #  # ]:          0 :         while ((flow = TAILQ_FIRST(&hw->dh_flow_list))) {
     578         [ #  # ]:          0 :                 TAILQ_REMOVE(&hw->dh_flow_list, flow, next);
     579         [ #  # ]:          0 :                 if (flow->driver_flow)
     580                 :            :                         dh_flow = (struct zxdh_flow *)flow->driver_flow;
     581         [ #  # ]:          0 :                 if (dh_flow == NULL) {
     582                 :          0 :                         PMD_DRV_LOG(ERR, "Invalid flow Failed to destroy flow.");
     583                 :          0 :                         ret = rte_flow_error_set(error, ENOTSUP,
     584                 :            :                                         RTE_FLOW_ERROR_TYPE_HANDLE,
     585                 :            :                                         NULL,
     586                 :            :                                         "Invalid flow, flush failed");
     587                 :          0 :                         return ret;
     588                 :            :                 }
     589                 :            : 
     590                 :          0 :                 zxdh_flow_free(dh_flow);
     591                 :          0 :                 rte_free(flow);
     592                 :            :         }
     593                 :            :         return ret;
     594                 :            : }
     595                 :            : 
     596                 :            : static void
     597                 :          0 : handle_res_dump(struct rte_eth_dev *dev)
     598                 :            : {
     599                 :          0 :         struct zxdh_hw *priv =  dev->data->dev_private;
     600                 :          0 :         uint16_t hwres_base = priv->vport.pfid << 10;
     601                 :            :         uint16_t hwres_cnt = ZXDH_MAX_FLOW_NUM >> 1;
     602                 :            :         uint16_t i;
     603                 :            : 
     604                 :          0 :         PMD_DRV_LOG(DEBUG, "hwres_base %d", hwres_base);
     605                 :            :         rte_spinlock_lock(&fd_hw_res_lock);
     606         [ #  # ]:          0 :         for (i = 0; i < hwres_cnt; i++) {
     607         [ #  # ]:          0 :                 if (fd_hwres_bitmap[hwres_base + i] == 1)
     608                 :          0 :                         PMD_DRV_LOG(DEBUG, "used idx %d", i + hwres_base);
     609                 :            :         }
     610                 :            :         rte_spinlock_unlock(&fd_hw_res_lock);
     611                 :          0 : }
     612                 :            : 
     613                 :            : static int
     614                 :          0 : zxdh_flow_dev_dump(struct rte_eth_dev *dev,
     615                 :            :                         struct rte_flow *flow,
     616                 :            :                         FILE *file,
     617                 :            :                         struct rte_flow_error *error __rte_unused)
     618                 :            : {
     619                 :          0 :         struct zxdh_hw *hw =  dev->data->dev_private;
     620                 :            :         struct rte_flow *entry;
     621                 :            :         struct zxdh_flow *entry_flow;
     622                 :            :         uint32_t dtb_qid = 0;
     623                 :          0 :         uint32_t entry_num = 0;
     624                 :            :         uint16_t ret = 0;
     625                 :            :         ZXDH_DTB_ACL_ENTRY_INFO_T *fd_entry = NULL;
     626                 :            :         uint8_t *key = NULL;
     627                 :            :         uint8_t *key_mask = NULL;
     628                 :            :         uint8_t *result = NULL;
     629                 :            : 
     630         [ #  # ]:          0 :         if (flow) {
     631                 :          0 :                 entry_flow = flow_exist_check(dev, (struct zxdh_flow *)flow->driver_flow);
     632         [ #  # ]:          0 :                 if (entry_flow) {
     633                 :          0 :                         PMD_DRV_LOG(DEBUG, "handle idx %d:", entry_flow->flowentry.hw_idx);
     634                 :          0 :                         offlow_key_dump(&entry_flow->flowentry.fd_flow.key,
     635                 :            :                                 &entry_flow->flowentry.fd_flow.key_mask, file);
     636                 :          0 :                         offlow_result_dump(&entry_flow->flowentry.fd_flow.result, file);
     637                 :            :                 }
     638                 :            :         } else {
     639         [ #  # ]:          0 :                 if (hw->is_pf) {
     640                 :          0 :                         dtb_qid = hw->dev_sd->dtb_sd.queueid;
     641                 :          0 :                         fd_entry = calloc(1, sizeof(ZXDH_DTB_ACL_ENTRY_INFO_T) * ZXDH_MAX_FLOW_NUM);
     642                 :          0 :                         key = calloc(1, sizeof(struct fd_flow_key) * ZXDH_MAX_FLOW_NUM);
     643                 :          0 :                         key_mask = calloc(1, sizeof(struct fd_flow_key) * ZXDH_MAX_FLOW_NUM);
     644                 :          0 :                         result = calloc(1, sizeof(struct fd_flow_result) * ZXDH_MAX_FLOW_NUM);
     645   [ #  #  #  # ]:          0 :                         if (!fd_entry || !key || !key_mask || !result) {
     646                 :          0 :                                 PMD_DRV_LOG(ERR, "fd_entry malloc failed!");
     647                 :          0 :                                 goto end;
     648                 :            :                         }
     649                 :            : 
     650         [ #  # ]:          0 :                         for (int i = 0; i < ZXDH_MAX_FLOW_NUM; i++) {
     651                 :          0 :                                 fd_entry[i].key_data = key + i * sizeof(struct fd_flow_key);
     652                 :          0 :                                 fd_entry[i].key_mask = key_mask + i * sizeof(struct fd_flow_key);
     653                 :          0 :                                 fd_entry[i].p_as_rslt = result + i * sizeof(struct fd_flow_result);
     654                 :            :                         }
     655                 :          0 :                         ret = zxdh_np_dtb_acl_table_dump_by_vport(hw->dev_id, dtb_qid,
     656                 :          0 :                                                 ZXDH_SDT_FD_TABLE, hw->vport.vport, &entry_num,
     657                 :            :                                                 (uint8_t *)fd_entry);
     658         [ #  # ]:          0 :                         if (ret) {
     659                 :          0 :                                 PMD_DRV_LOG(ERR, "dpp_dtb_acl_table_dump_by_vport failed!");
     660                 :          0 :                                 goto end;
     661                 :            :                         }
     662         [ #  # ]:          0 :                         for (uint32_t i = 0; i < entry_num; i++) {
     663                 :          0 :                                 offlow_key_dump((struct fd_flow_key *)fd_entry[i].key_data,
     664                 :          0 :                                         (struct fd_flow_key *)fd_entry[i].key_mask, file);
     665                 :          0 :                                 offlow_result_dump((struct fd_flow_result *)fd_entry[i].p_as_rslt,
     666                 :            :                                                 file);
     667                 :            :                         }
     668                 :          0 :                         free(result);
     669                 :          0 :                         free(key_mask);
     670                 :          0 :                         free(key);
     671                 :          0 :                         free(fd_entry);
     672                 :            :                 } else {
     673                 :            :                         entry = calloc(1, sizeof(struct rte_flow));
     674                 :          0 :                         entry_flow = calloc(1, sizeof(struct zxdh_flow));
     675         [ #  # ]:          0 :                         TAILQ_FOREACH(entry, &hw->dh_flow_list, next) {
     676                 :          0 :                                 entry_flow = (struct zxdh_flow *)entry->driver_flow;
     677                 :          0 :                                 offlow_key_dump(&entry_flow->flowentry.fd_flow.key,
     678                 :            :                                                 &entry_flow->flowentry.fd_flow.key_mask, file);
     679                 :          0 :                                 offlow_result_dump(&entry_flow->flowentry.fd_flow.result, file);
     680                 :            :                         }
     681                 :          0 :                         free(entry_flow);
     682                 :            :                         free(entry);
     683                 :            :                 }
     684                 :            :         }
     685                 :          0 :         handle_res_dump(dev);
     686                 :            : 
     687                 :          0 :         return 0;
     688                 :          0 : end:
     689                 :          0 :         free(result);
     690                 :          0 :         free(key_mask);
     691                 :          0 :         free(key);
     692                 :          0 :         free(fd_entry);
     693                 :          0 :         return -1;
     694                 :            : }
     695                 :            : 
     696                 :            : static int32_t
     697                 :          0 : get_available_handle(struct zxdh_hw *hw, uint16_t vport)
     698                 :            : {
     699                 :            :         int ret = 0;
     700                 :          0 :         uint32_t handle_idx = 0;
     701                 :            : 
     702                 :          0 :         ret = zxdh_np_dtb_acl_index_request(hw->dev_id, ZXDH_SDT_FD_TABLE, vport, &handle_idx);
     703         [ #  # ]:          0 :         if (ret) {
     704                 :          0 :                 PMD_DRV_LOG(ERR, "Failed to allocate memory for hw!");
     705                 :          0 :                 return INVALID_HANDLEIDX;
     706                 :            :         }
     707                 :          0 :         return handle_idx;
     708                 :            : }
     709                 :            : 
     710                 :          0 : static int free_handle(struct zxdh_hw *hw, uint16_t handle_idx, uint16_t vport)
     711                 :            : {
     712                 :          0 :         int ret = zxdh_np_dtb_acl_index_release(hw->dev_id, ZXDH_SDT_FD_TABLE, vport, handle_idx);
     713                 :            : 
     714         [ #  # ]:          0 :         if (ret) {
     715                 :          0 :                 PMD_DRV_LOG(ERR, "Failed to free handle_idx %d for hw!", handle_idx);
     716                 :          0 :                 return -1;
     717                 :            :         }
     718                 :            :         return 0;
     719                 :            : }
     720                 :            : 
     721                 :            : static uint16_t
     722                 :          0 : zxdh_encap0_to_dtbentry(struct zxdh_hw *hw __rte_unused,
     723                 :            :                         struct zxdh_flow *dh_flow,
     724                 :            :                         ZXDH_DTB_USER_ENTRY_T *dtb_entry)
     725                 :            : {
     726                 :            :         ZXDH_DTB_ERAM_ENTRY_INFO_T *dtb_eram_entry;
     727                 :          0 :         dtb_eram_entry = rte_zmalloc(NULL, sizeof(ZXDH_DTB_ERAM_ENTRY_INFO_T), 0);
     728                 :            : 
     729         [ #  # ]:          0 :         if (dtb_eram_entry == NULL)
     730                 :            :                 return INVALID_HANDLEIDX;
     731                 :            : 
     732                 :          0 :         dtb_eram_entry->index = dh_flow->flowentry.fd_flow.result.encap0_index * 2;
     733                 :          0 :         dtb_eram_entry->p_data = (uint32_t *)&dh_flow->encap0;
     734                 :            : 
     735                 :          0 :         dtb_entry->sdt_no = ZXDH_SDT_TUNNEL_ENCAP0_TABLE;
     736                 :          0 :         dtb_entry->p_entry_data = dtb_eram_entry;
     737                 :          0 :         return 0;
     738                 :            : }
     739                 :            : 
     740                 :            : static uint16_t
     741                 :          0 : zxdh_encap0_ip_to_dtbentry(struct zxdh_hw *hw __rte_unused,
     742                 :            :                         struct zxdh_flow *dh_flow,
     743                 :            :                         ZXDH_DTB_USER_ENTRY_T *dtb_entry)
     744                 :            : {
     745                 :            :         ZXDH_DTB_ERAM_ENTRY_INFO_T *dtb_eram_entry;
     746                 :          0 :         dtb_eram_entry = rte_zmalloc(NULL, sizeof(ZXDH_DTB_ERAM_ENTRY_INFO_T), 0);
     747                 :            : 
     748         [ #  # ]:          0 :         if (dtb_eram_entry == NULL)
     749                 :            :                 return INVALID_HANDLEIDX;
     750                 :            : 
     751                 :          0 :         dtb_eram_entry->index = dh_flow->flowentry.fd_flow.result.encap0_index * 2 + 1;
     752                 :          0 :         dtb_eram_entry->p_data = (uint32_t *)&dh_flow->encap0.dip;
     753                 :          0 :         dtb_entry->sdt_no = ZXDH_SDT_TUNNEL_ENCAP0_TABLE;
     754                 :          0 :         dtb_entry->p_entry_data = dtb_eram_entry;
     755                 :          0 :         return 0;
     756                 :            : }
     757                 :            : 
     758                 :          0 : static uint16_t zxdh_encap1_to_dtbentry(struct zxdh_hw *hw __rte_unused,
     759                 :            :                                                          struct zxdh_flow *dh_flow,
     760                 :            :                                                          ZXDH_DTB_USER_ENTRY_T *dtb_entry)
     761                 :            : {
     762                 :            :         ZXDH_DTB_ERAM_ENTRY_INFO_T *dtb_eram_entry;
     763                 :          0 :         dtb_eram_entry = rte_zmalloc(NULL, sizeof(ZXDH_DTB_ERAM_ENTRY_INFO_T), 0);
     764                 :            : 
     765         [ #  # ]:          0 :         if (dtb_eram_entry == NULL)
     766                 :            :                 return INVALID_HANDLEIDX;
     767                 :            : 
     768         [ #  # ]:          0 :         if (dh_flow->encap0.ethtype == 0)
     769                 :          0 :                 dtb_eram_entry->index = dh_flow->flowentry.fd_flow.result.encap1_index * 4;
     770                 :            :         else
     771                 :          0 :                 dtb_eram_entry->index = dh_flow->flowentry.fd_flow.result.encap1_index * 4 + 1;
     772                 :            : 
     773                 :          0 :         dtb_eram_entry->p_data = (uint32_t *)&dh_flow->encap1;
     774                 :            : 
     775                 :          0 :         dtb_entry->sdt_no = ZXDH_SDT_TUNNEL_ENCAP1_TABLE;
     776                 :          0 :         dtb_entry->p_entry_data = dtb_eram_entry;
     777                 :          0 :         return 0;
     778                 :            : }
     779                 :            : 
     780                 :            : static uint16_t
     781                 :          0 : zxdh_encap1_ip_to_dtbentry(struct zxdh_hw *hw __rte_unused,
     782                 :            :                         struct zxdh_flow *dh_flow,
     783                 :            :                         ZXDH_DTB_USER_ENTRY_T *dtb_entry)
     784                 :            : {
     785                 :            :         ZXDH_DTB_ERAM_ENTRY_INFO_T *dtb_eram_entry;
     786                 :          0 :         dtb_eram_entry = rte_zmalloc(NULL, sizeof(ZXDH_DTB_ERAM_ENTRY_INFO_T), 0);
     787                 :            : 
     788         [ #  # ]:          0 :         if (dtb_eram_entry == NULL)
     789                 :            :                 return INVALID_HANDLEIDX;
     790         [ #  # ]:          0 :         if (dh_flow->encap0.ethtype == 0)
     791                 :          0 :                 dtb_eram_entry->index = dh_flow->flowentry.fd_flow.result.encap1_index * 4 + 2;
     792                 :            :         else
     793                 :          0 :                 dtb_eram_entry->index = dh_flow->flowentry.fd_flow.result.encap1_index * 4 + 3;
     794                 :          0 :         dtb_eram_entry->p_data = (uint32_t *)&dh_flow->encap1.sip;
     795                 :          0 :         dtb_entry->sdt_no = ZXDH_SDT_TUNNEL_ENCAP1_TABLE;
     796                 :          0 :         dtb_entry->p_entry_data = dtb_eram_entry;
     797                 :          0 :         return 0;
     798                 :            : }
     799                 :            : 
     800                 :          0 : static int zxdh_hw_encap_insert(struct rte_eth_dev *dev,
     801                 :            :                                         struct zxdh_flow *dh_flow,
     802                 :            :                                         struct rte_flow_error *error)
     803                 :            : {
     804                 :            :         uint32_t ret;
     805                 :          0 :         struct zxdh_hw *hw = dev->data->dev_private;
     806                 :          0 :         uint32_t dtb_qid = hw->dev_sd->dtb_sd.queueid;
     807                 :          0 :         ZXDH_DTB_USER_ENTRY_T dtb_entry = {0};
     808                 :            : 
     809                 :          0 :         zxdh_encap0_to_dtbentry(hw, dh_flow, &dtb_entry);
     810                 :          0 :         ret = zxdh_np_dtb_table_entry_write(hw->dev_id, dtb_qid, 1, &dtb_entry);
     811                 :            :         zxdh_fd_flow_free_dtbentry(&dtb_entry);
     812         [ #  # ]:          0 :         if (ret) {
     813                 :          0 :                 rte_flow_error_set(error, EINVAL,
     814                 :            :                                                         RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
     815                 :            :                                                         "write to hw failed");
     816                 :          0 :                 return -1;
     817                 :            :         }
     818                 :            : 
     819                 :          0 :         zxdh_encap0_ip_to_dtbentry(hw, dh_flow, &dtb_entry);
     820                 :          0 :         ret = zxdh_np_dtb_table_entry_write(hw->dev_id, dtb_qid, 1, &dtb_entry);
     821                 :            :         zxdh_fd_flow_free_dtbentry(&dtb_entry);
     822         [ #  # ]:          0 :         if (ret) {
     823                 :          0 :                 rte_flow_error_set(error, EINVAL,
     824                 :            :                                 RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
     825                 :            :                                 "write to hw failed");
     826                 :          0 :                 return -1;
     827                 :            :         }
     828                 :            : 
     829                 :          0 :         zxdh_encap1_to_dtbentry(hw, dh_flow, &dtb_entry);
     830                 :          0 :         ret = zxdh_np_dtb_table_entry_write(hw->dev_id, dtb_qid, 1, &dtb_entry);
     831                 :            :         zxdh_fd_flow_free_dtbentry(&dtb_entry);
     832         [ #  # ]:          0 :         if (ret) {
     833                 :          0 :                 rte_flow_error_set(error, EINVAL,
     834                 :            :                                         RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
     835                 :            :                                         "write to hw failed");
     836                 :          0 :                 return -1;
     837                 :            :         }
     838                 :            : 
     839                 :          0 :         zxdh_encap1_ip_to_dtbentry(hw, dh_flow, &dtb_entry);
     840                 :          0 :         ret = zxdh_np_dtb_table_entry_write(hw->dev_id, dtb_qid, 1, &dtb_entry);
     841                 :            :         zxdh_fd_flow_free_dtbentry(&dtb_entry);
     842         [ #  # ]:          0 :         if (ret) {
     843                 :          0 :                 rte_flow_error_set(error, EINVAL,
     844                 :            :                                         RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
     845                 :            :                                         "write to hw failed");
     846                 :          0 :                 return -1;
     847                 :            :         }
     848                 :            :         return 0;
     849                 :            : }
     850                 :            : 
     851                 :            : static uint16_t
     852                 :          0 : zxdh_fd_flow_to_dtbentry(struct zxdh_hw *hw __rte_unused,
     853                 :            :                 struct zxdh_flow_info *fdflow,
     854                 :            :                 ZXDH_DTB_USER_ENTRY_T *dtb_entry)
     855                 :            : {
     856                 :            :         ZXDH_DTB_ACL_ENTRY_INFO_T *dtb_acl_entry;
     857                 :            :         uint16_t handle_idx = 0;
     858                 :          0 :         dtb_acl_entry = rte_zmalloc("fdflow_dtbentry", sizeof(ZXDH_DTB_ACL_ENTRY_INFO_T), 0);
     859                 :            : 
     860         [ #  # ]:          0 :         if (dtb_acl_entry == NULL)
     861                 :            :                 return INVALID_HANDLEIDX;
     862                 :            : 
     863                 :          0 :         dtb_acl_entry->key_data = (uint8_t *)&fdflow->fd_flow.key;
     864                 :          0 :         dtb_acl_entry->key_mask = (uint8_t *)&fdflow->fd_flow.key_mask;
     865                 :          0 :         dtb_acl_entry->p_as_rslt = (uint8_t *)&fdflow->fd_flow.result;
     866                 :            : 
     867                 :          0 :         handle_idx = fdflow->hw_idx;
     868                 :            : 
     869         [ #  # ]:          0 :         if (handle_idx >= ZXDH_MAX_FLOW_NUM) {
     870                 :          0 :                 rte_free(dtb_acl_entry);
     871                 :          0 :                 return INVALID_HANDLEIDX;
     872                 :            :         }
     873                 :          0 :         dtb_acl_entry->handle = handle_idx;
     874                 :          0 :         dtb_entry->sdt_no = ZXDH_SDT_FD_TABLE;
     875                 :          0 :         dtb_entry->p_entry_data = dtb_acl_entry;
     876                 :          0 :         return handle_idx;
     877                 :            : }
     878                 :            : 
     879                 :          0 : static int zxdh_hw_flow_insert(struct rte_eth_dev *dev,
     880                 :            :                                                                 struct zxdh_flow *dh_flow,
     881                 :            :                                                                 struct rte_flow_error *error,
     882                 :            :                                                                 uint16_t vport)
     883                 :            : {
     884                 :          0 :         struct zxdh_hw *hw = dev->data->dev_private;
     885                 :          0 :         uint32_t dtb_qid = hw->dev_sd->dtb_sd.queueid;
     886                 :          0 :         ZXDH_DTB_USER_ENTRY_T dtb_entry = {0};
     887                 :            :         uint32_t ret;
     888                 :            :         uint16_t handle_idx;
     889                 :            : 
     890                 :          0 :         struct zxdh_flow_info *flow = &dh_flow->flowentry;
     891                 :          0 :         handle_idx = zxdh_fd_flow_to_dtbentry(hw, flow, &dtb_entry);
     892         [ #  # ]:          0 :         if (handle_idx == INVALID_HANDLEIDX) {
     893                 :          0 :                 rte_flow_error_set(error, EINVAL,
     894                 :            :                                                  RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
     895                 :            :                                                  "Failed to allocate memory for hw");
     896                 :          0 :                 return -1;
     897                 :            :         }
     898                 :          0 :         ret = zxdh_np_dtb_table_entry_write(hw->dev_id, dtb_qid, 1, &dtb_entry);
     899                 :            :         zxdh_fd_flow_free_dtbentry(&dtb_entry);
     900         [ #  # ]:          0 :         if (ret) {
     901                 :          0 :                 ret = free_handle(hw, handle_idx, vport);
     902         [ #  # ]:          0 :                 if (ret) {
     903                 :          0 :                         rte_flow_error_set(error, EINVAL,
     904                 :            :                                                  RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
     905                 :            :                                                  "release handle_idx to hw failed");
     906                 :          0 :                         return -1;
     907                 :            :                 }
     908                 :          0 :                 rte_flow_error_set(error, EINVAL,
     909                 :            :                                                  RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
     910                 :            :                                                  "write to hw failed");
     911                 :          0 :                 return -1;
     912                 :            :         }
     913                 :          0 :         dh_flow->flowentry.hw_idx = handle_idx;
     914                 :          0 :         return 0;
     915                 :            : }
     916                 :            : 
     917                 :            : static int
     918                 :          0 : hw_count_query(struct zxdh_hw *hw, uint32_t countid, bool clear,
     919                 :            :                 struct flow_stats *fstats, struct rte_flow_error *error)
     920                 :            : {
     921                 :            :         uint32_t stats_id = 0;
     922                 :            :         int ret = 0;
     923                 :            :         stats_id = countid;
     924         [ #  # ]:          0 :         if (stats_id >= ZXDH_MAX_FLOW_NUM) {
     925                 :          0 :                 PMD_DRV_LOG(DEBUG, "query count id %d invalid", stats_id);
     926                 :          0 :                 ret = rte_flow_error_set(error, ENODEV,
     927                 :            :                                  RTE_FLOW_ERROR_TYPE_HANDLE,
     928                 :            :                                  NULL,
     929                 :            :                                  "query count id invalid");
     930                 :          0 :                 return -rte_errno;
     931                 :            :         }
     932                 :          0 :         PMD_DRV_LOG(DEBUG, "query count id %d,clear %d ", stats_id, clear);
     933         [ #  # ]:          0 :         if (!clear)
     934                 :          0 :                 ret = zxdh_np_dtb_stats_get(hw->dev_id, hw->dev_sd->dtb_sd.queueid, 1,
     935                 :            :                                         stats_id + ZXDH_FLOW_STATS_INGRESS_BASE,
     936                 :            :                                         (uint32_t *)fstats);
     937                 :            :         else
     938                 :          0 :                 ret = zxdh_np_stat_ppu_cnt_get_ex(hw->dev_id, 1,
     939                 :            :                                         stats_id + ZXDH_FLOW_STATS_INGRESS_BASE,
     940                 :            :                                         1, (uint32_t *)fstats);
     941         [ #  # ]:          0 :         if (ret)
     942                 :          0 :                 rte_flow_error_set(error, EINVAL,
     943                 :            :                                  RTE_FLOW_ERROR_TYPE_ACTION, NULL,
     944                 :            :                                          "fail to get flow stats");
     945                 :            :         return ret;
     946                 :            : }
     947                 :            : 
     948                 :            : static int
     949                 :          0 : count_deref(struct zxdh_hw *hw, uint32_t countid,
     950                 :            :                 struct rte_flow_error *error)
     951                 :            : {
     952                 :            :         int ret = 0;
     953                 :            :         struct count_res *count_res = &flow_count_ref[countid];
     954                 :          0 :         struct flow_stats fstats = {0};
     955                 :            : 
     956                 :          0 :         rte_spinlock_lock(&count_res->count_lock);
     957                 :            : 
     958         [ #  # ]:          0 :         if (count_res->count_ref >= 1) {
     959                 :          0 :                 count_res->count_ref--;
     960                 :            :         } else {
     961                 :            :                 rte_spinlock_unlock(&count_res->count_lock);
     962                 :          0 :                 return rte_flow_error_set(error, ENOTSUP,
     963                 :            :                                          RTE_FLOW_ERROR_TYPE_ACTION_CONF,
     964                 :            :                                          NULL,
     965                 :            :                                          "count deref underflow");
     966                 :            :         }
     967         [ #  # ]:          0 :         if (count_res->count_ref == 0)
     968                 :          0 :                 ret = hw_count_query(hw, countid, 1, &fstats, error);
     969                 :            : 
     970                 :            :         rte_spinlock_unlock(&count_res->count_lock);
     971                 :          0 :         return ret;
     972                 :            : }
     973                 :            : 
     974                 :            : static int
     975                 :          0 : count_ref(struct zxdh_hw *hw, uint32_t countid, struct rte_flow_error *error)
     976                 :            : {
     977                 :            :         int ret = 0;
     978                 :            :         struct count_res *count_res = &flow_count_ref[countid];
     979                 :          0 :         struct flow_stats fstats = {0};
     980                 :            : 
     981                 :          0 :         rte_spinlock_lock(&count_res->count_lock);
     982         [ #  # ]:          0 :         if (count_res->count_ref < 255) {
     983                 :          0 :                 count_res->count_ref++;
     984                 :            :         } else {
     985                 :            :                 rte_spinlock_unlock(&count_res->count_lock);
     986                 :          0 :                 return rte_flow_error_set(error, ENOTSUP,
     987                 :            :                                          RTE_FLOW_ERROR_TYPE_ACTION_CONF,
     988                 :            :                                          NULL,
     989                 :            :                                          "count ref overflow");
     990                 :            :         }
     991                 :            : 
     992         [ #  # ]:          0 :         if (count_res->count_ref == 1)
     993                 :          0 :                 ret = hw_count_query(hw, countid, 1, &fstats, error);
     994                 :            : 
     995                 :            :         rte_spinlock_unlock(&count_res->count_lock);
     996                 :          0 :         return ret;
     997                 :            : }
     998                 :            : 
     999                 :            : int
    1000                 :          0 : pf_fd_hw_apply(struct rte_eth_dev *dev, struct zxdh_flow *dh_flow,
    1001                 :            :                 struct rte_flow_error *error, uint16_t vport, uint16_t pcieid)
    1002                 :            : {
    1003                 :            :         int ret = 0;
    1004                 :          0 :         struct zxdh_hw *hw = dev->data->dev_private;
    1005                 :            :         uint8_t vf_index = 0;
    1006                 :          0 :         uint8_t action_bits = dh_flow->flowentry.fd_flow.result.action_idx;
    1007                 :            :         uint32_t countid  = MAX_FLOW_COUNT_NUM;
    1008                 :            :         uint32_t handle_idx = 0;
    1009                 :            :         union zxdh_virport_num port = {0};
    1010                 :            : 
    1011                 :            :         port.vport = vport;
    1012                 :          0 :         handle_idx = get_available_handle(hw, vport);
    1013         [ #  # ]:          0 :         if (handle_idx >= ZXDH_MAX_FLOW_NUM) {
    1014                 :          0 :                 rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_HANDLE, NULL, "Failed to allocate memory for hw");
    1015                 :          0 :                 return -1;
    1016                 :            :         }
    1017                 :          0 :         dh_flow->flowentry.hw_idx = handle_idx;
    1018         [ #  # ]:          0 :         if ((action_bits & (1 << FD_ACTION_COUNT_BIT)) != 0) {
    1019                 :            :                 countid = handle_idx;
    1020                 :          0 :                 dh_flow->flowentry.fd_flow.result.countid = countid;
    1021                 :            :         }
    1022                 :            : 
    1023         [ #  # ]:          0 :         if ((action_bits & (1 << FD_ACTION_VXLAN_ENCAP)) != 0) {
    1024                 :          0 :                 dh_flow->flowentry.fd_flow.result.encap0_index = handle_idx;
    1025         [ #  # ]:          0 :                 if (!port.vf_flag) {
    1026                 :          0 :                         dh_flow->flowentry.fd_flow.result.encap1_index =
    1027                 :          0 :                                 hw->hash_search_index * MAX_ENCAP1_NUM;
    1028                 :            :                 } else {
    1029                 :          0 :                         vf_index = VF_IDX(pcieid);
    1030         [ #  # ]:          0 :                         if (vf_index < (ZXDH_MAX_VF - 1)) {
    1031                 :          0 :                                 dh_flow->flowentry.fd_flow.result.encap1_index =
    1032                 :          0 :                                         hw->hash_search_index * MAX_ENCAP1_NUM + vf_index + 1;
    1033                 :            :                         } else {
    1034                 :          0 :                                 rte_flow_error_set(error, EINVAL,
    1035                 :            :                                                 RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
    1036                 :            :                                                 "encap1 vf_index is too big");
    1037                 :          0 :                                 return -1;
    1038                 :            :                         }
    1039                 :            :                 }
    1040                 :          0 :                 PMD_DRV_LOG(DEBUG, "encap_index (%d)(%d)",
    1041                 :            :                                 dh_flow->flowentry.fd_flow.result.encap0_index,
    1042                 :            :                                 dh_flow->flowentry.fd_flow.result.encap1_index);
    1043         [ #  # ]:          0 :                 if (zxdh_hw_encap_insert(dev, dh_flow, error) != 0)
    1044                 :            :                         return -1;
    1045                 :            :         }
    1046                 :          0 :         ret = zxdh_hw_flow_insert(dev, dh_flow, error, vport);
    1047         [ #  # ]:          0 :         if (!ret && countid < MAX_FLOW_COUNT_NUM)
    1048                 :          0 :                 ret = count_ref(hw, countid, error);
    1049                 :            : 
    1050         [ #  # ]:          0 :         if (!ret) {
    1051         [ #  # ]:          0 :                 if (!port.vf_flag) {
    1052         [ #  # ]:          0 :                         if (((action_bits & (1 << FD_ACTION_VXLAN_ENCAP)) != 0) ||
    1053                 :            :                                 ((action_bits & (1 << FD_ACTION_VXLAN_DECAP)) != 0)) {
    1054                 :          0 :                                 hw->vxlan_fd_num++;
    1055         [ #  # ]:          0 :                                 if (hw->vxlan_fd_num == 1)
    1056                 :          0 :                                         set_vxlan_enable(dev, 1, error);
    1057                 :            :                         }
    1058                 :            :                 }
    1059                 :            :         }
    1060                 :            : 
    1061                 :            :         return ret;
    1062                 :            : }
    1063                 :            : 
    1064                 :            : static int
    1065                 :          0 : zxdh_hw_flow_del(struct rte_eth_dev *dev,
    1066                 :            :                                                         struct zxdh_flow *dh_flow,
    1067                 :            :                                                         struct rte_flow_error *error,
    1068                 :            :                                                         uint16_t vport)
    1069                 :            : {
    1070                 :          0 :         struct zxdh_flow_info *flow = &dh_flow->flowentry;
    1071                 :          0 :         ZXDH_DTB_USER_ENTRY_T dtb_entry = {0};
    1072                 :          0 :         struct zxdh_hw *hw = dev->data->dev_private;
    1073                 :          0 :         uint32_t dtb_qid = hw->dev_sd->dtb_sd.queueid;
    1074                 :            :         uint32_t ret;
    1075                 :            :         uint16_t handle_idx;
    1076                 :            : 
    1077                 :          0 :         handle_idx = zxdh_fd_flow_to_dtbentry(hw, flow, &dtb_entry);
    1078         [ #  # ]:          0 :         if (handle_idx >= ZXDH_MAX_FLOW_NUM) {
    1079                 :          0 :                 rte_flow_error_set(error, EINVAL,
    1080                 :            :                                                  RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
    1081                 :            :                                                  "Failed to allocate memory for hw");
    1082                 :          0 :                 return -1;
    1083                 :            :         }
    1084                 :          0 :         ret = zxdh_np_dtb_table_entry_delete(hw->dev_id, dtb_qid, 1, &dtb_entry);
    1085                 :            :         zxdh_fd_flow_free_dtbentry(&dtb_entry);
    1086         [ #  # ]:          0 :         if (ret) {
    1087                 :          0 :                 rte_flow_error_set(error, EINVAL,
    1088                 :            :                                                  RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
    1089                 :            :                                                  "delete to hw failed");
    1090                 :          0 :                 return -1;
    1091                 :            :         }
    1092                 :          0 :         ret = free_handle(hw, handle_idx, vport);
    1093         [ #  # ]:          0 :         if (ret) {
    1094                 :          0 :                 rte_flow_error_set(error, EINVAL,
    1095                 :            :                                                 RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
    1096                 :            :                                                 "release handle_idx to hw failed");
    1097                 :          0 :                 return -1;
    1098                 :            :         }
    1099                 :          0 :         PMD_DRV_LOG(DEBUG, "release handle_idx to hw success! %d", handle_idx);
    1100                 :          0 :         return ret;
    1101                 :            : }
    1102                 :            : 
    1103                 :            : int
    1104                 :          0 : pf_fd_hw_destroy(struct rte_eth_dev *dev, struct zxdh_flow *dh_flow,
    1105                 :            :                 struct rte_flow_error *error, uint16_t vport,
    1106                 :            :                 uint16_t pcieid __rte_unused)
    1107                 :            : {
    1108                 :          0 :         struct zxdh_hw *hw = dev->data->dev_private;
    1109                 :            :         union zxdh_virport_num port = {0};
    1110                 :            :         int ret = 0;
    1111                 :            : 
    1112                 :            :         port.vport = vport;
    1113                 :          0 :         ret = zxdh_hw_flow_del(dev, dh_flow, error, vport);
    1114                 :          0 :         PMD_DRV_LOG(DEBUG, "destroy handle id %d", dh_flow->flowentry.hw_idx);
    1115         [ #  # ]:          0 :         if (!ret) {
    1116                 :          0 :                 uint8_t action_bits = dh_flow->flowentry.fd_flow.result.action_idx;
    1117                 :            :                 uint32_t countid;
    1118                 :          0 :                 countid = dh_flow->flowentry.hw_idx;
    1119         [ #  # ]:          0 :                 if ((action_bits & (1 << FD_ACTION_COUNT_BIT)) != 0)
    1120                 :          0 :                         ret = count_deref(hw, countid, error);
    1121         [ #  # ]:          0 :                 if (!port.vf_flag) {
    1122         [ #  # ]:          0 :                         if (((action_bits & (1 << FD_ACTION_VXLAN_ENCAP)) != 0) ||
    1123                 :            :                                 ((action_bits & (1 << FD_ACTION_VXLAN_DECAP)) != 0)) {
    1124                 :          0 :                                 hw->vxlan_fd_num--;
    1125         [ #  # ]:          0 :                                 if (hw->vxlan_fd_num == 0)
    1126                 :          0 :                                         set_vxlan_enable(dev, 0, error);
    1127                 :            :                         }
    1128                 :            :                 }
    1129                 :            :         }
    1130                 :          0 :         return ret;
    1131                 :            : }
    1132                 :            : 
    1133                 :            : static int
    1134                 :          0 : zxdh_hw_flow_query(struct rte_eth_dev *dev, struct zxdh_flow *dh_flow,
    1135                 :            :                 struct rte_flow_error *error)
    1136                 :            : {
    1137                 :          0 :         struct zxdh_hw *hw = dev->data->dev_private;
    1138                 :            :         int ret = 0;
    1139                 :          0 :         struct zxdh_flow_info *flow = &dh_flow->flowentry;
    1140                 :            :         ZXDH_DTB_USER_ENTRY_T dtb_entry;
    1141                 :            :         uint16_t handle_idx;
    1142                 :            : 
    1143                 :          0 :         handle_idx = zxdh_fd_flow_to_dtbentry(hw, flow, &dtb_entry);
    1144         [ #  # ]:          0 :         if (handle_idx >= ZXDH_MAX_FLOW_NUM) {
    1145                 :          0 :                 rte_flow_error_set(error, EINVAL,
    1146                 :            :                                 RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
    1147                 :            :                                 "Failed to build hw entry for query");
    1148                 :            :                 ret = -1;
    1149                 :          0 :                 goto free_res;
    1150                 :            :         }
    1151                 :          0 :         ret = zxdh_np_dtb_table_entry_get(hw->dev_id, hw->dev_sd->dtb_sd.queueid, &dtb_entry, 0);
    1152         [ #  # ]:          0 :         if (ret != 0) {
    1153                 :          0 :                 rte_flow_error_set(error, EINVAL,
    1154                 :            :                                 RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
    1155                 :            :                                 "Failed query  entry from hw ");
    1156                 :          0 :                 goto free_res;
    1157                 :            :         }
    1158                 :            : 
    1159                 :          0 : free_res:
    1160                 :            :         zxdh_fd_flow_free_dtbentry(&dtb_entry);
    1161                 :          0 :         return ret;
    1162                 :            : }
    1163                 :            : 
    1164                 :            : int
    1165                 :          0 : pf_fd_hw_query_count(struct rte_eth_dev *dev,
    1166                 :            :                         struct zxdh_flow *flow,
    1167                 :            :                         struct rte_flow_query_count *count,
    1168                 :            :                         struct rte_flow_error *error)
    1169                 :            : {
    1170                 :          0 :         struct zxdh_hw *hw =  dev->data->dev_private;
    1171                 :          0 :         struct flow_stats  fstats = {0};
    1172                 :            :         int ret = 0;
    1173                 :            :         uint32_t countid;
    1174                 :            : 
    1175                 :          0 :         memset(&flow->flowentry.fd_flow.result, 0, sizeof(struct fd_flow_result));
    1176                 :          0 :         ret = zxdh_hw_flow_query(dev, flow, error);
    1177         [ #  # ]:          0 :         if (ret) {
    1178                 :          0 :                 ret = rte_flow_error_set(error, ENODEV,
    1179                 :            :                                  RTE_FLOW_ERROR_TYPE_HANDLE,
    1180                 :            :                                  NULL,
    1181                 :            :                                  "query failed");
    1182                 :          0 :                 return -rte_errno;
    1183                 :            :         }
    1184                 :          0 :         countid = flow->flowentry.hw_idx;
    1185         [ #  # ]:          0 :         if (countid >= ZXDH_MAX_FLOW_NUM) {
    1186                 :          0 :                 ret = rte_flow_error_set(error, ENODEV,
    1187                 :            :                                  RTE_FLOW_ERROR_TYPE_HANDLE,
    1188                 :            :                                  NULL,
    1189                 :            :                                  "query count id invalid");
    1190                 :          0 :                 return -rte_errno;
    1191                 :            :         }
    1192                 :          0 :         ret = hw_count_query(hw, countid, 0, &fstats, error);
    1193         [ #  # ]:          0 :         if (ret) {
    1194                 :          0 :                 rte_flow_error_set(error, EINVAL,
    1195                 :            :                                  RTE_FLOW_ERROR_TYPE_ACTION, NULL,
    1196                 :            :                                          "fail to get flow stats");
    1197                 :          0 :                         return ret;
    1198                 :            :         }
    1199                 :          0 :         count->bytes = (uint64_t)(rte_le_to_cpu_32(fstats.hit_bytes_hi)) << 32 |
    1200                 :          0 :                                         rte_le_to_cpu_32(fstats.hit_bytes_lo);
    1201                 :          0 :         count->hits = (uint64_t)(rte_le_to_cpu_32(fstats.hit_pkts_hi)) << 32 |
    1202                 :          0 :                                         rte_le_to_cpu_32(fstats.hit_pkts_lo);
    1203                 :          0 :         return ret;
    1204                 :            : }
    1205                 :            : 
    1206                 :            : static int
    1207                 :          0 : fd_flow_parse_attr(struct rte_eth_dev *dev __rte_unused,
    1208                 :            :                 const struct rte_flow_attr *attr,
    1209                 :            :                 struct rte_flow_error *error,
    1210                 :            :                 struct zxdh_flow *dh_flow)
    1211                 :            : {
    1212                 :            :         /* Not supported */
    1213         [ #  # ]:          0 :         if (attr->priority) {
    1214                 :          0 :                 rte_flow_error_set(error, EINVAL,
    1215                 :            :                                    RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY,
    1216                 :            :                                    attr, "Not support priority.");
    1217                 :          0 :                 return -rte_errno;
    1218                 :            :         }
    1219                 :            : 
    1220                 :            :         /* Not supported */
    1221         [ #  # ]:          0 :         if (attr->group >= MAX_GROUP) {
    1222                 :          0 :                 rte_flow_error_set(error, EINVAL,
    1223                 :            :                                    RTE_FLOW_ERROR_TYPE_ATTR_GROUP,
    1224                 :            :                                    attr, "Not support group.");
    1225                 :          0 :                 return -rte_errno;
    1226                 :            :         }
    1227                 :            : 
    1228         [ #  # ]:          0 :         if (dh_flow) {
    1229                 :          0 :                 dh_flow->group = attr->group;
    1230                 :          0 :                 dh_flow->direct = (attr->ingress == 1) ? 0 : 1;
    1231                 :          0 :                 dh_flow->pri = attr->priority;
    1232                 :            :         }
    1233                 :            : 
    1234                 :            :         return 0;
    1235                 :            : }
    1236                 :            : 
    1237                 :          0 : static int fd_flow_parse_pattern(struct rte_eth_dev *dev, const struct rte_flow_item *items,
    1238                 :            :                          struct rte_flow_error *error, struct zxdh_flow *dh_flow)
    1239                 :            : {
    1240                 :          0 :         struct zxdh_hw *priv = dev->data->dev_private;
    1241                 :            :         struct zxdh_flow_info *flow = NULL;
    1242                 :            :         const struct rte_flow_item *item;
    1243                 :            :         const struct rte_flow_item_eth *eth_spec, *eth_mask;
    1244                 :            :         const struct rte_flow_item_vlan *vlan_spec, *vlan_mask;
    1245                 :            :         const struct rte_flow_item_ipv4 *ipv4_spec, *ipv4_mask;
    1246                 :            :         const struct rte_flow_item_ipv6 *ipv6_spec = NULL, *ipv6_mask = NULL;
    1247                 :            :         const struct rte_flow_item_tcp *tcp_spec, *tcp_mask;
    1248                 :            :         const struct rte_flow_item_udp *udp_spec, *udp_mask;
    1249                 :            :         const struct rte_flow_item_sctp *sctp_spec, *sctp_mask;
    1250                 :            :         const struct rte_flow_item_vxlan *vxlan_spec, *vxlan_mask;
    1251                 :            :         struct fd_flow_key *key, *key_mask;
    1252                 :            : 
    1253         [ #  # ]:          0 :         if (dh_flow) {
    1254                 :          0 :                 flow = &dh_flow->flowentry;
    1255                 :            :         } else {
    1256                 :          0 :                 flow = rte_zmalloc("dh_flow", sizeof(*flow), 0);
    1257         [ #  # ]:          0 :                 if (flow == NULL) {
    1258                 :          0 :                         rte_flow_error_set(error, EINVAL,
    1259                 :            :                                                  RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
    1260                 :            :                                                  "Failed to allocate memory ");
    1261                 :          0 :                         return -rte_errno;
    1262                 :            :                 }
    1263                 :            :         }
    1264                 :            : 
    1265                 :            :         key = &flow->fd_flow.key;
    1266                 :          0 :         key_mask = &flow->fd_flow.key_mask;
    1267         [ #  # ]:          0 :         key->vfid = rte_cpu_to_be_16(priv->vfid);
    1268                 :          0 :         key_mask->vfid  = 0xffff;
    1269         [ #  # ]:          0 :         for (; items->type != RTE_FLOW_ITEM_TYPE_END; items++) {
    1270                 :            :                 item = items;
    1271         [ #  # ]:          0 :                 if (items->last) {
    1272                 :          0 :                         rte_flow_error_set(error, EINVAL,
    1273                 :            :                                          RTE_FLOW_ERROR_TYPE_ITEM,
    1274                 :            :                                          items,
    1275                 :            :                                          "Not support range");
    1276                 :          0 :                         return -rte_errno;
    1277                 :            :                 }
    1278                 :            : 
    1279   [ #  #  #  #  :          0 :                 switch (item->type) {
          #  #  #  #  #  
                      # ]
    1280                 :          0 :                 case RTE_FLOW_ITEM_TYPE_ETH:
    1281                 :          0 :                         eth_spec = item->spec;
    1282                 :          0 :                         eth_mask = item->mask;
    1283         [ #  # ]:          0 :                         if (eth_spec && eth_mask) {
    1284                 :          0 :                                 key->mac_dst = eth_spec->dst;
    1285                 :          0 :                                 key->mac_src  = eth_spec->src;
    1286                 :          0 :                                 key_mask->mac_dst  = eth_mask->dst;
    1287                 :          0 :                                 key_mask->mac_src  = eth_mask->src;
    1288                 :            : 
    1289         [ #  # ]:          0 :                                 if (eth_mask->type == 0xffff) {
    1290                 :          0 :                                         key->ether_type = eth_spec->type;
    1291                 :          0 :                                         key_mask->ether_type = eth_mask->type;
    1292                 :            :                                 }
    1293                 :            :                         }
    1294                 :            :                         break;
    1295                 :          0 :                 case RTE_FLOW_ITEM_TYPE_VLAN:
    1296                 :          0 :                         vlan_spec = item->spec;
    1297                 :          0 :                         vlan_mask = item->mask;
    1298         [ #  # ]:          0 :                         if (vlan_spec && vlan_mask) {
    1299                 :          0 :                                 key->vlan_tci  = vlan_spec->tci;
    1300                 :          0 :                                 key_mask->vlan_tci = vlan_mask->tci;
    1301                 :            :                         }
    1302                 :            :                         break;
    1303                 :          0 :                 case RTE_FLOW_ITEM_TYPE_IPV4:
    1304                 :          0 :                         ipv4_spec = item->spec;
    1305                 :          0 :                         ipv4_mask = item->mask;
    1306                 :            : 
    1307         [ #  # ]:          0 :                         if (ipv4_spec && ipv4_mask) {
    1308                 :            :                                 /* Check IPv4 mask and update input set */
    1309         [ #  # ]:          0 :                                 if (ipv4_mask->hdr.version_ihl ||
    1310         [ #  # ]:          0 :                                         ipv4_mask->hdr.total_length ||
    1311         [ #  # ]:          0 :                                         ipv4_mask->hdr.packet_id ||
    1312         [ #  # ]:          0 :                                         ipv4_mask->hdr.hdr_checksum ||
    1313         [ #  # ]:          0 :                                         ipv4_mask->hdr.time_to_live) {
    1314                 :          0 :                                         rte_flow_error_set(error, EINVAL,
    1315                 :            :                                                          RTE_FLOW_ERROR_TYPE_ITEM,
    1316                 :            :                                                          item,
    1317                 :            :                                                          "Invalid IPv4 mask.");
    1318                 :          0 :                                         return -rte_errno;
    1319                 :            :                                 }
    1320                 :            :                                         /* Get the filter info */
    1321                 :          0 :                                 key->nw_proto =
    1322                 :          0 :                                                 ipv4_spec->hdr.next_proto_id;
    1323                 :          0 :                                 key->tos =
    1324                 :          0 :                                                 ipv4_spec->hdr.type_of_service;
    1325                 :          0 :                                 key_mask->nw_proto =
    1326                 :          0 :                                                 ipv4_mask->hdr.next_proto_id;
    1327                 :          0 :                                 key_mask->tos =
    1328                 :          0 :                                                 ipv4_mask->hdr.type_of_service;
    1329                 :          0 :                                 key->frag_flag = (ipv4_spec->hdr.fragment_offset != 0) ? 1 : 0;
    1330                 :          0 :                                 key_mask->frag_flag = (ipv4_mask->hdr.fragment_offset != 0) ? 1 : 0;
    1331                 :          0 :                                 rte_memcpy((uint32_t *)key->src_ip + 3,
    1332         [ #  # ]:          0 :                                                          &ipv4_spec->hdr.src_addr, 4);
    1333                 :          0 :                                 rte_memcpy((uint32_t *)key->dst_ip + 3,
    1334         [ #  # ]:          0 :                                                          &ipv4_spec->hdr.dst_addr, 4);
    1335                 :          0 :                                 rte_memcpy((uint32_t *)key_mask->src_ip + 3,
    1336         [ #  # ]:          0 :                                                          &ipv4_mask->hdr.src_addr, 4);
    1337                 :          0 :                                 rte_memcpy((uint32_t *)key_mask->dst_ip + 3,
    1338         [ #  # ]:          0 :                                                          &ipv4_mask->hdr.dst_addr, 4);
    1339                 :            :                         }
    1340                 :            :                         break;
    1341                 :          0 :                 case RTE_FLOW_ITEM_TYPE_IPV6:
    1342                 :          0 :                         ipv6_spec = item->spec;
    1343                 :          0 :                         ipv6_mask = item->mask;
    1344                 :            : 
    1345         [ #  # ]:          0 :                         if (ipv6_spec && ipv6_mask) {
    1346                 :            :                                 /* Check IPv6 mask and update input set */
    1347         [ #  # ]:          0 :                                 if (ipv6_mask->hdr.payload_len ||
    1348         [ #  # ]:          0 :                                          ipv6_mask->hdr.hop_limits == UINT8_MAX) {
    1349                 :          0 :                                         rte_flow_error_set(error, EINVAL,
    1350                 :            :                                                 RTE_FLOW_ERROR_TYPE_ITEM,
    1351                 :            :                                                 item,
    1352                 :            :                                                 "Invalid IPv6 mask");
    1353                 :          0 :                                         return -rte_errno;
    1354                 :            :                                 }
    1355                 :          0 :                                 key->tc =
    1356                 :          0 :                                         (uint8_t)((ipv6_spec->hdr.vtc_flow &
    1357                 :          0 :                                                                 RTE_IPV6_HDR_TC_MASK) >>
    1358                 :            :                                                                 RTE_IPV6_HDR_TC_SHIFT);
    1359                 :          0 :                                 key_mask->tc =
    1360                 :          0 :                                         (uint8_t)((ipv6_mask->hdr.vtc_flow &
    1361                 :          0 :                                                                 RTE_IPV6_HDR_TC_MASK) >>
    1362                 :            :                                                                 RTE_IPV6_HDR_TC_SHIFT);
    1363                 :            : 
    1364                 :          0 :                                 key->nw_proto = ipv6_spec->hdr.proto;
    1365                 :          0 :                                 key_mask->nw_proto = ipv6_mask->hdr.proto;
    1366                 :            : 
    1367                 :          0 :                                 rte_memcpy(key->src_ip,
    1368         [ #  # ]:          0 :                                                          &ipv6_spec->hdr.src_addr, 16);
    1369                 :          0 :                                 rte_memcpy(key->dst_ip,
    1370         [ #  # ]:          0 :                                                          &ipv6_spec->hdr.dst_addr, 16);
    1371                 :          0 :                                 rte_memcpy(key_mask->src_ip,
    1372         [ #  # ]:          0 :                                                          &ipv6_mask->hdr.src_addr, 16);
    1373                 :          0 :                                 rte_memcpy(key_mask->dst_ip,
    1374         [ #  # ]:          0 :                                                          &ipv6_mask->hdr.dst_addr, 16);
    1375                 :            :                         }
    1376                 :            :                         break;
    1377                 :          0 :                 case RTE_FLOW_ITEM_TYPE_TCP:
    1378                 :          0 :                         tcp_spec = item->spec;
    1379                 :          0 :                         tcp_mask = item->mask;
    1380                 :            : 
    1381         [ #  # ]:          0 :                         if (tcp_spec && tcp_mask) {
    1382                 :            :                                 /* Check TCP mask and update input set */
    1383         [ #  # ]:          0 :                                 if (tcp_mask->hdr.sent_seq ||
    1384         [ #  # ]:          0 :                                         tcp_mask->hdr.recv_ack ||
    1385         [ #  # ]:          0 :                                         tcp_mask->hdr.data_off ||
    1386         [ #  # ]:          0 :                                         tcp_mask->hdr.tcp_flags ||
    1387         [ #  # ]:          0 :                                         tcp_mask->hdr.rx_win ||
    1388         [ #  # ]:          0 :                                         tcp_mask->hdr.cksum ||
    1389         [ #  # ]:          0 :                                         tcp_mask->hdr.tcp_urp ||
    1390         [ #  # ]:          0 :                                         (tcp_mask->hdr.src_port &&
    1391                 :          0 :                                         tcp_mask->hdr.src_port != UINT16_MAX) ||
    1392         [ #  # ]:          0 :                                         (tcp_mask->hdr.dst_port &&
    1393                 :            :                                         tcp_mask->hdr.dst_port != UINT16_MAX)) {
    1394                 :          0 :                                         rte_flow_error_set(error, EINVAL,
    1395                 :            :                                                                  RTE_FLOW_ERROR_TYPE_ITEM,
    1396                 :            :                                                                  item,
    1397                 :            :                                                                  "Invalid TCP mask");
    1398                 :          0 :                                         return -rte_errno;
    1399                 :            :                                 }
    1400                 :            : 
    1401                 :          0 :                                 key->tp_src = tcp_spec->hdr.src_port;
    1402                 :          0 :                                 key_mask->tp_src = tcp_mask->hdr.src_port;
    1403                 :            : 
    1404                 :          0 :                                 key->tp_dst = tcp_spec->hdr.dst_port;
    1405                 :          0 :                                 key_mask->tp_dst = tcp_mask->hdr.dst_port;
    1406                 :            :                         }
    1407                 :            :                         break;
    1408                 :          0 :                 case RTE_FLOW_ITEM_TYPE_UDP:
    1409                 :          0 :                         udp_spec = item->spec;
    1410                 :          0 :                         udp_mask = item->mask;
    1411                 :            : 
    1412         [ #  # ]:          0 :                         if (udp_spec && udp_mask) {
    1413                 :            :                                 /* Check UDP mask and update input set*/
    1414         [ #  # ]:          0 :                                 if (udp_mask->hdr.dgram_len ||
    1415         [ #  # ]:          0 :                                         udp_mask->hdr.dgram_cksum ||
    1416         [ #  # ]:          0 :                                         (udp_mask->hdr.src_port &&
    1417                 :          0 :                                         udp_mask->hdr.src_port != UINT16_MAX) ||
    1418         [ #  # ]:          0 :                                         (udp_mask->hdr.dst_port &&
    1419                 :            :                                         udp_mask->hdr.dst_port != UINT16_MAX)) {
    1420                 :          0 :                                         rte_flow_error_set(error, EINVAL,
    1421                 :            :                                                                          RTE_FLOW_ERROR_TYPE_ITEM,
    1422                 :            :                                                                          item,
    1423                 :            :                                                                          "Invalid UDP mask");
    1424                 :          0 :                                         return -rte_errno;
    1425                 :            :                                 }
    1426                 :            : 
    1427                 :          0 :                                 key->tp_src = udp_spec->hdr.src_port;
    1428                 :          0 :                                 key_mask->tp_src = udp_mask->hdr.src_port;
    1429                 :            : 
    1430                 :          0 :                                 key->tp_dst = udp_spec->hdr.dst_port;
    1431                 :          0 :                                 key_mask->tp_dst = udp_mask->hdr.dst_port;
    1432                 :            :                         }
    1433                 :            :                         break;
    1434                 :          0 :                 case RTE_FLOW_ITEM_TYPE_SCTP:
    1435                 :          0 :                         sctp_spec = item->spec;
    1436                 :          0 :                         sctp_mask = item->mask;
    1437                 :            : 
    1438         [ #  # ]:          0 :                         if (!(sctp_spec && sctp_mask))
    1439                 :            :                                 break;
    1440                 :            : 
    1441                 :            :                         /* Check SCTP mask and update input set */
    1442         [ #  # ]:          0 :                         if (sctp_mask->hdr.cksum) {
    1443                 :          0 :                                 rte_flow_error_set(error, EINVAL,
    1444                 :            :                                                    RTE_FLOW_ERROR_TYPE_ITEM,
    1445                 :            :                                                    item,
    1446                 :            :                                                    "Invalid sctp mask");
    1447                 :          0 :                                 return -rte_errno;
    1448                 :            :                         }
    1449                 :            : 
    1450                 :            :                         /* Mask for SCTP src/dst ports not supported */
    1451         [ #  # ]:          0 :                         if (sctp_mask->hdr.src_port &&
    1452                 :            :                                 sctp_mask->hdr.src_port != UINT16_MAX)
    1453                 :          0 :                                 return -rte_errno;
    1454         [ #  # ]:          0 :                         if (sctp_mask->hdr.dst_port &&
    1455                 :            :                                 sctp_mask->hdr.dst_port != UINT16_MAX)
    1456                 :          0 :                                 return -rte_errno;
    1457                 :            : 
    1458                 :          0 :                         key->tp_src = sctp_spec->hdr.src_port;
    1459                 :          0 :                         key_mask->tp_src = sctp_mask->hdr.src_port;
    1460                 :          0 :                         key->tp_dst = sctp_spec->hdr.dst_port;
    1461                 :          0 :                         key_mask->tp_dst = sctp_mask->hdr.dst_port;
    1462                 :          0 :                         break;
    1463                 :          0 :                 case RTE_FLOW_ITEM_TYPE_VXLAN:
    1464                 :            :                 {
    1465                 :          0 :                         vxlan_spec = item->spec;
    1466                 :          0 :                         vxlan_mask = item->mask;
    1467                 :            :                         static const struct rte_flow_item_vxlan flow_item_vxlan_mask = {
    1468                 :            :                                 .vni = {0xff, 0xff, 0xff},
    1469                 :            :                         };
    1470         [ #  # ]:          0 :                         if (!(vxlan_spec && vxlan_mask))
    1471                 :            :                                 break;
    1472         [ #  # ]:          0 :                         if (memcmp(vxlan_mask, &flow_item_vxlan_mask,
    1473                 :            :                                 sizeof(struct rte_flow_item_vxlan))) {
    1474                 :          0 :                                 rte_flow_error_set(error, EINVAL,
    1475                 :            :                                                                  RTE_FLOW_ERROR_TYPE_ITEM,
    1476                 :            :                                                                  item,
    1477                 :            :                                                                  "Invalid vxlan mask");
    1478                 :          0 :                                         return -rte_errno;
    1479                 :            :                         }
    1480         [ #  # ]:          0 :                         rte_memcpy(key->vni, vxlan_spec->vni, 3);
    1481         [ #  # ]:          0 :                         rte_memcpy(key_mask->vni, vxlan_mask->vni, 3);
    1482                 :            :                         break;
    1483                 :            :                 }
    1484                 :            :                 case RTE_FLOW_ACTION_TYPE_VOID:
    1485                 :            :                         break;
    1486                 :          0 :                 default:
    1487                 :          0 :                                 return rte_flow_error_set(error, ENOTSUP,
    1488                 :            :                                                         RTE_FLOW_ERROR_TYPE_ITEM,
    1489                 :            :                                                         NULL, "item not supported");
    1490                 :            :                 }
    1491                 :            :         }
    1492                 :            : 
    1493                 :            :         data_bitwise(key_mask, sizeof(*key_mask));
    1494                 :            :         return 0;
    1495                 :            : }
    1496                 :            : 
    1497                 :            : static inline int
    1498                 :          0 : validate_action_rss(struct rte_eth_dev *dev,
    1499                 :            :                          const struct rte_flow_action *action,
    1500                 :            :                          struct rte_flow_error *error)
    1501                 :            : {
    1502                 :          0 :         const struct rte_flow_action_rss *rss = action->conf;
    1503                 :            : 
    1504         [ #  # ]:          0 :         if (rss->func != RTE_ETH_HASH_FUNCTION_DEFAULT &&
    1505                 :            :                 rss->func != RTE_ETH_HASH_FUNCTION_TOEPLITZ) {
    1506                 :          0 :                 rte_flow_error_set(error, ENOTSUP,
    1507                 :            :                                 RTE_FLOW_ERROR_TYPE_ACTION_CONF,
    1508                 :          0 :                                 &rss->func,
    1509                 :            :                                 "RSS hash function not supported");
    1510                 :          0 :                 return -rte_errno;
    1511                 :            :                 }
    1512                 :            : 
    1513         [ #  # ]:          0 :         if (rss->level > 1) {
    1514                 :          0 :                 rte_flow_error_set(error, ENOTSUP,
    1515                 :            :                                 RTE_FLOW_ERROR_TYPE_ACTION_CONF,
    1516                 :          0 :                                 &rss->level,
    1517                 :            :                                 "tunnel RSS is not supported");
    1518                 :          0 :                 return -rte_errno;
    1519                 :            :         }
    1520                 :            : 
    1521                 :            :         /* allow RSS key_len 0 in case of NULL (default) RSS key. */
    1522   [ #  #  #  # ]:          0 :         if (rss->key_len == 0 && rss->key != NULL) {
    1523                 :          0 :                 rte_flow_error_set(error, ENOTSUP,
    1524                 :            :                                 RTE_FLOW_ERROR_TYPE_ACTION_CONF,
    1525                 :          0 :                                 &rss->key_len,
    1526                 :            :                                 "RSS hash key length 0");
    1527                 :          0 :                 return -rte_errno;
    1528                 :            :         }
    1529                 :            : 
    1530         [ #  # ]:          0 :         if (rss->key_len > 0 && rss->key_len < ZXDH_RSS_HASH_KEY_LEN) {
    1531                 :          0 :                 rte_flow_error_set(error, ENOTSUP,
    1532                 :            :                                 RTE_FLOW_ERROR_TYPE_ACTION_CONF,
    1533                 :          0 :                                 &rss->key_len,
    1534                 :            :                                 "RSS hash key too small, value is 40U");
    1535                 :          0 :                 return -rte_errno;
    1536                 :            :         }
    1537                 :            : 
    1538         [ #  # ]:          0 :         if (rss->key_len > ZXDH_RSS_HASH_KEY_LEN) {
    1539                 :          0 :                 rte_flow_error_set(error, ENOTSUP,
    1540                 :            :                                 RTE_FLOW_ERROR_TYPE_ACTION_CONF,
    1541                 :          0 :                                 &rss->key_len,
    1542                 :            :                                 "RSS hash key too large, value is 40U");
    1543                 :          0 :                 return -rte_errno;
    1544                 :            :         }
    1545                 :            : 
    1546         [ #  # ]:          0 :         if (!rss->queue_num) {
    1547                 :          0 :                 rte_flow_error_set(error, EINVAL,
    1548                 :            :                                 RTE_FLOW_ERROR_TYPE_ACTION_CONF,
    1549                 :          0 :                                 &dev->data->nb_rx_queues, "No queues configured");
    1550                 :          0 :                 return -rte_errno;
    1551                 :            :         }
    1552                 :            : 
    1553                 :            :         return 0;
    1554                 :            : }
    1555                 :            : 
    1556                 :            : static int
    1557                 :          0 : fd_flow_parse_vxlan_encap(struct rte_eth_dev *dev __rte_unused,
    1558                 :            :                 const struct rte_flow_item *item,
    1559                 :            :                 struct zxdh_flow *dh_flow)
    1560                 :            : {
    1561                 :            :         const struct rte_flow_item *items;
    1562                 :            :         const struct rte_flow_item_eth *item_eth;
    1563                 :            :         const struct rte_flow_item_vlan *item_vlan;
    1564                 :            :         const struct rte_flow_item_ipv4 *item_ipv4;
    1565                 :            :         const struct rte_flow_item_ipv6 *item_ipv6;
    1566                 :            :         const struct rte_flow_item_udp *item_udp;
    1567                 :            :         const struct rte_flow_item_vxlan *item_vxlan;
    1568                 :            :         uint32_t i = 0;
    1569                 :            :         rte_be32_t addr;
    1570                 :            : 
    1571         [ #  # ]:          0 :         for (i = 0; i < ACTION_VXLAN_ENCAP_ITEMS_NUM; i++) {
    1572                 :          0 :                 items = &item[i];
    1573   [ #  #  #  #  :          0 :                 switch (items->type) {
                #  #  # ]
    1574                 :          0 :                 case RTE_FLOW_ITEM_TYPE_ETH:
    1575                 :          0 :                         item_eth = items->spec;
    1576         [ #  # ]:          0 :                         rte_memcpy(&dh_flow->encap0.dst_mac1, item_eth->dst.addr_bytes, 2);
    1577         [ #  # ]:          0 :                         rte_memcpy(&dh_flow->encap1.src_mac1, item_eth->src.addr_bytes, 2);
    1578         [ #  # ]:          0 :                         rte_memcpy(&dh_flow->encap0.dst_mac2, &item_eth->dst.addr_bytes[2], 4);
    1579         [ #  # ]:          0 :                         rte_memcpy(&dh_flow->encap1.src_mac2, &item_eth->src.addr_bytes[2], 4);
    1580         [ #  # ]:          0 :                         dh_flow->encap0.dst_mac1 = rte_bswap16(dh_flow->encap0.dst_mac1);
    1581         [ #  # ]:          0 :                         dh_flow->encap1.src_mac1 = rte_bswap16(dh_flow->encap1.src_mac1);
    1582         [ #  # ]:          0 :                         dh_flow->encap0.dst_mac2 = rte_bswap32(dh_flow->encap0.dst_mac2);
    1583         [ #  # ]:          0 :                         dh_flow->encap1.src_mac2 = rte_bswap32(dh_flow->encap1.src_mac2);
    1584                 :          0 :                         break;
    1585                 :          0 :                 case RTE_FLOW_ITEM_TYPE_VLAN:
    1586                 :          0 :                         item_vlan = items->spec;
    1587                 :          0 :                         dh_flow->encap1.vlan_tci = item_vlan->hdr.vlan_tci;
    1588                 :          0 :                         break;
    1589                 :          0 :                 case RTE_FLOW_ITEM_TYPE_IPV4:
    1590                 :          0 :                         item_ipv4 = items->spec;
    1591                 :          0 :                         dh_flow->encap0.ethtype = 0;
    1592                 :          0 :                         dh_flow->encap0.tos = item_ipv4->hdr.type_of_service;
    1593                 :          0 :                         dh_flow->encap0.ttl = item_ipv4->hdr.time_to_live;
    1594         [ #  # ]:          0 :                         addr = rte_bswap32(item_ipv4->hdr.src_addr);
    1595         [ #  # ]:          0 :                         rte_memcpy((uint32_t *)dh_flow->encap1.sip.ip_addr + 3, &addr, 4);
    1596         [ #  # ]:          0 :                         addr = rte_bswap32(item_ipv4->hdr.dst_addr);
    1597         [ #  # ]:          0 :                         rte_memcpy((uint32_t *)dh_flow->encap0.dip.ip_addr + 3, &addr, 4);
    1598                 :            :                         break;
    1599                 :          0 :                 case RTE_FLOW_ITEM_TYPE_IPV6:
    1600                 :          0 :                         item_ipv6 = items->spec;
    1601                 :          0 :                         dh_flow->encap0.ethtype = 1;
    1602                 :          0 :                         dh_flow->encap0.tos =
    1603                 :          0 :                                         (item_ipv6->hdr.vtc_flow & RTE_IPV6_HDR_TC_MASK) >>
    1604                 :            :                                                 RTE_IPV6_HDR_TC_SHIFT;
    1605                 :          0 :                         dh_flow->encap0.ttl = item_ipv6->hdr.hop_limits;
    1606         [ #  # ]:          0 :                         rte_memcpy(dh_flow->encap1.sip.ip_addr, &item_ipv6->hdr.src_addr, 16);
    1607                 :          0 :                         dh_flow->encap1.sip.ip_addr[0] =
    1608         [ #  # ]:          0 :                                 rte_bswap32(dh_flow->encap1.sip.ip_addr[0]);
    1609                 :          0 :                         dh_flow->encap1.sip.ip_addr[1] =
    1610         [ #  # ]:          0 :                                 rte_bswap32(dh_flow->encap1.sip.ip_addr[1]);
    1611                 :          0 :                         dh_flow->encap1.sip.ip_addr[2] =
    1612         [ #  # ]:          0 :                                 rte_bswap32(dh_flow->encap1.sip.ip_addr[2]);
    1613                 :          0 :                         dh_flow->encap1.sip.ip_addr[3] =
    1614         [ #  # ]:          0 :                                 rte_bswap32(dh_flow->encap1.sip.ip_addr[3]);
    1615         [ #  # ]:          0 :                         rte_memcpy(dh_flow->encap0.dip.ip_addr, &item_ipv6->hdr.dst_addr, 16);
    1616                 :          0 :                         dh_flow->encap0.dip.ip_addr[0] =
    1617         [ #  # ]:          0 :                                         rte_bswap32(dh_flow->encap0.dip.ip_addr[0]);
    1618                 :          0 :                         dh_flow->encap0.dip.ip_addr[1] =
    1619         [ #  # ]:          0 :                                         rte_bswap32(dh_flow->encap0.dip.ip_addr[1]);
    1620                 :          0 :                         dh_flow->encap0.dip.ip_addr[2] =
    1621         [ #  # ]:          0 :                                         rte_bswap32(dh_flow->encap0.dip.ip_addr[2]);
    1622                 :          0 :                         dh_flow->encap0.dip.ip_addr[3] =
    1623         [ #  # ]:          0 :                                         rte_bswap32(dh_flow->encap0.dip.ip_addr[3]);
    1624                 :          0 :                         break;
    1625                 :          0 :                 case RTE_FLOW_ITEM_TYPE_UDP:
    1626                 :          0 :                         item_udp = items->spec;
    1627                 :          0 :                         dh_flow->encap0.tp_dst = item_udp->hdr.dst_port;
    1628         [ #  # ]:          0 :                         dh_flow->encap0.tp_dst = rte_bswap16(dh_flow->encap0.tp_dst);
    1629                 :          0 :                         break;
    1630                 :          0 :                 case RTE_FLOW_ITEM_TYPE_VXLAN:
    1631                 :          0 :                         item_vxlan = items->spec;
    1632                 :          0 :                         dh_flow->encap0.vni = item_vxlan->vni[0] * 65536 +
    1633                 :          0 :                                         item_vxlan->vni[1] * 256 + item_vxlan->vni[2];
    1634                 :          0 :                         break;
    1635                 :            :                 case RTE_FLOW_ITEM_TYPE_VOID:
    1636                 :            :                         break;
    1637                 :            :                 default:
    1638                 :            :                         break;
    1639                 :            :                 }
    1640                 :            :         }
    1641                 :          0 :         dh_flow->encap0.hit_flag = 1;
    1642                 :          0 :         dh_flow->encap1.hit_flag = 1;
    1643                 :            : 
    1644                 :          0 :         return 0;
    1645                 :            : }
    1646                 :            : 
    1647                 :            : static int
    1648                 :          0 : fd_flow_parse_action(struct rte_eth_dev *dev, const struct rte_flow_action *actions,
    1649                 :            :                          struct rte_flow_error *error, struct zxdh_flow *dh_flow)
    1650                 :            : {
    1651                 :            :         struct zxdh_flow_info *flow = NULL;
    1652                 :            :         struct fd_flow_result *result = NULL;
    1653                 :            :         const struct rte_flow_item *enc_item = NULL;
    1654                 :            :         uint8_t action_bitmap = 0;
    1655                 :            :         uint32_t dest_num = 0;
    1656                 :            :         uint32_t mark_num = 0;
    1657                 :            :         uint32_t counter_num = 0;
    1658                 :            :         int ret;
    1659                 :            : 
    1660                 :          0 :         rte_errno = 0;
    1661         [ #  # ]:          0 :         if (dh_flow) {
    1662                 :          0 :                 flow = &dh_flow->flowentry;
    1663                 :            :         } else {
    1664                 :          0 :                 flow = rte_zmalloc("dh_flow", sizeof(*flow), 0);
    1665         [ #  # ]:          0 :                 if (flow == NULL) {
    1666                 :          0 :                         rte_flow_error_set(error, EINVAL,
    1667                 :            :                                          RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
    1668                 :            :                                          "Failed to allocate memory ");
    1669                 :          0 :                         return -rte_errno;
    1670                 :            :                 }
    1671                 :            :         }
    1672                 :            :         result = &flow->fd_flow.result;
    1673                 :          0 :         action_bitmap = result->action_idx;
    1674                 :            : 
    1675         [ #  # ]:          0 :         for (; actions->type != RTE_FLOW_ACTION_TYPE_END; actions++) {
    1676   [ #  #  #  #  :          0 :                 switch (actions->type) {
             #  #  #  # ]
    1677                 :          0 :                 case RTE_FLOW_ACTION_TYPE_RSS:
    1678                 :            :                 {
    1679                 :          0 :                         dest_num++;
    1680         [ #  # ]:          0 :                         if (action_bitmap & (1 << FD_ACTION_RSS_BIT)) {
    1681                 :          0 :                                 rte_flow_error_set(error, EINVAL,
    1682                 :            :                                                 RTE_FLOW_ERROR_TYPE_ACTION, actions,
    1683                 :            :                                                 "rss action does no support.");
    1684                 :          0 :                                 goto free_flow;
    1685                 :            :                         }
    1686                 :          0 :                         ret = validate_action_rss(dev, actions, error);
    1687         [ #  # ]:          0 :                         if (ret)
    1688                 :          0 :                                 goto free_flow;
    1689                 :          0 :                         action_bitmap |= (1 << FD_ACTION_RSS_BIT);
    1690                 :          0 :                         break;
    1691                 :            :                 }
    1692                 :          0 :                 case RTE_FLOW_ACTION_TYPE_MARK:
    1693                 :            :                 {
    1694                 :          0 :                         mark_num++;
    1695         [ #  # ]:          0 :                         if (action_bitmap & (1 << FD_ACTION_MARK_BIT)) {
    1696                 :          0 :                                 rte_flow_error_set(error, EINVAL,
    1697                 :            :                                                 RTE_FLOW_ERROR_TYPE_ACTION, actions,
    1698                 :            :                                                 "multi mark action no support.");
    1699                 :          0 :                                 goto free_flow;
    1700                 :            :                         }
    1701                 :          0 :                         const struct rte_flow_action_mark *act_mark = actions->conf;
    1702                 :          0 :                         result->mark_fd_id = rte_cpu_to_le_32(act_mark->id);
    1703                 :          0 :                         action_bitmap |= (1 << FD_ACTION_MARK_BIT);
    1704                 :          0 :                         break;
    1705                 :            :                 }
    1706                 :          0 :                 case RTE_FLOW_ACTION_TYPE_COUNT:
    1707                 :            :                 {
    1708                 :          0 :                         counter_num++;
    1709         [ #  # ]:          0 :                         if (action_bitmap & (1 << FD_ACTION_COUNT_BIT)) {
    1710                 :          0 :                                 rte_flow_error_set(error, EINVAL,
    1711                 :            :                                                 RTE_FLOW_ERROR_TYPE_ACTION, actions,
    1712                 :            :                                                 "multi count action no support.");
    1713                 :          0 :                                 goto free_flow;
    1714                 :            :                         }
    1715                 :          0 :                         const struct rte_flow_action_count *act_count = actions->conf;
    1716         [ #  # ]:          0 :                         if (act_count->id > MAX_FLOW_COUNT_NUM) {
    1717                 :          0 :                                 rte_flow_error_set(error, EINVAL,
    1718                 :            :                                                         RTE_FLOW_ERROR_TYPE_ACTION, actions,
    1719                 :            :                                                         "count action id no support.");
    1720                 :          0 :                                 goto free_flow;
    1721                 :            :                         };
    1722                 :          0 :                         result->countid = act_count->id;
    1723                 :          0 :                         action_bitmap |= (1 << FD_ACTION_COUNT_BIT);
    1724                 :          0 :                         break;
    1725                 :            :                 }
    1726                 :          0 :                 case RTE_FLOW_ACTION_TYPE_QUEUE:
    1727                 :            :                 {
    1728                 :          0 :                         dest_num++;
    1729         [ #  # ]:          0 :                         if (action_bitmap & (1 << FD_ACTION_QUEUE_BIT)) {
    1730                 :          0 :                                 rte_flow_error_set(error, EINVAL,
    1731                 :            :                                                 RTE_FLOW_ERROR_TYPE_ACTION, actions,
    1732                 :            :                                                 "multi queue action no support.");
    1733                 :          0 :                                 goto free_flow;
    1734                 :            :                         }
    1735                 :            :                         const struct rte_flow_action_queue *act_q;
    1736                 :          0 :                         act_q = actions->conf;
    1737         [ #  # ]:          0 :                         if (act_q->index >= dev->data->nb_rx_queues) {
    1738                 :          0 :                                 rte_flow_error_set(error, EINVAL,
    1739                 :            :                                                 RTE_FLOW_ERROR_TYPE_ACTION, actions,
    1740                 :            :                                                 "Invalid queue ID");
    1741                 :          0 :                                 goto free_flow;
    1742                 :            :                         }
    1743                 :          0 :                         ret = zxdh_hw_qid_to_logic_qid(dev, act_q->index << 1);
    1744                 :            :                         if (ret < 0) {
    1745                 :            :                                 rte_flow_error_set(error, EINVAL,
    1746                 :            :                                                 RTE_FLOW_ERROR_TYPE_ACTION, actions,
    1747                 :            :                                                 "Invalid phy queue ID .");
    1748                 :            :                                 goto free_flow;
    1749                 :            :                         }
    1750                 :          0 :                         result->qid = rte_cpu_to_le_16(ret);
    1751                 :          0 :                         action_bitmap |= (1 << FD_ACTION_QUEUE_BIT);
    1752                 :            : 
    1753                 :          0 :                         PMD_DRV_LOG(DEBUG, "QID RET 0x%x", result->qid);
    1754                 :          0 :                         break;
    1755                 :            :                 }
    1756                 :          0 :                 case RTE_FLOW_ACTION_TYPE_DROP:
    1757                 :            :                 {
    1758                 :          0 :                         dest_num++;
    1759         [ #  # ]:          0 :                         if (action_bitmap & (1 << FD_ACTION_DROP_BIT)) {
    1760                 :          0 :                                 rte_flow_error_set(error, EINVAL,
    1761                 :            :                                                 RTE_FLOW_ERROR_TYPE_ACTION, actions,
    1762                 :            :                                                 "multi drop action no support.");
    1763                 :          0 :                                 goto free_flow;
    1764                 :            :                         }
    1765                 :          0 :                         action_bitmap |= (1 << FD_ACTION_DROP_BIT);
    1766                 :          0 :                         break;
    1767                 :            :                 }
    1768                 :          0 :                 case RTE_FLOW_ACTION_TYPE_VXLAN_DECAP:
    1769                 :            :                 {
    1770                 :          0 :                         dest_num++;
    1771         [ #  # ]:          0 :                         if (action_bitmap & (1 << FD_ACTION_VXLAN_DECAP)) {
    1772                 :          0 :                                 rte_flow_error_set(error, EINVAL,
    1773                 :            :                                                 RTE_FLOW_ERROR_TYPE_ACTION, actions,
    1774                 :            :                                                 "multi drop action no support.");
    1775                 :          0 :                                 goto free_flow;
    1776                 :            :                         }
    1777                 :          0 :                         action_bitmap |= (1 << FD_ACTION_VXLAN_DECAP);
    1778                 :          0 :                         break;
    1779                 :            :                 }
    1780                 :          0 :                 case RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP:
    1781                 :          0 :                         enc_item = ((const struct rte_flow_action_vxlan_encap *)
    1782                 :          0 :                                    actions->conf)->definition;
    1783         [ #  # ]:          0 :                         if (dh_flow != NULL)
    1784                 :          0 :                                 fd_flow_parse_vxlan_encap(dev, enc_item, dh_flow);
    1785                 :          0 :                         dest_num++;
    1786         [ #  # ]:          0 :                         if (action_bitmap & (1 << FD_ACTION_VXLAN_ENCAP)) {
    1787                 :          0 :                                 rte_flow_error_set(error, EINVAL,
    1788                 :            :                                                 RTE_FLOW_ERROR_TYPE_ACTION, actions,
    1789                 :            :                                                 "multi drop action no support.");
    1790                 :          0 :                                 goto free_flow;
    1791                 :            :                         }
    1792                 :          0 :                         action_bitmap |= (1 << FD_ACTION_VXLAN_ENCAP);
    1793                 :          0 :                         break;
    1794                 :          0 :                 default:
    1795                 :          0 :                         rte_flow_error_set(error, EINVAL,
    1796                 :            :                                 RTE_FLOW_ERROR_TYPE_ACTION, actions,
    1797                 :            :                                 "Invalid action.");
    1798                 :          0 :                         goto free_flow;
    1799                 :            :                 }
    1800                 :            :         }
    1801                 :            : 
    1802         [ #  # ]:          0 :         if (dest_num >= 2) {
    1803                 :          0 :                 rte_flow_error_set(error, EINVAL,
    1804                 :            :                            RTE_FLOW_ERROR_TYPE_ACTION, actions,
    1805                 :            :                            "Unsupported action combination");
    1806                 :          0 :                 return -rte_errno;
    1807                 :            :         }
    1808                 :            : 
    1809         [ #  # ]:          0 :         if (mark_num >= 2) {
    1810                 :          0 :                 rte_flow_error_set(error, EINVAL,
    1811                 :            :                            RTE_FLOW_ERROR_TYPE_ACTION, actions,
    1812                 :            :                            "Too many mark actions");
    1813                 :          0 :                 return -rte_errno;
    1814                 :            :         }
    1815                 :            : 
    1816         [ #  # ]:          0 :         if (counter_num >= 2) {
    1817                 :          0 :                 rte_flow_error_set(error, EINVAL,
    1818                 :            :                            RTE_FLOW_ERROR_TYPE_ACTION, actions,
    1819                 :            :                            "Too many count actions");
    1820                 :          0 :                 return -rte_errno;
    1821                 :            :         }
    1822                 :            : 
    1823         [ #  # ]:          0 :         if (dest_num + mark_num + counter_num == 0) {
    1824                 :          0 :                 rte_flow_error_set(error, EINVAL,
    1825                 :            :                            RTE_FLOW_ERROR_TYPE_ACTION, actions,
    1826                 :            :                            "Empty action, packet forwarding as default");
    1827                 :          0 :                 return -rte_errno;
    1828                 :            :         }
    1829                 :            : 
    1830                 :          0 :         result->action_idx = action_bitmap;
    1831                 :          0 :         return 0;
    1832                 :            : 
    1833                 :          0 : free_flow:
    1834         [ #  # ]:          0 :         if (!dh_flow)
    1835                 :          0 :                 rte_free(flow);
    1836                 :          0 :         return -rte_errno;
    1837                 :            : }
    1838                 :            : 
    1839                 :            : static int
    1840                 :          0 : fd_parse_pattern_action(struct rte_eth_dev *dev,
    1841                 :            :                         const struct rte_flow_attr *attr,
    1842                 :            :                         const struct rte_flow_item pattern[],
    1843                 :            :                         const struct rte_flow_action *actions,
    1844                 :            :                         struct rte_flow_error *error, struct zxdh_flow *dh_flow)
    1845                 :            : {
    1846                 :            :         int ret = 0;
    1847                 :          0 :         ret = fd_flow_parse_attr(dev, attr, error, dh_flow);
    1848         [ #  # ]:          0 :         if (ret < 0)
    1849                 :          0 :                 return -rte_errno;
    1850                 :          0 :         ret = fd_flow_parse_pattern(dev, pattern, error, dh_flow);
    1851         [ #  # ]:          0 :         if (ret < 0)
    1852                 :          0 :                 return -rte_errno;
    1853                 :            : 
    1854                 :          0 :         ret = fd_flow_parse_action(dev, actions, error, dh_flow);
    1855         [ #  # ]:          0 :         if (ret < 0)
    1856                 :          0 :                 return -rte_errno;
    1857                 :            :         return 0;
    1858                 :            : }
    1859                 :            : 
    1860                 :            : struct dh_flow_engine pf_fd_engine = {
    1861                 :            :         .apply = pf_fd_hw_apply,
    1862                 :            :         .destroy = pf_fd_hw_destroy,
    1863                 :            :         .query_count = pf_fd_hw_query_count,
    1864                 :            :         .parse_pattern_action = fd_parse_pattern_action,
    1865                 :            :         .type = FLOW_TYPE_FD_TCAM,
    1866                 :            : };
    1867                 :            : 
    1868                 :            : 
    1869                 :            : static int
    1870                 :          0 : vf_flow_msg_process(enum zxdh_msg_type msg_type, struct rte_eth_dev *dev,
    1871                 :            :                 struct zxdh_flow *dh_flow, struct rte_flow_error *error,
    1872                 :            :                 struct rte_flow_query_count *count)
    1873                 :            : {
    1874                 :            :         int ret = 0;
    1875                 :          0 :         struct zxdh_hw *hw = dev->data->dev_private;
    1876                 :          0 :         struct zxdh_msg_info msg_info = {0};
    1877                 :            :         struct zxdh_flow_op_msg *flow_msg = &msg_info.data.flow_msg;
    1878                 :            : 
    1879                 :          0 :         uint8_t zxdh_msg_reply_info[ZXDH_ST_SZ_BYTES(msg_reply_info)] = {0};
    1880                 :            :         void *reply_body_addr = ZXDH_ADDR_OF(msg_reply_info, zxdh_msg_reply_info, reply_body);
    1881                 :            :         void *flow_rsp_addr = ZXDH_ADDR_OF(msg_reply_body, reply_body_addr, flow_rsp);
    1882                 :          0 :         uint8_t flow_op_rsp[sizeof(struct zxdh_flow_op_rsp)] = {0};
    1883                 :            :         uint16_t len = sizeof(struct zxdh_flow_op_rsp) - 4;
    1884                 :            :         struct zxdh_flow_op_rsp *flow_rsp = (struct zxdh_flow_op_rsp *)flow_op_rsp;
    1885                 :            : 
    1886         [ #  # ]:          0 :         dh_flow->hash_search_index = hw->hash_search_index;
    1887                 :            :         rte_memcpy(&flow_msg->dh_flow, dh_flow, sizeof(struct zxdh_flow));
    1888                 :            : 
    1889                 :          0 :         zxdh_msg_head_build(hw, msg_type, &msg_info);
    1890                 :          0 :         ret = zxdh_vf_send_msg_to_pf(dev, &msg_info, sizeof(struct zxdh_msg_info),
    1891                 :            :                         (void *)zxdh_msg_reply_info, ZXDH_ST_SZ_BYTES(msg_reply_info));
    1892                 :          0 :         zxdh_adjust_flow_op_rsp_memory_layout(flow_rsp_addr, len, flow_op_rsp);
    1893         [ #  # ]:          0 :         if (ret) {
    1894                 :          0 :                 PMD_DRV_LOG(ERR, "port %d flow op %d failed ret %d", hw->port_id, msg_type, ret);
    1895         [ #  # ]:          0 :                 if (ret == -2) {
    1896                 :          0 :                         PMD_DRV_LOG(ERR, "port %d  flow %d failed: cause %s",
    1897                 :            :                                  hw->port_id, msg_type, flow_rsp->error.reason);
    1898                 :          0 :                         rte_flow_error_set(error, EBUSY,
    1899                 :            :                                          RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
    1900                 :            :                                          flow_rsp->error.reason);
    1901                 :            :                 } else {
    1902                 :          0 :                         rte_flow_error_set(error, EBUSY,
    1903                 :            :                                          RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
    1904                 :            :                                          "msg channel error");
    1905                 :            :                 }
    1906                 :          0 :                 return ret;
    1907                 :            :         }
    1908                 :            : 
    1909         [ #  # ]:          0 :         if (msg_type == ZXDH_FLOW_HW_ADD)
    1910                 :          0 :                 dh_flow->flowentry.hw_idx = flow_rsp->dh_flow.flowentry.hw_idx;
    1911         [ #  # ]:          0 :         if (count)
    1912                 :            :                 rte_memcpy((void *)count, &flow_rsp->count, sizeof(flow_rsp->count));
    1913                 :            : 
    1914                 :            :         return ret;
    1915                 :            : }
    1916                 :            : 
    1917                 :            : static int
    1918                 :          0 : vf_fd_apply(struct rte_eth_dev *dev, struct zxdh_flow *dh_flow,
    1919                 :            :                 struct rte_flow_error *error, uint16_t vport __rte_unused,
    1920                 :            :                 uint16_t pcieid __rte_unused)
    1921                 :            : {
    1922                 :            :         int ret = 0;
    1923                 :          0 :         struct zxdh_hw *hw = dev->data->dev_private;
    1924                 :          0 :         ret =  vf_flow_msg_process(ZXDH_FLOW_HW_ADD, dev, dh_flow, error, NULL);
    1925         [ #  # ]:          0 :         if (!ret) {
    1926                 :          0 :                 uint8_t action_bits = dh_flow->flowentry.fd_flow.result.action_idx;
    1927         [ #  # ]:          0 :                 if (((action_bits & (1 << FD_ACTION_VXLAN_ENCAP)) != 0) ||
    1928                 :            :                                 ((action_bits & (1 << FD_ACTION_VXLAN_DECAP)) != 0)) {
    1929                 :          0 :                         hw->vxlan_fd_num++;
    1930         [ #  # ]:          0 :                         if (hw->vxlan_fd_num == 1) {
    1931                 :          0 :                                 set_vxlan_enable(dev, 1, error);
    1932                 :          0 :                                 PMD_DRV_LOG(DEBUG, "vf set_vxlan_enable");
    1933                 :            :                         }
    1934                 :            :                 }
    1935                 :            :         }
    1936                 :          0 :         return ret;
    1937                 :            : }
    1938                 :            : 
    1939                 :            : static int
    1940                 :          0 : vf_fd_destroy(struct rte_eth_dev *dev, struct zxdh_flow *dh_flow,
    1941                 :            :                 struct rte_flow_error *error, uint16_t vport __rte_unused,
    1942                 :            :                 uint16_t pcieid __rte_unused)
    1943                 :            : {
    1944                 :            :         int ret = 0;
    1945                 :          0 :         struct zxdh_hw *hw = dev->data->dev_private;
    1946                 :          0 :         ret = vf_flow_msg_process(ZXDH_FLOW_HW_DEL, dev, dh_flow, error, NULL);
    1947         [ #  # ]:          0 :         if (!ret) {
    1948                 :          0 :                 uint8_t action_bits = dh_flow->flowentry.fd_flow.result.action_idx;
    1949         [ #  # ]:          0 :                 if (((action_bits & (1 << FD_ACTION_VXLAN_ENCAP)) != 0) ||
    1950                 :            :                                 ((action_bits & (1 << FD_ACTION_VXLAN_DECAP)) != 0)) {
    1951                 :          0 :                         hw->vxlan_fd_num--;
    1952         [ #  # ]:          0 :                         if (hw->vxlan_fd_num == 0) {
    1953                 :          0 :                                 set_vxlan_enable(dev, 0, error);
    1954                 :          0 :                                 PMD_DRV_LOG(DEBUG, "vf set_vxlan_disable");
    1955                 :            :                         }
    1956                 :            :                 }
    1957                 :            :         }
    1958                 :          0 :         return ret;
    1959                 :            : }
    1960                 :            : 
    1961                 :            : static int
    1962                 :          0 : vf_fd_query_count(struct rte_eth_dev *dev,
    1963                 :            :                 struct zxdh_flow *dh_flow,
    1964                 :            :                 struct rte_flow_query_count *count,
    1965                 :            :                 struct rte_flow_error *error)
    1966                 :            : {
    1967                 :            :         int ret = 0;
    1968                 :          0 :         ret = vf_flow_msg_process(ZXDH_FLOW_HW_GET, dev, dh_flow, error, count);
    1969                 :          0 :         return ret;
    1970                 :            : }
    1971                 :            : 
    1972                 :            : 
    1973                 :            : static struct dh_flow_engine vf_fd_engine = {
    1974                 :            :         .apply = vf_fd_apply,
    1975                 :            :         .destroy = vf_fd_destroy,
    1976                 :            :         .parse_pattern_action = fd_parse_pattern_action,
    1977                 :            :         .query_count = vf_fd_query_count,
    1978                 :            :         .type = FLOW_TYPE_FD_TCAM,
    1979                 :            : };
    1980                 :            : 
    1981                 :          0 : void zxdh_flow_init(struct rte_eth_dev *dev)
    1982                 :            : {
    1983                 :          0 :         struct zxdh_hw *priv =  dev->data->dev_private;
    1984         [ #  # ]:          0 :         if (priv->is_pf)
    1985                 :          0 :                 zxdh_register_flow_engine(&pf_fd_engine);
    1986                 :            :         else
    1987                 :          0 :                 zxdh_register_flow_engine(&vf_fd_engine);
    1988                 :          0 :         TAILQ_INIT(&priv->dh_flow_list);
    1989                 :          0 : }
    1990                 :            : 
    1991                 :            : const struct rte_flow_ops zxdh_flow_ops = {
    1992                 :            :         .validate = zxdh_flow_validate,
    1993                 :            :         .create = zxdh_flow_create,
    1994                 :            :         .destroy = zxdh_flow_destroy,
    1995                 :            :         .flush = zxdh_flow_flush,
    1996                 :            :         .query = zxdh_flow_query,
    1997                 :            :         .dev_dump = zxdh_flow_dev_dump,
    1998                 :            : };
    1999                 :            : 
    2000                 :            : int
    2001                 :          0 : zxdh_flow_ops_get(struct rte_eth_dev *dev __rte_unused,
    2002                 :            :                 const struct rte_flow_ops **ops)
    2003                 :            : {
    2004                 :          0 :         *ops = &zxdh_flow_ops;
    2005                 :            : 
    2006                 :          0 :         return 0;
    2007                 :            : }
    2008                 :            : 
    2009                 :            : void
    2010                 :          0 : zxdh_flow_release(struct rte_eth_dev *dev)
    2011                 :            : {
    2012                 :          0 :         struct rte_flow_error error = {0};
    2013                 :          0 :         const struct rte_flow_ops *flow_ops = NULL;
    2014                 :            : 
    2015   [ #  #  #  # ]:          0 :         if (dev->dev_ops && dev->dev_ops->flow_ops_get)
    2016                 :          0 :                 dev->dev_ops->flow_ops_get(dev, &flow_ops);
    2017   [ #  #  #  # ]:          0 :         if (flow_ops && flow_ops->flush)
    2018                 :          0 :                 flow_ops->flush(dev, &error);
    2019                 :          0 : }

Generated by: LCOV version 1.14