LCOV - code coverage report
Current view: top level - drivers/net/hns3 - hns3_flow.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 0 1111 0.0 %
Date: 2025-07-01 21:32:37 Functions: 0 71 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 813 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  * Copyright(c) 2018-2021 HiSilicon Limited.
       3                 :            :  */
       4                 :            : 
       5                 :            : #include <rte_flow_driver.h>
       6                 :            : #include <rte_io.h>
       7                 :            : #include <rte_malloc.h>
       8                 :            : 
       9                 :            : #include "hns3_ethdev.h"
      10                 :            : #include "hns3_logs.h"
      11                 :            : #include "hns3_flow.h"
      12                 :            : 
      13                 :            : #define NEXT_ITEM_OF_ACTION(act, actions, index) \
      14                 :            :         do { \
      15                 :            :                 (act) = (actions) + (index); \
      16                 :            :                 while ((act)->type == RTE_FLOW_ACTION_TYPE_VOID) { \
      17                 :            :                         (index)++; \
      18                 :            :                         (act) = (actions) + (index); \
      19                 :            :                 } \
      20                 :            :         } while (0)
      21                 :            : 
      22                 :            : #define NEXT_ITEM_OF_PATTERN(item, pattern, index) \
      23                 :            :         do { \
      24                 :            :                 (item) = (pattern) + (index); \
      25                 :            :                 while ((item)->type == RTE_FLOW_ITEM_TYPE_VOID) { \
      26                 :            :                         (index)++; \
      27                 :            :                         (item) = (pattern) + (index); \
      28                 :            :                 } \
      29                 :            :         } while (0)
      30                 :            : 
      31                 :            : #define HNS3_HASH_HDR_ETH       RTE_BIT64(0)
      32                 :            : #define HNS3_HASH_HDR_IPV4      RTE_BIT64(1)
      33                 :            : #define HNS3_HASH_HDR_IPV6      RTE_BIT64(2)
      34                 :            : #define HNS3_HASH_HDR_TCP       RTE_BIT64(3)
      35                 :            : #define HNS3_HASH_HDR_UDP       RTE_BIT64(4)
      36                 :            : #define HNS3_HASH_HDR_SCTP      RTE_BIT64(5)
      37                 :            : 
      38                 :            : #define HNS3_HASH_VOID_NEXT_ALLOW       BIT_ULL(RTE_FLOW_ITEM_TYPE_ETH)
      39                 :            : 
      40                 :            : #define HNS3_HASH_ETH_NEXT_ALLOW        (BIT_ULL(RTE_FLOW_ITEM_TYPE_IPV4) | \
      41                 :            :                                          BIT_ULL(RTE_FLOW_ITEM_TYPE_IPV6))
      42                 :            : 
      43                 :            : #define HNS3_HASH_IP_NEXT_ALLOW         (BIT_ULL(RTE_FLOW_ITEM_TYPE_TCP) | \
      44                 :            :                                          BIT_ULL(RTE_FLOW_ITEM_TYPE_UDP) | \
      45                 :            :                                          BIT_ULL(RTE_FLOW_ITEM_TYPE_SCTP))
      46                 :            : 
      47                 :            : static const uint64_t hash_pattern_next_allow_items[] = {
      48                 :            :         [RTE_FLOW_ITEM_TYPE_VOID] = HNS3_HASH_VOID_NEXT_ALLOW,
      49                 :            :         [RTE_FLOW_ITEM_TYPE_ETH]  = HNS3_HASH_ETH_NEXT_ALLOW,
      50                 :            :         [RTE_FLOW_ITEM_TYPE_IPV4] = HNS3_HASH_IP_NEXT_ALLOW,
      51                 :            :         [RTE_FLOW_ITEM_TYPE_IPV6] = HNS3_HASH_IP_NEXT_ALLOW,
      52                 :            : };
      53                 :            : 
      54                 :            : static const uint64_t hash_pattern_item_header[] = {
      55                 :            :         [RTE_FLOW_ITEM_TYPE_ETH]  = HNS3_HASH_HDR_ETH,
      56                 :            :         [RTE_FLOW_ITEM_TYPE_IPV4] = HNS3_HASH_HDR_IPV4,
      57                 :            :         [RTE_FLOW_ITEM_TYPE_IPV6] = HNS3_HASH_HDR_IPV6,
      58                 :            :         [RTE_FLOW_ITEM_TYPE_TCP]  = HNS3_HASH_HDR_TCP,
      59                 :            :         [RTE_FLOW_ITEM_TYPE_UDP]  = HNS3_HASH_HDR_UDP,
      60                 :            :         [RTE_FLOW_ITEM_TYPE_SCTP] = HNS3_HASH_HDR_SCTP,
      61                 :            : };
      62                 :            : 
      63                 :            : #define HNS3_HASH_IPV4          (HNS3_HASH_HDR_ETH | HNS3_HASH_HDR_IPV4)
      64                 :            : #define HNS3_HASH_IPV4_TCP      (HNS3_HASH_HDR_ETH | \
      65                 :            :                                  HNS3_HASH_HDR_IPV4 | \
      66                 :            :                                  HNS3_HASH_HDR_TCP)
      67                 :            : #define HNS3_HASH_IPV4_UDP      (HNS3_HASH_HDR_ETH | \
      68                 :            :                                  HNS3_HASH_HDR_IPV4 | \
      69                 :            :                                  HNS3_HASH_HDR_UDP)
      70                 :            : #define HNS3_HASH_IPV4_SCTP     (HNS3_HASH_HDR_ETH | \
      71                 :            :                                  HNS3_HASH_HDR_IPV4 | \
      72                 :            :                                  HNS3_HASH_HDR_SCTP)
      73                 :            : #define HNS3_HASH_IPV6          (HNS3_HASH_HDR_ETH | HNS3_HASH_HDR_IPV6)
      74                 :            : #define HNS3_HASH_IPV6_TCP      (HNS3_HASH_HDR_ETH | \
      75                 :            :                                  HNS3_HASH_HDR_IPV6 | \
      76                 :            :                                  HNS3_HASH_HDR_TCP)
      77                 :            : #define HNS3_HASH_IPV6_UDP      (HNS3_HASH_HDR_ETH | \
      78                 :            :                                  HNS3_HASH_HDR_IPV6 | \
      79                 :            :                                  HNS3_HASH_HDR_UDP)
      80                 :            : #define HNS3_HASH_IPV6_SCTP     (HNS3_HASH_HDR_ETH | \
      81                 :            :                                  HNS3_HASH_HDR_IPV6 | \
      82                 :            :                                  HNS3_HASH_HDR_SCTP)
      83                 :            : 
      84                 :            : static const struct hns3_hash_map_info {
      85                 :            :         /* flow type specified, zero means action works for all flow types. */
      86                 :            :         uint64_t pattern_type;
      87                 :            :         uint64_t rss_pctype; /* packet type with prefix RTE_ETH_RSS_xxx */
      88                 :            :         uint64_t l3l4_types; /* Supported L3/L4 RSS types for this packet type */
      89                 :            :         uint64_t hw_pctype; /* packet type in driver */
      90                 :            :         uint64_t tuple_mask; /* full tuples of the hw_pctype */
      91                 :            : } hash_map_table[] = {
      92                 :            :         /* IPV4 */
      93                 :            :         { HNS3_HASH_IPV4,
      94                 :            :           RTE_ETH_RSS_IPV4, HNS3_RSS_SUPPORT_L3_SRC_DST,
      95                 :            :           HNS3_RSS_PCTYPE_IPV4_NONF, HNS3_RSS_TUPLE_IPV4_NONF_M },
      96                 :            :         { HNS3_HASH_IPV4,
      97                 :            :           RTE_ETH_RSS_NONFRAG_IPV4_OTHER, HNS3_RSS_SUPPORT_L3_SRC_DST,
      98                 :            :           HNS3_RSS_PCTYPE_IPV4_NONF, HNS3_RSS_TUPLE_IPV4_NONF_M },
      99                 :            :         { HNS3_HASH_IPV4,
     100                 :            :           RTE_ETH_RSS_FRAG_IPV4, HNS3_RSS_SUPPORT_L3_SRC_DST,
     101                 :            :           HNS3_RSS_PCTYPE_IPV4_FLAG, HNS3_RSS_TUPLE_IPV4_FLAG_M },
     102                 :            :         { HNS3_HASH_IPV4_TCP,
     103                 :            :           RTE_ETH_RSS_NONFRAG_IPV4_TCP, HNS3_RSS_SUPPORT_L3L4,
     104                 :            :           HNS3_RSS_PCTYPE_IPV4_TCP, HNS3_RSS_TUPLE_IPV4_TCP_M },
     105                 :            :         { HNS3_HASH_IPV4_UDP,
     106                 :            :           RTE_ETH_RSS_NONFRAG_IPV4_UDP, HNS3_RSS_SUPPORT_L3L4,
     107                 :            :           HNS3_RSS_PCTYPE_IPV4_UDP, HNS3_RSS_TUPLE_IPV4_UDP_M },
     108                 :            :         { HNS3_HASH_IPV4_SCTP,
     109                 :            :           RTE_ETH_RSS_NONFRAG_IPV4_SCTP, HNS3_RSS_SUPPORT_L3L4,
     110                 :            :           HNS3_RSS_PCTYPE_IPV4_SCTP, HNS3_RSS_TUPLE_IPV4_SCTP_M },
     111                 :            :         /* IPV6 */
     112                 :            :         { HNS3_HASH_IPV6,
     113                 :            :           RTE_ETH_RSS_IPV6, HNS3_RSS_SUPPORT_L3_SRC_DST,
     114                 :            :           HNS3_RSS_PCTYPE_IPV6_NONF, HNS3_RSS_TUPLE_IPV6_NONF_M },
     115                 :            :         { HNS3_HASH_IPV6,
     116                 :            :           RTE_ETH_RSS_NONFRAG_IPV6_OTHER, HNS3_RSS_SUPPORT_L3_SRC_DST,
     117                 :            :           HNS3_RSS_PCTYPE_IPV6_NONF, HNS3_RSS_TUPLE_IPV6_NONF_M },
     118                 :            :         { HNS3_HASH_IPV6,
     119                 :            :           RTE_ETH_RSS_FRAG_IPV6, HNS3_RSS_SUPPORT_L3_SRC_DST,
     120                 :            :           HNS3_RSS_PCTYPE_IPV6_FLAG, HNS3_RSS_TUPLE_IPV6_FLAG_M },
     121                 :            :         { HNS3_HASH_IPV6_TCP,
     122                 :            :           RTE_ETH_RSS_NONFRAG_IPV6_TCP, HNS3_RSS_SUPPORT_L3L4,
     123                 :            :           HNS3_RSS_PCTYPE_IPV6_TCP, HNS3_RSS_TUPLE_IPV6_TCP_M },
     124                 :            :         { HNS3_HASH_IPV6_UDP,
     125                 :            :           RTE_ETH_RSS_NONFRAG_IPV6_UDP, HNS3_RSS_SUPPORT_L3L4,
     126                 :            :           HNS3_RSS_PCTYPE_IPV6_UDP, HNS3_RSS_TUPLE_IPV6_UDP_M },
     127                 :            :         { HNS3_HASH_IPV6_SCTP,
     128                 :            :           RTE_ETH_RSS_NONFRAG_IPV6_SCTP, HNS3_RSS_SUPPORT_L3L4,
     129                 :            :           HNS3_RSS_PCTYPE_IPV6_SCTP, HNS3_RSS_TUPLE_IPV6_SCTP_M },
     130                 :            : };
     131                 :            : 
     132                 :            : static const uint8_t full_mask[VNI_OR_TNI_LEN] = { 0xFF, 0xFF, 0xFF };
     133                 :            : static const uint8_t zero_mask[VNI_OR_TNI_LEN] = { 0x00, 0x00, 0x00 };
     134                 :            : 
     135                 :            : /* Special Filter id for non-specific packet flagging. Don't change value */
     136                 :            : #define HNS3_MAX_FILTER_ID      0x0FFF
     137                 :            : 
     138                 :            : #define ETHER_TYPE_MASK         0xFFFF
     139                 :            : #define IPPROTO_MASK            0xFF
     140                 :            : #define TUNNEL_TYPE_MASK        0xFFFF
     141                 :            : 
     142                 :            : #define HNS3_TUNNEL_TYPE_VXLAN          0x12B5
     143                 :            : #define HNS3_TUNNEL_TYPE_VXLAN_GPE      0x12B6
     144                 :            : #define HNS3_TUNNEL_TYPE_GENEVE         0x17C1
     145                 :            : #define HNS3_TUNNEL_TYPE_NVGRE          0x6558
     146                 :            : 
     147                 :            : static enum rte_flow_item_type first_items[] = {
     148                 :            :         RTE_FLOW_ITEM_TYPE_ETH,
     149                 :            :         RTE_FLOW_ITEM_TYPE_IPV4,
     150                 :            :         RTE_FLOW_ITEM_TYPE_IPV6,
     151                 :            :         RTE_FLOW_ITEM_TYPE_TCP,
     152                 :            :         RTE_FLOW_ITEM_TYPE_UDP,
     153                 :            :         RTE_FLOW_ITEM_TYPE_SCTP,
     154                 :            :         RTE_FLOW_ITEM_TYPE_ICMP,
     155                 :            :         RTE_FLOW_ITEM_TYPE_NVGRE,
     156                 :            :         RTE_FLOW_ITEM_TYPE_VXLAN,
     157                 :            :         RTE_FLOW_ITEM_TYPE_GENEVE,
     158                 :            :         RTE_FLOW_ITEM_TYPE_VXLAN_GPE,
     159                 :            :         RTE_FLOW_ITEM_TYPE_PTYPE
     160                 :            : };
     161                 :            : 
     162                 :            : static enum rte_flow_item_type L2_next_items[] = {
     163                 :            :         RTE_FLOW_ITEM_TYPE_VLAN,
     164                 :            :         RTE_FLOW_ITEM_TYPE_IPV4,
     165                 :            :         RTE_FLOW_ITEM_TYPE_IPV6,
     166                 :            :         RTE_FLOW_ITEM_TYPE_PTYPE
     167                 :            : };
     168                 :            : 
     169                 :            : static enum rte_flow_item_type L3_next_items[] = {
     170                 :            :         RTE_FLOW_ITEM_TYPE_TCP,
     171                 :            :         RTE_FLOW_ITEM_TYPE_UDP,
     172                 :            :         RTE_FLOW_ITEM_TYPE_SCTP,
     173                 :            :         RTE_FLOW_ITEM_TYPE_NVGRE,
     174                 :            :         RTE_FLOW_ITEM_TYPE_ICMP,
     175                 :            :         RTE_FLOW_ITEM_TYPE_PTYPE
     176                 :            : };
     177                 :            : 
     178                 :            : static enum rte_flow_item_type L4_next_items[] = {
     179                 :            :         RTE_FLOW_ITEM_TYPE_VXLAN,
     180                 :            :         RTE_FLOW_ITEM_TYPE_GENEVE,
     181                 :            :         RTE_FLOW_ITEM_TYPE_VXLAN_GPE
     182                 :            : };
     183                 :            : 
     184                 :            : static enum rte_flow_item_type tunnel_next_items[] = {
     185                 :            :         RTE_FLOW_ITEM_TYPE_ETH,
     186                 :            :         RTE_FLOW_ITEM_TYPE_VLAN
     187                 :            : };
     188                 :            : 
     189                 :            : struct items_step_mngr {
     190                 :            :         enum rte_flow_item_type *items;
     191                 :            :         size_t count;
     192                 :            : };
     193                 :            : 
     194                 :            : static inline void
     195                 :            : net_addr_to_host(uint32_t *dst, const rte_be32_t *src, size_t len)
     196                 :            : {
     197                 :            :         size_t i;
     198                 :            : 
     199   [ #  #  #  #  :          0 :         for (i = 0; i < len; i++)
             #  #  #  # ]
     200   [ #  #  #  #  :          0 :                 dst[i] = rte_be_to_cpu_32(src[i]);
             #  #  #  # ]
     201                 :            : }
     202                 :            : 
     203                 :            : /*
     204                 :            :  * This function is used to parse filter type.
     205                 :            :  * 1. As we know RSS is used to spread packets among several queues, the flow
     206                 :            :  *    API provide the struct rte_flow_action_rss, user could config its field
     207                 :            :  *    sush as: func/level/types/key/queue to control RSS function.
     208                 :            :  * 2. The flow API also supports queue region configuration for hns3. It was
     209                 :            :  *    implemented by FDIR + RSS in hns3 hardware, user can create one FDIR rule
     210                 :            :  *    which action is RSS queues region.
     211                 :            :  * 3. When action is RSS, we use the following rule to distinguish:
     212                 :            :  *    Case 1: pattern has ETH and all fields in RSS action except 'queues' are
     213                 :            :  *            zero or default, indicate it is queue region configuration.
     214                 :            :  *    Case other: an rss general action.
     215                 :            :  */
     216                 :            : static void
     217                 :          0 : hns3_parse_filter_type(const struct rte_flow_item pattern[],
     218                 :            :                        const struct rte_flow_action actions[],
     219                 :            :                        struct hns3_filter_info *filter_info)
     220                 :            : {
     221                 :            :         const struct rte_flow_action_rss *rss_act;
     222                 :            :         const struct rte_flow_action *act = NULL;
     223                 :            :         bool only_has_queues = false;
     224                 :            :         bool have_eth = false;
     225                 :            : 
     226         [ #  # ]:          0 :         for (; actions->type != RTE_FLOW_ACTION_TYPE_END; actions++) {
     227         [ #  # ]:          0 :                 if (actions->type == RTE_FLOW_ACTION_TYPE_RSS) {
     228                 :            :                         act = actions;
     229                 :            :                         break;
     230                 :            :                 }
     231                 :            :         }
     232         [ #  # ]:          0 :         if (act == NULL) {
     233                 :          0 :                 filter_info->type = RTE_ETH_FILTER_FDIR;
     234                 :          0 :                 return;
     235                 :            :         }
     236                 :            : 
     237         [ #  # ]:          0 :         for (; pattern->type != RTE_FLOW_ITEM_TYPE_END; pattern++) {
     238         [ #  # ]:          0 :                 if (pattern->type == RTE_FLOW_ITEM_TYPE_ETH) {
     239                 :            :                         have_eth = true;
     240                 :            :                         break;
     241                 :            :                 }
     242                 :            :         }
     243                 :            : 
     244                 :          0 :         rss_act = act->conf;
     245         [ #  # ]:          0 :         only_has_queues = (rss_act->queue_num > 0) &&
     246         [ #  # ]:          0 :                           (rss_act->func == RTE_ETH_HASH_FUNCTION_DEFAULT &&
     247   [ #  #  #  # ]:          0 :                            rss_act->types == 0 && rss_act->key_len == 0);
     248         [ #  # ]:          0 :         if (have_eth && only_has_queues) {
     249                 :            :                 /*
     250                 :            :                  * Pattern has ETH and all fields in RSS action except 'queues'
     251                 :            :                  * are zero or default, which indicates this is queue region
     252                 :            :                  * configuration.
     253                 :            :                  */
     254                 :          0 :                 filter_info->type = RTE_ETH_FILTER_FDIR;
     255                 :          0 :                 return;
     256                 :            :         }
     257                 :            : 
     258                 :          0 :         filter_info->type = RTE_ETH_FILTER_HASH;
     259                 :            : }
     260                 :            : 
     261                 :            : static inline struct hns3_flow_counter *
     262                 :            : hns3_counter_lookup(struct rte_eth_dev *dev, uint32_t id)
     263                 :            : {
     264                 :          0 :         struct hns3_adapter *hns = dev->data->dev_private;
     265                 :            :         struct hns3_pf *pf = &hns->pf;
     266                 :            :         struct hns3_flow_counter *cnt;
     267                 :            : 
     268   [ #  #  #  #  :          0 :         LIST_FOREACH(cnt, &pf->flow_counters, next) {
          #  #  #  #  #  
                #  #  # ]
     269   [ #  #  #  #  :          0 :                 if (cnt->id == id)
          #  #  #  #  #  
                #  #  # ]
     270                 :            :                         return cnt;
     271                 :            :         }
     272                 :            :         return NULL;
     273                 :            : }
     274                 :            : 
     275                 :            : static int
     276                 :          0 : hns3_counter_new(struct rte_eth_dev *dev, uint32_t indirect, uint32_t id,
     277                 :            :                  struct rte_flow_error *error)
     278                 :            : {
     279                 :          0 :         struct hns3_adapter *hns = dev->data->dev_private;
     280                 :            :         struct hns3_pf *pf = &hns->pf;
     281                 :          0 :         struct hns3_hw *hw = &hns->hw;
     282                 :            :         struct hns3_flow_counter *cnt;
     283                 :            :         uint64_t value;
     284                 :            :         int ret;
     285                 :            : 
     286                 :            :         cnt = hns3_counter_lookup(dev, id);
     287         [ #  # ]:          0 :         if (cnt) {
     288   [ #  #  #  # ]:          0 :                 if (!cnt->indirect || cnt->indirect != indirect)
     289                 :          0 :                         return rte_flow_error_set(error, EINVAL,
     290                 :            :                                 RTE_FLOW_ERROR_TYPE_ACTION_CONF,
     291                 :            :                                 cnt,
     292                 :            :                                 "Counter id is used, indirect flag not match");
     293                 :            :                 /* Clear the indirect counter on first use. */
     294         [ #  # ]:          0 :                 if (cnt->indirect && cnt->ref_cnt == 1)
     295                 :          0 :                         (void)hns3_fd_get_count(hw, id, &value);
     296                 :          0 :                 cnt->ref_cnt++;
     297                 :          0 :                 return 0;
     298                 :            :         }
     299                 :            : 
     300                 :            :         /* Clear the counter by read ops because the counter is read-clear */
     301                 :          0 :         ret = hns3_fd_get_count(hw, id, &value);
     302         [ #  # ]:          0 :         if (ret)
     303                 :          0 :                 return rte_flow_error_set(error, EIO,
     304                 :            :                                           RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
     305                 :            :                                           "Clear counter failed!");
     306                 :            : 
     307                 :          0 :         cnt = rte_zmalloc("hns3 counter", sizeof(*cnt), 0);
     308         [ #  # ]:          0 :         if (cnt == NULL)
     309                 :          0 :                 return rte_flow_error_set(error, ENOMEM,
     310                 :            :                                           RTE_FLOW_ERROR_TYPE_HANDLE, cnt,
     311                 :            :                                           "Alloc mem for counter failed");
     312                 :          0 :         cnt->id = id;
     313                 :          0 :         cnt->indirect = indirect;
     314                 :          0 :         cnt->ref_cnt = 1;
     315                 :          0 :         cnt->hits = 0;
     316         [ #  # ]:          0 :         LIST_INSERT_HEAD(&pf->flow_counters, cnt, next);
     317                 :          0 :         return 0;
     318                 :            : }
     319                 :            : 
     320                 :            : static int
     321                 :          0 : hns3_counter_query(struct rte_eth_dev *dev, struct rte_flow *flow,
     322                 :            :                    struct rte_flow_query_count *qc,
     323                 :            :                    struct rte_flow_error *error)
     324                 :            : {
     325                 :          0 :         struct hns3_adapter *hns = dev->data->dev_private;
     326                 :            :         struct hns3_flow_counter *cnt;
     327                 :            :         uint64_t value;
     328                 :            :         int ret;
     329                 :            : 
     330                 :            :         /* FDIR is available only in PF driver */
     331         [ #  # ]:          0 :         if (hns->is_vf)
     332                 :          0 :                 return rte_flow_error_set(error, ENOTSUP,
     333                 :            :                                           RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
     334                 :            :                                           "Fdir is not supported in VF");
     335                 :          0 :         cnt = hns3_counter_lookup(dev, flow->counter_id);
     336         [ #  # ]:          0 :         if (cnt == NULL)
     337                 :          0 :                 return rte_flow_error_set(error, EINVAL,
     338                 :            :                                           RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
     339                 :            :                                           "Can't find counter id");
     340                 :            : 
     341                 :          0 :         ret = hns3_fd_get_count(&hns->hw, flow->counter_id, &value);
     342         [ #  # ]:          0 :         if (ret) {
     343                 :          0 :                 rte_flow_error_set(error, -ret, RTE_FLOW_ERROR_TYPE_HANDLE,
     344                 :            :                                    NULL, "Read counter fail.");
     345                 :          0 :                 return ret;
     346                 :            :         }
     347                 :          0 :         qc->hits_set = 1;
     348                 :          0 :         qc->hits = value;
     349                 :          0 :         qc->bytes_set = 0;
     350                 :          0 :         qc->bytes = 0;
     351                 :            : 
     352                 :          0 :         return 0;
     353                 :            : }
     354                 :            : 
     355                 :            : static int
     356                 :          0 : hns3_counter_release(struct rte_eth_dev *dev, uint32_t id)
     357                 :            : {
     358                 :          0 :         struct hns3_adapter *hns = dev->data->dev_private;
     359                 :            :         struct hns3_hw *hw = &hns->hw;
     360                 :            :         struct hns3_flow_counter *cnt;
     361                 :            : 
     362                 :            :         cnt = hns3_counter_lookup(dev, id);
     363         [ #  # ]:          0 :         if (cnt == NULL) {
     364                 :          0 :                 hns3_err(hw, "Can't find available counter to release");
     365                 :          0 :                 return -EINVAL;
     366                 :            :         }
     367                 :          0 :         cnt->ref_cnt--;
     368         [ #  # ]:          0 :         if (cnt->ref_cnt == 0) {
     369         [ #  # ]:          0 :                 LIST_REMOVE(cnt, next);
     370                 :          0 :                 rte_free(cnt);
     371                 :            :         }
     372                 :            :         return 0;
     373                 :            : }
     374                 :            : 
     375                 :            : static void
     376                 :          0 : hns3_counter_flush(struct rte_eth_dev *dev)
     377                 :            : {
     378                 :          0 :         struct hns3_pf *pf = HNS3_DEV_PRIVATE_TO_PF(dev->data->dev_private);
     379                 :            :         LIST_HEAD(counters, hns3_flow_counter) indir_counters;
     380                 :            :         struct hns3_flow_counter *cnt_ptr;
     381                 :            : 
     382                 :          0 :         LIST_INIT(&indir_counters);
     383                 :          0 :         cnt_ptr = LIST_FIRST(&pf->flow_counters);
     384         [ #  # ]:          0 :         while (cnt_ptr) {
     385         [ #  # ]:          0 :                 LIST_REMOVE(cnt_ptr, next);
     386         [ #  # ]:          0 :                 if (cnt_ptr->indirect)
     387         [ #  # ]:          0 :                         LIST_INSERT_HEAD(&indir_counters, cnt_ptr, next);
     388                 :            :                 else
     389                 :          0 :                         rte_free(cnt_ptr);
     390                 :          0 :                 cnt_ptr = LIST_FIRST(&pf->flow_counters);
     391                 :            :         }
     392                 :            : 
     393                 :            :         /* Reset the indirect action and add to pf->flow_counters list. */
     394                 :          0 :         cnt_ptr = LIST_FIRST(&indir_counters);
     395         [ #  # ]:          0 :         while (cnt_ptr) {
     396         [ #  # ]:          0 :                 LIST_REMOVE(cnt_ptr, next);
     397                 :          0 :                 cnt_ptr->ref_cnt = 1;
     398                 :          0 :                 cnt_ptr->hits = 0;
     399         [ #  # ]:          0 :                 LIST_INSERT_HEAD(&pf->flow_counters, cnt_ptr, next);
     400                 :          0 :                 cnt_ptr = LIST_FIRST(&indir_counters);
     401                 :            :         }
     402                 :          0 : }
     403                 :            : 
     404                 :            : static int
     405                 :          0 : hns3_handle_action_queue(struct rte_eth_dev *dev,
     406                 :            :                          const struct rte_flow_action *action,
     407                 :            :                          struct hns3_fdir_rule *rule,
     408                 :            :                          struct rte_flow_error *error)
     409                 :            : {
     410                 :          0 :         struct hns3_adapter *hns = dev->data->dev_private;
     411                 :            :         const struct rte_flow_action_queue *queue;
     412                 :            :         struct hns3_hw *hw = &hns->hw;
     413                 :            : 
     414                 :          0 :         queue = (const struct rte_flow_action_queue *)action->conf;
     415         [ #  # ]:          0 :         if (queue->index >= hw->data->nb_rx_queues) {
     416                 :          0 :                 hns3_err(hw, "queue ID(%u) is greater than number of available queue (%u) in driver.",
     417                 :            :                          queue->index, hw->data->nb_rx_queues);
     418                 :          0 :                 return rte_flow_error_set(error, EINVAL,
     419                 :            :                                           RTE_FLOW_ERROR_TYPE_ACTION_CONF,
     420                 :            :                                           action, "Invalid queue ID in PF");
     421                 :            :         }
     422                 :            : 
     423                 :          0 :         rule->queue_id = queue->index;
     424                 :          0 :         rule->nb_queues = 1;
     425                 :          0 :         rule->action = HNS3_FD_ACTION_ACCEPT_PACKET;
     426                 :          0 :         return 0;
     427                 :            : }
     428                 :            : 
     429                 :            : static int
     430                 :          0 : hns3_handle_action_queue_region(struct rte_eth_dev *dev,
     431                 :            :                                 const struct rte_flow_action *action,
     432                 :            :                                 struct hns3_fdir_rule *rule,
     433                 :            :                                 struct rte_flow_error *error)
     434                 :            : {
     435                 :          0 :         struct hns3_adapter *hns = dev->data->dev_private;
     436                 :          0 :         const struct rte_flow_action_rss *conf = action->conf;
     437                 :            :         struct hns3_hw *hw = &hns->hw;
     438                 :            :         uint16_t idx;
     439                 :            : 
     440         [ #  # ]:          0 :         if (!hns3_dev_get_support(hw, FD_QUEUE_REGION))
     441                 :          0 :                 return rte_flow_error_set(error, ENOTSUP,
     442                 :            :                         RTE_FLOW_ERROR_TYPE_ACTION, action,
     443                 :            :                         "Not support config queue region!");
     444                 :            : 
     445         [ #  # ]:          0 :         if ((!rte_is_power_of_2(conf->queue_num)) ||
     446         [ #  # ]:          0 :                 conf->queue_num > hw->rss_size_max ||
     447         [ #  # ]:          0 :                 conf->queue[0] >= hw->data->nb_rx_queues ||
     448         [ #  # ]:          0 :                 conf->queue[0] + conf->queue_num > hw->data->nb_rx_queues) {
     449                 :          0 :                 return rte_flow_error_set(error, EINVAL,
     450                 :            :                         RTE_FLOW_ERROR_TYPE_ACTION_CONF, action,
     451                 :            :                         "Invalid start queue ID and queue num! the start queue "
     452                 :            :                         "ID must valid, the queue num must be power of 2 and "
     453                 :            :                         "<= rss_size_max.");
     454                 :            :         }
     455                 :            : 
     456         [ #  # ]:          0 :         for (idx = 1; idx < conf->queue_num; idx++) {
     457         [ #  # ]:          0 :                 if (conf->queue[idx] != conf->queue[idx - 1] + 1)
     458                 :          0 :                         return rte_flow_error_set(error, EINVAL,
     459                 :            :                                 RTE_FLOW_ERROR_TYPE_ACTION_CONF, action,
     460                 :            :                                 "Invalid queue ID sequence! the queue ID "
     461                 :            :                                 "must be continuous increment.");
     462                 :            :         }
     463                 :            : 
     464                 :          0 :         rule->queue_id = conf->queue[0];
     465                 :          0 :         rule->nb_queues = conf->queue_num;
     466                 :          0 :         rule->action = HNS3_FD_ACTION_ACCEPT_PACKET;
     467                 :          0 :         return 0;
     468                 :            : }
     469                 :            : 
     470                 :            : static int
     471                 :          0 : hns3_handle_action_indirect(struct rte_eth_dev *dev,
     472                 :            :                             const struct rte_flow_action *action,
     473                 :            :                             struct hns3_fdir_rule *rule,
     474                 :            :                             struct rte_flow_error *error)
     475                 :            : {
     476                 :            :         struct rte_flow_action_handle indir;
     477                 :            : 
     478                 :          0 :         indir.val64 = (uint64_t)action->conf;
     479         [ #  # ]:          0 :         if (indir.indirect_type != HNS3_INDIRECT_ACTION_TYPE_COUNT)
     480                 :          0 :                 return rte_flow_error_set(error, EINVAL,
     481                 :            :                                 RTE_FLOW_ERROR_TYPE_ACTION_CONF,
     482                 :            :                                 action, "Invalid indirect type");
     483                 :            : 
     484         [ #  # ]:          0 :         if (hns3_counter_lookup(dev, indir.counter_id) == NULL)
     485                 :          0 :                 return rte_flow_error_set(error, EINVAL,
     486                 :            :                                 RTE_FLOW_ERROR_TYPE_ACTION_CONF,
     487                 :            :                                 action, "Counter id not exist");
     488                 :            : 
     489                 :          0 :         rule->act_cnt.id = indir.counter_id;
     490                 :          0 :         rule->flags |= (HNS3_RULE_FLAG_COUNTER | HNS3_RULE_FLAG_COUNTER_INDIR);
     491                 :            : 
     492                 :          0 :         return 0;
     493                 :            : }
     494                 :            : 
     495                 :            : /*
     496                 :            :  * Parse actions structure from the provided pattern.
     497                 :            :  * The pattern is validated as the items are copied.
     498                 :            :  *
     499                 :            :  * @param actions[in]
     500                 :            :  * @param rule[out]
     501                 :            :  *   NIC specific actions derived from the actions.
     502                 :            :  * @param error[out]
     503                 :            :  */
     504                 :            : static int
     505                 :          0 : hns3_handle_actions(struct rte_eth_dev *dev,
     506                 :            :                     const struct rte_flow_action actions[],
     507                 :            :                     struct hns3_fdir_rule *rule, struct rte_flow_error *error)
     508                 :            : {
     509                 :          0 :         struct hns3_adapter *hns = dev->data->dev_private;
     510                 :            :         const struct rte_flow_action_count *act_count;
     511                 :            :         const struct rte_flow_action_mark *mark;
     512                 :            :         struct hns3_pf *pf = &hns->pf;
     513                 :            :         uint32_t counter_num;
     514                 :            :         int ret;
     515                 :            : 
     516         [ #  # ]:          0 :         for (; actions->type != RTE_FLOW_ACTION_TYPE_END; actions++) {
     517   [ #  #  #  #  :          0 :                 switch (actions->type) {
             #  #  #  #  
                      # ]
     518                 :          0 :                 case RTE_FLOW_ACTION_TYPE_QUEUE:
     519                 :          0 :                         ret = hns3_handle_action_queue(dev, actions, rule,
     520                 :            :                                                        error);
     521         [ #  # ]:          0 :                         if (ret)
     522                 :          0 :                                 return ret;
     523                 :            :                         break;
     524                 :          0 :                 case RTE_FLOW_ACTION_TYPE_DROP:
     525                 :          0 :                         rule->action = HNS3_FD_ACTION_DROP_PACKET;
     526                 :          0 :                         break;
     527                 :            :                 /*
     528                 :            :                  * Here RSS's real action is queue region.
     529                 :            :                  * Queue region is implemented by FDIR + RSS in hns3 hardware,
     530                 :            :                  * the FDIR's action is one queue region (start_queue_id and
     531                 :            :                  * queue_num), then RSS spread packets to the queue region by
     532                 :            :                  * RSS algorithm.
     533                 :            :                  */
     534                 :          0 :                 case RTE_FLOW_ACTION_TYPE_RSS:
     535                 :          0 :                         ret = hns3_handle_action_queue_region(dev, actions,
     536                 :            :                                                               rule, error);
     537         [ #  # ]:          0 :                         if (ret)
     538                 :          0 :                                 return ret;
     539                 :            :                         break;
     540                 :          0 :                 case RTE_FLOW_ACTION_TYPE_MARK:
     541                 :          0 :                         mark =
     542                 :            :                             (const struct rte_flow_action_mark *)actions->conf;
     543         [ #  # ]:          0 :                         if (mark->id >= HNS3_MAX_FILTER_ID)
     544                 :          0 :                                 return rte_flow_error_set(error, EINVAL,
     545                 :            :                                                 RTE_FLOW_ERROR_TYPE_ACTION_CONF,
     546                 :            :                                                 actions,
     547                 :            :                                                 "Invalid Mark ID");
     548                 :          0 :                         rule->fd_id = mark->id;
     549                 :          0 :                         rule->flags |= HNS3_RULE_FLAG_FDID;
     550                 :          0 :                         break;
     551                 :          0 :                 case RTE_FLOW_ACTION_TYPE_FLAG:
     552                 :          0 :                         rule->fd_id = HNS3_MAX_FILTER_ID;
     553                 :          0 :                         rule->flags |= HNS3_RULE_FLAG_FDID;
     554                 :          0 :                         break;
     555                 :          0 :                 case RTE_FLOW_ACTION_TYPE_COUNT:
     556                 :          0 :                         act_count =
     557                 :            :                             (const struct rte_flow_action_count *)actions->conf;
     558                 :          0 :                         counter_num = pf->fdir.fd_cfg.cnt_num[HNS3_FD_STAGE_1];
     559         [ #  # ]:          0 :                         if (act_count->id >= counter_num)
     560                 :          0 :                                 return rte_flow_error_set(error, EINVAL,
     561                 :            :                                                 RTE_FLOW_ERROR_TYPE_ACTION_CONF,
     562                 :            :                                                 actions,
     563                 :            :                                                 "Invalid counter id");
     564                 :          0 :                         rule->act_cnt = *act_count;
     565                 :          0 :                         rule->flags |= HNS3_RULE_FLAG_COUNTER;
     566                 :          0 :                         rule->flags &= ~HNS3_RULE_FLAG_COUNTER_INDIR;
     567                 :          0 :                         break;
     568                 :          0 :                 case RTE_FLOW_ACTION_TYPE_INDIRECT:
     569                 :          0 :                         ret = hns3_handle_action_indirect(dev, actions, rule,
     570                 :            :                                                           error);
     571         [ #  # ]:          0 :                         if (ret)
     572                 :          0 :                                 return ret;
     573                 :            :                         break;
     574                 :            :                 case RTE_FLOW_ACTION_TYPE_VOID:
     575                 :            :                         break;
     576                 :          0 :                 default:
     577                 :          0 :                         return rte_flow_error_set(error, ENOTSUP,
     578                 :            :                                                   RTE_FLOW_ERROR_TYPE_ACTION,
     579                 :            :                                                   NULL, "Unsupported action");
     580                 :            :                 }
     581                 :            :         }
     582                 :            : 
     583                 :            :         return 0;
     584                 :            : }
     585                 :            : 
     586                 :            : static int
     587                 :          0 : hns3_check_attr(const struct rte_flow_attr *attr, struct rte_flow_error *error)
     588                 :            : {
     589         [ #  # ]:          0 :         if (!attr->ingress)
     590                 :          0 :                 return rte_flow_error_set(error, EINVAL,
     591                 :            :                                           RTE_FLOW_ERROR_TYPE_ATTR_INGRESS,
     592                 :            :                                           attr, "Ingress can't be zero");
     593         [ #  # ]:          0 :         if (attr->egress)
     594                 :          0 :                 return rte_flow_error_set(error, ENOTSUP,
     595                 :            :                                           RTE_FLOW_ERROR_TYPE_ATTR_EGRESS,
     596                 :            :                                           attr, "Not support egress");
     597         [ #  # ]:          0 :         if (attr->transfer)
     598                 :          0 :                 return rte_flow_error_set(error, ENOTSUP,
     599                 :            :                                           RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER,
     600                 :            :                                           attr, "No support for transfer");
     601         [ #  # ]:          0 :         if (attr->group)
     602                 :          0 :                 return rte_flow_error_set(error, ENOTSUP,
     603                 :            :                                           RTE_FLOW_ERROR_TYPE_ATTR_GROUP,
     604                 :            :                                           attr, "Not support group");
     605                 :            :         return 0;
     606                 :            : }
     607                 :            : 
     608                 :            : static int
     609                 :          0 : hns3_check_tuple(const struct rte_eth_dev *dev, const struct hns3_fdir_rule *rule,
     610                 :            :                  struct rte_flow_error *error)
     611                 :            : {
     612                 :          0 :         const char * const err_msg[] = {
     613                 :            :                 "Not support outer dst mac",
     614                 :            :                 "Not support outer src mac",
     615                 :            :                 "Not support outer vlan1 tag",
     616                 :            :                 "Not support outer vlan2 tag",
     617                 :            :                 "Not support outer eth type",
     618                 :            :                 "Not support outer l2 rsv",
     619                 :            :                 "Not support outer ip tos",
     620                 :            :                 "Not support outer ip proto",
     621                 :            :                 "Not support outer src ip",
     622                 :            :                 "Not support outer dst ip",
     623                 :            :                 "Not support outer l3 rsv",
     624                 :            :                 "Not support outer src port",
     625                 :            :                 "Not support outer dst port",
     626                 :            :                 "Not support outer l4 rsv",
     627                 :            :                 "Not support outer tun vni",
     628                 :            :                 "Not support outer tun flow id",
     629                 :            :                 "Not support inner dst mac",
     630                 :            :                 "Not support inner src mac",
     631                 :            :                 "Not support inner vlan tag1",
     632                 :            :                 "Not support inner vlan tag2",
     633                 :            :                 "Not support inner eth type",
     634                 :            :                 "Not support inner l2 rsv",
     635                 :            :                 "Not support inner ip tos",
     636                 :            :                 "Not support inner ip proto",
     637                 :            :                 "Not support inner src ip",
     638                 :            :                 "Not support inner dst ip",
     639                 :            :                 "Not support inner l3 rsv",
     640                 :            :                 "Not support inner src port",
     641                 :            :                 "Not support inner dst port",
     642                 :            :                 "Not support inner sctp tag",
     643                 :            :         };
     644                 :          0 :         struct hns3_adapter *hns = dev->data->dev_private;
     645                 :          0 :         uint32_t tuple_active = hns->pf.fdir.fd_cfg.key_cfg[HNS3_FD_STAGE_1].tuple_active;
     646                 :            :         uint32_t i;
     647                 :            : 
     648         [ #  # ]:          0 :         for (i = 0; i < MAX_TUPLE; i++) {
     649         [ #  # ]:          0 :                 if ((rule->input_set & BIT(i)) == 0)
     650                 :          0 :                         continue;
     651         [ #  # ]:          0 :                 if (tuple_active & BIT(i))
     652                 :          0 :                         continue;
     653                 :          0 :                 return rte_flow_error_set(error, ENOTSUP,
     654                 :            :                                           RTE_FLOW_ERROR_TYPE_ITEM,
     655                 :          0 :                                           NULL, err_msg[i]);
     656                 :            :         }
     657                 :            : 
     658                 :            :         return 0;
     659                 :            : }
     660                 :            : 
     661                 :            : static int
     662                 :          0 : hns3_parse_eth(const struct rte_flow_item *item, struct hns3_fdir_rule *rule,
     663                 :            :                struct rte_flow_error *error __rte_unused)
     664                 :            : {
     665                 :            :         const struct rte_flow_item_eth *eth_spec;
     666                 :            :         const struct rte_flow_item_eth *eth_mask;
     667                 :            : 
     668                 :            :         /* Only used to describe the protocol stack. */
     669   [ #  #  #  # ]:          0 :         if (item->spec == NULL && item->mask == NULL)
     670                 :            :                 return 0;
     671                 :            : 
     672                 :          0 :         eth_mask = item->mask;
     673         [ #  # ]:          0 :         if (eth_mask) {
     674         [ #  # ]:          0 :                 if (eth_mask->hdr.ether_type) {
     675                 :          0 :                         hns3_set_bit(rule->input_set, INNER_ETH_TYPE, 1);
     676                 :          0 :                         rule->key_conf.mask.ether_type =
     677         [ #  # ]:          0 :                             rte_be_to_cpu_16(eth_mask->hdr.ether_type);
     678                 :            :                 }
     679         [ #  # ]:          0 :                 if (!rte_is_zero_ether_addr(&eth_mask->hdr.src_addr)) {
     680                 :          0 :                         hns3_set_bit(rule->input_set, INNER_SRC_MAC, 1);
     681                 :          0 :                         memcpy(rule->key_conf.mask.src_mac,
     682                 :          0 :                                eth_mask->hdr.src_addr.addr_bytes, RTE_ETHER_ADDR_LEN);
     683                 :            :                 }
     684         [ #  # ]:          0 :                 if (!rte_is_zero_ether_addr(&eth_mask->hdr.dst_addr)) {
     685                 :          0 :                         hns3_set_bit(rule->input_set, INNER_DST_MAC, 1);
     686                 :          0 :                         memcpy(rule->key_conf.mask.dst_mac,
     687                 :          0 :                                eth_mask->hdr.dst_addr.addr_bytes, RTE_ETHER_ADDR_LEN);
     688                 :            :                 }
     689         [ #  # ]:          0 :                 if (eth_mask->has_vlan)
     690                 :          0 :                         rule->has_vlan_m = true;
     691                 :            :         }
     692                 :            : 
     693                 :          0 :         eth_spec = item->spec;
     694   [ #  #  #  #  :          0 :         if (eth_mask && eth_mask->has_vlan && eth_spec->has_vlan) {
                   #  # ]
     695                 :          0 :                 rule->key_conf.vlan_num++;
     696                 :          0 :                 rule->has_vlan_v = true;
     697                 :            :         }
     698                 :            : 
     699         [ #  # ]:          0 :         rule->key_conf.spec.ether_type = rte_be_to_cpu_16(eth_spec->hdr.ether_type);
     700                 :          0 :         memcpy(rule->key_conf.spec.src_mac, eth_spec->hdr.src_addr.addr_bytes,
     701                 :            :                RTE_ETHER_ADDR_LEN);
     702                 :          0 :         memcpy(rule->key_conf.spec.dst_mac, eth_spec->hdr.dst_addr.addr_bytes,
     703                 :            :                RTE_ETHER_ADDR_LEN);
     704                 :          0 :         return 0;
     705                 :            : }
     706                 :            : 
     707                 :            : static int
     708                 :          0 : hns3_parse_vlan(const struct rte_flow_item *item, struct hns3_fdir_rule *rule,
     709                 :            :                 struct rte_flow_error *error)
     710                 :            : {
     711                 :            :         const struct rte_flow_item_vlan *vlan_spec;
     712                 :            :         const struct rte_flow_item_vlan *vlan_mask;
     713                 :            : 
     714   [ #  #  #  # ]:          0 :         if (rule->has_vlan_m && !rule->has_vlan_v)
     715                 :          0 :                 return rte_flow_error_set(error, EINVAL,
     716                 :            :                                           RTE_FLOW_ERROR_TYPE_ITEM, item,
     717                 :            :                                           "VLAN item is conflict with 'has_vlan is 0' in ETH item");
     718                 :            : 
     719   [ #  #  #  # ]:          0 :         if (rule->has_more_vlan_m && !rule->has_more_vlan_v)
     720                 :          0 :                 return rte_flow_error_set(error, EINVAL,
     721                 :            :                                           RTE_FLOW_ERROR_TYPE_ITEM, item,
     722                 :            :                                           "VLAN item is conflict with 'has_more_vlan is 0' in the previous VLAN item");
     723                 :            : 
     724   [ #  #  #  # ]:          0 :         if (rule->has_vlan_m && rule->has_vlan_v) {
     725                 :          0 :                 rule->has_vlan_m = false;
     726                 :          0 :                 rule->key_conf.vlan_num--;
     727                 :            :         }
     728                 :            : 
     729   [ #  #  #  # ]:          0 :         if (rule->has_more_vlan_m && rule->has_more_vlan_v) {
     730                 :          0 :                 rule->has_more_vlan_m = false;
     731                 :          0 :                 rule->key_conf.vlan_num--;
     732                 :            :         }
     733                 :            : 
     734                 :          0 :         rule->key_conf.vlan_num++;
     735         [ #  # ]:          0 :         if (rule->key_conf.vlan_num > VLAN_TAG_NUM_MAX)
     736                 :          0 :                 return rte_flow_error_set(error, EINVAL,
     737                 :            :                                           RTE_FLOW_ERROR_TYPE_ITEM, item,
     738                 :            :                                           "Vlan_num is more than 2");
     739                 :            : 
     740                 :            :         /* Only used to describe the protocol stack. */
     741   [ #  #  #  # ]:          0 :         if (item->spec == NULL && item->mask == NULL)
     742                 :            :                 return 0;
     743                 :            : 
     744                 :          0 :         vlan_mask = item->mask;
     745         [ #  # ]:          0 :         if (vlan_mask) {
     746         [ #  # ]:          0 :                 if (vlan_mask->hdr.vlan_tci) {
     747         [ #  # ]:          0 :                         if (rule->key_conf.vlan_num == 1) {
     748                 :          0 :                                 hns3_set_bit(rule->input_set, INNER_VLAN_TAG1,
     749                 :            :                                              1);
     750                 :          0 :                                 rule->key_conf.mask.vlan_tag1 =
     751         [ #  # ]:          0 :                                     rte_be_to_cpu_16(vlan_mask->hdr.vlan_tci);
     752                 :            :                         } else {
     753                 :          0 :                                 hns3_set_bit(rule->input_set, INNER_VLAN_TAG2,
     754                 :            :                                              1);
     755                 :          0 :                                 rule->key_conf.mask.vlan_tag2 =
     756         [ #  # ]:          0 :                                     rte_be_to_cpu_16(vlan_mask->hdr.vlan_tci);
     757                 :            :                         }
     758                 :            :                 }
     759         [ #  # ]:          0 :                 if (vlan_mask->has_more_vlan)
     760                 :          0 :                         rule->has_more_vlan_m = true;
     761                 :            :         }
     762                 :            : 
     763                 :            :         vlan_spec = item->spec;
     764         [ #  # ]:          0 :         if (rule->key_conf.vlan_num == 1)
     765                 :          0 :                 rule->key_conf.spec.vlan_tag1 =
     766         [ #  # ]:          0 :                     rte_be_to_cpu_16(vlan_spec->hdr.vlan_tci);
     767                 :            :         else
     768                 :          0 :                 rule->key_conf.spec.vlan_tag2 =
     769         [ #  # ]:          0 :                     rte_be_to_cpu_16(vlan_spec->hdr.vlan_tci);
     770                 :            : 
     771   [ #  #  #  #  :          0 :         if (vlan_mask && vlan_mask->has_more_vlan && vlan_spec->has_more_vlan) {
                   #  # ]
     772                 :          0 :                 rule->key_conf.vlan_num++;
     773         [ #  # ]:          0 :                 if (rule->key_conf.vlan_num > VLAN_TAG_NUM_MAX)
     774                 :          0 :                         return rte_flow_error_set(error, EINVAL,
     775                 :            :                                           RTE_FLOW_ERROR_TYPE_ITEM, item,
     776                 :            :                                           "Vlan_num is more than 2");
     777                 :          0 :                 rule->has_more_vlan_v = true;
     778                 :            :         }
     779                 :            : 
     780                 :            :         return 0;
     781                 :            : }
     782                 :            : 
     783                 :            : static bool
     784                 :            : hns3_check_ipv4_mask_supported(const struct rte_flow_item_ipv4 *ipv4_mask)
     785                 :            : {
     786   [ #  #  #  # ]:          0 :         if (ipv4_mask->hdr.total_length || ipv4_mask->hdr.packet_id ||
     787   [ #  #  #  # ]:          0 :             ipv4_mask->hdr.fragment_offset || ipv4_mask->hdr.time_to_live ||
     788         [ #  # ]:          0 :             ipv4_mask->hdr.hdr_checksum)
     789                 :            :                 return false;
     790                 :            : 
     791                 :            :         return true;
     792                 :            : }
     793                 :            : 
     794                 :            : static int
     795                 :          0 : hns3_parse_ipv4(const struct rte_flow_item *item, struct hns3_fdir_rule *rule,
     796                 :            :                 struct rte_flow_error *error)
     797                 :            : {
     798                 :            :         const struct rte_flow_item_ipv4 *ipv4_spec;
     799                 :            :         const struct rte_flow_item_ipv4 *ipv4_mask;
     800                 :            : 
     801                 :          0 :         hns3_set_bit(rule->input_set, INNER_ETH_TYPE, 1);
     802                 :          0 :         rule->key_conf.spec.ether_type = RTE_ETHER_TYPE_IPV4;
     803                 :          0 :         rule->key_conf.mask.ether_type = ETHER_TYPE_MASK;
     804                 :            : 
     805                 :            :         /* Only used to describe the protocol stack. */
     806   [ #  #  #  # ]:          0 :         if (item->spec == NULL && item->mask == NULL)
     807                 :            :                 return 0;
     808                 :            : 
     809         [ #  # ]:          0 :         if (item->mask) {
     810                 :            :                 ipv4_mask = item->mask;
     811                 :            :                 if (!hns3_check_ipv4_mask_supported(ipv4_mask)) {
     812                 :          0 :                         return rte_flow_error_set(error, EINVAL,
     813                 :            :                                                   RTE_FLOW_ERROR_TYPE_ITEM_MASK,
     814                 :            :                                                   item,
     815                 :            :                                                   "Only support src & dst ip,tos,proto in IPV4");
     816                 :            :                 }
     817                 :            : 
     818         [ #  # ]:          0 :                 if (ipv4_mask->hdr.src_addr) {
     819                 :          0 :                         hns3_set_bit(rule->input_set, INNER_SRC_IP, 1);
     820                 :          0 :                         rule->key_conf.mask.src_ip[IP_ADDR_KEY_ID] =
     821         [ #  # ]:          0 :                             rte_be_to_cpu_32(ipv4_mask->hdr.src_addr);
     822                 :            :                 }
     823                 :            : 
     824         [ #  # ]:          0 :                 if (ipv4_mask->hdr.dst_addr) {
     825                 :          0 :                         hns3_set_bit(rule->input_set, INNER_DST_IP, 1);
     826                 :          0 :                         rule->key_conf.mask.dst_ip[IP_ADDR_KEY_ID] =
     827         [ #  # ]:          0 :                             rte_be_to_cpu_32(ipv4_mask->hdr.dst_addr);
     828                 :            :                 }
     829                 :            : 
     830         [ #  # ]:          0 :                 if (ipv4_mask->hdr.type_of_service) {
     831                 :          0 :                         hns3_set_bit(rule->input_set, INNER_IP_TOS, 1);
     832                 :          0 :                         rule->key_conf.mask.ip_tos =
     833                 :            :                             ipv4_mask->hdr.type_of_service;
     834                 :            :                 }
     835                 :            : 
     836         [ #  # ]:          0 :                 if (ipv4_mask->hdr.next_proto_id) {
     837                 :          0 :                         hns3_set_bit(rule->input_set, INNER_IP_PROTO, 1);
     838                 :          0 :                         rule->key_conf.mask.ip_proto =
     839                 :            :                             ipv4_mask->hdr.next_proto_id;
     840                 :            :                 }
     841                 :            :         }
     842                 :            : 
     843                 :            :         ipv4_spec = item->spec;
     844                 :          0 :         rule->key_conf.spec.src_ip[IP_ADDR_KEY_ID] =
     845         [ #  # ]:          0 :             rte_be_to_cpu_32(ipv4_spec->hdr.src_addr);
     846                 :          0 :         rule->key_conf.spec.dst_ip[IP_ADDR_KEY_ID] =
     847         [ #  # ]:          0 :             rte_be_to_cpu_32(ipv4_spec->hdr.dst_addr);
     848                 :          0 :         rule->key_conf.spec.ip_tos = ipv4_spec->hdr.type_of_service;
     849                 :          0 :         rule->key_conf.spec.ip_proto = ipv4_spec->hdr.next_proto_id;
     850                 :          0 :         return 0;
     851                 :            : }
     852                 :            : 
     853                 :            : static int
     854                 :          0 : hns3_parse_ipv6(const struct rte_flow_item *item, struct hns3_fdir_rule *rule,
     855                 :            :                 struct rte_flow_error *error)
     856                 :            : {
     857                 :            :         const struct rte_flow_item_ipv6 *ipv6_spec;
     858                 :            :         const struct rte_flow_item_ipv6 *ipv6_mask;
     859                 :            : 
     860                 :          0 :         hns3_set_bit(rule->input_set, INNER_ETH_TYPE, 1);
     861                 :          0 :         rule->key_conf.spec.ether_type = RTE_ETHER_TYPE_IPV6;
     862                 :          0 :         rule->key_conf.mask.ether_type = ETHER_TYPE_MASK;
     863                 :            : 
     864                 :            :         /* Only used to describe the protocol stack. */
     865   [ #  #  #  # ]:          0 :         if (item->spec == NULL && item->mask == NULL)
     866                 :            :                 return 0;
     867                 :            : 
     868         [ #  # ]:          0 :         if (item->mask) {
     869                 :            :                 ipv6_mask = item->mask;
     870   [ #  #  #  # ]:          0 :                 if (ipv6_mask->hdr.vtc_flow || ipv6_mask->hdr.payload_len ||
     871                 :            :                     ipv6_mask->hdr.hop_limits) {
     872                 :          0 :                         return rte_flow_error_set(error, EINVAL,
     873                 :            :                                                   RTE_FLOW_ERROR_TYPE_ITEM_MASK,
     874                 :            :                                                   item,
     875                 :            :                                                   "Only support src & dst ip,proto in IPV6");
     876                 :            :                 }
     877                 :          0 :                 net_addr_to_host(rule->key_conf.mask.src_ip,
     878                 :          0 :                                  (const rte_be32_t *)&ipv6_mask->hdr.src_addr,
     879                 :            :                                  IP_ADDR_LEN);
     880                 :          0 :                 net_addr_to_host(rule->key_conf.mask.dst_ip,
     881                 :          0 :                                  (const rte_be32_t *)&ipv6_mask->hdr.dst_addr,
     882                 :            :                                  IP_ADDR_LEN);
     883                 :          0 :                 rule->key_conf.mask.ip_proto = ipv6_mask->hdr.proto;
     884         [ #  # ]:          0 :                 if (rule->key_conf.mask.src_ip[IP_ADDR_KEY_ID])
     885                 :          0 :                         hns3_set_bit(rule->input_set, INNER_SRC_IP, 1);
     886         [ #  # ]:          0 :                 if (rule->key_conf.mask.dst_ip[IP_ADDR_KEY_ID])
     887                 :          0 :                         hns3_set_bit(rule->input_set, INNER_DST_IP, 1);
     888         [ #  # ]:          0 :                 if (ipv6_mask->hdr.proto)
     889                 :          0 :                         hns3_set_bit(rule->input_set, INNER_IP_PROTO, 1);
     890                 :            :         }
     891                 :            : 
     892                 :            :         ipv6_spec = item->spec;
     893                 :          0 :         net_addr_to_host(rule->key_conf.spec.src_ip,
     894                 :          0 :                          (const rte_be32_t *)&ipv6_spec->hdr.src_addr,
     895                 :            :                          IP_ADDR_LEN);
     896                 :          0 :         net_addr_to_host(rule->key_conf.spec.dst_ip,
     897                 :          0 :                          (const rte_be32_t *)&ipv6_spec->hdr.dst_addr,
     898                 :            :                          IP_ADDR_LEN);
     899                 :          0 :         rule->key_conf.spec.ip_proto = ipv6_spec->hdr.proto;
     900                 :            : 
     901                 :          0 :         return 0;
     902                 :            : }
     903                 :            : 
     904                 :            : static bool
     905                 :          0 : hns3_check_tcp_mask_supported(const struct rte_flow_item_tcp *tcp_mask)
     906                 :            : {
     907   [ #  #  #  # ]:          0 :         if (tcp_mask->hdr.sent_seq || tcp_mask->hdr.recv_ack ||
     908   [ #  #  #  # ]:          0 :             tcp_mask->hdr.data_off || tcp_mask->hdr.tcp_flags ||
     909   [ #  #  #  # ]:          0 :             tcp_mask->hdr.rx_win || tcp_mask->hdr.cksum ||
     910         [ #  # ]:          0 :             tcp_mask->hdr.tcp_urp)
     911                 :          0 :                 return false;
     912                 :            : 
     913                 :            :         return true;
     914                 :            : }
     915                 :            : 
     916                 :            : static int
     917                 :          0 : hns3_parse_tcp(const struct rte_flow_item *item, struct hns3_fdir_rule *rule,
     918                 :            :                struct rte_flow_error *error)
     919                 :            : {
     920                 :            :         const struct rte_flow_item_tcp *tcp_spec;
     921                 :            :         const struct rte_flow_item_tcp *tcp_mask;
     922                 :            : 
     923                 :          0 :         hns3_set_bit(rule->input_set, INNER_IP_PROTO, 1);
     924                 :          0 :         rule->key_conf.spec.ip_proto = IPPROTO_TCP;
     925                 :          0 :         rule->key_conf.mask.ip_proto = IPPROTO_MASK;
     926                 :            : 
     927                 :            :         /* Only used to describe the protocol stack. */
     928   [ #  #  #  # ]:          0 :         if (item->spec == NULL && item->mask == NULL)
     929                 :            :                 return 0;
     930                 :            : 
     931         [ #  # ]:          0 :         if (item->mask) {
     932                 :            :                 tcp_mask = item->mask;
     933         [ #  # ]:          0 :                 if (!hns3_check_tcp_mask_supported(tcp_mask)) {
     934                 :          0 :                         return rte_flow_error_set(error, EINVAL,
     935                 :            :                                                   RTE_FLOW_ERROR_TYPE_ITEM_MASK,
     936                 :            :                                                   item,
     937                 :            :                                                   "Only support src & dst port in TCP");
     938                 :            :                 }
     939                 :            : 
     940         [ #  # ]:          0 :                 if (tcp_mask->hdr.src_port) {
     941                 :          0 :                         hns3_set_bit(rule->input_set, INNER_SRC_PORT, 1);
     942                 :          0 :                         rule->key_conf.mask.src_port =
     943         [ #  # ]:          0 :                             rte_be_to_cpu_16(tcp_mask->hdr.src_port);
     944                 :            :                 }
     945         [ #  # ]:          0 :                 if (tcp_mask->hdr.dst_port) {
     946                 :          0 :                         hns3_set_bit(rule->input_set, INNER_DST_PORT, 1);
     947                 :          0 :                         rule->key_conf.mask.dst_port =
     948         [ #  # ]:          0 :                             rte_be_to_cpu_16(tcp_mask->hdr.dst_port);
     949                 :            :                 }
     950                 :            :         }
     951                 :            : 
     952                 :            :         tcp_spec = item->spec;
     953         [ #  # ]:          0 :         rule->key_conf.spec.src_port = rte_be_to_cpu_16(tcp_spec->hdr.src_port);
     954         [ #  # ]:          0 :         rule->key_conf.spec.dst_port = rte_be_to_cpu_16(tcp_spec->hdr.dst_port);
     955                 :            : 
     956                 :          0 :         return 0;
     957                 :            : }
     958                 :            : 
     959                 :            : static int
     960                 :          0 : hns3_parse_udp(const struct rte_flow_item *item, struct hns3_fdir_rule *rule,
     961                 :            :                struct rte_flow_error *error)
     962                 :            : {
     963                 :            :         const struct rte_flow_item_udp *udp_spec;
     964                 :            :         const struct rte_flow_item_udp *udp_mask;
     965                 :            : 
     966                 :          0 :         hns3_set_bit(rule->input_set, INNER_IP_PROTO, 1);
     967                 :          0 :         rule->key_conf.spec.ip_proto = IPPROTO_UDP;
     968                 :          0 :         rule->key_conf.mask.ip_proto = IPPROTO_MASK;
     969                 :            : 
     970                 :            :         /* Only used to describe the protocol stack. */
     971   [ #  #  #  # ]:          0 :         if (item->spec == NULL && item->mask == NULL)
     972                 :            :                 return 0;
     973                 :            : 
     974         [ #  # ]:          0 :         if (item->mask) {
     975                 :            :                 udp_mask = item->mask;
     976   [ #  #  #  # ]:          0 :                 if (udp_mask->hdr.dgram_len || udp_mask->hdr.dgram_cksum) {
     977                 :          0 :                         return rte_flow_error_set(error, EINVAL,
     978                 :            :                                                   RTE_FLOW_ERROR_TYPE_ITEM_MASK,
     979                 :            :                                                   item,
     980                 :            :                                                   "Only support src & dst port in UDP");
     981                 :            :                 }
     982         [ #  # ]:          0 :                 if (udp_mask->hdr.src_port) {
     983                 :          0 :                         hns3_set_bit(rule->input_set, INNER_SRC_PORT, 1);
     984                 :          0 :                         rule->key_conf.mask.src_port =
     985         [ #  # ]:          0 :                             rte_be_to_cpu_16(udp_mask->hdr.src_port);
     986                 :            :                 }
     987         [ #  # ]:          0 :                 if (udp_mask->hdr.dst_port) {
     988                 :          0 :                         hns3_set_bit(rule->input_set, INNER_DST_PORT, 1);
     989                 :          0 :                         rule->key_conf.mask.dst_port =
     990         [ #  # ]:          0 :                             rte_be_to_cpu_16(udp_mask->hdr.dst_port);
     991                 :            :                 }
     992                 :            :         }
     993                 :            : 
     994                 :            :         udp_spec = item->spec;
     995         [ #  # ]:          0 :         rule->key_conf.spec.src_port = rte_be_to_cpu_16(udp_spec->hdr.src_port);
     996         [ #  # ]:          0 :         rule->key_conf.spec.dst_port = rte_be_to_cpu_16(udp_spec->hdr.dst_port);
     997                 :            : 
     998                 :          0 :         return 0;
     999                 :            : }
    1000                 :            : 
    1001                 :            : static int
    1002                 :          0 : hns3_parse_sctp(const struct rte_flow_item *item, struct hns3_fdir_rule *rule,
    1003                 :            :                 struct rte_flow_error *error)
    1004                 :            : {
    1005                 :            :         const struct rte_flow_item_sctp *sctp_spec;
    1006                 :            :         const struct rte_flow_item_sctp *sctp_mask;
    1007                 :            : 
    1008                 :          0 :         hns3_set_bit(rule->input_set, INNER_IP_PROTO, 1);
    1009                 :          0 :         rule->key_conf.spec.ip_proto = IPPROTO_SCTP;
    1010                 :          0 :         rule->key_conf.mask.ip_proto = IPPROTO_MASK;
    1011                 :            : 
    1012                 :            :         /* Only used to describe the protocol stack. */
    1013   [ #  #  #  # ]:          0 :         if (item->spec == NULL && item->mask == NULL)
    1014                 :            :                 return 0;
    1015                 :            : 
    1016         [ #  # ]:          0 :         if (item->mask) {
    1017                 :            :                 sctp_mask = item->mask;
    1018         [ #  # ]:          0 :                 if (sctp_mask->hdr.cksum)
    1019                 :          0 :                         return rte_flow_error_set(error, EINVAL,
    1020                 :            :                                                   RTE_FLOW_ERROR_TYPE_ITEM_MASK,
    1021                 :            :                                                   item,
    1022                 :            :                                                   "Only support src & dst port & v-tag in SCTP");
    1023         [ #  # ]:          0 :                 if (sctp_mask->hdr.src_port) {
    1024                 :          0 :                         hns3_set_bit(rule->input_set, INNER_SRC_PORT, 1);
    1025                 :          0 :                         rule->key_conf.mask.src_port =
    1026         [ #  # ]:          0 :                             rte_be_to_cpu_16(sctp_mask->hdr.src_port);
    1027                 :            :                 }
    1028         [ #  # ]:          0 :                 if (sctp_mask->hdr.dst_port) {
    1029                 :          0 :                         hns3_set_bit(rule->input_set, INNER_DST_PORT, 1);
    1030                 :          0 :                         rule->key_conf.mask.dst_port =
    1031         [ #  # ]:          0 :                             rte_be_to_cpu_16(sctp_mask->hdr.dst_port);
    1032                 :            :                 }
    1033         [ #  # ]:          0 :                 if (sctp_mask->hdr.tag) {
    1034                 :          0 :                         hns3_set_bit(rule->input_set, INNER_SCTP_TAG, 1);
    1035                 :          0 :                         rule->key_conf.mask.sctp_tag =
    1036         [ #  # ]:          0 :                             rte_be_to_cpu_32(sctp_mask->hdr.tag);
    1037                 :            :                 }
    1038                 :            :         }
    1039                 :            : 
    1040                 :            :         sctp_spec = item->spec;
    1041                 :          0 :         rule->key_conf.spec.src_port =
    1042         [ #  # ]:          0 :             rte_be_to_cpu_16(sctp_spec->hdr.src_port);
    1043                 :          0 :         rule->key_conf.spec.dst_port =
    1044         [ #  # ]:          0 :             rte_be_to_cpu_16(sctp_spec->hdr.dst_port);
    1045         [ #  # ]:          0 :         rule->key_conf.spec.sctp_tag = rte_be_to_cpu_32(sctp_spec->hdr.tag);
    1046                 :            : 
    1047                 :          0 :         return 0;
    1048                 :            : }
    1049                 :            : 
    1050                 :            : /*
    1051                 :            :  * Check items before tunnel, save inner configs to outer configs, and clear
    1052                 :            :  * inner configs.
    1053                 :            :  * The key consists of two parts: meta_data and tuple keys.
    1054                 :            :  * Meta data uses 15 bits, including vlan_num(2bit), des_port(12bit) and tunnel
    1055                 :            :  * packet(1bit).
    1056                 :            :  * Tuple keys uses 384bit, including ot_dst-mac(48bit), ot_dst-port(16bit),
    1057                 :            :  * ot_tun_vni(24bit), ot_flow_id(8bit), src-mac(48bit), dst-mac(48bit),
    1058                 :            :  * src-ip(32/128bit), dst-ip(32/128bit), src-port(16bit), dst-port(16bit),
    1059                 :            :  * tos(8bit), ether-proto(16bit), ip-proto(8bit), vlantag1(16bit),
    1060                 :            :  * Vlantag2(16bit) and sctp-tag(32bit).
    1061                 :            :  */
    1062                 :            : static int
    1063                 :          0 : hns3_handle_tunnel(const struct rte_flow_item *item,
    1064                 :            :                    struct hns3_fdir_rule *rule, struct rte_flow_error *error)
    1065                 :            : {
    1066                 :            :         /* check eth config */
    1067         [ #  # ]:          0 :         if (rule->input_set & (BIT(INNER_SRC_MAC) | BIT(INNER_DST_MAC)))
    1068                 :          0 :                 return rte_flow_error_set(error, EINVAL,
    1069                 :            :                                           RTE_FLOW_ERROR_TYPE_ITEM,
    1070                 :            :                                           item, "Outer eth mac is unsupported");
    1071         [ #  # ]:          0 :         if (rule->input_set & BIT(INNER_ETH_TYPE)) {
    1072                 :          0 :                 hns3_set_bit(rule->input_set, OUTER_ETH_TYPE, 1);
    1073                 :          0 :                 rule->key_conf.spec.outer_ether_type =
    1074                 :          0 :                     rule->key_conf.spec.ether_type;
    1075                 :          0 :                 rule->key_conf.mask.outer_ether_type =
    1076                 :          0 :                     rule->key_conf.mask.ether_type;
    1077                 :          0 :                 hns3_set_bit(rule->input_set, INNER_ETH_TYPE, 0);
    1078                 :          0 :                 rule->key_conf.spec.ether_type = 0;
    1079                 :          0 :                 rule->key_conf.mask.ether_type = 0;
    1080                 :            :         }
    1081                 :            : 
    1082         [ #  # ]:          0 :         if (rule->input_set & BIT(INNER_VLAN_TAG1)) {
    1083                 :          0 :                 hns3_set_bit(rule->input_set, OUTER_VLAN_TAG_FST, 1);
    1084                 :          0 :                 hns3_set_bit(rule->input_set, INNER_VLAN_TAG1, 0);
    1085                 :          0 :                 rule->key_conf.spec.outer_vlan_tag1 = rule->key_conf.spec.vlan_tag1;
    1086                 :          0 :                 rule->key_conf.mask.outer_vlan_tag1 = rule->key_conf.mask.vlan_tag1;
    1087                 :          0 :                 rule->key_conf.spec.vlan_tag1 = 0;
    1088                 :          0 :                 rule->key_conf.mask.vlan_tag1 = 0;
    1089                 :            :         }
    1090         [ #  # ]:          0 :         if (rule->input_set & BIT(INNER_VLAN_TAG2)) {
    1091                 :          0 :                 hns3_set_bit(rule->input_set, OUTER_VLAN_TAG_SEC, 1);
    1092                 :          0 :                 hns3_set_bit(rule->input_set, INNER_VLAN_TAG2, 0);
    1093                 :          0 :                 rule->key_conf.spec.outer_vlan_tag2 = rule->key_conf.spec.vlan_tag2;
    1094                 :          0 :                 rule->key_conf.mask.outer_vlan_tag2 = rule->key_conf.mask.vlan_tag2;
    1095                 :          0 :                 rule->key_conf.spec.vlan_tag2 = 0;
    1096                 :          0 :                 rule->key_conf.mask.vlan_tag2 = 0;
    1097                 :            :         }
    1098                 :            : 
    1099                 :            :         /* clear vlan_num for inner vlan select */
    1100                 :          0 :         rule->key_conf.outer_vlan_num = rule->key_conf.vlan_num;
    1101                 :          0 :         rule->key_conf.vlan_num = 0;
    1102                 :            : 
    1103                 :            :         /* check L3 config */
    1104         [ #  # ]:          0 :         if (rule->input_set &
    1105                 :            :             (BIT(INNER_SRC_IP) | BIT(INNER_DST_IP) | BIT(INNER_IP_TOS)))
    1106                 :          0 :                 return rte_flow_error_set(error, EINVAL,
    1107                 :            :                                           RTE_FLOW_ERROR_TYPE_ITEM,
    1108                 :            :                                           item, "Outer ip is unsupported");
    1109         [ #  # ]:          0 :         if (rule->input_set & BIT(INNER_IP_PROTO)) {
    1110                 :          0 :                 hns3_set_bit(rule->input_set, OUTER_IP_PROTO, 1);
    1111                 :          0 :                 rule->key_conf.spec.outer_proto = rule->key_conf.spec.ip_proto;
    1112                 :          0 :                 rule->key_conf.mask.outer_proto = rule->key_conf.mask.ip_proto;
    1113                 :          0 :                 hns3_set_bit(rule->input_set, INNER_IP_PROTO, 0);
    1114                 :          0 :                 rule->key_conf.spec.ip_proto = 0;
    1115                 :          0 :                 rule->key_conf.mask.ip_proto = 0;
    1116                 :            :         }
    1117                 :            : 
    1118                 :            :         /* check L4 config */
    1119         [ #  # ]:          0 :         if (rule->input_set & BIT(INNER_SCTP_TAG))
    1120                 :          0 :                 return rte_flow_error_set(error, EINVAL,
    1121                 :            :                                           RTE_FLOW_ERROR_TYPE_ITEM, item,
    1122                 :            :                                           "Outer sctp tag is unsupported");
    1123                 :            : 
    1124         [ #  # ]:          0 :         if (rule->input_set & BIT(INNER_SRC_PORT)) {
    1125                 :          0 :                 hns3_set_bit(rule->input_set, OUTER_SRC_PORT, 1);
    1126                 :          0 :                 rule->key_conf.spec.outer_src_port =
    1127                 :          0 :                     rule->key_conf.spec.src_port;
    1128                 :          0 :                 rule->key_conf.mask.outer_src_port =
    1129                 :          0 :                     rule->key_conf.mask.src_port;
    1130                 :          0 :                 hns3_set_bit(rule->input_set, INNER_SRC_PORT, 0);
    1131                 :          0 :                 rule->key_conf.spec.src_port = 0;
    1132                 :          0 :                 rule->key_conf.mask.src_port = 0;
    1133                 :            :         }
    1134         [ #  # ]:          0 :         if (rule->input_set & BIT(INNER_DST_PORT)) {
    1135                 :          0 :                 hns3_set_bit(rule->input_set, INNER_DST_PORT, 0);
    1136                 :          0 :                 rule->key_conf.spec.dst_port = 0;
    1137                 :          0 :                 rule->key_conf.mask.dst_port = 0;
    1138                 :            :         }
    1139                 :            :         return 0;
    1140                 :            : }
    1141                 :            : 
    1142                 :            : static int
    1143                 :          0 : hns3_parse_vxlan(const struct rte_flow_item *item, struct hns3_fdir_rule *rule,
    1144                 :            :                  struct rte_flow_error *error)
    1145                 :            : {
    1146                 :            :         const struct rte_flow_item_vxlan *vxlan_spec;
    1147                 :            :         const struct rte_flow_item_vxlan *vxlan_mask;
    1148                 :            : 
    1149                 :          0 :         hns3_set_bit(rule->input_set, OUTER_DST_PORT, 1);
    1150                 :          0 :         rule->key_conf.mask.tunnel_type = TUNNEL_TYPE_MASK;
    1151         [ #  # ]:          0 :         if (item->type == RTE_FLOW_ITEM_TYPE_VXLAN)
    1152                 :          0 :                 rule->key_conf.spec.tunnel_type = HNS3_TUNNEL_TYPE_VXLAN;
    1153                 :            :         else
    1154                 :          0 :                 rule->key_conf.spec.tunnel_type = HNS3_TUNNEL_TYPE_VXLAN_GPE;
    1155                 :            : 
    1156                 :            :         /* Only used to describe the protocol stack. */
    1157   [ #  #  #  # ]:          0 :         if (item->spec == NULL && item->mask == NULL)
    1158                 :            :                 return 0;
    1159                 :            : 
    1160                 :          0 :         vxlan_mask = item->mask;
    1161                 :            :         vxlan_spec = item->spec;
    1162                 :            : 
    1163         [ #  # ]:          0 :         if (vxlan_mask->hdr.flags)
    1164                 :          0 :                 return rte_flow_error_set(error, EINVAL,
    1165                 :            :                                           RTE_FLOW_ERROR_TYPE_ITEM_MASK, item,
    1166                 :            :                                           "Flags is not supported in VxLAN");
    1167                 :            : 
    1168                 :            :         /* VNI must be totally masked or not. */
    1169         [ #  # ]:          0 :         if (memcmp(vxlan_mask->hdr.vni, full_mask, VNI_OR_TNI_LEN) &&
    1170         [ #  # ]:          0 :             memcmp(vxlan_mask->hdr.vni, zero_mask, VNI_OR_TNI_LEN))
    1171                 :          0 :                 return rte_flow_error_set(error, EINVAL,
    1172                 :            :                                           RTE_FLOW_ERROR_TYPE_ITEM_MASK, item,
    1173                 :            :                                           "VNI must be totally masked or not in VxLAN");
    1174         [ #  # ]:          0 :         if (vxlan_mask->hdr.vni[0]) {
    1175                 :          0 :                 hns3_set_bit(rule->input_set, OUTER_TUN_VNI, 1);
    1176                 :          0 :                 memcpy(rule->key_conf.mask.outer_tun_vni, vxlan_mask->hdr.vni,
    1177                 :            :                            VNI_OR_TNI_LEN);
    1178                 :            :         }
    1179                 :          0 :         memcpy(rule->key_conf.spec.outer_tun_vni, vxlan_spec->hdr.vni,
    1180                 :            :                    VNI_OR_TNI_LEN);
    1181                 :          0 :         return 0;
    1182                 :            : }
    1183                 :            : 
    1184                 :            : static int
    1185                 :          0 : hns3_parse_nvgre(const struct rte_flow_item *item, struct hns3_fdir_rule *rule,
    1186                 :            :                  struct rte_flow_error *error)
    1187                 :            : {
    1188                 :            :         const struct rte_flow_item_nvgre *nvgre_spec;
    1189                 :            :         const struct rte_flow_item_nvgre *nvgre_mask;
    1190                 :            : 
    1191                 :          0 :         hns3_set_bit(rule->input_set, OUTER_IP_PROTO, 1);
    1192                 :          0 :         rule->key_conf.spec.outer_proto = IPPROTO_GRE;
    1193                 :          0 :         rule->key_conf.mask.outer_proto = IPPROTO_MASK;
    1194                 :            : 
    1195                 :          0 :         hns3_set_bit(rule->input_set, OUTER_DST_PORT, 1);
    1196                 :          0 :         rule->key_conf.spec.tunnel_type = HNS3_TUNNEL_TYPE_NVGRE;
    1197                 :          0 :         rule->key_conf.mask.tunnel_type = ~HNS3_TUNNEL_TYPE_NVGRE;
    1198                 :            :         /* Only used to describe the protocol stack. */
    1199   [ #  #  #  # ]:          0 :         if (item->spec == NULL && item->mask == NULL)
    1200                 :            :                 return 0;
    1201                 :            : 
    1202                 :          0 :         nvgre_mask = item->mask;
    1203                 :            :         nvgre_spec = item->spec;
    1204                 :            : 
    1205   [ #  #  #  # ]:          0 :         if (nvgre_mask->protocol || nvgre_mask->c_k_s_rsvd0_ver)
    1206                 :          0 :                 return rte_flow_error_set(error, EINVAL,
    1207                 :            :                                           RTE_FLOW_ERROR_TYPE_ITEM_MASK, item,
    1208                 :            :                                           "Ver/protocol is not supported in NVGRE");
    1209                 :            : 
    1210                 :            :         /* TNI must be totally masked or not. */
    1211         [ #  # ]:          0 :         if (memcmp(nvgre_mask->tni, full_mask, VNI_OR_TNI_LEN) &&
    1212         [ #  # ]:          0 :             memcmp(nvgre_mask->tni, zero_mask, VNI_OR_TNI_LEN))
    1213                 :          0 :                 return rte_flow_error_set(error, EINVAL,
    1214                 :            :                                           RTE_FLOW_ERROR_TYPE_ITEM_MASK, item,
    1215                 :            :                                           "TNI must be totally masked or not in NVGRE");
    1216                 :            : 
    1217         [ #  # ]:          0 :         if (nvgre_mask->tni[0]) {
    1218                 :          0 :                 hns3_set_bit(rule->input_set, OUTER_TUN_VNI, 1);
    1219                 :          0 :                 memcpy(rule->key_conf.mask.outer_tun_vni, nvgre_mask->tni,
    1220                 :            :                            VNI_OR_TNI_LEN);
    1221                 :            :         }
    1222         [ #  # ]:          0 :         memcpy(rule->key_conf.spec.outer_tun_vni, nvgre_spec->tni,
    1223                 :            :                    VNI_OR_TNI_LEN);
    1224                 :            : 
    1225         [ #  # ]:          0 :         if (nvgre_mask->flow_id) {
    1226                 :          0 :                 hns3_set_bit(rule->input_set, OUTER_TUN_FLOW_ID, 1);
    1227                 :          0 :                 rule->key_conf.mask.outer_tun_flow_id = nvgre_mask->flow_id;
    1228                 :            :         }
    1229                 :          0 :         rule->key_conf.spec.outer_tun_flow_id = nvgre_spec->flow_id;
    1230                 :          0 :         return 0;
    1231                 :            : }
    1232                 :            : 
    1233                 :            : static int
    1234                 :          0 : hns3_parse_geneve(const struct rte_flow_item *item, struct hns3_fdir_rule *rule,
    1235                 :            :                   struct rte_flow_error *error)
    1236                 :            : {
    1237                 :            :         const struct rte_flow_item_geneve *geneve_spec;
    1238                 :            :         const struct rte_flow_item_geneve *geneve_mask;
    1239                 :            : 
    1240                 :          0 :         hns3_set_bit(rule->input_set, OUTER_DST_PORT, 1);
    1241                 :          0 :         rule->key_conf.spec.tunnel_type = HNS3_TUNNEL_TYPE_GENEVE;
    1242                 :          0 :         rule->key_conf.mask.tunnel_type = TUNNEL_TYPE_MASK;
    1243                 :            :         /* Only used to describe the protocol stack. */
    1244   [ #  #  #  # ]:          0 :         if (item->spec == NULL && item->mask == NULL)
    1245                 :            :                 return 0;
    1246                 :            : 
    1247                 :          0 :         geneve_mask = item->mask;
    1248                 :            :         geneve_spec = item->spec;
    1249                 :            : 
    1250   [ #  #  #  # ]:          0 :         if (geneve_mask->ver_opt_len_o_c_rsvd0 || geneve_mask->protocol)
    1251                 :          0 :                 return rte_flow_error_set(error, EINVAL,
    1252                 :            :                                           RTE_FLOW_ERROR_TYPE_ITEM_MASK, item,
    1253                 :            :                                           "Ver/protocol is not supported in GENEVE");
    1254                 :            :         /* VNI must be totally masked or not. */
    1255         [ #  # ]:          0 :         if (memcmp(geneve_mask->vni, full_mask, VNI_OR_TNI_LEN) &&
    1256         [ #  # ]:          0 :             memcmp(geneve_mask->vni, zero_mask, VNI_OR_TNI_LEN))
    1257                 :          0 :                 return rte_flow_error_set(error, EINVAL,
    1258                 :            :                                           RTE_FLOW_ERROR_TYPE_ITEM_MASK, item,
    1259                 :            :                                           "VNI must be totally masked or not in GENEVE");
    1260         [ #  # ]:          0 :         if (geneve_mask->vni[0]) {
    1261                 :          0 :                 hns3_set_bit(rule->input_set, OUTER_TUN_VNI, 1);
    1262                 :          0 :                 memcpy(rule->key_conf.mask.outer_tun_vni, geneve_mask->vni,
    1263                 :            :                            VNI_OR_TNI_LEN);
    1264                 :            :         }
    1265                 :          0 :         memcpy(rule->key_conf.spec.outer_tun_vni, geneve_spec->vni,
    1266                 :            :                    VNI_OR_TNI_LEN);
    1267                 :          0 :         return 0;
    1268                 :            : }
    1269                 :            : 
    1270                 :            : static int
    1271                 :          0 : hns3_parse_ptype(const struct rte_flow_item *item, struct hns3_fdir_rule *rule,
    1272                 :            :                   struct rte_flow_error *error)
    1273                 :            : {
    1274                 :          0 :         const struct rte_flow_item_ptype *spec = item->spec;
    1275                 :          0 :         const struct rte_flow_item_ptype *mask = item->mask;
    1276                 :            : 
    1277         [ #  # ]:          0 :         if (spec == NULL || mask == NULL)
    1278                 :          0 :                 return rte_flow_error_set(error, EINVAL,
    1279                 :            :                                           RTE_FLOW_ERROR_TYPE_ITEM, item,
    1280                 :            :                                           "PTYPE must set spec and mask at the same time!");
    1281                 :            : 
    1282         [ #  # ]:          0 :         if (spec->packet_type != RTE_PTYPE_TUNNEL_MASK ||
    1283         [ #  # ]:          0 :             (mask->packet_type & RTE_PTYPE_TUNNEL_MASK) != RTE_PTYPE_TUNNEL_MASK)
    1284                 :          0 :                 return rte_flow_error_set(error, EINVAL,
    1285                 :            :                                           RTE_FLOW_ERROR_TYPE_ITEM_MASK, item,
    1286                 :            :                                           "PTYPE only support general tunnel!");
    1287                 :            : 
    1288                 :            :         /*
    1289                 :            :          * Set tunnel_type to non-zero, so that meta-data's tunnel packet bit
    1290                 :            :          * will be set, then hardware will match tunnel packet.
    1291                 :            :          */
    1292                 :          0 :         rule->key_conf.spec.tunnel_type = 1;
    1293                 :          0 :         return 0;
    1294                 :            : }
    1295                 :            : 
    1296                 :            : static int
    1297                 :          0 : hns3_parse_tunnel(const struct rte_flow_item *item, struct hns3_fdir_rule *rule,
    1298                 :            :                   struct rte_flow_error *error)
    1299                 :            : {
    1300                 :            :         int ret;
    1301                 :            : 
    1302   [ #  #  #  # ]:          0 :         if (item->spec == NULL && item->mask)
    1303                 :          0 :                 return rte_flow_error_set(error, EINVAL,
    1304                 :            :                                           RTE_FLOW_ERROR_TYPE_ITEM, item,
    1305                 :            :                                           "Can't configure FDIR with mask "
    1306                 :            :                                           "but without spec");
    1307   [ #  #  #  # ]:          0 :         else if (item->spec && (item->mask == NULL))
    1308                 :          0 :                 return rte_flow_error_set(error, EINVAL,
    1309                 :            :                                           RTE_FLOW_ERROR_TYPE_ITEM, item,
    1310                 :            :                                           "Tunnel packets must configure "
    1311                 :            :                                           "with mask");
    1312                 :            : 
    1313         [ #  # ]:          0 :         if (rule->key_conf.spec.tunnel_type != 0)
    1314                 :          0 :                 return rte_flow_error_set(error, EINVAL,
    1315                 :            :                                           RTE_FLOW_ERROR_TYPE_ITEM,
    1316                 :            :                                           item, "Too many tunnel headers!");
    1317                 :            : 
    1318   [ #  #  #  #  :          0 :         switch (item->type) {
                      # ]
    1319                 :          0 :         case RTE_FLOW_ITEM_TYPE_VXLAN:
    1320                 :            :         case RTE_FLOW_ITEM_TYPE_VXLAN_GPE:
    1321                 :          0 :                 ret = hns3_parse_vxlan(item, rule, error);
    1322                 :          0 :                 break;
    1323                 :          0 :         case RTE_FLOW_ITEM_TYPE_NVGRE:
    1324                 :          0 :                 ret = hns3_parse_nvgre(item, rule, error);
    1325                 :          0 :                 break;
    1326                 :          0 :         case RTE_FLOW_ITEM_TYPE_GENEVE:
    1327                 :          0 :                 ret = hns3_parse_geneve(item, rule, error);
    1328                 :          0 :                 break;
    1329                 :          0 :         case RTE_FLOW_ITEM_TYPE_PTYPE:
    1330                 :          0 :                 ret = hns3_parse_ptype(item, rule, error);
    1331                 :          0 :                 break;
    1332                 :          0 :         default:
    1333                 :          0 :                 return rte_flow_error_set(error, ENOTSUP,
    1334                 :            :                                           RTE_FLOW_ERROR_TYPE_ITEM,
    1335                 :            :                                           NULL, "Unsupported tunnel type!");
    1336                 :            :         }
    1337         [ #  # ]:          0 :         if (ret)
    1338                 :            :                 return ret;
    1339                 :          0 :         return hns3_handle_tunnel(item, rule, error);
    1340                 :            : }
    1341                 :            : 
    1342                 :            : static int
    1343                 :          0 : hns3_parse_normal(const struct rte_flow_item *item, struct hns3_fdir_rule *rule,
    1344                 :            :                   struct items_step_mngr *step_mngr,
    1345                 :            :                   struct rte_flow_error *error)
    1346                 :            : {
    1347                 :            :         int ret;
    1348                 :            : 
    1349   [ #  #  #  # ]:          0 :         if (item->spec == NULL && item->mask)
    1350                 :          0 :                 return rte_flow_error_set(error, EINVAL,
    1351                 :            :                                           RTE_FLOW_ERROR_TYPE_ITEM, item,
    1352                 :            :                                           "Can't configure FDIR with mask "
    1353                 :            :                                           "but without spec");
    1354                 :            : 
    1355   [ #  #  #  #  :          0 :         switch (item->type) {
             #  #  #  # ]
    1356                 :          0 :         case RTE_FLOW_ITEM_TYPE_ETH:
    1357                 :          0 :                 ret = hns3_parse_eth(item, rule, error);
    1358                 :          0 :                 step_mngr->items = L2_next_items;
    1359                 :          0 :                 step_mngr->count = RTE_DIM(L2_next_items);
    1360                 :          0 :                 break;
    1361                 :          0 :         case RTE_FLOW_ITEM_TYPE_VLAN:
    1362                 :          0 :                 ret = hns3_parse_vlan(item, rule, error);
    1363                 :          0 :                 step_mngr->items = L2_next_items;
    1364                 :          0 :                 step_mngr->count = RTE_DIM(L2_next_items);
    1365                 :          0 :                 break;
    1366                 :          0 :         case RTE_FLOW_ITEM_TYPE_IPV4:
    1367                 :          0 :                 ret = hns3_parse_ipv4(item, rule, error);
    1368                 :          0 :                 step_mngr->items = L3_next_items;
    1369                 :          0 :                 step_mngr->count = RTE_DIM(L3_next_items);
    1370                 :          0 :                 break;
    1371                 :          0 :         case RTE_FLOW_ITEM_TYPE_IPV6:
    1372                 :          0 :                 ret = hns3_parse_ipv6(item, rule, error);
    1373                 :          0 :                 step_mngr->items = L3_next_items;
    1374                 :          0 :                 step_mngr->count = RTE_DIM(L3_next_items);
    1375                 :          0 :                 break;
    1376                 :          0 :         case RTE_FLOW_ITEM_TYPE_TCP:
    1377                 :          0 :                 ret = hns3_parse_tcp(item, rule, error);
    1378                 :          0 :                 step_mngr->items = L4_next_items;
    1379                 :          0 :                 step_mngr->count = RTE_DIM(L4_next_items);
    1380                 :          0 :                 break;
    1381                 :          0 :         case RTE_FLOW_ITEM_TYPE_UDP:
    1382                 :          0 :                 ret = hns3_parse_udp(item, rule, error);
    1383                 :          0 :                 step_mngr->items = L4_next_items;
    1384                 :          0 :                 step_mngr->count = RTE_DIM(L4_next_items);
    1385                 :          0 :                 break;
    1386                 :          0 :         case RTE_FLOW_ITEM_TYPE_SCTP:
    1387                 :          0 :                 ret = hns3_parse_sctp(item, rule, error);
    1388                 :          0 :                 step_mngr->items = L4_next_items;
    1389                 :          0 :                 step_mngr->count = RTE_DIM(L4_next_items);
    1390                 :          0 :                 break;
    1391                 :          0 :         default:
    1392                 :          0 :                 return rte_flow_error_set(error, ENOTSUP,
    1393                 :            :                                           RTE_FLOW_ERROR_TYPE_ITEM,
    1394                 :            :                                           NULL, "Unsupported normal type!");
    1395                 :            :         }
    1396                 :            : 
    1397                 :            :         return ret;
    1398                 :            : }
    1399                 :            : 
    1400                 :            : static int
    1401                 :          0 : hns3_validate_item(const struct rte_flow_item *item,
    1402                 :            :                    struct items_step_mngr step_mngr,
    1403                 :            :                    struct rte_flow_error *error)
    1404                 :            : {
    1405                 :            :         uint32_t i;
    1406                 :            : 
    1407         [ #  # ]:          0 :         if (item->last)
    1408                 :          0 :                 return rte_flow_error_set(error, ENOTSUP,
    1409                 :            :                                           RTE_FLOW_ERROR_TYPE_ITEM_LAST, item,
    1410                 :            :                                           "Not supported last point for range");
    1411                 :            : 
    1412         [ #  # ]:          0 :         for (i = 0; i < step_mngr.count; i++) {
    1413         [ #  # ]:          0 :                 if (item->type == step_mngr.items[i])
    1414                 :            :                         break;
    1415                 :            :         }
    1416                 :            : 
    1417         [ #  # ]:          0 :         if (i == step_mngr.count) {
    1418                 :          0 :                 return rte_flow_error_set(error, EINVAL,
    1419                 :            :                                           RTE_FLOW_ERROR_TYPE_ITEM,
    1420                 :            :                                           item, "Inval or missing item");
    1421                 :            :         }
    1422                 :            :         return 0;
    1423                 :            : }
    1424                 :            : 
    1425                 :            : static inline bool
    1426                 :            : is_tunnel_packet(enum rte_flow_item_type type)
    1427                 :            : {
    1428                 :            :         if (type == RTE_FLOW_ITEM_TYPE_VXLAN_GPE ||
    1429                 :            :             type == RTE_FLOW_ITEM_TYPE_VXLAN ||
    1430                 :            :             type == RTE_FLOW_ITEM_TYPE_NVGRE ||
    1431                 :            :             type == RTE_FLOW_ITEM_TYPE_GENEVE ||
    1432                 :            :             /*
    1433                 :            :              * Here treat PTYPE as tunnel type because driver only support PTYPE_TUNNEL,
    1434                 :            :              * other PTYPE will return error in hns3_parse_ptype() later.
    1435                 :            :              */
    1436                 :            :             type == RTE_FLOW_ITEM_TYPE_PTYPE)
    1437                 :            :                 return true;
    1438                 :            :         return false;
    1439                 :            : }
    1440                 :            : 
    1441                 :            : static int
    1442                 :          0 : hns3_handle_attributes(struct rte_eth_dev *dev,
    1443                 :            :                        const struct rte_flow_attr *attr,
    1444                 :            :                        struct hns3_fdir_rule *rule,
    1445                 :            :                        struct rte_flow_error *error)
    1446                 :            : {
    1447                 :          0 :         struct hns3_pf *pf = HNS3_DEV_PRIVATE_TO_PF(dev->data->dev_private);
    1448                 :          0 :         struct hns3_fdir_info fdir = pf->fdir;
    1449                 :            :         uint32_t rule_num;
    1450                 :            : 
    1451         [ #  # ]:          0 :         if (fdir.index_cfg != HNS3_FDIR_INDEX_CONFIG_PRIORITY) {
    1452         [ #  # ]:          0 :                 if (attr->priority == 0)
    1453                 :            :                         return 0;
    1454                 :          0 :                 return rte_flow_error_set(error, ENOTSUP,
    1455                 :            :                                           RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY,
    1456                 :            :                                           attr, "Not support priority");
    1457                 :            :         }
    1458                 :            : 
    1459                 :            :         rule_num = fdir.fd_cfg.rule_num[HNS3_FD_STAGE_1];
    1460         [ #  # ]:          0 :         if (attr->priority >= rule_num)
    1461                 :          0 :                 return rte_flow_error_set(error, EINVAL,
    1462                 :            :                                           RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY,
    1463                 :            :                                           attr, "Priority out of range");
    1464                 :            : 
    1465         [ #  # ]:          0 :         if (fdir.hash_map[attr->priority] != NULL)
    1466                 :          0 :                 return rte_flow_error_set(error, EINVAL,
    1467                 :            :                                           RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY,
    1468                 :            :                                           attr, "Priority already exists");
    1469                 :            : 
    1470                 :          0 :         rule->location = attr->priority;
    1471                 :            : 
    1472                 :          0 :         return 0;
    1473                 :            : }
    1474                 :            : 
    1475                 :            : /*
    1476                 :            :  * Parse the flow director rule.
    1477                 :            :  * The supported PATTERN:
    1478                 :            :  *   case: non-tunnel packet:
    1479                 :            :  *     ETH : src-mac, dst-mac, ethertype
    1480                 :            :  *     VLAN: tag1, tag2
    1481                 :            :  *     IPv4: src-ip, dst-ip, tos, proto
    1482                 :            :  *     IPv6: src-ip(last 32 bit addr), dst-ip(last 32 bit addr), proto
    1483                 :            :  *     UDP : src-port, dst-port
    1484                 :            :  *     TCP : src-port, dst-port
    1485                 :            :  *     SCTP: src-port, dst-port, tag
    1486                 :            :  *   case: tunnel packet:
    1487                 :            :  *     OUTER-ETH: ethertype
    1488                 :            :  *     OUTER-L3 : proto
    1489                 :            :  *     OUTER-L4 : src-port, dst-port
    1490                 :            :  *     TUNNEL   : vni, flow-id(only valid when NVGRE)
    1491                 :            :  *     INNER-ETH/VLAN/IPv4/IPv6/UDP/TCP/SCTP: same as non-tunnel packet
    1492                 :            :  * The supported ACTION:
    1493                 :            :  *    QUEUE
    1494                 :            :  *    DROP
    1495                 :            :  *    COUNT
    1496                 :            :  *    MARK: the id range [0, 4094]
    1497                 :            :  *    FLAG
    1498                 :            :  *    RSS: only valid if firmware support FD_QUEUE_REGION.
    1499                 :            :  */
    1500                 :            : static int
    1501                 :          0 : hns3_parse_fdir_filter(struct rte_eth_dev *dev,
    1502                 :            :                        const struct rte_flow_attr *attr,
    1503                 :            :                        const struct rte_flow_item pattern[],
    1504                 :            :                        const struct rte_flow_action actions[],
    1505                 :            :                        struct hns3_fdir_rule *rule,
    1506                 :            :                        struct rte_flow_error *error)
    1507                 :            : {
    1508                 :          0 :         struct hns3_adapter *hns = dev->data->dev_private;
    1509                 :            :         const struct rte_flow_item *item;
    1510                 :            :         struct items_step_mngr step_mngr;
    1511                 :            :         int ret;
    1512                 :            : 
    1513                 :            :         /* FDIR is available only in PF driver */
    1514         [ #  # ]:          0 :         if (hns->is_vf)
    1515                 :          0 :                 return rte_flow_error_set(error, ENOTSUP,
    1516                 :            :                                           RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
    1517                 :            :                                           "Fdir not supported in VF");
    1518                 :            : 
    1519                 :          0 :         ret = hns3_handle_attributes(dev, attr, rule, error);
    1520         [ #  # ]:          0 :         if (ret)
    1521                 :            :                 return ret;
    1522                 :            : 
    1523                 :          0 :         step_mngr.items = first_items;
    1524                 :          0 :         step_mngr.count = RTE_DIM(first_items);
    1525         [ #  # ]:          0 :         for (item = pattern; item->type != RTE_FLOW_ITEM_TYPE_END; item++) {
    1526         [ #  # ]:          0 :                 if (item->type == RTE_FLOW_ITEM_TYPE_VOID)
    1527                 :          0 :                         continue;
    1528                 :            : 
    1529                 :          0 :                 ret = hns3_validate_item(item, step_mngr, error);
    1530         [ #  # ]:          0 :                 if (ret)
    1531                 :          0 :                         return ret;
    1532                 :            : 
    1533         [ #  # ]:          0 :                 if (is_tunnel_packet(item->type)) {
    1534                 :          0 :                         ret = hns3_parse_tunnel(item, rule, error);
    1535         [ #  # ]:          0 :                         if (ret)
    1536                 :          0 :                                 return ret;
    1537                 :          0 :                         step_mngr.items = tunnel_next_items;
    1538                 :          0 :                         step_mngr.count = RTE_DIM(tunnel_next_items);
    1539                 :            :                 } else {
    1540                 :          0 :                         ret = hns3_parse_normal(item, rule, &step_mngr, error);
    1541         [ #  # ]:          0 :                         if (ret)
    1542                 :          0 :                                 return ret;
    1543                 :            :                 }
    1544                 :            :         }
    1545                 :            : 
    1546                 :          0 :         ret = hns3_check_tuple(dev, rule, error);
    1547         [ #  # ]:          0 :         if (ret)
    1548                 :            :                 return ret;
    1549                 :            : 
    1550                 :          0 :         return hns3_handle_actions(dev, actions, rule, error);
    1551                 :            : }
    1552                 :            : 
    1553                 :            : static void
    1554                 :          0 : hns3_filterlist_flush(struct rte_eth_dev *dev)
    1555                 :            : {
    1556                 :          0 :         struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
    1557                 :            :         struct hns3_fdir_rule_ele *fdir_rule_ptr;
    1558                 :            :         struct hns3_flow_mem *flow_node;
    1559                 :            : 
    1560                 :          0 :         fdir_rule_ptr = TAILQ_FIRST(&hw->flow_fdir_list);
    1561         [ #  # ]:          0 :         while (fdir_rule_ptr) {
    1562         [ #  # ]:          0 :                 TAILQ_REMOVE(&hw->flow_fdir_list, fdir_rule_ptr, entries);
    1563                 :          0 :                 rte_free(fdir_rule_ptr);
    1564                 :          0 :                 fdir_rule_ptr = TAILQ_FIRST(&hw->flow_fdir_list);
    1565                 :            :         }
    1566                 :            : 
    1567                 :          0 :         flow_node = TAILQ_FIRST(&hw->flow_list);
    1568         [ #  # ]:          0 :         while (flow_node) {
    1569         [ #  # ]:          0 :                 TAILQ_REMOVE(&hw->flow_list, flow_node, entries);
    1570                 :          0 :                 rte_free(flow_node->flow);
    1571                 :          0 :                 rte_free(flow_node);
    1572                 :          0 :                 flow_node = TAILQ_FIRST(&hw->flow_list);
    1573                 :            :         }
    1574                 :          0 : }
    1575                 :            : 
    1576                 :            : static bool
    1577                 :          0 : hns3_flow_rule_key_same(const struct rte_flow_action_rss *comp,
    1578                 :            :                         const struct rte_flow_action_rss *with)
    1579                 :            : {
    1580         [ #  # ]:          0 :         if (comp->key_len != with->key_len)
    1581                 :            :                 return false;
    1582                 :            : 
    1583         [ #  # ]:          0 :         if (with->key_len == 0)
    1584                 :            :                 return true;
    1585                 :            : 
    1586   [ #  #  #  # ]:          0 :         if (comp->key == NULL && with->key == NULL)
    1587                 :            :                 return true;
    1588                 :            : 
    1589   [ #  #  #  # ]:          0 :         if (!(comp->key != NULL && with->key != NULL))
    1590                 :            :                 return false;
    1591                 :            : 
    1592                 :          0 :         return !memcmp(comp->key, with->key, with->key_len);
    1593                 :            : }
    1594                 :            : 
    1595                 :            : static bool
    1596                 :          0 : hns3_flow_rule_queues_same(const struct rte_flow_action_rss *comp,
    1597                 :            :                            const struct rte_flow_action_rss *with)
    1598                 :            : {
    1599         [ #  # ]:          0 :         if (comp->queue_num != with->queue_num)
    1600                 :            :                 return false;
    1601                 :            : 
    1602         [ #  # ]:          0 :         if (with->queue_num == 0)
    1603                 :            :                 return true;
    1604                 :            : 
    1605   [ #  #  #  # ]:          0 :         if (comp->queue == NULL && with->queue == NULL)
    1606                 :            :                 return true;
    1607                 :            : 
    1608   [ #  #  #  # ]:          0 :         if (!(comp->queue != NULL && with->queue != NULL))
    1609                 :            :                 return false;
    1610                 :            : 
    1611                 :          0 :         return !memcmp(comp->queue, with->queue, with->queue_num);
    1612                 :            : }
    1613                 :            : 
    1614                 :            : static bool
    1615                 :          0 : hns3_action_rss_same(const struct rte_flow_action_rss *comp,
    1616                 :            :                      const struct rte_flow_action_rss *with)
    1617                 :            : {
    1618                 :            :         bool same_level;
    1619                 :            :         bool same_types;
    1620                 :            :         bool same_func;
    1621                 :            : 
    1622                 :          0 :         same_level = (comp->level == with->level);
    1623                 :          0 :         same_types = (comp->types == with->types);
    1624                 :          0 :         same_func = (comp->func == with->func);
    1625                 :            : 
    1626         [ #  # ]:          0 :         return same_level && same_types && same_func &&
    1627   [ #  #  #  # ]:          0 :                 hns3_flow_rule_key_same(comp, with) &&
    1628         [ #  # ]:          0 :                 hns3_flow_rule_queues_same(comp, with);
    1629                 :            : }
    1630                 :            : 
    1631                 :            : static bool
    1632                 :            : hns3_valid_ipv6_sctp_rss_types(struct hns3_hw *hw, uint64_t types)
    1633                 :            : {
    1634                 :            :         /*
    1635                 :            :          * Some hardware don't support to use src/dst port fields to hash
    1636                 :            :          * for IPV6 SCTP packet type.
    1637                 :            :          */
    1638         [ #  # ]:          0 :         if (types & RTE_ETH_RSS_NONFRAG_IPV6_SCTP &&
    1639         [ #  # ]:          0 :             types & HNS3_RSS_SUPPORT_L4_SRC_DST &&
    1640         [ #  # ]:          0 :             !hw->rss_info.ipv6_sctp_offload_supported)
    1641                 :            :                 return false;
    1642                 :            : 
    1643                 :            :         return true;
    1644                 :            : }
    1645                 :            : 
    1646                 :            : static int
    1647                 :            : hns3_flow_parse_hash_func(const struct rte_flow_action_rss *rss_act,
    1648                 :            :                           struct hns3_flow_rss_conf *rss_conf,
    1649                 :            :                           struct rte_flow_error *error)
    1650                 :            : {
    1651                 :          0 :         if (rss_act->func >= RTE_ETH_HASH_FUNCTION_MAX)
    1652                 :          0 :                 return rte_flow_error_set(error, ENOTSUP,
    1653                 :            :                                           RTE_FLOW_ERROR_TYPE_ACTION_CONF,
    1654                 :            :                                           NULL, "RSS hash func are not supported");
    1655                 :            : 
    1656                 :          0 :         rss_conf->conf.func = rss_act->func;
    1657                 :            :         return 0;
    1658                 :            : }
    1659                 :            : 
    1660                 :            : static int
    1661                 :          0 : hns3_flow_parse_hash_key(struct hns3_hw *hw,
    1662                 :            :                          const struct rte_flow_action_rss *rss_act,
    1663                 :            :                          struct hns3_flow_rss_conf *rss_conf,
    1664                 :            :                          struct rte_flow_error *error)
    1665                 :            : {
    1666         [ #  # ]:          0 :         if (rss_act->key_len != hw->rss_key_size)
    1667                 :          0 :                 return rte_flow_error_set(error, EINVAL,
    1668                 :            :                                           RTE_FLOW_ERROR_TYPE_ACTION_CONF,
    1669                 :            :                                           NULL, "invalid RSS key length");
    1670                 :            : 
    1671         [ #  # ]:          0 :         if (rss_act->key != NULL)
    1672                 :          0 :                 memcpy(rss_conf->key, rss_act->key, rss_act->key_len);
    1673                 :            :         else
    1674                 :          0 :                 memcpy(rss_conf->key, hns3_hash_key,
    1675                 :          0 :                         RTE_MIN(sizeof(hns3_hash_key), rss_act->key_len));
    1676                 :            :         /* Need to record if user sets hash key. */
    1677                 :          0 :         rss_conf->conf.key = rss_act->key;
    1678                 :          0 :         rss_conf->conf.key_len = rss_act->key_len;
    1679                 :            : 
    1680                 :          0 :         return 0;
    1681                 :            : }
    1682                 :            : 
    1683                 :            : static int
    1684                 :          0 : hns3_flow_parse_queues(struct hns3_hw *hw,
    1685                 :            :                        const struct rte_flow_action_rss *rss_act,
    1686                 :            :                        struct hns3_flow_rss_conf *rss_conf,
    1687                 :            :                        struct rte_flow_error *error)
    1688                 :            : {
    1689                 :            :         uint16_t i;
    1690                 :            : 
    1691         [ #  # ]:          0 :         if (rss_act->queue_num > hw->rss_ind_tbl_size)
    1692                 :          0 :                 return rte_flow_error_set(error, ENOTSUP,
    1693                 :            :                                           RTE_FLOW_ERROR_TYPE_ACTION_CONF,
    1694                 :            :                                           NULL,
    1695                 :            :                                           "queue number can not exceed RSS indirection table.");
    1696                 :            : 
    1697         [ #  # ]:          0 :         if (rss_act->queue_num > HNS3_RSS_QUEUES_BUFFER_NUM)
    1698                 :          0 :                 return rte_flow_error_set(error, ENOTSUP,
    1699                 :            :                                           RTE_FLOW_ERROR_TYPE_ACTION_CONF,
    1700                 :            :                                           NULL,
    1701                 :            :                                           "queue number configured exceeds queue buffer size driver supported");
    1702                 :            : 
    1703         [ #  # ]:          0 :         for (i = 0; i < rss_act->queue_num; i++) {
    1704         [ #  # ]:          0 :                 if (rss_act->queue[i] >= hw->alloc_rss_size)
    1705                 :          0 :                         return rte_flow_error_set(error, EINVAL,
    1706                 :            :                                                 RTE_FLOW_ERROR_TYPE_ACTION_CONF,
    1707                 :            :                                                 NULL,
    1708                 :            :                                                 "queue id must be less than queue number allocated to a TC");
    1709                 :            :         }
    1710                 :            : 
    1711                 :          0 :         memcpy(rss_conf->queue, rss_act->queue,
    1712                 :          0 :                rss_act->queue_num * sizeof(rss_conf->queue[0]));
    1713                 :          0 :         rss_conf->conf.queue = rss_conf->queue;
    1714                 :          0 :         rss_conf->conf.queue_num = rss_act->queue_num;
    1715                 :            : 
    1716                 :          0 :         return 0;
    1717                 :            : }
    1718                 :            : 
    1719                 :            : static int
    1720                 :          0 : hns3_flow_get_hw_pctype(struct hns3_hw *hw,
    1721                 :            :                         const struct rte_flow_action_rss *rss_act,
    1722                 :            :                         const struct hns3_hash_map_info *map,
    1723                 :            :                         struct hns3_flow_rss_conf *rss_conf,
    1724                 :            :                         struct rte_flow_error *error)
    1725                 :            : {
    1726                 :            :         uint64_t l3l4_src_dst, l3l4_refine, left_types;
    1727                 :            : 
    1728         [ #  # ]:          0 :         if (rss_act->types == 0) {
    1729                 :            :                 /* Disable RSS hash of this packet type if types is zero. */
    1730                 :          0 :                 rss_conf->hw_pctypes |= map->hw_pctype;
    1731                 :          0 :                 return 0;
    1732                 :            :         }
    1733                 :            : 
    1734                 :            :         /*
    1735                 :            :          * Can not have extra types except rss_pctype and l3l4_type in this map.
    1736                 :            :          */
    1737                 :          0 :         left_types = ~map->rss_pctype & rss_act->types;
    1738         [ #  # ]:          0 :         if (left_types & ~map->l3l4_types)
    1739                 :          0 :                 return rte_flow_error_set(error, EINVAL,
    1740                 :            :                                           RTE_FLOW_ERROR_TYPE_ACTION_CONF, NULL,
    1741                 :            :                                           "cannot set extra types.");
    1742                 :            : 
    1743                 :            :         l3l4_src_dst = left_types;
    1744                 :            :         /* L3/L4 SRC and DST shouldn't be specified at the same time. */
    1745                 :            :         l3l4_refine = rte_eth_rss_hf_refine(l3l4_src_dst);
    1746         [ #  # ]:          0 :         if (l3l4_refine != l3l4_src_dst)
    1747                 :          0 :                 return rte_flow_error_set(error, ENOTSUP,
    1748                 :            :                                           RTE_FLOW_ERROR_TYPE_ACTION_CONF, NULL,
    1749                 :            :                                           "cannot specify L3_SRC/DST_ONLY or L4_SRC/DST_ONLY at the same.");
    1750                 :            : 
    1751                 :            :         if (!hns3_valid_ipv6_sctp_rss_types(hw, rss_act->types))
    1752                 :          0 :                 return rte_flow_error_set(error, ENOTSUP,
    1753                 :            :                                           RTE_FLOW_ERROR_TYPE_ACTION_CONF, NULL,
    1754                 :            :                                           "hardware doesn't support to use L4 src/dst to hash for IPV6-SCTP.");
    1755                 :            : 
    1756                 :          0 :         rss_conf->hw_pctypes |= map->hw_pctype;
    1757                 :            : 
    1758                 :          0 :         return 0;
    1759                 :            : }
    1760                 :            : 
    1761                 :            : static int
    1762                 :          0 : hns3_flow_parse_rss_types_by_ptype(struct hns3_hw *hw,
    1763                 :            :                                    const struct rte_flow_action_rss *rss_act,
    1764                 :            :                                    uint64_t pattern_type,
    1765                 :            :                                    struct hns3_flow_rss_conf *rss_conf,
    1766                 :            :                                    struct rte_flow_error *error)
    1767                 :            : {
    1768                 :            :         const struct hns3_hash_map_info *map;
    1769                 :            :         bool matched = false;
    1770                 :            :         uint16_t i;
    1771                 :            :         int ret;
    1772                 :            : 
    1773         [ #  # ]:          0 :         for (i = 0; i < RTE_DIM(hash_map_table); i++) {
    1774                 :          0 :                 map = &hash_map_table[i];
    1775         [ #  # ]:          0 :                 if (map->pattern_type != pattern_type) {
    1776                 :            :                         /*
    1777                 :            :                          * If the target pattern type is already matched with
    1778                 :            :                          * the one before this pattern in the hash map table,
    1779                 :            :                          * no need to continue walk.
    1780                 :            :                          */
    1781         [ #  # ]:          0 :                         if (matched)
    1782                 :            :                                 break;
    1783                 :          0 :                         continue;
    1784                 :            :                 }
    1785                 :            :                 matched = true;
    1786                 :            : 
    1787                 :            :                 /*
    1788                 :            :                  * If pattern type is matched and the 'types' is zero, all packet flow
    1789                 :            :                  * types related to this pattern type disable RSS hash.
    1790                 :            :                  * Otherwise, RSS types must match the pattern type and cannot have no
    1791                 :            :                  * extra or unsupported types.
    1792                 :            :                  */
    1793   [ #  #  #  # ]:          0 :                 if (rss_act->types != 0 && !(map->rss_pctype & rss_act->types))
    1794                 :          0 :                         continue;
    1795                 :            : 
    1796                 :          0 :                 ret = hns3_flow_get_hw_pctype(hw, rss_act, map, rss_conf, error);
    1797         [ #  # ]:          0 :                 if (ret != 0)
    1798                 :          0 :                         return ret;
    1799                 :            :         }
    1800                 :            : 
    1801         [ #  # ]:          0 :         if (rss_conf->hw_pctypes != 0)
    1802                 :            :                 return 0;
    1803                 :            : 
    1804         [ #  # ]:          0 :         if (matched)
    1805                 :          0 :                 return rte_flow_error_set(error, ENOTSUP,
    1806                 :            :                                           RTE_FLOW_ERROR_TYPE_ACTION_CONF,
    1807                 :            :                                           NULL, "RSS types are unsupported");
    1808                 :            : 
    1809                 :          0 :         return rte_flow_error_set(error, ENOTSUP,
    1810                 :            :                                   RTE_FLOW_ERROR_TYPE_ACTION_CONF,
    1811                 :            :                                   NULL, "Pattern specified is unsupported");
    1812                 :            : }
    1813                 :            : 
    1814                 :            : static uint64_t
    1815                 :            : hns3_flow_get_all_hw_pctypes(uint64_t types)
    1816                 :            : {
    1817                 :            :         uint64_t hw_pctypes = 0;
    1818                 :            :         uint16_t i;
    1819                 :            : 
    1820         [ #  # ]:          0 :         for (i = 0; i < RTE_DIM(hash_map_table); i++) {
    1821         [ #  # ]:          0 :                 if (types & hash_map_table[i].rss_pctype)
    1822                 :          0 :                         hw_pctypes |= hash_map_table[i].hw_pctype;
    1823                 :            :         }
    1824                 :            : 
    1825                 :            :         return hw_pctypes;
    1826                 :            : }
    1827                 :            : 
    1828                 :            : static int
    1829                 :          0 : hns3_flow_parse_rss_types(struct hns3_hw *hw,
    1830                 :            :                           const struct rte_flow_action_rss *rss_act,
    1831                 :            :                           uint64_t pattern_type,
    1832                 :            :                           struct hns3_flow_rss_conf *rss_conf,
    1833                 :            :                           struct rte_flow_error *error)
    1834                 :            : {
    1835                 :          0 :         rss_conf->conf.types = rss_act->types;
    1836                 :            : 
    1837                 :            :         /* no pattern specified to set global RSS types. */
    1838         [ #  # ]:          0 :         if (pattern_type == 0) {
    1839         [ #  # ]:          0 :                 if (!hns3_check_rss_types_valid(hw, rss_act->types))
    1840                 :          0 :                         return rte_flow_error_set(error, EINVAL,
    1841                 :            :                                         RTE_FLOW_ERROR_TYPE_ACTION_CONF,
    1842                 :            :                                         NULL, "RSS types is invalid.");
    1843                 :          0 :                 rss_conf->hw_pctypes =
    1844                 :          0 :                                 hns3_flow_get_all_hw_pctypes(rss_act->types);
    1845                 :          0 :                 return 0;
    1846                 :            :         }
    1847                 :            : 
    1848                 :          0 :         return hns3_flow_parse_rss_types_by_ptype(hw, rss_act, pattern_type,
    1849                 :            :                                                   rss_conf, error);
    1850                 :            : }
    1851                 :            : 
    1852                 :            : static int
    1853                 :          0 : hns3_flow_parse_hash_global_conf(struct rte_eth_dev *dev,
    1854                 :            :                                  const struct rte_flow_action_rss *rss_act,
    1855                 :            :                                  struct hns3_flow_rss_conf *rss_conf,
    1856                 :            :                                  struct rte_flow_error *error)
    1857                 :            : {
    1858         [ #  # ]:          0 :         struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
    1859                 :            :         int ret;
    1860                 :            : 
    1861                 :            :         ret = hns3_flow_parse_hash_func(rss_act, rss_conf, error);
    1862         [ #  # ]:          0 :         if (ret != 0)
    1863                 :            :                 return ret;
    1864                 :            : 
    1865         [ #  # ]:          0 :         if (rss_act->queue_num > 0) {
    1866                 :          0 :                 ret = hns3_flow_parse_queues(hw, rss_act, rss_conf, error);
    1867         [ #  # ]:          0 :                 if (ret != 0)
    1868                 :            :                         return ret;
    1869                 :            :         }
    1870                 :            : 
    1871         [ #  # ]:          0 :         if (rss_act->key_len > 0) {
    1872                 :          0 :                 ret = hns3_flow_parse_hash_key(hw, rss_act, rss_conf, error);
    1873         [ #  # ]:          0 :                 if (ret != 0)
    1874                 :            :                         return ret;
    1875                 :            :         }
    1876                 :            : 
    1877                 :          0 :         return hns3_flow_parse_rss_types(hw, rss_act, rss_conf->pattern_type,
    1878                 :            :                                          rss_conf, error);
    1879                 :            : }
    1880                 :            : 
    1881                 :            : static int
    1882                 :          0 : hns3_flow_parse_pattern_type(const struct rte_flow_item pattern[],
    1883                 :            :                              uint64_t *ptype, struct rte_flow_error *error)
    1884                 :            : {
    1885                 :            :         enum rte_flow_item_type pre_type = RTE_FLOW_ITEM_TYPE_VOID;
    1886                 :            :         const char *message = "Pattern specified isn't supported";
    1887                 :            :         uint64_t item_hdr, pattern_hdrs = 0;
    1888                 :            :         enum rte_flow_item_type cur_type;
    1889                 :            : 
    1890         [ #  # ]:          0 :         for (; pattern->type != RTE_FLOW_ITEM_TYPE_END; pattern++) {
    1891         [ #  # ]:          0 :                 if (pattern->type == RTE_FLOW_ITEM_TYPE_VOID)
    1892                 :          0 :                         continue;
    1893   [ #  #  #  #  :          0 :                 if (pattern->mask || pattern->spec || pattern->last) {
                   #  # ]
    1894                 :            :                         message = "Header info shouldn't be specified";
    1895                 :          0 :                         goto unsup;
    1896                 :            :                 }
    1897                 :            : 
    1898                 :            :                 /* Check the sub-item allowed by the previous item . */
    1899         [ #  # ]:          0 :                 if (pre_type >= RTE_DIM(hash_pattern_next_allow_items) ||
    1900         [ #  # ]:          0 :                     !(hash_pattern_next_allow_items[pre_type] &
    1901                 :            :                                 BIT_ULL(pattern->type)))
    1902                 :          0 :                         goto unsup;
    1903                 :            : 
    1904                 :            :                 cur_type = pattern->type;
    1905                 :            :                 /* Unsupported for current type being greater than array size. */
    1906         [ #  # ]:          0 :                 if (cur_type >= RTE_DIM(hash_pattern_item_header))
    1907                 :          0 :                         goto unsup;
    1908                 :            : 
    1909                 :            :                 /* The value is zero, which means unsupported current header. */
    1910                 :          0 :                 item_hdr = hash_pattern_item_header[cur_type];
    1911         [ #  # ]:          0 :                 if (item_hdr == 0)
    1912                 :          0 :                         goto unsup;
    1913                 :            : 
    1914                 :            :                 /* Have duplicate pattern header. */
    1915         [ #  # ]:          0 :                 if (item_hdr & pattern_hdrs)
    1916                 :          0 :                         goto unsup;
    1917                 :            :                 pre_type = cur_type;
    1918                 :          0 :                 pattern_hdrs |= item_hdr;
    1919                 :            :         }
    1920                 :            : 
    1921         [ #  # ]:          0 :         if (pattern_hdrs != 0) {
    1922                 :          0 :                 *ptype = pattern_hdrs;
    1923                 :          0 :                 return 0;
    1924                 :            :         }
    1925                 :            : 
    1926                 :          0 : unsup:
    1927                 :          0 :         return rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ITEM,
    1928                 :            :                                   pattern, message);
    1929                 :            : }
    1930                 :            : 
    1931                 :            : static int
    1932                 :          0 : hns3_flow_parse_pattern_act(struct rte_eth_dev *dev,
    1933                 :            :                             const struct rte_flow_item pattern[],
    1934                 :            :                             const struct rte_flow_action_rss *rss_act,
    1935                 :            :                             struct hns3_flow_rss_conf *rss_conf,
    1936                 :            :                             struct rte_flow_error *error)
    1937                 :            : {
    1938         [ #  # ]:          0 :         struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
    1939                 :            :         int ret;
    1940                 :            : 
    1941                 :            :         ret = hns3_flow_parse_hash_func(rss_act, rss_conf, error);
    1942         [ #  # ]:          0 :         if (ret != 0)
    1943                 :            :                 return ret;
    1944                 :            : 
    1945         [ #  # ]:          0 :         if (rss_act->key_len > 0) {
    1946                 :          0 :                 ret = hns3_flow_parse_hash_key(hw, rss_act, rss_conf, error);
    1947         [ #  # ]:          0 :                 if (ret != 0)
    1948                 :            :                         return ret;
    1949                 :            :         }
    1950                 :            : 
    1951         [ #  # ]:          0 :         if (rss_act->queue_num > 0) {
    1952                 :          0 :                 ret = hns3_flow_parse_queues(hw, rss_act, rss_conf, error);
    1953         [ #  # ]:          0 :                 if (ret != 0)
    1954                 :            :                         return ret;
    1955                 :            :         }
    1956                 :            : 
    1957                 :          0 :         ret = hns3_flow_parse_pattern_type(pattern, &rss_conf->pattern_type,
    1958                 :            :                                            error);
    1959         [ #  # ]:          0 :         if (ret != 0)
    1960                 :            :                 return ret;
    1961                 :            : 
    1962                 :          0 :         ret = hns3_flow_parse_rss_types(hw, rss_act, rss_conf->pattern_type,
    1963                 :            :                                         rss_conf, error);
    1964         [ #  # ]:          0 :         if (ret != 0)
    1965                 :            :                 return ret;
    1966                 :            : 
    1967         [ #  # ]:          0 :         if (rss_act->func != RTE_ETH_HASH_FUNCTION_DEFAULT ||
    1968         [ #  # ]:          0 :             rss_act->key_len > 0 || rss_act->queue_num > 0)
    1969                 :          0 :                 hns3_warn(hw, "hash func, key and queues are global config, which work for all flow types. "
    1970                 :            :                           "Recommend: don't set them together with pattern.");
    1971                 :            : 
    1972                 :            :         return 0;
    1973                 :            : }
    1974                 :            : 
    1975                 :            : static bool
    1976                 :          0 : hns3_rss_action_is_dup(struct hns3_hw *hw,
    1977                 :            :                        const struct hns3_flow_rss_conf *conf)
    1978                 :            : {
    1979                 :            :         struct hns3_rss_conf_ele *filter;
    1980                 :            : 
    1981         [ #  # ]:          0 :         TAILQ_FOREACH(filter, &hw->flow_rss_list, entries) {
    1982         [ #  # ]:          0 :                 if (conf->pattern_type != filter->filter_info.pattern_type)
    1983                 :          0 :                         continue;
    1984                 :            : 
    1985         [ #  # ]:          0 :                 if (hns3_action_rss_same(&filter->filter_info.conf, &conf->conf))
    1986                 :            :                         return true;
    1987                 :            :         }
    1988                 :            : 
    1989                 :            :         return false;
    1990                 :            : }
    1991                 :            : 
    1992                 :            : /*
    1993                 :            :  * This function is used to parse rss action validation.
    1994                 :            :  */
    1995                 :            : static int
    1996                 :          0 : hns3_parse_rss_filter(struct rte_eth_dev *dev,
    1997                 :            :                       const struct rte_flow_item pattern[],
    1998                 :            :                       const struct rte_flow_action *actions,
    1999                 :            :                       struct hns3_flow_rss_conf *rss_conf,
    2000                 :            :                       struct rte_flow_error *error)
    2001                 :            : {
    2002                 :          0 :         struct hns3_adapter *hns = dev->data->dev_private;
    2003                 :            :         const struct rte_flow_action_rss *rss_act;
    2004                 :            :         const struct rte_flow_action *act;
    2005                 :            :         const struct rte_flow_item *pat;
    2006                 :          0 :         struct hns3_hw *hw = &hns->hw;
    2007                 :            :         uint32_t index = 0;
    2008                 :            :         int ret;
    2009                 :            : 
    2010         [ #  # ]:          0 :         NEXT_ITEM_OF_ACTION(act, actions, index);
    2011         [ #  # ]:          0 :         if (actions[1].type != RTE_FLOW_ACTION_TYPE_END)
    2012                 :          0 :                 return rte_flow_error_set(error, EINVAL,
    2013                 :            :                                           RTE_FLOW_ERROR_TYPE_ACTION,
    2014                 :          0 :                                           &actions[1],
    2015                 :            :                                           "Only support one action for RSS.");
    2016                 :            : 
    2017                 :          0 :         rss_act = (const struct rte_flow_action_rss *)act->conf;
    2018         [ #  # ]:          0 :         if (rss_act == NULL) {
    2019                 :          0 :                 return rte_flow_error_set(error, EINVAL,
    2020                 :            :                                           RTE_FLOW_ERROR_TYPE_ACTION_CONF,
    2021                 :            :                                           act, "lost RSS action configuration");
    2022                 :            :         }
    2023                 :            : 
    2024         [ #  # ]:          0 :         if (rss_act->level != 0)
    2025                 :          0 :                 return rte_flow_error_set(error, ENOTSUP,
    2026                 :            :                                           RTE_FLOW_ERROR_TYPE_ACTION_CONF,
    2027                 :            :                                           act,
    2028                 :            :                                           "RSS level is not supported");
    2029                 :            : 
    2030                 :            :         index = 0;
    2031         [ #  # ]:          0 :         NEXT_ITEM_OF_PATTERN(pat, pattern, index);
    2032         [ #  # ]:          0 :         if (pat[0].type == RTE_FLOW_ITEM_TYPE_END) {
    2033                 :          0 :                 rss_conf->pattern_type = 0;
    2034                 :          0 :                 ret = hns3_flow_parse_hash_global_conf(dev, rss_act,
    2035                 :            :                                                        rss_conf, error);
    2036                 :            :         } else {
    2037                 :          0 :                 ret = hns3_flow_parse_pattern_act(dev, pat, rss_act,
    2038                 :            :                                                   rss_conf, error);
    2039                 :            :         }
    2040         [ #  # ]:          0 :         if (ret != 0)
    2041                 :            :                 return ret;
    2042                 :            : 
    2043         [ #  # ]:          0 :         if (hns3_rss_action_is_dup(hw, rss_conf))
    2044                 :          0 :                 return rte_flow_error_set(error, EINVAL,
    2045                 :            :                                           RTE_FLOW_ERROR_TYPE_ACTION_CONF,
    2046                 :            :                                           act, "duplicate RSS rule");
    2047                 :            : 
    2048                 :            :         return 0;
    2049                 :            : }
    2050                 :            : 
    2051                 :            : static int
    2052                 :          0 : hns3_update_indir_table(struct hns3_hw *hw,
    2053                 :            :                         const struct rte_flow_action_rss *conf, uint16_t num)
    2054                 :            : {
    2055                 :            :         uint16_t indir_tbl[HNS3_RSS_IND_TBL_SIZE_MAX];
    2056                 :            :         uint16_t j;
    2057                 :            :         uint32_t i;
    2058                 :            : 
    2059                 :            :         /* Fill in redirection table */
    2060         [ #  # ]:          0 :         for (i = 0, j = 0; i < hw->rss_ind_tbl_size; i++, j++) {
    2061                 :          0 :                 j %= num;
    2062         [ #  # ]:          0 :                 if (conf->queue[j] >= hw->alloc_rss_size) {
    2063                 :          0 :                         hns3_err(hw, "queue id(%u) set to redirection table "
    2064                 :            :                                  "exceeds queue number(%u) allocated to a TC.",
    2065                 :            :                                  conf->queue[j], hw->alloc_rss_size);
    2066                 :          0 :                         return -EINVAL;
    2067                 :            :                 }
    2068                 :          0 :                 indir_tbl[i] = conf->queue[j];
    2069                 :            :         }
    2070                 :            : 
    2071                 :          0 :         return hns3_set_rss_indir_table(hw, indir_tbl, hw->rss_ind_tbl_size);
    2072                 :            : }
    2073                 :            : 
    2074                 :            : static uint64_t
    2075                 :            : hns3_flow_get_pctype_tuple_mask(uint64_t hw_pctype)
    2076                 :            : {
    2077                 :            :         uint64_t tuple_mask = 0;
    2078                 :            :         uint16_t i;
    2079                 :            : 
    2080         [ #  # ]:          0 :         for (i = 0; i < RTE_DIM(hash_map_table); i++) {
    2081         [ #  # ]:          0 :                 if (hw_pctype == hash_map_table[i].hw_pctype) {
    2082                 :          0 :                         tuple_mask = hash_map_table[i].tuple_mask;
    2083                 :          0 :                         break;
    2084                 :            :                 }
    2085                 :            :         }
    2086                 :            : 
    2087                 :            :         return tuple_mask;
    2088                 :            : }
    2089                 :            : 
    2090                 :            : static int
    2091                 :          0 : hns3_flow_set_rss_ptype_tuple(struct hns3_hw *hw,
    2092                 :            :                               struct hns3_flow_rss_conf *rss_conf)
    2093                 :            : {
    2094                 :            :         uint64_t old_tuple_fields, new_tuple_fields;
    2095                 :            :         uint64_t hw_pctypes, tuples, tuple_mask = 0;
    2096                 :            :         bool cfg_global_tuple;
    2097                 :            :         int ret;
    2098                 :            : 
    2099                 :          0 :         cfg_global_tuple = (rss_conf->pattern_type == 0);
    2100         [ #  # ]:          0 :         if (!cfg_global_tuple) {
    2101                 :            :                 /*
    2102                 :            :                  * To ensure that different packets do not affect each other,
    2103                 :            :                  * we have to first read all tuple fields, and then only modify
    2104                 :            :                  * the tuples for the specified packet type.
    2105                 :            :                  */
    2106                 :          0 :                 ret = hns3_get_rss_tuple_field(hw, &old_tuple_fields);
    2107         [ #  # ]:          0 :                 if (ret != 0)
    2108                 :            :                         return ret;
    2109                 :            : 
    2110                 :          0 :                 new_tuple_fields = old_tuple_fields;
    2111                 :          0 :                 hw_pctypes = rss_conf->hw_pctypes;
    2112         [ #  # ]:          0 :                 while (hw_pctypes > 0) {
    2113                 :            :                         uint32_t idx = rte_bsf64(hw_pctypes);
    2114                 :          0 :                         uint64_t pctype = BIT_ULL(idx);
    2115                 :            : 
    2116                 :            :                         tuple_mask = hns3_flow_get_pctype_tuple_mask(pctype);
    2117                 :          0 :                         tuples = hns3_rss_calc_tuple_filed(rss_conf->conf.types);
    2118                 :          0 :                         new_tuple_fields &= ~tuple_mask;
    2119                 :          0 :                         new_tuple_fields |= tuples;
    2120                 :          0 :                         hw_pctypes &= ~pctype;
    2121                 :            :                 }
    2122                 :            :         } else {
    2123                 :            :                 new_tuple_fields =
    2124                 :          0 :                         hns3_rss_calc_tuple_filed(rss_conf->conf.types);
    2125                 :            :         }
    2126                 :            : 
    2127                 :          0 :         ret = hns3_set_rss_tuple_field(hw, new_tuple_fields);
    2128         [ #  # ]:          0 :         if (ret != 0)
    2129                 :            :                 return ret;
    2130                 :            : 
    2131         [ #  # ]:          0 :         if (!cfg_global_tuple)
    2132                 :          0 :                 hns3_info(hw, "RSS tuple fields changed from 0x%" PRIx64 " to 0x%" PRIx64,
    2133                 :            :                           old_tuple_fields, new_tuple_fields);
    2134                 :            : 
    2135                 :            :         return 0;
    2136                 :            : }
    2137                 :            : 
    2138                 :            : static int
    2139                 :          0 : hns3_config_rss_filter(struct hns3_hw *hw,
    2140                 :            :                        struct hns3_flow_rss_conf *rss_conf)
    2141                 :            : {
    2142                 :            :         struct rte_flow_action_rss *rss_act;
    2143                 :            :         int ret;
    2144                 :            : 
    2145                 :          0 :         rss_act = &rss_conf->conf;
    2146         [ #  # ]:          0 :         if (rss_act->queue_num > 0) {
    2147                 :          0 :                 ret = hns3_update_indir_table(hw, rss_act, rss_act->queue_num);
    2148         [ #  # ]:          0 :                 if (ret) {
    2149                 :          0 :                         hns3_err(hw, "set queues action failed, ret = %d", ret);
    2150                 :          0 :                         return ret;
    2151                 :            :                 }
    2152                 :            :         }
    2153                 :            : 
    2154         [ #  # ]:          0 :         if (rss_act->key_len > 0 ||
    2155         [ #  # ]:          0 :             rss_act->func != RTE_ETH_HASH_FUNCTION_DEFAULT) {
    2156                 :          0 :                 ret = hns3_update_rss_algo_key(hw, rss_act->func, rss_conf->key,
    2157                 :            :                                                rss_act->key_len);
    2158         [ #  # ]:          0 :                 if (ret != 0) {
    2159                 :          0 :                         hns3_err(hw, "set func or hash key action failed, ret = %d",
    2160                 :            :                                  ret);
    2161                 :          0 :                         return ret;
    2162                 :            :                 }
    2163                 :            :         }
    2164                 :            : 
    2165         [ #  # ]:          0 :         if (rss_conf->hw_pctypes > 0) {
    2166                 :          0 :                 ret = hns3_flow_set_rss_ptype_tuple(hw, rss_conf);
    2167         [ #  # ]:          0 :                 if (ret != 0) {
    2168                 :          0 :                         hns3_err(hw, "set types action failed, ret = %d", ret);
    2169                 :          0 :                         return ret;
    2170                 :            :                 }
    2171                 :            :         }
    2172                 :            : 
    2173                 :            :         return 0;
    2174                 :            : }
    2175                 :            : 
    2176                 :            : static int
    2177                 :          0 : hns3_clear_rss_filter(struct rte_eth_dev *dev)
    2178                 :            : {
    2179                 :          0 :         struct hns3_adapter *hns = dev->data->dev_private;
    2180                 :            :         struct hns3_rss_conf_ele *rss_filter_ptr;
    2181                 :            :         struct hns3_hw *hw = &hns->hw;
    2182                 :            : 
    2183                 :          0 :         rss_filter_ptr = TAILQ_FIRST(&hw->flow_rss_list);
    2184         [ #  # ]:          0 :         while (rss_filter_ptr) {
    2185         [ #  # ]:          0 :                 TAILQ_REMOVE(&hw->flow_rss_list, rss_filter_ptr, entries);
    2186                 :          0 :                 rte_free(rss_filter_ptr);
    2187                 :          0 :                 rss_filter_ptr = TAILQ_FIRST(&hw->flow_rss_list);
    2188                 :            :         }
    2189                 :            : 
    2190                 :          0 :         return hns3_config_rss(hns);
    2191                 :            : }
    2192                 :            : 
    2193                 :            : static int
    2194                 :          0 : hns3_reconfig_all_rss_filter(struct hns3_hw *hw)
    2195                 :            : {
    2196                 :            :         struct hns3_rss_conf_ele *filter;
    2197                 :            :         uint32_t rule_no = 0;
    2198                 :            :         int ret;
    2199                 :            : 
    2200         [ #  # ]:          0 :         TAILQ_FOREACH(filter, &hw->flow_rss_list, entries) {
    2201                 :          0 :                 ret = hns3_config_rss_filter(hw, &filter->filter_info);
    2202         [ #  # ]:          0 :                 if (ret != 0) {
    2203                 :          0 :                         hns3_err(hw, "config %uth RSS filter failed, ret = %d",
    2204                 :            :                                  rule_no, ret);
    2205                 :          0 :                         return ret;
    2206                 :            :                 }
    2207                 :          0 :                 rule_no++;
    2208                 :            :         }
    2209                 :            : 
    2210                 :            :         return 0;
    2211                 :            : }
    2212                 :            : 
    2213                 :            : static int
    2214                 :          0 : hns3_restore_rss_filter(struct hns3_hw *hw)
    2215                 :            : {
    2216                 :            :         int ret;
    2217                 :            : 
    2218                 :          0 :         pthread_mutex_lock(&hw->flows_lock);
    2219                 :          0 :         ret = hns3_reconfig_all_rss_filter(hw);
    2220                 :          0 :         pthread_mutex_unlock(&hw->flows_lock);
    2221                 :            : 
    2222                 :          0 :         return ret;
    2223                 :            : }
    2224                 :            : 
    2225                 :            : int
    2226                 :          0 : hns3_restore_filter(struct hns3_adapter *hns)
    2227                 :            : {
    2228                 :          0 :         struct hns3_hw *hw = &hns->hw;
    2229                 :            :         int ret;
    2230                 :            : 
    2231                 :          0 :         ret = hns3_restore_all_fdir_filter(hns);
    2232         [ #  # ]:          0 :         if (ret != 0)
    2233                 :            :                 return ret;
    2234                 :            : 
    2235                 :          0 :         return hns3_restore_rss_filter(hw);
    2236                 :            : }
    2237                 :            : 
    2238                 :            : static int
    2239                 :          0 : hns3_flow_args_check(const struct rte_flow_attr *attr,
    2240                 :            :                      const struct rte_flow_item pattern[],
    2241                 :            :                      const struct rte_flow_action actions[],
    2242                 :            :                      struct rte_flow_error *error)
    2243                 :            : {
    2244         [ #  # ]:          0 :         if (pattern == NULL)
    2245                 :          0 :                 return rte_flow_error_set(error, EINVAL,
    2246                 :            :                                           RTE_FLOW_ERROR_TYPE_ITEM_NUM,
    2247                 :            :                                           NULL, "NULL pattern.");
    2248                 :            : 
    2249         [ #  # ]:          0 :         if (actions == NULL)
    2250                 :          0 :                 return rte_flow_error_set(error, EINVAL,
    2251                 :            :                                           RTE_FLOW_ERROR_TYPE_ACTION_NUM,
    2252                 :            :                                           NULL, "NULL action.");
    2253                 :            : 
    2254         [ #  # ]:          0 :         if (attr == NULL)
    2255                 :          0 :                 return rte_flow_error_set(error, EINVAL,
    2256                 :            :                                           RTE_FLOW_ERROR_TYPE_ATTR,
    2257                 :            :                                           NULL, "NULL attribute.");
    2258                 :            : 
    2259                 :          0 :         return hns3_check_attr(attr, error);
    2260                 :            : }
    2261                 :            : 
    2262                 :            : /*
    2263                 :            :  * Check if the flow rule is supported by hns3.
    2264                 :            :  * It only checks the format. Don't guarantee the rule can be programmed into
    2265                 :            :  * the HW. Because there can be no enough room for the rule.
    2266                 :            :  */
    2267                 :            : static int
    2268                 :          0 : hns3_flow_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr,
    2269                 :            :                    const struct rte_flow_item pattern[],
    2270                 :            :                    const struct rte_flow_action actions[],
    2271                 :            :                    struct rte_flow_error *error,
    2272                 :            :                    struct hns3_filter_info *filter_info)
    2273                 :            : {
    2274                 :            :         union hns3_filter_conf *conf;
    2275                 :            :         int ret;
    2276                 :            : 
    2277                 :          0 :         ret = hns3_flow_args_check(attr, pattern, actions, error);
    2278         [ #  # ]:          0 :         if (ret)
    2279                 :            :                 return ret;
    2280                 :            : 
    2281                 :          0 :         hns3_parse_filter_type(pattern, actions, filter_info);
    2282                 :            :         conf = &filter_info->conf;
    2283         [ #  # ]:          0 :         if (filter_info->type == RTE_ETH_FILTER_HASH)
    2284                 :          0 :                 return hns3_parse_rss_filter(dev, pattern, actions,
    2285                 :            :                                              &conf->rss_conf, error);
    2286                 :            : 
    2287                 :          0 :         return hns3_parse_fdir_filter(dev, attr, pattern, actions,
    2288                 :            :                                       &conf->fdir_conf, error);
    2289                 :            : }
    2290                 :            : 
    2291                 :            : static int
    2292                 :          0 : hns3_flow_rebuild_all_rss_filter(struct hns3_adapter *hns)
    2293                 :            : {
    2294                 :          0 :         struct hns3_hw *hw = &hns->hw;
    2295                 :            :         int ret;
    2296                 :            : 
    2297                 :          0 :         ret = hns3_config_rss(hns);
    2298         [ #  # ]:          0 :         if (ret != 0) {
    2299                 :          0 :                 hns3_err(hw, "restore original RSS configuration failed, ret = %d.",
    2300                 :            :                          ret);
    2301                 :          0 :                 return ret;
    2302                 :            :         }
    2303                 :          0 :         ret = hns3_reconfig_all_rss_filter(hw);
    2304         [ #  # ]:          0 :         if (ret != 0)
    2305                 :          0 :                 hns3_err(hw, "rebuild all RSS filter failed, ret = %d.", ret);
    2306                 :            : 
    2307                 :            :         return ret;
    2308                 :            : }
    2309                 :            : 
    2310                 :            : static int
    2311                 :          0 : hns3_flow_create_rss_rule(struct rte_eth_dev *dev,
    2312                 :            :                           struct hns3_flow_rss_conf *rss_conf,
    2313                 :            :                           struct rte_flow *flow)
    2314                 :            : {
    2315                 :          0 :         struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
    2316                 :            :         struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
    2317                 :            :         struct hns3_rss_conf_ele *rss_filter_ptr;
    2318                 :            :         struct hns3_flow_rss_conf *new_conf;
    2319                 :            :         struct rte_flow_action_rss *rss_act;
    2320                 :            :         int ret;
    2321                 :            : 
    2322                 :          0 :         rss_filter_ptr = rte_zmalloc("hns3 rss filter",
    2323                 :            :                                      sizeof(struct hns3_rss_conf_ele), 0);
    2324         [ #  # ]:          0 :         if (rss_filter_ptr == NULL) {
    2325                 :          0 :                 hns3_err(hw, "failed to allocate hns3_rss_filter memory");
    2326                 :          0 :                 return -ENOMEM;
    2327                 :            :         }
    2328                 :            : 
    2329         [ #  # ]:          0 :         new_conf = &rss_filter_ptr->filter_info;
    2330                 :            :         memcpy(new_conf, rss_conf, sizeof(*new_conf));
    2331                 :            :         rss_act = &new_conf->conf;
    2332         [ #  # ]:          0 :         if (rss_act->queue_num > 0)
    2333                 :          0 :                 new_conf->conf.queue = new_conf->queue;
    2334                 :            :         /*
    2335                 :            :          * There are two ways to deliver hash key action:
    2336                 :            :          * 1> 'key_len' is greater than zero and 'key' isn't NULL.
    2337                 :            :          * 2> 'key_len' is greater than zero, but 'key' is NULL.
    2338                 :            :          * For case 2, we need to keep 'key' of the new_conf is NULL so as to
    2339                 :            :          * inherit the configuration from user in case of failing to verify
    2340                 :            :          * duplicate rule later.
    2341                 :            :          */
    2342   [ #  #  #  # ]:          0 :         if (rss_act->key_len > 0 && rss_act->key != NULL)
    2343                 :          0 :                 new_conf->conf.key = new_conf->key;
    2344                 :            : 
    2345                 :          0 :         ret = hns3_config_rss_filter(hw, new_conf);
    2346         [ #  # ]:          0 :         if (ret != 0) {
    2347                 :          0 :                 rte_free(rss_filter_ptr);
    2348                 :          0 :                 (void)hns3_flow_rebuild_all_rss_filter(hns);
    2349                 :          0 :                 return ret;
    2350                 :            :         }
    2351                 :            : 
    2352                 :          0 :         TAILQ_INSERT_TAIL(&hw->flow_rss_list, rss_filter_ptr, entries);
    2353                 :          0 :         flow->rule = rss_filter_ptr;
    2354                 :          0 :         flow->filter_type = RTE_ETH_FILTER_HASH;
    2355                 :            : 
    2356                 :          0 :         return 0;
    2357                 :            : }
    2358                 :            : 
    2359                 :            : static int
    2360                 :          0 : hns3_flow_create_fdir_rule(struct rte_eth_dev *dev,
    2361                 :            :                            struct hns3_fdir_rule *fdir_rule,
    2362                 :            :                            struct rte_flow_error *error,
    2363                 :            :                            struct rte_flow *flow)
    2364                 :            : {
    2365                 :          0 :         struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
    2366                 :            :         struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
    2367                 :            :         struct hns3_fdir_rule_ele *fdir_rule_ptr;
    2368                 :            :         bool indir;
    2369                 :            :         int ret;
    2370                 :            : 
    2371                 :          0 :         indir = !!(fdir_rule->flags & HNS3_RULE_FLAG_COUNTER_INDIR);
    2372         [ #  # ]:          0 :         if (fdir_rule->flags & HNS3_RULE_FLAG_COUNTER) {
    2373                 :          0 :                 ret = hns3_counter_new(dev, indir, fdir_rule->act_cnt.id,
    2374                 :            :                                        error);
    2375         [ #  # ]:          0 :                 if (ret != 0)
    2376                 :            :                         return ret;
    2377                 :            : 
    2378                 :          0 :                 flow->counter_id = fdir_rule->act_cnt.id;
    2379                 :            :         }
    2380                 :            : 
    2381                 :          0 :         fdir_rule_ptr = rte_zmalloc("hns3 fdir rule",
    2382                 :            :                                     sizeof(struct hns3_fdir_rule_ele), 0);
    2383         [ #  # ]:          0 :         if (fdir_rule_ptr == NULL) {
    2384                 :          0 :                 hns3_err(hw, "failed to allocate fdir_rule memory.");
    2385                 :            :                 ret = -ENOMEM;
    2386                 :          0 :                 goto err_malloc;
    2387                 :            :         }
    2388                 :            : 
    2389                 :            :         /*
    2390                 :            :          * After all the preceding tasks are successfully configured, configure
    2391                 :            :          * rules to the hardware to simplify the rollback of rules in the
    2392                 :            :          * hardware.
    2393                 :            :          */
    2394                 :          0 :         ret = hns3_fdir_filter_program(hns, fdir_rule, false);
    2395         [ #  # ]:          0 :         if (ret != 0)
    2396                 :          0 :                 goto err_fdir_filter;
    2397                 :            : 
    2398                 :          0 :         memcpy(&fdir_rule_ptr->fdir_conf, fdir_rule,
    2399                 :            :                 sizeof(struct hns3_fdir_rule));
    2400                 :          0 :         TAILQ_INSERT_TAIL(&hw->flow_fdir_list, fdir_rule_ptr, entries);
    2401                 :          0 :         flow->rule = fdir_rule_ptr;
    2402                 :          0 :         flow->filter_type = RTE_ETH_FILTER_FDIR;
    2403                 :            : 
    2404                 :          0 :         return 0;
    2405                 :            : 
    2406                 :            : err_fdir_filter:
    2407                 :          0 :         rte_free(fdir_rule_ptr);
    2408                 :          0 : err_malloc:
    2409         [ #  # ]:          0 :         if (fdir_rule->flags & HNS3_RULE_FLAG_COUNTER)
    2410                 :          0 :                 hns3_counter_release(dev, fdir_rule->act_cnt.id);
    2411                 :            : 
    2412                 :            :         return ret;
    2413                 :            : }
    2414                 :            : 
    2415                 :            : /*
    2416                 :            :  * Create or destroy a flow rule.
    2417                 :            :  * Theorically one rule can match more than one filters.
    2418                 :            :  * We will let it use the filter which it hit first.
    2419                 :            :  * So, the sequence matters.
    2420                 :            :  */
    2421                 :            : static struct rte_flow *
    2422                 :          0 : hns3_flow_create(struct rte_eth_dev *dev, const struct rte_flow_attr *attr,
    2423                 :            :                  const struct rte_flow_item pattern[],
    2424                 :            :                  const struct rte_flow_action actions[],
    2425                 :            :                  struct rte_flow_error *error)
    2426                 :            : {
    2427                 :          0 :         struct hns3_adapter *hns = dev->data->dev_private;
    2428                 :          0 :         struct hns3_filter_info filter_info = {0};
    2429                 :            :         struct hns3_flow_mem *flow_node;
    2430                 :            :         struct hns3_hw *hw = &hns->hw;
    2431                 :            :         union hns3_filter_conf *conf;
    2432                 :            :         struct rte_flow *flow;
    2433                 :            :         int ret;
    2434                 :            : 
    2435                 :          0 :         ret = hns3_flow_validate(dev, attr, pattern, actions, error,
    2436                 :            :                                  &filter_info);
    2437         [ #  # ]:          0 :         if (ret)
    2438                 :            :                 return NULL;
    2439                 :            : 
    2440                 :          0 :         flow = rte_zmalloc("hns3 flow", sizeof(struct rte_flow), 0);
    2441         [ #  # ]:          0 :         if (flow == NULL) {
    2442                 :          0 :                 rte_flow_error_set(error, ENOMEM, RTE_FLOW_ERROR_TYPE_HANDLE,
    2443                 :            :                                    NULL, "Failed to allocate flow memory");
    2444                 :          0 :                 return NULL;
    2445                 :            :         }
    2446                 :          0 :         flow_node = rte_zmalloc("hns3 flow node",
    2447                 :            :                                 sizeof(struct hns3_flow_mem), 0);
    2448         [ #  # ]:          0 :         if (flow_node == NULL) {
    2449                 :          0 :                 rte_flow_error_set(error, ENOMEM, RTE_FLOW_ERROR_TYPE_HANDLE,
    2450                 :            :                                    NULL, "Failed to allocate flow list memory");
    2451                 :          0 :                 rte_free(flow);
    2452                 :          0 :                 return NULL;
    2453                 :            :         }
    2454                 :            : 
    2455                 :          0 :         flow_node->flow = flow;
    2456                 :            :         conf = &filter_info.conf;
    2457                 :          0 :         TAILQ_INSERT_TAIL(&hw->flow_list, flow_node, entries);
    2458         [ #  # ]:          0 :         if (filter_info.type == RTE_ETH_FILTER_HASH)
    2459                 :          0 :                 ret = hns3_flow_create_rss_rule(dev, &conf->rss_conf, flow);
    2460                 :            :         else
    2461                 :          0 :                 ret = hns3_flow_create_fdir_rule(dev, &conf->fdir_conf,
    2462                 :            :                                                  error, flow);
    2463         [ #  # ]:          0 :         if (ret == 0)
    2464                 :            :                 return flow;
    2465                 :            : 
    2466                 :          0 :         rte_flow_error_set(error, -ret, RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
    2467                 :            :                            "Failed to create flow");
    2468         [ #  # ]:          0 :         TAILQ_REMOVE(&hw->flow_list, flow_node, entries);
    2469                 :          0 :         rte_free(flow_node);
    2470                 :          0 :         rte_free(flow);
    2471                 :            : 
    2472                 :          0 :         return NULL;
    2473                 :            : }
    2474                 :            : 
    2475                 :            : /* Destroy a flow rule on hns3. */
    2476                 :            : static int
    2477                 :          0 : hns3_flow_destroy(struct rte_eth_dev *dev, struct rte_flow *flow,
    2478                 :            :                   struct rte_flow_error *error)
    2479                 :            : {
    2480                 :          0 :         struct hns3_adapter *hns = dev->data->dev_private;
    2481                 :            :         struct hns3_fdir_rule_ele *fdir_rule_ptr;
    2482                 :            :         struct hns3_rss_conf_ele *rss_filter_ptr;
    2483                 :            :         struct hns3_flow_mem *flow_node;
    2484                 :            :         enum rte_filter_type filter_type;
    2485                 :            :         struct hns3_fdir_rule fdir_rule;
    2486                 :            :         struct hns3_hw *hw = &hns->hw;
    2487                 :            :         int ret;
    2488                 :            : 
    2489         [ #  # ]:          0 :         if (flow == NULL)
    2490                 :          0 :                 return rte_flow_error_set(error, EINVAL,
    2491                 :            :                                           RTE_FLOW_ERROR_TYPE_HANDLE,
    2492                 :            :                                           flow, "Flow is NULL");
    2493                 :            : 
    2494                 :          0 :         filter_type = flow->filter_type;
    2495      [ #  #  # ]:          0 :         switch (filter_type) {
    2496                 :          0 :         case RTE_ETH_FILTER_FDIR:
    2497                 :          0 :                 fdir_rule_ptr = (struct hns3_fdir_rule_ele *)flow->rule;
    2498                 :          0 :                 memcpy(&fdir_rule, &fdir_rule_ptr->fdir_conf,
    2499                 :            :                            sizeof(struct hns3_fdir_rule));
    2500                 :            : 
    2501                 :          0 :                 ret = hns3_fdir_filter_program(hns, &fdir_rule, true);
    2502         [ #  # ]:          0 :                 if (ret)
    2503                 :          0 :                         return rte_flow_error_set(error, EIO,
    2504                 :            :                                                   RTE_FLOW_ERROR_TYPE_HANDLE,
    2505                 :            :                                                   flow,
    2506                 :            :                                                   "Destroy FDIR fail.Try again");
    2507         [ #  # ]:          0 :                 if (fdir_rule.flags & HNS3_RULE_FLAG_COUNTER)
    2508                 :          0 :                         hns3_counter_release(dev, fdir_rule.act_cnt.id);
    2509         [ #  # ]:          0 :                 TAILQ_REMOVE(&hw->flow_fdir_list, fdir_rule_ptr, entries);
    2510                 :          0 :                 rte_free(fdir_rule_ptr);
    2511                 :            :                 fdir_rule_ptr = NULL;
    2512                 :          0 :                 break;
    2513                 :          0 :         case RTE_ETH_FILTER_HASH:
    2514                 :          0 :                 rss_filter_ptr = (struct hns3_rss_conf_ele *)flow->rule;
    2515         [ #  # ]:          0 :                 TAILQ_REMOVE(&hw->flow_rss_list, rss_filter_ptr, entries);
    2516                 :          0 :                 rte_free(rss_filter_ptr);
    2517                 :            :                 rss_filter_ptr = NULL;
    2518                 :          0 :                 (void)hns3_flow_rebuild_all_rss_filter(hns);
    2519                 :          0 :                 break;
    2520                 :          0 :         default:
    2521                 :          0 :                 return rte_flow_error_set(error, EINVAL,
    2522                 :            :                                           RTE_FLOW_ERROR_TYPE_HANDLE, flow,
    2523                 :            :                                           "Unsupported filter type");
    2524                 :            :         }
    2525                 :            : 
    2526         [ #  # ]:          0 :         TAILQ_FOREACH(flow_node, &hw->flow_list, entries) {
    2527         [ #  # ]:          0 :                 if (flow_node->flow == flow) {
    2528         [ #  # ]:          0 :                         TAILQ_REMOVE(&hw->flow_list, flow_node, entries);
    2529                 :          0 :                         rte_free(flow_node);
    2530                 :            :                         flow_node = NULL;
    2531                 :          0 :                         break;
    2532                 :            :                 }
    2533                 :            :         }
    2534                 :          0 :         rte_free(flow);
    2535                 :            : 
    2536                 :          0 :         return 0;
    2537                 :            : }
    2538                 :            : 
    2539                 :            : /*  Destroy all flow rules associated with a port on hns3. */
    2540                 :            : static int
    2541                 :          0 : hns3_flow_flush(struct rte_eth_dev *dev, struct rte_flow_error *error)
    2542                 :            : {
    2543                 :          0 :         struct hns3_adapter *hns = dev->data->dev_private;
    2544                 :            :         int ret;
    2545                 :            : 
    2546                 :            :         /* FDIR is available only in PF driver */
    2547         [ #  # ]:          0 :         if (!hns->is_vf) {
    2548                 :          0 :                 ret = hns3_clear_all_fdir_filter(hns);
    2549         [ #  # ]:          0 :                 if (ret) {
    2550                 :          0 :                         rte_flow_error_set(error, ret,
    2551                 :            :                                            RTE_FLOW_ERROR_TYPE_HANDLE,
    2552                 :            :                                            NULL, "Failed to flush rule");
    2553                 :          0 :                         return ret;
    2554                 :            :                 }
    2555                 :          0 :                 hns3_counter_flush(dev);
    2556                 :            :         }
    2557                 :            : 
    2558                 :          0 :         ret = hns3_clear_rss_filter(dev);
    2559         [ #  # ]:          0 :         if (ret) {
    2560                 :          0 :                 rte_flow_error_set(error, ret, RTE_FLOW_ERROR_TYPE_HANDLE,
    2561                 :            :                                    NULL, "Failed to flush rss filter");
    2562                 :          0 :                 return ret;
    2563                 :            :         }
    2564                 :            : 
    2565                 :          0 :         hns3_filterlist_flush(dev);
    2566                 :            : 
    2567                 :          0 :         return 0;
    2568                 :            : }
    2569                 :            : 
    2570                 :            : /* Query an existing flow rule. */
    2571                 :            : static int
    2572                 :          0 : hns3_flow_query(struct rte_eth_dev *dev, struct rte_flow *flow,
    2573                 :            :                 const struct rte_flow_action *actions, void *data,
    2574                 :            :                 struct rte_flow_error *error)
    2575                 :            : {
    2576                 :            :         struct rte_flow_action_rss *rss_conf;
    2577                 :            :         struct hns3_rss_conf_ele *rss_rule;
    2578                 :            :         struct rte_flow_query_count *qc;
    2579                 :            :         int ret;
    2580                 :            : 
    2581         [ #  # ]:          0 :         if (!flow->rule)
    2582                 :          0 :                 return rte_flow_error_set(error, EINVAL,
    2583                 :            :                         RTE_FLOW_ERROR_TYPE_HANDLE, NULL, "invalid rule");
    2584                 :            : 
    2585         [ #  # ]:          0 :         for (; actions->type != RTE_FLOW_ACTION_TYPE_END; actions++) {
    2586   [ #  #  #  # ]:          0 :                 switch (actions->type) {
    2587                 :            :                 case RTE_FLOW_ACTION_TYPE_VOID:
    2588                 :            :                         break;
    2589                 :          0 :                 case RTE_FLOW_ACTION_TYPE_COUNT:
    2590                 :            :                         qc = (struct rte_flow_query_count *)data;
    2591                 :          0 :                         ret = hns3_counter_query(dev, flow, qc, error);
    2592         [ #  # ]:          0 :                         if (ret)
    2593                 :          0 :                                 return ret;
    2594                 :            :                         break;
    2595                 :          0 :                 case RTE_FLOW_ACTION_TYPE_RSS:
    2596         [ #  # ]:          0 :                         if (flow->filter_type != RTE_ETH_FILTER_HASH) {
    2597                 :          0 :                                 return rte_flow_error_set(error, ENOTSUP,
    2598                 :            :                                         RTE_FLOW_ERROR_TYPE_ACTION,
    2599                 :            :                                         actions, "action is not supported");
    2600                 :            :                         }
    2601                 :            :                         rss_conf = (struct rte_flow_action_rss *)data;
    2602                 :          0 :                         rss_rule = (struct hns3_rss_conf_ele *)flow->rule;
    2603         [ #  # ]:          0 :                         rte_memcpy(rss_conf, &rss_rule->filter_info.conf,
    2604                 :            :                                    sizeof(struct rte_flow_action_rss));
    2605                 :            :                         break;
    2606                 :          0 :                 default:
    2607                 :          0 :                         return rte_flow_error_set(error, ENOTSUP,
    2608                 :            :                                 RTE_FLOW_ERROR_TYPE_ACTION,
    2609                 :            :                                 actions, "action is not supported");
    2610                 :            :                 }
    2611                 :            :         }
    2612                 :            : 
    2613                 :            :         return 0;
    2614                 :            : }
    2615                 :            : 
    2616                 :            : static int
    2617                 :          0 : hns3_flow_validate_wrap(struct rte_eth_dev *dev,
    2618                 :            :                         const struct rte_flow_attr *attr,
    2619                 :            :                         const struct rte_flow_item pattern[],
    2620                 :            :                         const struct rte_flow_action actions[],
    2621                 :            :                         struct rte_flow_error *error)
    2622                 :            : {
    2623                 :          0 :         struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
    2624                 :          0 :         struct hns3_filter_info filter_info = {0};
    2625                 :            :         int ret;
    2626                 :            : 
    2627                 :          0 :         pthread_mutex_lock(&hw->flows_lock);
    2628                 :          0 :         ret = hns3_flow_validate(dev, attr, pattern, actions, error,
    2629                 :            :                                  &filter_info);
    2630                 :          0 :         pthread_mutex_unlock(&hw->flows_lock);
    2631                 :            : 
    2632                 :          0 :         return ret;
    2633                 :            : }
    2634                 :            : 
    2635                 :            : static struct rte_flow *
    2636                 :          0 : hns3_flow_create_wrap(struct rte_eth_dev *dev, const struct rte_flow_attr *attr,
    2637                 :            :                       const struct rte_flow_item pattern[],
    2638                 :            :                       const struct rte_flow_action actions[],
    2639                 :            :                       struct rte_flow_error *error)
    2640                 :            : {
    2641                 :          0 :         struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
    2642                 :            :         struct rte_flow *flow;
    2643                 :            : 
    2644                 :          0 :         pthread_mutex_lock(&hw->flows_lock);
    2645                 :          0 :         flow = hns3_flow_create(dev, attr, pattern, actions, error);
    2646                 :          0 :         pthread_mutex_unlock(&hw->flows_lock);
    2647                 :            : 
    2648                 :          0 :         return flow;
    2649                 :            : }
    2650                 :            : 
    2651                 :            : static int
    2652                 :          0 : hns3_flow_destroy_wrap(struct rte_eth_dev *dev, struct rte_flow *flow,
    2653                 :            :                        struct rte_flow_error *error)
    2654                 :            : {
    2655                 :          0 :         struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
    2656                 :            :         int ret;
    2657                 :            : 
    2658                 :          0 :         pthread_mutex_lock(&hw->flows_lock);
    2659                 :          0 :         ret = hns3_flow_destroy(dev, flow, error);
    2660                 :          0 :         pthread_mutex_unlock(&hw->flows_lock);
    2661                 :            : 
    2662                 :          0 :         return ret;
    2663                 :            : }
    2664                 :            : 
    2665                 :            : static int
    2666                 :          0 : hns3_flow_flush_wrap(struct rte_eth_dev *dev, struct rte_flow_error *error)
    2667                 :            : {
    2668                 :          0 :         struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
    2669                 :            :         int ret;
    2670                 :            : 
    2671                 :          0 :         pthread_mutex_lock(&hw->flows_lock);
    2672                 :          0 :         ret = hns3_flow_flush(dev, error);
    2673                 :          0 :         pthread_mutex_unlock(&hw->flows_lock);
    2674                 :            : 
    2675                 :          0 :         return ret;
    2676                 :            : }
    2677                 :            : 
    2678                 :            : static int
    2679                 :          0 : hns3_flow_query_wrap(struct rte_eth_dev *dev, struct rte_flow *flow,
    2680                 :            :                      const struct rte_flow_action *actions, void *data,
    2681                 :            :                      struct rte_flow_error *error)
    2682                 :            : {
    2683                 :          0 :         struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
    2684                 :            :         int ret;
    2685                 :            : 
    2686                 :          0 :         pthread_mutex_lock(&hw->flows_lock);
    2687                 :          0 :         ret = hns3_flow_query(dev, flow, actions, data, error);
    2688                 :          0 :         pthread_mutex_unlock(&hw->flows_lock);
    2689                 :            : 
    2690                 :          0 :         return ret;
    2691                 :            : }
    2692                 :            : 
    2693                 :            : static int
    2694                 :          0 : hns3_check_indir_action(const struct rte_flow_indir_action_conf *conf,
    2695                 :            :                         const struct rte_flow_action *action,
    2696                 :            :                         struct rte_flow_error *error)
    2697                 :            : {
    2698         [ #  # ]:          0 :         if (!conf->ingress)
    2699                 :          0 :                 return rte_flow_error_set(error, EINVAL,
    2700                 :            :                                 RTE_FLOW_ERROR_TYPE_ACTION,
    2701                 :            :                                 NULL, "Indir action ingress can't be zero");
    2702                 :            : 
    2703         [ #  # ]:          0 :         if (conf->egress)
    2704                 :          0 :                 return rte_flow_error_set(error, EINVAL,
    2705                 :            :                                 RTE_FLOW_ERROR_TYPE_ACTION,
    2706                 :            :                                 NULL, "Indir action not support egress");
    2707                 :            : 
    2708         [ #  # ]:          0 :         if (conf->transfer)
    2709                 :          0 :                 return rte_flow_error_set(error, EINVAL,
    2710                 :            :                                 RTE_FLOW_ERROR_TYPE_ACTION,
    2711                 :            :                                 NULL, "Indir action not support transfer");
    2712                 :            : 
    2713         [ #  # ]:          0 :         if (action->type != RTE_FLOW_ACTION_TYPE_COUNT)
    2714                 :          0 :                 return rte_flow_error_set(error, EINVAL,
    2715                 :            :                                 RTE_FLOW_ERROR_TYPE_ACTION,
    2716                 :            :                                 NULL, "Indir action only support count");
    2717                 :            : 
    2718                 :            :         return 0;
    2719                 :            : }
    2720                 :            : 
    2721                 :            : static struct rte_flow_action_handle *
    2722                 :          0 : hns3_flow_action_create(struct rte_eth_dev *dev,
    2723                 :            :                         const struct rte_flow_indir_action_conf *conf,
    2724                 :            :                         const struct rte_flow_action *action,
    2725                 :            :                         struct rte_flow_error *error)
    2726                 :            : {
    2727                 :          0 :         struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
    2728                 :            :         struct hns3_pf *pf = HNS3_DEV_PRIVATE_TO_PF(dev->data->dev_private);
    2729                 :            :         const struct rte_flow_action_count *act_count;
    2730                 :            :         struct rte_flow_action_handle handle;
    2731                 :            :         struct hns3_flow_counter *counter;
    2732                 :            : 
    2733         [ #  # ]:          0 :         if (hns3_check_indir_action(conf, action, error))
    2734                 :            :                 return NULL;
    2735                 :            : 
    2736                 :          0 :         pthread_mutex_lock(&hw->flows_lock);
    2737                 :            : 
    2738                 :          0 :         act_count = (const struct rte_flow_action_count *)action->conf;
    2739         [ #  # ]:          0 :         if (act_count->id >= pf->fdir.fd_cfg.cnt_num[HNS3_FD_STAGE_1]) {
    2740                 :          0 :                 rte_flow_error_set(error, EINVAL,
    2741                 :            :                                    RTE_FLOW_ERROR_TYPE_ACTION_CONF,
    2742                 :            :                                    action, "Invalid counter id");
    2743                 :          0 :                 goto err_exit;
    2744                 :            :         }
    2745                 :            : 
    2746         [ #  # ]:          0 :         if (hns3_counter_new(dev, false, act_count->id, error))
    2747                 :          0 :                 goto err_exit;
    2748                 :            : 
    2749                 :          0 :         counter = hns3_counter_lookup(dev, act_count->id);
    2750         [ #  # ]:          0 :         if (counter == NULL) {
    2751                 :          0 :                 rte_flow_error_set(error, EINVAL,
    2752                 :            :                                    RTE_FLOW_ERROR_TYPE_ACTION_CONF,
    2753                 :            :                                    action, "Counter id not found");
    2754                 :          0 :                 goto err_exit;
    2755                 :            :         }
    2756                 :            : 
    2757                 :          0 :         counter->indirect = true;
    2758                 :          0 :         handle.indirect_type = HNS3_INDIRECT_ACTION_TYPE_COUNT;
    2759                 :          0 :         handle.counter_id = counter->id;
    2760                 :            : 
    2761                 :          0 :         pthread_mutex_unlock(&hw->flows_lock);
    2762                 :          0 :         return (struct rte_flow_action_handle *)handle.val64;
    2763                 :            : 
    2764                 :          0 : err_exit:
    2765                 :          0 :         pthread_mutex_unlock(&hw->flows_lock);
    2766                 :          0 :         return NULL;
    2767                 :            : }
    2768                 :            : 
    2769                 :            : static int
    2770                 :          0 : hns3_flow_action_destroy(struct rte_eth_dev *dev,
    2771                 :            :                          struct rte_flow_action_handle *handle,
    2772                 :            :                          struct rte_flow_error *error)
    2773                 :            : {
    2774                 :          0 :         struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
    2775                 :            :         struct rte_flow_action_handle indir;
    2776                 :            :         struct hns3_flow_counter *counter;
    2777                 :            : 
    2778                 :          0 :         pthread_mutex_lock(&hw->flows_lock);
    2779                 :            : 
    2780                 :          0 :         indir.val64 = (uint64_t)handle;
    2781         [ #  # ]:          0 :         if (indir.indirect_type != HNS3_INDIRECT_ACTION_TYPE_COUNT) {
    2782                 :          0 :                 pthread_mutex_unlock(&hw->flows_lock);
    2783                 :          0 :                 return rte_flow_error_set(error, EINVAL,
    2784                 :            :                                         RTE_FLOW_ERROR_TYPE_ACTION_CONF,
    2785                 :            :                                         handle, "Invalid indirect type");
    2786                 :            :         }
    2787                 :            : 
    2788                 :            :         counter = hns3_counter_lookup(dev, indir.counter_id);
    2789         [ #  # ]:          0 :         if (counter == NULL) {
    2790                 :          0 :                 pthread_mutex_unlock(&hw->flows_lock);
    2791                 :          0 :                 return rte_flow_error_set(error, EINVAL,
    2792                 :            :                                 RTE_FLOW_ERROR_TYPE_ACTION_CONF,
    2793                 :            :                                 handle, "Counter id not exist");
    2794                 :            :         }
    2795                 :            : 
    2796         [ #  # ]:          0 :         if (counter->ref_cnt > 1) {
    2797                 :          0 :                 pthread_mutex_unlock(&hw->flows_lock);
    2798                 :          0 :                 return rte_flow_error_set(error, EBUSY,
    2799                 :            :                                 RTE_FLOW_ERROR_TYPE_HANDLE,
    2800                 :            :                                 handle, "Counter id in use");
    2801                 :            :         }
    2802                 :            : 
    2803                 :          0 :         (void)hns3_counter_release(dev, indir.counter_id);
    2804                 :            : 
    2805                 :          0 :         pthread_mutex_unlock(&hw->flows_lock);
    2806                 :          0 :         return 0;
    2807                 :            : }
    2808                 :            : 
    2809                 :            : static int
    2810                 :          0 : hns3_flow_action_query(struct rte_eth_dev *dev,
    2811                 :            :                  const struct rte_flow_action_handle *handle,
    2812                 :            :                  void *data,
    2813                 :            :                  struct rte_flow_error *error)
    2814                 :            : {
    2815                 :          0 :         struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
    2816                 :            :         struct rte_flow_action_handle indir;
    2817                 :            :         struct rte_flow flow;
    2818                 :            :         int ret;
    2819                 :            : 
    2820                 :          0 :         pthread_mutex_lock(&hw->flows_lock);
    2821                 :            : 
    2822                 :          0 :         indir.val64 = (uint64_t)handle;
    2823         [ #  # ]:          0 :         if (indir.indirect_type != HNS3_INDIRECT_ACTION_TYPE_COUNT) {
    2824                 :          0 :                 pthread_mutex_unlock(&hw->flows_lock);
    2825                 :          0 :                 return rte_flow_error_set(error, EINVAL,
    2826                 :            :                                         RTE_FLOW_ERROR_TYPE_ACTION_CONF,
    2827                 :            :                                         handle, "Invalid indirect type");
    2828                 :            :         }
    2829                 :            : 
    2830                 :            :         memset(&flow, 0, sizeof(flow));
    2831                 :          0 :         flow.counter_id = indir.counter_id;
    2832                 :          0 :         ret = hns3_counter_query(dev, &flow,
    2833                 :            :                                  (struct rte_flow_query_count *)data, error);
    2834                 :          0 :         pthread_mutex_unlock(&hw->flows_lock);
    2835                 :          0 :         return ret;
    2836                 :            : }
    2837                 :            : 
    2838                 :            : static const struct rte_flow_ops hns3_flow_ops = {
    2839                 :            :         .validate = hns3_flow_validate_wrap,
    2840                 :            :         .create = hns3_flow_create_wrap,
    2841                 :            :         .destroy = hns3_flow_destroy_wrap,
    2842                 :            :         .flush = hns3_flow_flush_wrap,
    2843                 :            :         .query = hns3_flow_query_wrap,
    2844                 :            :         .isolate = NULL,
    2845                 :            :         .action_handle_create = hns3_flow_action_create,
    2846                 :            :         .action_handle_destroy = hns3_flow_action_destroy,
    2847                 :            :         .action_handle_query = hns3_flow_action_query,
    2848                 :            : };
    2849                 :            : 
    2850                 :            : int
    2851                 :          0 : hns3_dev_flow_ops_get(struct rte_eth_dev *dev,
    2852                 :            :                       const struct rte_flow_ops **ops)
    2853                 :            : {
    2854                 :            :         struct hns3_hw *hw;
    2855                 :            : 
    2856                 :          0 :         hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
    2857         [ #  # ]:          0 :         if (hw->adapter_state >= HNS3_NIC_CLOSED)
    2858                 :            :                 return -ENODEV;
    2859                 :            : 
    2860                 :          0 :         *ops = &hns3_flow_ops;
    2861                 :          0 :         return 0;
    2862                 :            : }
    2863                 :            : 
    2864                 :            : void
    2865                 :          0 : hns3_flow_init(struct rte_eth_dev *dev)
    2866                 :            : {
    2867                 :          0 :         struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
    2868                 :            :         pthread_mutexattr_t attr;
    2869                 :            : 
    2870         [ #  # ]:          0 :         if (rte_eal_process_type() != RTE_PROC_PRIMARY)
    2871                 :          0 :                 return;
    2872                 :            : 
    2873                 :          0 :         pthread_mutexattr_init(&attr);
    2874                 :          0 :         pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
    2875                 :          0 :         pthread_mutex_init(&hw->flows_lock, &attr);
    2876                 :          0 :         dev->data->dev_flags |= RTE_ETH_DEV_FLOW_OPS_THREAD_SAFE;
    2877                 :            : 
    2878                 :          0 :         TAILQ_INIT(&hw->flow_fdir_list);
    2879                 :          0 :         TAILQ_INIT(&hw->flow_rss_list);
    2880                 :          0 :         TAILQ_INIT(&hw->flow_list);
    2881                 :            : }
    2882                 :            : 
    2883                 :            : void
    2884                 :          0 : hns3_flow_uninit(struct rte_eth_dev *dev)
    2885                 :            : {
    2886                 :            :         struct rte_flow_error error;
    2887         [ #  # ]:          0 :         if (rte_eal_process_type() == RTE_PROC_PRIMARY)
    2888                 :          0 :                 hns3_flow_flush_wrap(dev, &error);
    2889                 :          0 : }

Generated by: LCOV version 1.14