dpdk/drivers/net/iavf/iavf_hash.c
<<
>>
Prefs
   1/* SPDX-License-Identifier: BSD-3-Clause
   2 * Copyright(c) 2020 Intel Corporation
   3 */
   4
   5#include <sys/queue.h>
   6#include <stdio.h>
   7#include <errno.h>
   8#include <stdint.h>
   9#include <string.h>
  10#include <unistd.h>
  11#include <stdarg.h>
  12
  13#include <rte_debug.h>
  14#include <rte_ether.h>
  15#include <ethdev_driver.h>
  16#include <rte_log.h>
  17#include <rte_malloc.h>
  18#include <rte_eth_ctrl.h>
  19#include <rte_tailq.h>
  20#include <rte_flow_driver.h>
  21
  22#include "iavf_log.h"
  23#include "iavf.h"
  24#include "iavf_generic_flow.h"
  25
  26#define IAVF_PHINT_NONE                         0
  27#define IAVF_PHINT_GTPU                         BIT_ULL(0)
  28#define IAVF_PHINT_GTPU_EH                      BIT_ULL(1)
  29#define IAVF_PHINT_GTPU_EH_DWN                  BIT_ULL(2)
  30#define IAVF_PHINT_GTPU_EH_UP                   BIT_ULL(3)
  31#define IAVF_PHINT_OUTER_IPV4                   BIT_ULL(4)
  32#define IAVF_PHINT_OUTER_IPV6                   BIT_ULL(5)
  33#define IAVF_PHINT_GRE                          BIT_ULL(6)
  34/* the second IP header of GTPoGRE */
  35#define IAVF_PHINT_MID_IPV4                     BIT_ULL(7)
  36#define IAVF_PHINT_MID_IPV6                     BIT_ULL(8)
  37/* L2TPv2 */
  38#define IAVF_PHINT_L2TPV2                       BIT_ULL(9)
  39#define IAVF_PHINT_L2TPV2_LEN                   BIT_ULL(10)
  40/* Raw */
  41#define IAVF_PHINT_RAW                          BIT_ULL(11)
  42
  43#define IAVF_PHINT_GTPU_MSK     (IAVF_PHINT_GTPU        | \
  44                                 IAVF_PHINT_GTPU_EH     | \
  45                                 IAVF_PHINT_GTPU_EH_DWN | \
  46                                 IAVF_PHINT_GTPU_EH_UP)
  47
  48#define IAVF_PHINT_LAYERS_MSK   (IAVF_PHINT_OUTER_IPV4  | \
  49                                 IAVF_PHINT_OUTER_IPV6)
  50
  51#define IAVF_GTPU_EH_DWNLINK    0
  52#define IAVF_GTPU_EH_UPLINK     1
  53
  54struct iavf_hash_match_type {
  55        uint64_t hash_type;
  56        struct virtchnl_proto_hdrs *proto_hdrs;
  57        uint64_t pattern_hint;
  58};
  59
  60struct iavf_rss_meta {
  61        struct virtchnl_proto_hdrs proto_hdrs;
  62        enum virtchnl_rss_algorithm rss_algorithm;
  63        bool raw_ena;
  64};
  65
  66struct iavf_hash_flow_cfg {
  67        struct virtchnl_rss_cfg *rss_cfg;
  68        bool simple_xor;
  69};
  70
  71static int
  72iavf_hash_init(struct iavf_adapter *ad);
  73static int
  74iavf_hash_create(struct iavf_adapter *ad, struct rte_flow *flow, void *meta,
  75                 struct rte_flow_error *error);
  76static int
  77iavf_hash_destroy(struct iavf_adapter *ad, struct rte_flow *flow,
  78                  struct rte_flow_error *error);
  79static void
  80iavf_hash_uninit(struct iavf_adapter *ad);
  81static void
  82iavf_hash_free(struct rte_flow *flow);
  83static int
  84iavf_hash_parse_pattern_action(struct iavf_adapter *ad,
  85                               struct iavf_pattern_match_item *array,
  86                               uint32_t array_len,
  87                               const struct rte_flow_item pattern[],
  88                               const struct rte_flow_action actions[],
  89                               void **meta,
  90                               struct rte_flow_error *error);
  91
  92#define FIELD_SELECTOR(proto_hdr_field) \
  93                (1UL << ((proto_hdr_field) & PROTO_HDR_FIELD_MASK))
  94#define BUFF_NOUSED                     0
  95
  96#define proto_hdr_eth { \
  97        VIRTCHNL_PROTO_HDR_ETH, \
  98        FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_ETH_SRC) | \
  99        FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_ETH_DST), {BUFF_NOUSED} }
 100
 101#define proto_hdr_svlan { \
 102        VIRTCHNL_PROTO_HDR_S_VLAN, \
 103        FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_S_VLAN_ID), {BUFF_NOUSED} }
 104
 105#define proto_hdr_cvlan { \
 106        VIRTCHNL_PROTO_HDR_C_VLAN, \
 107        FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_C_VLAN_ID), {BUFF_NOUSED} }
 108
 109#define proto_hdr_ipv4 { \
 110        VIRTCHNL_PROTO_HDR_IPV4, \
 111        FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_SRC) | \
 112        FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_DST), {BUFF_NOUSED} }
 113
 114#define proto_hdr_ipv4_with_prot { \
 115        VIRTCHNL_PROTO_HDR_IPV4, \
 116        FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_SRC) | \
 117        FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_DST) | \
 118        FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV4_PROT), {BUFF_NOUSED} }
 119
 120#define proto_hdr_ipv6 { \
 121        VIRTCHNL_PROTO_HDR_IPV6, \
 122        FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_SRC) | \
 123        FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_DST), {BUFF_NOUSED} }
 124
 125#define proto_hdr_ipv6_frag { \
 126        VIRTCHNL_PROTO_HDR_IPV6_EH_FRAG, \
 127        FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_EH_FRAG_PKID), {BUFF_NOUSED} }
 128
 129#define proto_hdr_ipv6_with_prot { \
 130        VIRTCHNL_PROTO_HDR_IPV6, \
 131        FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_SRC) | \
 132        FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_DST) | \
 133        FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_IPV6_PROT), {BUFF_NOUSED} }
 134
 135#define proto_hdr_udp { \
 136        VIRTCHNL_PROTO_HDR_UDP, \
 137        FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_UDP_SRC_PORT) | \
 138        FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_UDP_DST_PORT), {BUFF_NOUSED} }
 139
 140#define proto_hdr_tcp { \
 141        VIRTCHNL_PROTO_HDR_TCP, \
 142        FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_TCP_SRC_PORT) | \
 143        FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_TCP_DST_PORT), {BUFF_NOUSED} }
 144
 145#define proto_hdr_sctp { \
 146        VIRTCHNL_PROTO_HDR_SCTP, \
 147        FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_SCTP_SRC_PORT) | \
 148        FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_SCTP_DST_PORT), {BUFF_NOUSED} }
 149
 150#define proto_hdr_esp { \
 151        VIRTCHNL_PROTO_HDR_ESP, \
 152        FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_ESP_SPI), {BUFF_NOUSED} }
 153
 154#define proto_hdr_ah { \
 155        VIRTCHNL_PROTO_HDR_AH, \
 156        FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_AH_SPI), {BUFF_NOUSED} }
 157
 158#define proto_hdr_l2tpv3 { \
 159        VIRTCHNL_PROTO_HDR_L2TPV3, \
 160        FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_L2TPV3_SESS_ID), {BUFF_NOUSED} }
 161
 162#define proto_hdr_pfcp { \
 163        VIRTCHNL_PROTO_HDR_PFCP, \
 164        FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_PFCP_SEID), {BUFF_NOUSED} }
 165
 166#define proto_hdr_gtpc { \
 167        VIRTCHNL_PROTO_HDR_GTPC, 0, {BUFF_NOUSED} }
 168
 169#define proto_hdr_ecpri { \
 170        VIRTCHNL_PROTO_HDR_ECPRI, \
 171        FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_ECPRI_PC_RTC_ID), {BUFF_NOUSED} }
 172
 173#define proto_hdr_l2tpv2 { \
 174        VIRTCHNL_PROTO_HDR_L2TPV2, \
 175        FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_L2TPV2_SESS_ID) | \
 176        FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_L2TPV2_LEN_SESS_ID), {BUFF_NOUSED} }
 177
 178#define proto_hdr_ppp { \
 179        VIRTCHNL_PROTO_HDR_PPP, 0, {BUFF_NOUSED} }
 180
 181#define TUNNEL_LEVEL_OUTER              0
 182#define TUNNEL_LEVEL_INNER              1
 183
 184/* proto_hdrs template */
 185struct virtchnl_proto_hdrs outer_ipv4_tmplt = {
 186        TUNNEL_LEVEL_OUTER, 4,
 187        {{proto_hdr_eth, proto_hdr_svlan, proto_hdr_cvlan, proto_hdr_ipv4}}
 188};
 189
 190struct virtchnl_proto_hdrs outer_ipv4_udp_tmplt = {
 191        TUNNEL_LEVEL_OUTER, 5,
 192        {{proto_hdr_eth, proto_hdr_svlan, proto_hdr_cvlan,
 193          proto_hdr_ipv4_with_prot,
 194          proto_hdr_udp}}
 195};
 196
 197struct virtchnl_proto_hdrs outer_ipv4_tcp_tmplt = {
 198        TUNNEL_LEVEL_OUTER, 5,
 199        {{proto_hdr_eth, proto_hdr_svlan, proto_hdr_cvlan,
 200          proto_hdr_ipv4_with_prot,
 201          proto_hdr_tcp}}
 202};
 203
 204struct virtchnl_proto_hdrs outer_ipv4_sctp_tmplt = {
 205        TUNNEL_LEVEL_OUTER, 5,
 206        {{proto_hdr_eth, proto_hdr_svlan, proto_hdr_cvlan, proto_hdr_ipv4,
 207          proto_hdr_sctp}}
 208};
 209
 210struct virtchnl_proto_hdrs outer_ipv6_tmplt = {
 211        TUNNEL_LEVEL_OUTER, 4,
 212        {{proto_hdr_eth, proto_hdr_svlan, proto_hdr_cvlan, proto_hdr_ipv6}}
 213};
 214
 215struct virtchnl_proto_hdrs outer_ipv6_frag_tmplt = {
 216        TUNNEL_LEVEL_OUTER, 5,
 217        {{proto_hdr_eth, proto_hdr_svlan, proto_hdr_cvlan,
 218          proto_hdr_ipv6, proto_hdr_ipv6_frag}}
 219};
 220
 221struct virtchnl_proto_hdrs outer_ipv6_udp_tmplt = {
 222        TUNNEL_LEVEL_OUTER, 5,
 223        {{proto_hdr_eth, proto_hdr_svlan, proto_hdr_cvlan,
 224          proto_hdr_ipv6_with_prot,
 225          proto_hdr_udp}}
 226};
 227
 228struct virtchnl_proto_hdrs outer_ipv6_tcp_tmplt = {
 229        TUNNEL_LEVEL_OUTER, 5,
 230        {{proto_hdr_eth, proto_hdr_svlan, proto_hdr_cvlan,
 231          proto_hdr_ipv6_with_prot,
 232          proto_hdr_tcp}}
 233};
 234
 235struct virtchnl_proto_hdrs outer_ipv6_sctp_tmplt = {
 236        TUNNEL_LEVEL_OUTER, 5,
 237        {{proto_hdr_eth, proto_hdr_svlan, proto_hdr_cvlan, proto_hdr_ipv6,
 238          proto_hdr_sctp}}
 239};
 240
 241struct virtchnl_proto_hdrs inner_ipv4_tmplt = {
 242        TUNNEL_LEVEL_INNER, 1, {{proto_hdr_ipv4}}
 243};
 244
 245struct virtchnl_proto_hdrs inner_ipv4_udp_tmplt = {
 246        TUNNEL_LEVEL_INNER, 2, {{proto_hdr_ipv4_with_prot, proto_hdr_udp}}
 247};
 248
 249struct virtchnl_proto_hdrs inner_ipv4_tcp_tmplt = {
 250        TUNNEL_LEVEL_INNER, 2, {{proto_hdr_ipv4_with_prot, proto_hdr_tcp}}
 251};
 252
 253struct virtchnl_proto_hdrs second_inner_ipv4_tmplt = {
 254        2, 1, {{proto_hdr_ipv4}}
 255};
 256
 257struct virtchnl_proto_hdrs second_inner_ipv4_udp_tmplt = {
 258        2, 2, {{proto_hdr_ipv4_with_prot, proto_hdr_udp}}
 259};
 260
 261struct virtchnl_proto_hdrs second_inner_ipv4_tcp_tmplt = {
 262        2, 2, {{proto_hdr_ipv4_with_prot, proto_hdr_tcp}}
 263};
 264
 265struct virtchnl_proto_hdrs second_inner_ipv6_tmplt = {
 266        2, 1, {{proto_hdr_ipv6}}
 267};
 268
 269struct virtchnl_proto_hdrs second_inner_ipv6_udp_tmplt = {
 270        2, 2, {{proto_hdr_ipv6_with_prot, proto_hdr_udp}}
 271};
 272
 273struct virtchnl_proto_hdrs second_inner_ipv6_tcp_tmplt = {
 274        2, 2, {{proto_hdr_ipv6_with_prot, proto_hdr_tcp}}
 275};
 276
 277struct virtchnl_proto_hdrs inner_ipv4_sctp_tmplt = {
 278        TUNNEL_LEVEL_INNER, 2, {{proto_hdr_ipv4, proto_hdr_sctp}}
 279};
 280
 281struct virtchnl_proto_hdrs inner_ipv6_tmplt = {
 282        TUNNEL_LEVEL_INNER, 1, {{proto_hdr_ipv6}}
 283};
 284
 285struct virtchnl_proto_hdrs inner_ipv6_udp_tmplt = {
 286        TUNNEL_LEVEL_INNER, 2, {{proto_hdr_ipv6_with_prot, proto_hdr_udp}}
 287};
 288
 289struct virtchnl_proto_hdrs inner_ipv6_tcp_tmplt = {
 290        TUNNEL_LEVEL_INNER, 2, {{proto_hdr_ipv6_with_prot, proto_hdr_tcp}}
 291};
 292
 293struct virtchnl_proto_hdrs inner_ipv6_sctp_tmplt = {
 294        TUNNEL_LEVEL_INNER, 2, {{proto_hdr_ipv6, proto_hdr_sctp}}
 295};
 296
 297struct virtchnl_proto_hdrs ipv4_esp_tmplt = {
 298        TUNNEL_LEVEL_OUTER, 2, {{proto_hdr_ipv4, proto_hdr_esp}}
 299};
 300
 301struct virtchnl_proto_hdrs ipv4_udp_esp_tmplt = {
 302        TUNNEL_LEVEL_OUTER, 3,
 303        {{proto_hdr_ipv4, proto_hdr_udp, proto_hdr_esp}}
 304};
 305
 306struct virtchnl_proto_hdrs ipv4_ah_tmplt = {
 307        TUNNEL_LEVEL_OUTER, 2, {{proto_hdr_ipv4, proto_hdr_ah}}
 308};
 309
 310struct virtchnl_proto_hdrs ipv6_esp_tmplt = {
 311        TUNNEL_LEVEL_OUTER, 2, {{proto_hdr_ipv6, proto_hdr_esp}}
 312};
 313
 314struct virtchnl_proto_hdrs ipv6_udp_esp_tmplt = {
 315        TUNNEL_LEVEL_OUTER, 3,
 316        {{proto_hdr_ipv6, proto_hdr_udp, proto_hdr_esp}}
 317};
 318
 319struct virtchnl_proto_hdrs ipv6_ah_tmplt = {
 320        TUNNEL_LEVEL_OUTER, 2, {{proto_hdr_ipv6, proto_hdr_ah}}
 321};
 322
 323struct virtchnl_proto_hdrs ipv4_l2tpv3_tmplt = {
 324        TUNNEL_LEVEL_OUTER, 2, {{proto_hdr_ipv4, proto_hdr_l2tpv3}}
 325};
 326
 327struct virtchnl_proto_hdrs ipv6_l2tpv3_tmplt = {
 328        TUNNEL_LEVEL_OUTER, 2, {{proto_hdr_ipv6, proto_hdr_l2tpv3}}
 329};
 330
 331struct virtchnl_proto_hdrs ipv4_pfcp_tmplt = {
 332        TUNNEL_LEVEL_OUTER, 2, {{proto_hdr_ipv4, proto_hdr_pfcp}}
 333};
 334
 335struct virtchnl_proto_hdrs ipv6_pfcp_tmplt = {
 336        TUNNEL_LEVEL_OUTER, 2, {{proto_hdr_ipv6, proto_hdr_pfcp}}
 337};
 338
 339struct virtchnl_proto_hdrs ipv4_udp_gtpc_tmplt = {
 340        TUNNEL_LEVEL_OUTER, 3,
 341        {{proto_hdr_ipv4, proto_hdr_udp, proto_hdr_gtpc}}
 342};
 343
 344struct virtchnl_proto_hdrs ipv6_udp_gtpc_tmplt = {
 345        TUNNEL_LEVEL_OUTER, 3,
 346        {{proto_hdr_ipv6, proto_hdr_udp, proto_hdr_gtpc}}
 347};
 348
 349struct virtchnl_proto_hdrs eth_ecpri_tmplt = {
 350        TUNNEL_LEVEL_OUTER, 2, {{proto_hdr_eth, proto_hdr_ecpri}}
 351};
 352
 353struct virtchnl_proto_hdrs ipv4_ecpri_tmplt = {
 354        TUNNEL_LEVEL_OUTER, 3,
 355        {{proto_hdr_ipv4, proto_hdr_udp, proto_hdr_ecpri}}
 356};
 357
 358struct virtchnl_proto_hdrs udp_l2tpv2_ppp_ipv4_tmplt = {
 359        TUNNEL_LEVEL_INNER, 3,
 360        {{proto_hdr_l2tpv2,
 361          proto_hdr_ppp,
 362          proto_hdr_ipv4}}
 363};
 364
 365struct virtchnl_proto_hdrs udp_l2tpv2_ppp_ipv6_tmplt = {
 366        TUNNEL_LEVEL_INNER, 3,
 367        {{proto_hdr_l2tpv2,
 368          proto_hdr_ppp,
 369          proto_hdr_ipv6}}
 370};
 371
 372struct virtchnl_proto_hdrs udp_l2tpv2_ppp_ipv4_udp_tmplt = {
 373        TUNNEL_LEVEL_INNER, 4,
 374        {{proto_hdr_l2tpv2,
 375          proto_hdr_ppp,
 376          proto_hdr_ipv4_with_prot,
 377          proto_hdr_udp}}
 378};
 379
 380struct virtchnl_proto_hdrs udp_l2tpv2_ppp_ipv4_tcp_tmplt = {
 381        TUNNEL_LEVEL_INNER, 4,
 382        {{proto_hdr_l2tpv2,
 383          proto_hdr_ppp,
 384          proto_hdr_ipv4_with_prot,
 385          proto_hdr_tcp}}
 386};
 387
 388struct virtchnl_proto_hdrs udp_l2tpv2_ppp_ipv6_udp_tmplt = {
 389        TUNNEL_LEVEL_INNER, 4,
 390        {{proto_hdr_l2tpv2,
 391          proto_hdr_ppp,
 392          proto_hdr_ipv6_with_prot,
 393          proto_hdr_udp}}
 394};
 395
 396struct virtchnl_proto_hdrs udp_l2tpv2_ppp_ipv6_tcp_tmplt = {
 397        TUNNEL_LEVEL_INNER, 4,
 398        {{proto_hdr_l2tpv2,
 399          proto_hdr_ppp,
 400          proto_hdr_ipv6_with_prot,
 401          proto_hdr_tcp}}
 402
 403};
 404
 405struct virtchnl_proto_hdrs ipv4_l2tpv2_tmplt = {
 406        TUNNEL_LEVEL_OUTER, 4,
 407        {{proto_hdr_eth,
 408          proto_hdr_ipv4,
 409          proto_hdr_udp,
 410          proto_hdr_l2tpv2}}
 411};
 412
 413struct virtchnl_proto_hdrs ipv6_l2tpv2_tmplt = {
 414        TUNNEL_LEVEL_OUTER, 4,
 415        {{proto_hdr_eth,
 416          proto_hdr_ipv6,
 417          proto_hdr_udp,
 418          proto_hdr_l2tpv2}}
 419};
 420
 421struct virtchnl_proto_hdrs ipv4_l2tpv2_ppp_tmplt = {
 422        TUNNEL_LEVEL_OUTER, 5,
 423        {{proto_hdr_eth,
 424          proto_hdr_ipv4,
 425          proto_hdr_udp,
 426          proto_hdr_l2tpv2,
 427          proto_hdr_ppp}}
 428};
 429
 430struct virtchnl_proto_hdrs ipv6_l2tpv2_ppp_tmplt = {
 431        TUNNEL_LEVEL_OUTER, 5,
 432        {{proto_hdr_eth,
 433          proto_hdr_ipv6,
 434          proto_hdr_udp,
 435          proto_hdr_l2tpv2,
 436          proto_hdr_ppp}}
 437};
 438
 439/* rss type super set */
 440
 441/* IPv4 outer */
 442#define IAVF_RSS_TYPE_OUTER_IPV4        (RTE_ETH_RSS_ETH | RTE_ETH_RSS_IPV4 | \
 443                                         RTE_ETH_RSS_FRAG_IPV4 | \
 444                                         RTE_ETH_RSS_IPV4_CHKSUM)
 445#define IAVF_RSS_TYPE_OUTER_IPV4_UDP    (IAVF_RSS_TYPE_OUTER_IPV4 | \
 446                                         RTE_ETH_RSS_NONFRAG_IPV4_UDP | \
 447                                         RTE_ETH_RSS_L4_CHKSUM)
 448#define IAVF_RSS_TYPE_OUTER_IPV4_TCP    (IAVF_RSS_TYPE_OUTER_IPV4 | \
 449                                         RTE_ETH_RSS_NONFRAG_IPV4_TCP | \
 450                                         RTE_ETH_RSS_L4_CHKSUM)
 451#define IAVF_RSS_TYPE_OUTER_IPV4_SCTP   (IAVF_RSS_TYPE_OUTER_IPV4 | \
 452                                         RTE_ETH_RSS_NONFRAG_IPV4_SCTP | \
 453                                         RTE_ETH_RSS_L4_CHKSUM)
 454/* IPv6 outer */
 455#define IAVF_RSS_TYPE_OUTER_IPV6        (RTE_ETH_RSS_ETH | RTE_ETH_RSS_IPV6)
 456#define IAVF_RSS_TYPE_OUTER_IPV6_FRAG   (IAVF_RSS_TYPE_OUTER_IPV6 | \
 457                                         RTE_ETH_RSS_FRAG_IPV6)
 458#define IAVF_RSS_TYPE_OUTER_IPV6_UDP    (IAVF_RSS_TYPE_OUTER_IPV6 | \
 459                                         RTE_ETH_RSS_NONFRAG_IPV6_UDP | \
 460                                         RTE_ETH_RSS_L4_CHKSUM)
 461#define IAVF_RSS_TYPE_OUTER_IPV6_TCP    (IAVF_RSS_TYPE_OUTER_IPV6 | \
 462                                         RTE_ETH_RSS_NONFRAG_IPV6_TCP | \
 463                                         RTE_ETH_RSS_L4_CHKSUM)
 464#define IAVF_RSS_TYPE_OUTER_IPV6_SCTP   (IAVF_RSS_TYPE_OUTER_IPV6 | \
 465                                         RTE_ETH_RSS_NONFRAG_IPV6_SCTP | \
 466                                         RTE_ETH_RSS_L4_CHKSUM)
 467/* VLAN IPV4 */
 468#define IAVF_RSS_TYPE_VLAN_IPV4         (IAVF_RSS_TYPE_OUTER_IPV4 | \
 469                                         RTE_ETH_RSS_S_VLAN | RTE_ETH_RSS_C_VLAN)
 470#define IAVF_RSS_TYPE_VLAN_IPV4_UDP     (IAVF_RSS_TYPE_OUTER_IPV4_UDP | \
 471                                         RTE_ETH_RSS_S_VLAN | RTE_ETH_RSS_C_VLAN)
 472#define IAVF_RSS_TYPE_VLAN_IPV4_TCP     (IAVF_RSS_TYPE_OUTER_IPV4_TCP | \
 473                                         RTE_ETH_RSS_S_VLAN | RTE_ETH_RSS_C_VLAN)
 474#define IAVF_RSS_TYPE_VLAN_IPV4_SCTP    (IAVF_RSS_TYPE_OUTER_IPV4_SCTP | \
 475                                         RTE_ETH_RSS_S_VLAN | RTE_ETH_RSS_C_VLAN)
 476/* VLAN IPv6 */
 477#define IAVF_RSS_TYPE_VLAN_IPV6         (IAVF_RSS_TYPE_OUTER_IPV6 | \
 478                                         RTE_ETH_RSS_S_VLAN | RTE_ETH_RSS_C_VLAN)
 479#define IAVF_RSS_TYPE_VLAN_IPV6_FRAG    (IAVF_RSS_TYPE_OUTER_IPV6_FRAG | \
 480                                         RTE_ETH_RSS_S_VLAN | RTE_ETH_RSS_C_VLAN)
 481#define IAVF_RSS_TYPE_VLAN_IPV6_UDP     (IAVF_RSS_TYPE_OUTER_IPV6_UDP | \
 482                                         RTE_ETH_RSS_S_VLAN | RTE_ETH_RSS_C_VLAN)
 483#define IAVF_RSS_TYPE_VLAN_IPV6_TCP     (IAVF_RSS_TYPE_OUTER_IPV6_TCP | \
 484                                         RTE_ETH_RSS_S_VLAN | RTE_ETH_RSS_C_VLAN)
 485#define IAVF_RSS_TYPE_VLAN_IPV6_SCTP    (IAVF_RSS_TYPE_OUTER_IPV6_SCTP | \
 486                                         RTE_ETH_RSS_S_VLAN | RTE_ETH_RSS_C_VLAN)
 487/* IPv4 inner */
 488#define IAVF_RSS_TYPE_INNER_IPV4        RTE_ETH_RSS_IPV4
 489#define IAVF_RSS_TYPE_INNER_IPV4_UDP    (RTE_ETH_RSS_IPV4 | \
 490                                         RTE_ETH_RSS_NONFRAG_IPV4_UDP)
 491#define IAVF_RSS_TYPE_INNER_IPV4_TCP    (RTE_ETH_RSS_IPV4 | \
 492                                         RTE_ETH_RSS_NONFRAG_IPV4_TCP)
 493#define IAVF_RSS_TYPE_INNER_IPV4_SCTP   (RTE_ETH_RSS_IPV4 | \
 494                                         RTE_ETH_RSS_NONFRAG_IPV4_SCTP)
 495/* IPv6 inner */
 496#define IAVF_RSS_TYPE_INNER_IPV6        RTE_ETH_RSS_IPV6
 497#define IAVF_RSS_TYPE_INNER_IPV6_UDP    (RTE_ETH_RSS_IPV6 | \
 498                                         RTE_ETH_RSS_NONFRAG_IPV6_UDP)
 499#define IAVF_RSS_TYPE_INNER_IPV6_TCP    (RTE_ETH_RSS_IPV6 | \
 500                                         RTE_ETH_RSS_NONFRAG_IPV6_TCP)
 501#define IAVF_RSS_TYPE_INNER_IPV6_SCTP   (RTE_ETH_RSS_IPV6 | \
 502                                         RTE_ETH_RSS_NONFRAG_IPV6_SCTP)
 503/* GTPU IPv4 */
 504#define IAVF_RSS_TYPE_GTPU_IPV4         (IAVF_RSS_TYPE_INNER_IPV4 | \
 505                                         RTE_ETH_RSS_GTPU)
 506#define IAVF_RSS_TYPE_GTPU_IPV4_UDP     (IAVF_RSS_TYPE_INNER_IPV4_UDP | \
 507                                         RTE_ETH_RSS_GTPU)
 508#define IAVF_RSS_TYPE_GTPU_IPV4_TCP     (IAVF_RSS_TYPE_INNER_IPV4_TCP | \
 509                                         RTE_ETH_RSS_GTPU)
 510/* GTPU IPv6 */
 511#define IAVF_RSS_TYPE_GTPU_IPV6         (IAVF_RSS_TYPE_INNER_IPV6 | \
 512                                         RTE_ETH_RSS_GTPU)
 513#define IAVF_RSS_TYPE_GTPU_IPV6_UDP     (IAVF_RSS_TYPE_INNER_IPV6_UDP | \
 514                                         RTE_ETH_RSS_GTPU)
 515#define IAVF_RSS_TYPE_GTPU_IPV6_TCP     (IAVF_RSS_TYPE_INNER_IPV6_TCP | \
 516                                         RTE_ETH_RSS_GTPU)
 517/* ESP, AH, L2TPV3 and PFCP */
 518#define IAVF_RSS_TYPE_IPV4_ESP          (RTE_ETH_RSS_ESP | RTE_ETH_RSS_IPV4)
 519#define IAVF_RSS_TYPE_IPV4_AH           (RTE_ETH_RSS_AH | RTE_ETH_RSS_IPV4)
 520#define IAVF_RSS_TYPE_IPV6_ESP          (RTE_ETH_RSS_ESP | RTE_ETH_RSS_IPV6)
 521#define IAVF_RSS_TYPE_IPV6_AH           (RTE_ETH_RSS_AH | RTE_ETH_RSS_IPV6)
 522#define IAVF_RSS_TYPE_IPV4_L2TPV3       (RTE_ETH_RSS_L2TPV3 | RTE_ETH_RSS_IPV4)
 523#define IAVF_RSS_TYPE_IPV6_L2TPV3       (RTE_ETH_RSS_L2TPV3 | RTE_ETH_RSS_IPV6)
 524#define IAVF_RSS_TYPE_IPV4_PFCP         (RTE_ETH_RSS_PFCP | RTE_ETH_RSS_IPV4)
 525#define IAVF_RSS_TYPE_IPV6_PFCP         (RTE_ETH_RSS_PFCP | RTE_ETH_RSS_IPV6)
 526
 527/* L2TPv2 */
 528#define IAVF_RSS_TYPE_ETH_L2TPV2        (RTE_ETH_RSS_ETH | RTE_ETH_RSS_L2TPV2)
 529
 530/**
 531 * Supported pattern for hash.
 532 * The first member is pattern item type,
 533 * the second member is input set mask,
 534 * the third member is virtchnl_proto_hdrs template
 535 */
 536static struct iavf_pattern_match_item iavf_hash_pattern_list[] = {
 537        /* IPv4 */
 538        {iavf_pattern_raw,                              IAVF_INSET_NONE,                NULL},
 539        {iavf_pattern_eth_ipv4,                         IAVF_RSS_TYPE_OUTER_IPV4,       &outer_ipv4_tmplt},
 540        {iavf_pattern_eth_ipv4_udp,                     IAVF_RSS_TYPE_OUTER_IPV4_UDP,   &outer_ipv4_udp_tmplt},
 541        {iavf_pattern_eth_ipv4_tcp,                     IAVF_RSS_TYPE_OUTER_IPV4_TCP,   &outer_ipv4_tcp_tmplt},
 542        {iavf_pattern_eth_ipv4_sctp,                    IAVF_RSS_TYPE_OUTER_IPV4_SCTP,  &outer_ipv4_sctp_tmplt},
 543        {iavf_pattern_eth_vlan_ipv4,                    IAVF_RSS_TYPE_VLAN_IPV4,        &outer_ipv4_tmplt},
 544        {iavf_pattern_eth_vlan_ipv4_udp,                IAVF_RSS_TYPE_VLAN_IPV4_UDP,    &outer_ipv4_udp_tmplt},
 545        {iavf_pattern_eth_vlan_ipv4_tcp,                IAVF_RSS_TYPE_VLAN_IPV4_TCP,    &outer_ipv4_tcp_tmplt},
 546        {iavf_pattern_eth_vlan_ipv4_sctp,               IAVF_RSS_TYPE_VLAN_IPV4_SCTP,   &outer_ipv4_sctp_tmplt},
 547        {iavf_pattern_eth_ipv4_gtpu,                    RTE_ETH_RSS_IPV4,                       &outer_ipv4_udp_tmplt},
 548        {iavf_pattern_eth_ipv4_gtpu_ipv4,               IAVF_RSS_TYPE_GTPU_IPV4,        &inner_ipv4_tmplt},
 549        {iavf_pattern_eth_ipv4_gtpu_ipv4_udp,           IAVF_RSS_TYPE_GTPU_IPV4_UDP,    &inner_ipv4_udp_tmplt},
 550        {iavf_pattern_eth_ipv4_gtpu_ipv4_tcp,           IAVF_RSS_TYPE_GTPU_IPV4_TCP,    &inner_ipv4_tcp_tmplt},
 551        {iavf_pattern_eth_ipv6_gtpu_ipv4,               IAVF_RSS_TYPE_GTPU_IPV4,        &inner_ipv4_tmplt},
 552        {iavf_pattern_eth_ipv6_gtpu_ipv4_udp,           IAVF_RSS_TYPE_GTPU_IPV4_UDP,    &inner_ipv4_udp_tmplt},
 553        {iavf_pattern_eth_ipv6_gtpu_ipv4_tcp,           IAVF_RSS_TYPE_GTPU_IPV4_TCP,    &inner_ipv4_tcp_tmplt},
 554        {iavf_pattern_eth_ipv4_gtpu_eh_ipv4,            IAVF_RSS_TYPE_GTPU_IPV4,        &inner_ipv4_tmplt},
 555        {iavf_pattern_eth_ipv4_gtpu_eh_ipv4_udp,        IAVF_RSS_TYPE_GTPU_IPV4_UDP,    &inner_ipv4_udp_tmplt},
 556        {iavf_pattern_eth_ipv4_gtpu_eh_ipv4_tcp,        IAVF_RSS_TYPE_GTPU_IPV4_TCP,    &inner_ipv4_tcp_tmplt},
 557        {iavf_pattern_eth_ipv6_gtpu_eh_ipv4,            IAVF_RSS_TYPE_GTPU_IPV4,        &inner_ipv4_tmplt},
 558        {iavf_pattern_eth_ipv6_gtpu_eh_ipv4_udp,        IAVF_RSS_TYPE_GTPU_IPV4_UDP,    &inner_ipv4_udp_tmplt},
 559        {iavf_pattern_eth_ipv6_gtpu_eh_ipv4_tcp,        IAVF_RSS_TYPE_GTPU_IPV4_TCP,    &inner_ipv4_tcp_tmplt},
 560        {iavf_pattern_eth_ipv4_gre_ipv4_gtpu_ipv4,              IAVF_RSS_TYPE_GTPU_IPV4,        &second_inner_ipv4_tmplt},
 561        {iavf_pattern_eth_ipv4_gre_ipv4_gtpu_ipv4_udp,          IAVF_RSS_TYPE_GTPU_IPV4_UDP,    &second_inner_ipv4_udp_tmplt},
 562        {iavf_pattern_eth_ipv4_gre_ipv4_gtpu_ipv4_tcp,          IAVF_RSS_TYPE_GTPU_IPV4_TCP,    &second_inner_ipv4_tcp_tmplt},
 563        {iavf_pattern_eth_ipv4_gre_ipv6_gtpu_ipv4,              IAVF_RSS_TYPE_GTPU_IPV4,        &second_inner_ipv4_tmplt},
 564        {iavf_pattern_eth_ipv4_gre_ipv6_gtpu_ipv4_udp,          IAVF_RSS_TYPE_GTPU_IPV4_UDP,    &second_inner_ipv4_udp_tmplt},
 565        {iavf_pattern_eth_ipv4_gre_ipv6_gtpu_ipv4_tcp,          IAVF_RSS_TYPE_GTPU_IPV4_TCP,    &second_inner_ipv4_tcp_tmplt},
 566        {iavf_pattern_eth_ipv6_gre_ipv4_gtpu_ipv4,              IAVF_RSS_TYPE_GTPU_IPV4,        &second_inner_ipv4_tmplt},
 567        {iavf_pattern_eth_ipv6_gre_ipv4_gtpu_ipv4_udp,          IAVF_RSS_TYPE_GTPU_IPV4_UDP,    &second_inner_ipv4_udp_tmplt},
 568        {iavf_pattern_eth_ipv6_gre_ipv4_gtpu_ipv4_tcp,          IAVF_RSS_TYPE_GTPU_IPV4_TCP,    &second_inner_ipv4_tcp_tmplt},
 569        {iavf_pattern_eth_ipv6_gre_ipv6_gtpu_ipv4,              IAVF_RSS_TYPE_GTPU_IPV4,        &second_inner_ipv4_tmplt},
 570        {iavf_pattern_eth_ipv6_gre_ipv6_gtpu_ipv4_udp,          IAVF_RSS_TYPE_GTPU_IPV4_UDP,    &second_inner_ipv4_udp_tmplt},
 571        {iavf_pattern_eth_ipv6_gre_ipv6_gtpu_ipv4_tcp,          IAVF_RSS_TYPE_GTPU_IPV4_TCP,    &second_inner_ipv4_tcp_tmplt},
 572        {iavf_pattern_eth_ipv4_gre_ipv4_gtpu_eh_ipv4,           IAVF_RSS_TYPE_GTPU_IPV4,        &second_inner_ipv4_tmplt},
 573        {iavf_pattern_eth_ipv4_gre_ipv4_gtpu_eh_ipv4_udp,       IAVF_RSS_TYPE_GTPU_IPV4_UDP,    &second_inner_ipv4_udp_tmplt},
 574        {iavf_pattern_eth_ipv4_gre_ipv4_gtpu_eh_ipv4_tcp,       IAVF_RSS_TYPE_GTPU_IPV4_TCP,    &second_inner_ipv4_tcp_tmplt},
 575        {iavf_pattern_eth_ipv4_gre_ipv6_gtpu_eh_ipv4,           IAVF_RSS_TYPE_GTPU_IPV4,        &second_inner_ipv4_tmplt},
 576        {iavf_pattern_eth_ipv4_gre_ipv6_gtpu_eh_ipv4_udp,       IAVF_RSS_TYPE_GTPU_IPV4_UDP,    &second_inner_ipv4_udp_tmplt},
 577        {iavf_pattern_eth_ipv4_gre_ipv6_gtpu_eh_ipv4_tcp,       IAVF_RSS_TYPE_GTPU_IPV4_TCP,    &second_inner_ipv4_tcp_tmplt},
 578        {iavf_pattern_eth_ipv6_gre_ipv4_gtpu_eh_ipv4,           IAVF_RSS_TYPE_GTPU_IPV4,        &second_inner_ipv4_tmplt},
 579        {iavf_pattern_eth_ipv6_gre_ipv4_gtpu_eh_ipv4_udp,       IAVF_RSS_TYPE_GTPU_IPV4_UDP,    &second_inner_ipv4_udp_tmplt},
 580        {iavf_pattern_eth_ipv6_gre_ipv4_gtpu_eh_ipv4_tcp,       IAVF_RSS_TYPE_GTPU_IPV4_TCP,    &second_inner_ipv4_tcp_tmplt},
 581        {iavf_pattern_eth_ipv6_gre_ipv6_gtpu_eh_ipv4,           IAVF_RSS_TYPE_GTPU_IPV4,        &second_inner_ipv4_tmplt},
 582        {iavf_pattern_eth_ipv6_gre_ipv6_gtpu_eh_ipv4_udp,       IAVF_RSS_TYPE_GTPU_IPV4_UDP,    &second_inner_ipv4_udp_tmplt},
 583        {iavf_pattern_eth_ipv6_gre_ipv6_gtpu_eh_ipv4_tcp,       IAVF_RSS_TYPE_GTPU_IPV4_TCP,    &second_inner_ipv4_tcp_tmplt},
 584        {iavf_pattern_eth_ipv4_esp,                     IAVF_RSS_TYPE_IPV4_ESP,         &ipv4_esp_tmplt},
 585        {iavf_pattern_eth_ipv4_udp_esp,                 IAVF_RSS_TYPE_IPV4_ESP,         &ipv4_udp_esp_tmplt},
 586        {iavf_pattern_eth_ipv4_ah,                      IAVF_RSS_TYPE_IPV4_AH,          &ipv4_ah_tmplt},
 587        {iavf_pattern_eth_ipv4_l2tpv3,                  IAVF_RSS_TYPE_IPV4_L2TPV3,      &ipv4_l2tpv3_tmplt},
 588        {iavf_pattern_eth_ipv4_pfcp,                    IAVF_RSS_TYPE_IPV4_PFCP,        &ipv4_pfcp_tmplt},
 589        {iavf_pattern_eth_ipv4_gtpc,                    RTE_ETH_RSS_IPV4,                       &ipv4_udp_gtpc_tmplt},
 590        {iavf_pattern_eth_ecpri,                        RTE_ETH_RSS_ECPRI,                      &eth_ecpri_tmplt},
 591        {iavf_pattern_eth_ipv4_ecpri,                   RTE_ETH_RSS_ECPRI,                      &ipv4_ecpri_tmplt},
 592        {iavf_pattern_eth_ipv4_gre_ipv4,                IAVF_RSS_TYPE_INNER_IPV4,       &inner_ipv4_tmplt},
 593        {iavf_pattern_eth_ipv6_gre_ipv4,                IAVF_RSS_TYPE_INNER_IPV4, &inner_ipv4_tmplt},
 594        {iavf_pattern_eth_ipv4_gre_ipv4_tcp,    IAVF_RSS_TYPE_INNER_IPV4_TCP, &inner_ipv4_tcp_tmplt},
 595        {iavf_pattern_eth_ipv6_gre_ipv4_tcp,    IAVF_RSS_TYPE_INNER_IPV4_TCP, &inner_ipv4_tcp_tmplt},
 596        {iavf_pattern_eth_ipv4_gre_ipv4_udp,    IAVF_RSS_TYPE_INNER_IPV4_UDP, &inner_ipv4_udp_tmplt},
 597        {iavf_pattern_eth_ipv6_gre_ipv4_udp,    IAVF_RSS_TYPE_INNER_IPV4_UDP, &inner_ipv4_udp_tmplt},
 598        {iavf_pattern_eth_ipv4_udp_l2tpv2,              IAVF_RSS_TYPE_ETH_L2TPV2,       &ipv4_l2tpv2_tmplt},
 599        {iavf_pattern_eth_ipv4_udp_l2tpv2_ppp,          IAVF_RSS_TYPE_ETH_L2TPV2,       &ipv4_l2tpv2_ppp_tmplt},
 600        {iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4,     IAVF_RSS_TYPE_INNER_IPV4,       &udp_l2tpv2_ppp_ipv4_tmplt},
 601        {iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4_udp, IAVF_RSS_TYPE_INNER_IPV4_UDP,   &udp_l2tpv2_ppp_ipv4_udp_tmplt},
 602        {iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4_tcp, IAVF_RSS_TYPE_INNER_IPV4_TCP,   &udp_l2tpv2_ppp_ipv4_tcp_tmplt},
 603        {iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4,     IAVF_RSS_TYPE_INNER_IPV4,       &udp_l2tpv2_ppp_ipv4_tmplt},
 604        {iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4_udp, IAVF_RSS_TYPE_INNER_IPV4_UDP,   &udp_l2tpv2_ppp_ipv4_udp_tmplt},
 605        {iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4_tcp, IAVF_RSS_TYPE_INNER_IPV4_TCP,   &udp_l2tpv2_ppp_ipv4_tcp_tmplt},
 606
 607        /* IPv6 */
 608        {iavf_pattern_eth_ipv6,                         IAVF_RSS_TYPE_OUTER_IPV6,       &outer_ipv6_tmplt},
 609        {iavf_pattern_eth_ipv6_frag_ext,                IAVF_RSS_TYPE_OUTER_IPV6_FRAG,  &outer_ipv6_frag_tmplt},
 610        {iavf_pattern_eth_ipv6_udp,                     IAVF_RSS_TYPE_OUTER_IPV6_UDP,   &outer_ipv6_udp_tmplt},
 611        {iavf_pattern_eth_ipv6_tcp,                     IAVF_RSS_TYPE_OUTER_IPV6_TCP,   &outer_ipv6_tcp_tmplt},
 612        {iavf_pattern_eth_ipv6_sctp,                    IAVF_RSS_TYPE_OUTER_IPV6_SCTP,  &outer_ipv6_sctp_tmplt},
 613        {iavf_pattern_eth_vlan_ipv6,                    IAVF_RSS_TYPE_VLAN_IPV6,        &outer_ipv6_tmplt},
 614        {iavf_pattern_eth_vlan_ipv6_frag_ext,           IAVF_RSS_TYPE_OUTER_IPV6_FRAG,  &outer_ipv6_frag_tmplt},
 615        {iavf_pattern_eth_vlan_ipv6_udp,                IAVF_RSS_TYPE_VLAN_IPV6_UDP,    &outer_ipv6_udp_tmplt},
 616        {iavf_pattern_eth_vlan_ipv6_tcp,                IAVF_RSS_TYPE_VLAN_IPV6_TCP,    &outer_ipv6_tcp_tmplt},
 617        {iavf_pattern_eth_vlan_ipv6_sctp,               IAVF_RSS_TYPE_VLAN_IPV6_SCTP,   &outer_ipv6_sctp_tmplt},
 618        {iavf_pattern_eth_ipv6_gtpu,                    RTE_ETH_RSS_IPV6,                       &outer_ipv6_udp_tmplt},
 619        {iavf_pattern_eth_ipv4_gtpu_ipv6,               IAVF_RSS_TYPE_GTPU_IPV6,        &inner_ipv6_tmplt},
 620        {iavf_pattern_eth_ipv4_gtpu_ipv6_udp,           IAVF_RSS_TYPE_GTPU_IPV6_UDP,    &inner_ipv6_udp_tmplt},
 621        {iavf_pattern_eth_ipv4_gtpu_ipv6_tcp,           IAVF_RSS_TYPE_GTPU_IPV6_TCP,    &inner_ipv6_tcp_tmplt},
 622        {iavf_pattern_eth_ipv6_gtpu_ipv6,               IAVF_RSS_TYPE_GTPU_IPV6,        &inner_ipv6_tmplt},
 623        {iavf_pattern_eth_ipv6_gtpu_ipv6_udp,           IAVF_RSS_TYPE_GTPU_IPV6_UDP,    &inner_ipv6_udp_tmplt},
 624        {iavf_pattern_eth_ipv6_gtpu_ipv6_tcp,           IAVF_RSS_TYPE_GTPU_IPV6_TCP,    &inner_ipv6_tcp_tmplt},
 625        {iavf_pattern_eth_ipv4_gtpu_eh_ipv6,            IAVF_RSS_TYPE_GTPU_IPV6,        &inner_ipv6_tmplt},
 626        {iavf_pattern_eth_ipv4_gtpu_eh_ipv6_udp,        IAVF_RSS_TYPE_GTPU_IPV6_UDP,    &inner_ipv6_udp_tmplt},
 627        {iavf_pattern_eth_ipv4_gtpu_eh_ipv6_tcp,        IAVF_RSS_TYPE_GTPU_IPV6_TCP,    &inner_ipv6_tcp_tmplt},
 628        {iavf_pattern_eth_ipv6_gtpu_eh_ipv6,            IAVF_RSS_TYPE_GTPU_IPV6,        &inner_ipv6_tmplt},
 629        {iavf_pattern_eth_ipv6_gtpu_eh_ipv6_udp,        IAVF_RSS_TYPE_GTPU_IPV6_UDP,    &inner_ipv6_udp_tmplt},
 630        {iavf_pattern_eth_ipv6_gtpu_eh_ipv6_tcp,        IAVF_RSS_TYPE_GTPU_IPV6_TCP,    &inner_ipv6_tcp_tmplt},
 631        {iavf_pattern_eth_ipv4_gre_ipv4_gtpu_ipv6,              IAVF_RSS_TYPE_GTPU_IPV6,        &second_inner_ipv6_tmplt},
 632        {iavf_pattern_eth_ipv4_gre_ipv4_gtpu_ipv6_udp,          IAVF_RSS_TYPE_GTPU_IPV6_UDP,    &second_inner_ipv6_udp_tmplt},
 633        {iavf_pattern_eth_ipv4_gre_ipv4_gtpu_ipv6_tcp,          IAVF_RSS_TYPE_GTPU_IPV6_TCP,    &second_inner_ipv6_tcp_tmplt},
 634        {iavf_pattern_eth_ipv4_gre_ipv6_gtpu_ipv6,              IAVF_RSS_TYPE_GTPU_IPV6,        &second_inner_ipv6_tmplt},
 635        {iavf_pattern_eth_ipv4_gre_ipv6_gtpu_ipv6_udp,          IAVF_RSS_TYPE_GTPU_IPV6_UDP,    &second_inner_ipv6_udp_tmplt},
 636        {iavf_pattern_eth_ipv4_gre_ipv6_gtpu_ipv6_tcp,          IAVF_RSS_TYPE_GTPU_IPV6_TCP,    &second_inner_ipv6_tcp_tmplt},
 637        {iavf_pattern_eth_ipv6_gre_ipv4_gtpu_ipv6,              IAVF_RSS_TYPE_GTPU_IPV6,        &second_inner_ipv6_tmplt},
 638        {iavf_pattern_eth_ipv6_gre_ipv4_gtpu_ipv6_udp,          IAVF_RSS_TYPE_GTPU_IPV6_UDP,    &second_inner_ipv6_udp_tmplt},
 639        {iavf_pattern_eth_ipv6_gre_ipv4_gtpu_ipv6_tcp,          IAVF_RSS_TYPE_GTPU_IPV6_TCP,    &second_inner_ipv6_tcp_tmplt},
 640        {iavf_pattern_eth_ipv6_gre_ipv6_gtpu_ipv6,              IAVF_RSS_TYPE_GTPU_IPV6,        &second_inner_ipv6_tmplt},
 641        {iavf_pattern_eth_ipv6_gre_ipv6_gtpu_ipv6_udp,          IAVF_RSS_TYPE_GTPU_IPV6_UDP,    &second_inner_ipv6_udp_tmplt},
 642        {iavf_pattern_eth_ipv6_gre_ipv6_gtpu_ipv6_tcp,          IAVF_RSS_TYPE_GTPU_IPV6_TCP,    &second_inner_ipv6_tcp_tmplt},
 643        {iavf_pattern_eth_ipv4_gre_ipv4_gtpu_eh_ipv6,           IAVF_RSS_TYPE_GTPU_IPV6,        &second_inner_ipv6_tmplt},
 644        {iavf_pattern_eth_ipv4_gre_ipv4_gtpu_eh_ipv6_udp,       IAVF_RSS_TYPE_GTPU_IPV6_UDP,    &second_inner_ipv6_udp_tmplt},
 645        {iavf_pattern_eth_ipv4_gre_ipv4_gtpu_eh_ipv6_tcp,       IAVF_RSS_TYPE_GTPU_IPV6_TCP,    &second_inner_ipv6_tcp_tmplt},
 646        {iavf_pattern_eth_ipv4_gre_ipv6_gtpu_eh_ipv6,           IAVF_RSS_TYPE_GTPU_IPV6,        &second_inner_ipv6_tmplt},
 647        {iavf_pattern_eth_ipv4_gre_ipv6_gtpu_eh_ipv6_udp,       IAVF_RSS_TYPE_GTPU_IPV6_UDP,    &second_inner_ipv6_udp_tmplt},
 648        {iavf_pattern_eth_ipv4_gre_ipv6_gtpu_eh_ipv6_tcp,       IAVF_RSS_TYPE_GTPU_IPV6_TCP,    &second_inner_ipv6_tcp_tmplt},
 649        {iavf_pattern_eth_ipv6_gre_ipv4_gtpu_eh_ipv6,           IAVF_RSS_TYPE_GTPU_IPV6,        &second_inner_ipv6_tmplt},
 650        {iavf_pattern_eth_ipv6_gre_ipv4_gtpu_eh_ipv6_udp,       IAVF_RSS_TYPE_GTPU_IPV6_UDP,    &second_inner_ipv6_udp_tmplt},
 651        {iavf_pattern_eth_ipv6_gre_ipv4_gtpu_eh_ipv6_tcp,       IAVF_RSS_TYPE_GTPU_IPV6_TCP,    &second_inner_ipv6_tcp_tmplt},
 652        {iavf_pattern_eth_ipv6_gre_ipv6_gtpu_eh_ipv6,           IAVF_RSS_TYPE_GTPU_IPV6,        &second_inner_ipv6_tmplt},
 653        {iavf_pattern_eth_ipv6_gre_ipv6_gtpu_eh_ipv6_udp,       IAVF_RSS_TYPE_GTPU_IPV6_UDP,    &second_inner_ipv6_udp_tmplt},
 654        {iavf_pattern_eth_ipv6_gre_ipv6_gtpu_eh_ipv6_tcp,       IAVF_RSS_TYPE_GTPU_IPV6_TCP,    &second_inner_ipv6_tcp_tmplt},
 655        {iavf_pattern_eth_ipv6_esp,                     IAVF_RSS_TYPE_IPV6_ESP,         &ipv6_esp_tmplt},
 656        {iavf_pattern_eth_ipv6_udp_esp,                 IAVF_RSS_TYPE_IPV6_ESP,         &ipv6_udp_esp_tmplt},
 657        {iavf_pattern_eth_ipv6_ah,                      IAVF_RSS_TYPE_IPV6_AH,          &ipv6_ah_tmplt},
 658        {iavf_pattern_eth_ipv6_l2tpv3,                  IAVF_RSS_TYPE_IPV6_L2TPV3,      &ipv6_l2tpv3_tmplt},
 659        {iavf_pattern_eth_ipv6_pfcp,                    IAVF_RSS_TYPE_IPV6_PFCP,        &ipv6_pfcp_tmplt},
 660        {iavf_pattern_eth_ipv6_gtpc,                    RTE_ETH_RSS_IPV6,                       &ipv6_udp_gtpc_tmplt},
 661        {iavf_pattern_eth_ipv4_gre_ipv6,                IAVF_RSS_TYPE_INNER_IPV6,       &inner_ipv6_tmplt},
 662        {iavf_pattern_eth_ipv6_gre_ipv6,                IAVF_RSS_TYPE_INNER_IPV6, &inner_ipv6_tmplt},
 663        {iavf_pattern_eth_ipv4_gre_ipv6_tcp,    IAVF_RSS_TYPE_INNER_IPV6_TCP, &inner_ipv6_tcp_tmplt},
 664        {iavf_pattern_eth_ipv6_gre_ipv6_tcp,    IAVF_RSS_TYPE_INNER_IPV6_TCP, &inner_ipv6_tcp_tmplt},
 665        {iavf_pattern_eth_ipv4_gre_ipv6_udp,    IAVF_RSS_TYPE_INNER_IPV6_UDP, &inner_ipv6_udp_tmplt},
 666        {iavf_pattern_eth_ipv6_gre_ipv6_udp,    IAVF_RSS_TYPE_INNER_IPV6_UDP, &inner_ipv6_udp_tmplt},
 667        {iavf_pattern_eth_ipv6_udp_l2tpv2,              IAVF_RSS_TYPE_ETH_L2TPV2,       &ipv6_l2tpv2_tmplt},
 668        {iavf_pattern_eth_ipv6_udp_l2tpv2_ppp,          IAVF_RSS_TYPE_ETH_L2TPV2,       &ipv6_l2tpv2_ppp_tmplt},
 669        {iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6,     IAVF_RSS_TYPE_INNER_IPV6,       &udp_l2tpv2_ppp_ipv6_tmplt},
 670        {iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6_udp, IAVF_RSS_TYPE_INNER_IPV6_UDP,   &udp_l2tpv2_ppp_ipv6_udp_tmplt},
 671        {iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6_tcp, IAVF_RSS_TYPE_INNER_IPV6_TCP,   &udp_l2tpv2_ppp_ipv6_tcp_tmplt},
 672        {iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6,     IAVF_RSS_TYPE_INNER_IPV6,       &udp_l2tpv2_ppp_ipv6_tmplt},
 673        {iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6_udp, IAVF_RSS_TYPE_INNER_IPV6_UDP,   &udp_l2tpv2_ppp_ipv6_udp_tmplt},
 674        {iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6_tcp, IAVF_RSS_TYPE_INNER_IPV6_TCP,   &udp_l2tpv2_ppp_ipv6_tcp_tmplt},
 675
 676};
 677
 678static struct iavf_flow_engine iavf_hash_engine = {
 679        .init = iavf_hash_init,
 680        .create = iavf_hash_create,
 681        .destroy = iavf_hash_destroy,
 682        .uninit = iavf_hash_uninit,
 683        .free = iavf_hash_free,
 684        .type = IAVF_FLOW_ENGINE_HASH,
 685};
 686
 687/* Register parser for comms package. */
 688static struct iavf_flow_parser iavf_hash_parser = {
 689        .engine = &iavf_hash_engine,
 690        .array = iavf_hash_pattern_list,
 691        .array_len = RTE_DIM(iavf_hash_pattern_list),
 692        .parse_pattern_action = iavf_hash_parse_pattern_action,
 693        .stage = IAVF_FLOW_STAGE_RSS,
 694};
 695
 696int
 697iavf_rss_hash_set(struct iavf_adapter *ad, uint64_t rss_hf, bool add)
 698{
 699        struct iavf_info *vf =  IAVF_DEV_PRIVATE_TO_VF(ad);
 700        struct virtchnl_rss_cfg rss_cfg;
 701
 702#define IAVF_RSS_HF_ALL ( \
 703        RTE_ETH_RSS_IPV4 | \
 704        RTE_ETH_RSS_IPV6 | \
 705        RTE_ETH_RSS_NONFRAG_IPV4_UDP | \
 706        RTE_ETH_RSS_NONFRAG_IPV6_UDP | \
 707        RTE_ETH_RSS_NONFRAG_IPV4_TCP | \
 708        RTE_ETH_RSS_NONFRAG_IPV6_TCP | \
 709        RTE_ETH_RSS_NONFRAG_IPV4_SCTP | \
 710        RTE_ETH_RSS_NONFRAG_IPV6_SCTP)
 711
 712        rss_cfg.rss_algorithm = VIRTCHNL_RSS_ALG_TOEPLITZ_ASYMMETRIC;
 713        if (rss_hf & RTE_ETH_RSS_IPV4) {
 714                rss_cfg.proto_hdrs = inner_ipv4_tmplt;
 715                iavf_add_del_rss_cfg(ad, &rss_cfg, add);
 716        }
 717
 718        if (rss_hf & RTE_ETH_RSS_NONFRAG_IPV4_UDP) {
 719                rss_cfg.proto_hdrs = inner_ipv4_udp_tmplt;
 720                iavf_add_del_rss_cfg(ad, &rss_cfg, add);
 721        }
 722
 723        if (rss_hf & RTE_ETH_RSS_NONFRAG_IPV4_TCP) {
 724                rss_cfg.proto_hdrs = inner_ipv4_tcp_tmplt;
 725                iavf_add_del_rss_cfg(ad, &rss_cfg, add);
 726        }
 727
 728        if (rss_hf & RTE_ETH_RSS_NONFRAG_IPV4_SCTP) {
 729                rss_cfg.proto_hdrs = inner_ipv4_sctp_tmplt;
 730                iavf_add_del_rss_cfg(ad, &rss_cfg, add);
 731        }
 732
 733        if (rss_hf & RTE_ETH_RSS_IPV6) {
 734                rss_cfg.proto_hdrs = inner_ipv6_tmplt;
 735                iavf_add_del_rss_cfg(ad, &rss_cfg, add);
 736        }
 737
 738        if (rss_hf & RTE_ETH_RSS_NONFRAG_IPV6_UDP) {
 739                rss_cfg.proto_hdrs = inner_ipv6_udp_tmplt;
 740                iavf_add_del_rss_cfg(ad, &rss_cfg, add);
 741        }
 742
 743        if (rss_hf & RTE_ETH_RSS_NONFRAG_IPV6_TCP) {
 744                rss_cfg.proto_hdrs = inner_ipv6_tcp_tmplt;
 745                iavf_add_del_rss_cfg(ad, &rss_cfg, add);
 746        }
 747
 748        if (rss_hf & RTE_ETH_RSS_NONFRAG_IPV6_SCTP) {
 749                rss_cfg.proto_hdrs = inner_ipv6_sctp_tmplt;
 750                iavf_add_del_rss_cfg(ad, &rss_cfg, add);
 751        }
 752
 753        vf->rss_hf = rss_hf & IAVF_RSS_HF_ALL;
 754        return 0;
 755}
 756
 757RTE_INIT(iavf_hash_engine_init)
 758{
 759        struct iavf_flow_engine *engine = &iavf_hash_engine;
 760
 761        iavf_register_flow_engine(engine);
 762}
 763
 764static int
 765iavf_hash_init(struct iavf_adapter *ad)
 766{
 767        struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(ad);
 768        struct iavf_flow_parser *parser;
 769        int ret;
 770
 771        if (vf->vf_reset)
 772                return -EIO;
 773
 774        if (!vf->vf_res)
 775                return -EINVAL;
 776
 777        if (!(vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_ADV_RSS_PF))
 778                return -ENOTSUP;
 779
 780        parser = &iavf_hash_parser;
 781
 782        ret = iavf_register_parser(parser, ad);
 783        if (ret) {
 784                PMD_DRV_LOG(ERR, "fail to register hash parser");
 785                return ret;
 786        }
 787
 788        return ret;
 789}
 790
 791static int
 792iavf_hash_parse_pattern(const struct rte_flow_item pattern[], uint64_t *phint,
 793                        struct rte_flow_error *error)
 794{
 795        const struct rte_flow_item *item = pattern;
 796        const struct rte_flow_item_gtp_psc *psc;
 797        const struct rte_flow_item_ecpri *ecpri;
 798        struct rte_ecpri_common_hdr ecpri_common;
 799        const struct rte_flow_item_l2tpv2 *l2tpv2;
 800        uint16_t flags_version;
 801
 802        for (item = pattern; item->type != RTE_FLOW_ITEM_TYPE_END; item++) {
 803                if (item->last) {
 804                        rte_flow_error_set(error, EINVAL,
 805                                           RTE_FLOW_ERROR_TYPE_ITEM, item,
 806                                           "Not support range");
 807                        return -rte_errno;
 808                }
 809
 810                switch (item->type) {
 811                case RTE_FLOW_ITEM_TYPE_RAW:
 812                        *phint |= IAVF_PHINT_RAW;
 813                        break;
 814                case RTE_FLOW_ITEM_TYPE_IPV4:
 815                        if (!(*phint & IAVF_PHINT_GTPU_MSK) &&
 816                            !(*phint & IAVF_PHINT_GRE) &&
 817                            !(*phint & IAVF_PHINT_L2TPV2))
 818                                *phint |= IAVF_PHINT_OUTER_IPV4;
 819                        if ((*phint & IAVF_PHINT_GRE) && !(*phint & IAVF_PHINT_GTPU_MSK))
 820                                *phint |= IAVF_PHINT_MID_IPV4;
 821                        break;
 822                case RTE_FLOW_ITEM_TYPE_IPV6:
 823                        if (!(*phint & IAVF_PHINT_GTPU_MSK) &&
 824                            !(*phint & IAVF_PHINT_GRE) &&
 825                            !(*phint & IAVF_PHINT_L2TPV2))
 826                                *phint |= IAVF_PHINT_OUTER_IPV6;
 827                        if ((*phint & IAVF_PHINT_GRE) && !(*phint & IAVF_PHINT_GTPU_MSK))
 828                                *phint |= IAVF_PHINT_MID_IPV6;
 829                        break;
 830                case RTE_FLOW_ITEM_TYPE_GTPU:
 831                        *phint |= IAVF_PHINT_GTPU;
 832                        break;
 833                case RTE_FLOW_ITEM_TYPE_GTP_PSC:
 834                        *phint |= IAVF_PHINT_GTPU_EH;
 835                        psc = item->spec;
 836                        if (!psc)
 837                                break;
 838                        else if (psc->hdr.type == IAVF_GTPU_EH_UPLINK)
 839                                *phint |= IAVF_PHINT_GTPU_EH_UP;
 840                        else if (psc->hdr.type == IAVF_GTPU_EH_DWNLINK)
 841                                *phint |= IAVF_PHINT_GTPU_EH_DWN;
 842                        break;
 843                case RTE_FLOW_ITEM_TYPE_ECPRI:
 844                        ecpri = item->spec;
 845                        if (!ecpri)
 846                                break;
 847
 848                        ecpri_common.u32 = rte_be_to_cpu_32(ecpri->hdr.common.u32);
 849
 850                        if (ecpri_common.type !=
 851                                 RTE_ECPRI_MSG_TYPE_IQ_DATA) {
 852                                rte_flow_error_set(error, EINVAL,
 853                                        RTE_FLOW_ERROR_TYPE_ITEM, item,
 854                                        "Unsupported common type.");
 855                                return -rte_errno;
 856                        }
 857                        break;
 858                case RTE_FLOW_ITEM_TYPE_GRE:
 859                        *phint |= IAVF_PHINT_GRE;
 860                        break;
 861                case RTE_FLOW_ITEM_TYPE_L2TPV2:
 862                        l2tpv2 = item->spec;
 863
 864                        if (l2tpv2) {
 865                                flags_version =
 866                                        rte_be_to_cpu_16(l2tpv2->hdr.common.flags_version);
 867                                if (flags_version & IAVF_L2TPV2_FLAGS_LEN)
 868                                        *phint |= IAVF_PHINT_L2TPV2_LEN;
 869                                else
 870                                        *phint |= IAVF_PHINT_L2TPV2;
 871                        } else {
 872                                *phint |= IAVF_PHINT_L2TPV2;
 873                        }
 874                        break;
 875                default:
 876                        break;
 877                }
 878        }
 879
 880        return 0;
 881}
 882
 883static int
 884iavf_hash_parse_raw_pattern(const struct rte_flow_item *item,
 885                        struct iavf_rss_meta *meta)
 886{
 887        const struct rte_flow_item_raw *raw_spec, *raw_mask;
 888        uint8_t *pkt_buf, *msk_buf;
 889        uint8_t spec_len, pkt_len;
 890        uint8_t tmp_val = 0;
 891        uint8_t tmp_c = 0;
 892        int i, j;
 893
 894        raw_spec = item->spec;
 895        raw_mask = item->mask;
 896
 897        spec_len = strlen((char *)(uintptr_t)raw_spec->pattern);
 898        if (strlen((char *)(uintptr_t)raw_mask->pattern) !=
 899                spec_len)
 900                return -rte_errno;
 901
 902        pkt_len = spec_len / 2;
 903
 904        pkt_buf = rte_zmalloc(NULL, pkt_len, 0);
 905        if (!pkt_buf)
 906                return -ENOMEM;
 907
 908        msk_buf = rte_zmalloc(NULL, pkt_len, 0);
 909        if (!msk_buf)
 910                return -ENOMEM;
 911
 912        /* convert string to int array */
 913        for (i = 0, j = 0; i < spec_len; i += 2, j++) {
 914                tmp_c = raw_spec->pattern[i];
 915                if (tmp_c >= 'a' && tmp_c <= 'f')
 916                        tmp_val = tmp_c - 'a' + 10;
 917                if (tmp_c >= 'A' && tmp_c <= 'F')
 918                        tmp_val = tmp_c - 'A' + 10;
 919                if (tmp_c >= '0' && tmp_c <= '9')
 920                        tmp_val = tmp_c - '0';
 921
 922                tmp_c = raw_spec->pattern[i + 1];
 923                if (tmp_c >= 'a' && tmp_c <= 'f')
 924                        pkt_buf[j] = tmp_val * 16 + tmp_c - 'a' + 10;
 925                if (tmp_c >= 'A' && tmp_c <= 'F')
 926                        pkt_buf[j] = tmp_val * 16 + tmp_c - 'A' + 10;
 927                if (tmp_c >= '0' && tmp_c <= '9')
 928                        pkt_buf[j] = tmp_val * 16 + tmp_c - '0';
 929
 930                tmp_c = raw_mask->pattern[i];
 931                if (tmp_c >= 'a' && tmp_c <= 'f')
 932                        tmp_val = tmp_c - 0x57;
 933                if (tmp_c >= 'A' && tmp_c <= 'F')
 934                        tmp_val = tmp_c - 0x37;
 935                if (tmp_c >= '0' && tmp_c <= '9')
 936                        tmp_val = tmp_c - '0';
 937
 938                tmp_c = raw_mask->pattern[i + 1];
 939                if (tmp_c >= 'a' && tmp_c <= 'f')
 940                        msk_buf[j] = tmp_val * 16 + tmp_c - 'a' + 10;
 941                if (tmp_c >= 'A' && tmp_c <= 'F')
 942                        msk_buf[j] = tmp_val * 16 + tmp_c - 'A' + 10;
 943                if (tmp_c >= '0' && tmp_c <= '9')
 944                        msk_buf[j] = tmp_val * 16 + tmp_c - '0';
 945        }
 946
 947        rte_memcpy(meta->proto_hdrs.raw.spec, pkt_buf, pkt_len);
 948        rte_memcpy(meta->proto_hdrs.raw.mask, msk_buf, pkt_len);
 949        meta->proto_hdrs.raw.pkt_len = pkt_len;
 950
 951        rte_free(pkt_buf);
 952        rte_free(msk_buf);
 953
 954        return 0;
 955}
 956
 957#define REFINE_PROTO_FLD(op, fld) \
 958        VIRTCHNL_##op##_PROTO_HDR_FIELD(hdr, VIRTCHNL_PROTO_HDR_##fld)
 959#define REPALCE_PROTO_FLD(fld_1, fld_2) \
 960do { \
 961        REFINE_PROTO_FLD(DEL, fld_1);   \
 962        REFINE_PROTO_FLD(ADD, fld_2);   \
 963} while (0)
 964
 965static void
 966iavf_hash_add_fragment_hdr(struct virtchnl_proto_hdrs *hdrs, int layer)
 967{
 968        struct virtchnl_proto_hdr *hdr1;
 969        struct virtchnl_proto_hdr *hdr2;
 970        int i;
 971
 972        if (layer < 0 || layer > hdrs->count)
 973                return;
 974
 975        /* shift headers layer */
 976        for (i = hdrs->count; i >= layer; i--) {
 977                hdr1 = &hdrs->proto_hdr[i];
 978                hdr2 = &hdrs->proto_hdr[i - 1];
 979                *hdr1 = *hdr2;
 980        }
 981
 982        /* adding dummy fragment header */
 983        hdr1 = &hdrs->proto_hdr[layer];
 984        VIRTCHNL_SET_PROTO_HDR_TYPE(hdr1, IPV4_FRAG);
 985        hdrs->count = ++layer;
 986}
 987
 988/* refine proto hdrs base on l2, l3, l4 rss type */
 989static void
 990iavf_refine_proto_hdrs_l234(struct virtchnl_proto_hdrs *proto_hdrs,
 991                            uint64_t rss_type)
 992{
 993        struct virtchnl_proto_hdr *hdr;
 994        int i;
 995
 996        for (i = 0; i < proto_hdrs->count; i++) {
 997                hdr = &proto_hdrs->proto_hdr[i];
 998                switch (hdr->type) {
 999                case VIRTCHNL_PROTO_HDR_ETH:
1000                        if (!(rss_type & RTE_ETH_RSS_ETH))
1001                                hdr->field_selector = 0;
1002                        else if (rss_type & RTE_ETH_RSS_L2_SRC_ONLY)
1003                                REFINE_PROTO_FLD(DEL, ETH_DST);
1004                        else if (rss_type & RTE_ETH_RSS_L2_DST_ONLY)
1005                                REFINE_PROTO_FLD(DEL, ETH_SRC);
1006                        break;
1007                case VIRTCHNL_PROTO_HDR_IPV4:
1008                        if (rss_type &
1009                            (RTE_ETH_RSS_IPV4 | RTE_ETH_RSS_FRAG_IPV4 |
1010                             RTE_ETH_RSS_NONFRAG_IPV4_UDP |
1011                             RTE_ETH_RSS_NONFRAG_IPV4_TCP |
1012                             RTE_ETH_RSS_NONFRAG_IPV4_SCTP)) {
1013                                if (rss_type & RTE_ETH_RSS_FRAG_IPV4) {
1014                                        iavf_hash_add_fragment_hdr(proto_hdrs, i + 1);
1015                                } else if (rss_type & RTE_ETH_RSS_L3_SRC_ONLY) {
1016                                        REFINE_PROTO_FLD(DEL, IPV4_DST);
1017                                } else if (rss_type & RTE_ETH_RSS_L3_DST_ONLY) {
1018                                        REFINE_PROTO_FLD(DEL, IPV4_SRC);
1019                                } else if (rss_type &
1020                                           (RTE_ETH_RSS_L4_SRC_ONLY |
1021                                            RTE_ETH_RSS_L4_DST_ONLY)) {
1022                                        REFINE_PROTO_FLD(DEL, IPV4_DST);
1023                                        REFINE_PROTO_FLD(DEL, IPV4_SRC);
1024                                }
1025                        } else {
1026                                hdr->field_selector = 0;
1027                        }
1028
1029                        if (rss_type & RTE_ETH_RSS_IPV4_CHKSUM)
1030                                REFINE_PROTO_FLD(ADD, IPV4_CHKSUM);
1031
1032                        break;
1033                case VIRTCHNL_PROTO_HDR_IPV4_FRAG:
1034                        if (rss_type &
1035                            (RTE_ETH_RSS_IPV4 | RTE_ETH_RSS_FRAG_IPV4 |
1036                             RTE_ETH_RSS_NONFRAG_IPV4_UDP |
1037                             RTE_ETH_RSS_NONFRAG_IPV4_TCP |
1038                             RTE_ETH_RSS_NONFRAG_IPV4_SCTP)) {
1039                                if (rss_type & RTE_ETH_RSS_FRAG_IPV4)
1040                                        REFINE_PROTO_FLD(ADD, IPV4_FRAG_PKID);
1041                        } else {
1042                                hdr->field_selector = 0;
1043                        }
1044
1045                        if (rss_type & RTE_ETH_RSS_IPV4_CHKSUM)
1046                                REFINE_PROTO_FLD(ADD, IPV4_CHKSUM);
1047
1048                        break;
1049                case VIRTCHNL_PROTO_HDR_IPV6:
1050                        if (rss_type &
1051                            (RTE_ETH_RSS_IPV6 | RTE_ETH_RSS_FRAG_IPV6 |
1052                             RTE_ETH_RSS_NONFRAG_IPV6_UDP |
1053                             RTE_ETH_RSS_NONFRAG_IPV6_TCP |
1054                             RTE_ETH_RSS_NONFRAG_IPV6_SCTP)) {
1055                                if (rss_type & RTE_ETH_RSS_L3_SRC_ONLY) {
1056                                        REFINE_PROTO_FLD(DEL, IPV6_DST);
1057                                } else if (rss_type & RTE_ETH_RSS_L3_DST_ONLY) {
1058                                        REFINE_PROTO_FLD(DEL, IPV6_SRC);
1059                                } else if (rss_type &
1060                                           (RTE_ETH_RSS_L4_SRC_ONLY |
1061                                            RTE_ETH_RSS_L4_DST_ONLY)) {
1062                                        REFINE_PROTO_FLD(DEL, IPV6_DST);
1063                                        REFINE_PROTO_FLD(DEL, IPV6_SRC);
1064                                }
1065                        } else {
1066                                hdr->field_selector = 0;
1067                        }
1068                        if (rss_type & RTE_ETH_RSS_L3_PRE64) {
1069                                if (REFINE_PROTO_FLD(TEST, IPV6_SRC))
1070                                        REPALCE_PROTO_FLD(IPV6_SRC,
1071                                                          IPV6_PREFIX64_SRC);
1072                                if (REFINE_PROTO_FLD(TEST, IPV6_DST))
1073                                        REPALCE_PROTO_FLD(IPV6_DST,
1074                                                          IPV6_PREFIX64_DST);
1075                        }
1076                        break;
1077                case VIRTCHNL_PROTO_HDR_IPV6_EH_FRAG:
1078                        if (rss_type & RTE_ETH_RSS_FRAG_IPV6)
1079                                REFINE_PROTO_FLD(ADD, IPV6_EH_FRAG_PKID);
1080                        else
1081                                hdr->field_selector = 0;
1082
1083                        break;
1084                case VIRTCHNL_PROTO_HDR_UDP:
1085                        if (rss_type &
1086                            (RTE_ETH_RSS_NONFRAG_IPV4_UDP |
1087                             RTE_ETH_RSS_NONFRAG_IPV6_UDP)) {
1088                                if (rss_type & RTE_ETH_RSS_L4_SRC_ONLY)
1089                                        REFINE_PROTO_FLD(DEL, UDP_DST_PORT);
1090                                else if (rss_type & RTE_ETH_RSS_L4_DST_ONLY)
1091                                        REFINE_PROTO_FLD(DEL, UDP_SRC_PORT);
1092                                else if (rss_type &
1093                                         (RTE_ETH_RSS_L3_SRC_ONLY |
1094                                          RTE_ETH_RSS_L3_DST_ONLY))
1095                                        hdr->field_selector = 0;
1096                        } else {
1097                                hdr->field_selector = 0;
1098                        }
1099
1100                        if (rss_type & RTE_ETH_RSS_L4_CHKSUM)
1101                                REFINE_PROTO_FLD(ADD, UDP_CHKSUM);
1102                        break;
1103                case VIRTCHNL_PROTO_HDR_TCP:
1104                        if (rss_type &
1105                            (RTE_ETH_RSS_NONFRAG_IPV4_TCP |
1106                             RTE_ETH_RSS_NONFRAG_IPV6_TCP)) {
1107                                if (rss_type & RTE_ETH_RSS_L4_SRC_ONLY)
1108                                        REFINE_PROTO_FLD(DEL, TCP_DST_PORT);
1109                                else if (rss_type & RTE_ETH_RSS_L4_DST_ONLY)
1110                                        REFINE_PROTO_FLD(DEL, TCP_SRC_PORT);
1111                                else if (rss_type &
1112                                         (RTE_ETH_RSS_L3_SRC_ONLY |
1113                                          RTE_ETH_RSS_L3_DST_ONLY))
1114                                        hdr->field_selector = 0;
1115                        } else {
1116                                hdr->field_selector = 0;
1117                        }
1118
1119                        if (rss_type & RTE_ETH_RSS_L4_CHKSUM)
1120                                REFINE_PROTO_FLD(ADD, TCP_CHKSUM);
1121                        break;
1122                case VIRTCHNL_PROTO_HDR_SCTP:
1123                        if (rss_type &
1124                            (RTE_ETH_RSS_NONFRAG_IPV4_SCTP |
1125                             RTE_ETH_RSS_NONFRAG_IPV6_SCTP)) {
1126                                if (rss_type & RTE_ETH_RSS_L4_SRC_ONLY)
1127                                        REFINE_PROTO_FLD(DEL, SCTP_DST_PORT);
1128                                else if (rss_type & RTE_ETH_RSS_L4_DST_ONLY)
1129                                        REFINE_PROTO_FLD(DEL, SCTP_SRC_PORT);
1130                                else if (rss_type &
1131                                         (RTE_ETH_RSS_L3_SRC_ONLY |
1132                                          RTE_ETH_RSS_L3_DST_ONLY))
1133                                        hdr->field_selector = 0;
1134                        } else {
1135                                hdr->field_selector = 0;
1136                        }
1137
1138                        if (rss_type & RTE_ETH_RSS_L4_CHKSUM)
1139                                REFINE_PROTO_FLD(ADD, SCTP_CHKSUM);
1140                        break;
1141                case VIRTCHNL_PROTO_HDR_S_VLAN:
1142                        if (!(rss_type & RTE_ETH_RSS_S_VLAN))
1143                                hdr->field_selector = 0;
1144                        break;
1145                case VIRTCHNL_PROTO_HDR_C_VLAN:
1146                        if (!(rss_type & RTE_ETH_RSS_C_VLAN))
1147                                hdr->field_selector = 0;
1148                        break;
1149                case VIRTCHNL_PROTO_HDR_L2TPV3:
1150                        if (!(rss_type & RTE_ETH_RSS_L2TPV3))
1151                                hdr->field_selector = 0;
1152                        break;
1153                case VIRTCHNL_PROTO_HDR_ESP:
1154                        if (!(rss_type & RTE_ETH_RSS_ESP))
1155                                hdr->field_selector = 0;
1156                        break;
1157                case VIRTCHNL_PROTO_HDR_AH:
1158                        if (!(rss_type & RTE_ETH_RSS_AH))
1159                                hdr->field_selector = 0;
1160                        break;
1161                case VIRTCHNL_PROTO_HDR_PFCP:
1162                        if (!(rss_type & RTE_ETH_RSS_PFCP))
1163                                hdr->field_selector = 0;
1164                        break;
1165                case VIRTCHNL_PROTO_HDR_ECPRI:
1166                        if (!(rss_type & RTE_ETH_RSS_ECPRI))
1167                                hdr->field_selector = 0;
1168                        break;
1169                case VIRTCHNL_PROTO_HDR_L2TPV2:
1170                        if (!(rss_type & RTE_ETH_RSS_L2TPV2))
1171                                hdr->field_selector = 0;
1172                        break;
1173                default:
1174                        break;
1175                }
1176        }
1177}
1178
1179/* refine proto hdrs base on gtpu rss type */
1180static void
1181iavf_refine_proto_hdrs_gtpu(struct virtchnl_proto_hdrs *proto_hdrs,
1182                            uint64_t rss_type)
1183{
1184        struct virtchnl_proto_hdr *hdr;
1185        int i;
1186
1187        if (!(rss_type & RTE_ETH_RSS_GTPU))
1188                return;
1189
1190        for (i = 0; i < proto_hdrs->count; i++) {
1191                hdr = &proto_hdrs->proto_hdr[i];
1192                switch (hdr->type) {
1193                case VIRTCHNL_PROTO_HDR_GTPU_IP:
1194                        REFINE_PROTO_FLD(ADD, GTPU_IP_TEID);
1195                        break;
1196                default:
1197                        break;
1198                }
1199        }
1200}
1201
1202static void
1203iavf_refine_proto_hdrs_by_pattern(struct virtchnl_proto_hdrs *proto_hdrs,
1204                                  uint64_t phint)
1205{
1206        struct virtchnl_proto_hdr *hdr1;
1207        struct virtchnl_proto_hdr *hdr2;
1208        int i, shift_count = 1;
1209        int tun_lvl = proto_hdrs->tunnel_level;
1210
1211        if (!(phint & IAVF_PHINT_GTPU_MSK) && !(phint & IAVF_PHINT_GRE))
1212                return;
1213
1214        while (tun_lvl) {
1215                if (phint & IAVF_PHINT_LAYERS_MSK)
1216                        shift_count = 2;
1217
1218                /* shift headers layer */
1219                for (i = proto_hdrs->count - 1 + shift_count;
1220                     i > shift_count - 1; i--) {
1221                        hdr1 = &proto_hdrs->proto_hdr[i];
1222                        hdr2 = &proto_hdrs->proto_hdr[i - shift_count];
1223                        *hdr1 = *hdr2;
1224                }
1225
1226                if (shift_count == 1) {
1227                        /* adding tunnel header at layer 0 */
1228                        hdr1 = &proto_hdrs->proto_hdr[0];
1229                } else {
1230                        /* adding tunnel header and outer ip header */
1231                        hdr1 = &proto_hdrs->proto_hdr[1];
1232                        hdr2 = &proto_hdrs->proto_hdr[0];
1233                        hdr2->field_selector = 0;
1234                        proto_hdrs->count++;
1235                        tun_lvl--;
1236
1237                        if (tun_lvl == TUNNEL_LEVEL_OUTER) {
1238                                if (phint & IAVF_PHINT_OUTER_IPV4)
1239                                        VIRTCHNL_SET_PROTO_HDR_TYPE(hdr2, IPV4);
1240                                else if (phint & IAVF_PHINT_OUTER_IPV6)
1241                                        VIRTCHNL_SET_PROTO_HDR_TYPE(hdr2, IPV6);
1242                        } else if (tun_lvl == TUNNEL_LEVEL_INNER) {
1243                                if (phint & IAVF_PHINT_MID_IPV4)
1244                                        VIRTCHNL_SET_PROTO_HDR_TYPE(hdr2, IPV4);
1245                                else if (phint & IAVF_PHINT_MID_IPV6)
1246                                        VIRTCHNL_SET_PROTO_HDR_TYPE(hdr2, IPV6);
1247                        }
1248                }
1249
1250                hdr1->field_selector = 0;
1251                proto_hdrs->count++;
1252
1253                if (phint & IAVF_PHINT_GTPU_EH_DWN)
1254                        VIRTCHNL_SET_PROTO_HDR_TYPE(hdr1, GTPU_EH_PDU_DWN);
1255                else if (phint & IAVF_PHINT_GTPU_EH_UP)
1256                        VIRTCHNL_SET_PROTO_HDR_TYPE(hdr1, GTPU_EH_PDU_UP);
1257                else if (phint & IAVF_PHINT_GTPU_EH)
1258                        VIRTCHNL_SET_PROTO_HDR_TYPE(hdr1, GTPU_EH);
1259                else if (phint & IAVF_PHINT_GTPU)
1260                        VIRTCHNL_SET_PROTO_HDR_TYPE(hdr1, GTPU_IP);
1261
1262                if (phint & IAVF_PHINT_GRE) {
1263                        if (phint & IAVF_PHINT_GTPU) {
1264                                /* if GTPoGRE, add GRE header at the outer tunnel  */
1265                                if (tun_lvl == TUNNEL_LEVEL_OUTER)
1266                                        VIRTCHNL_SET_PROTO_HDR_TYPE(hdr1, GRE);
1267                        } else {
1268                                        VIRTCHNL_SET_PROTO_HDR_TYPE(hdr1, GRE);
1269                        }
1270                }
1271        }
1272        proto_hdrs->tunnel_level = tun_lvl;
1273}
1274
1275static void
1276iavf_refine_proto_hdrs_l2tpv2(struct virtchnl_proto_hdrs *proto_hdrs,
1277                              uint64_t phint)
1278{
1279        struct virtchnl_proto_hdr *hdr, *hdr1;
1280        int i;
1281
1282        if (!(phint & IAVF_PHINT_L2TPV2) && !(phint & IAVF_PHINT_L2TPV2_LEN))
1283                return;
1284
1285        if (proto_hdrs->tunnel_level == TUNNEL_LEVEL_INNER) {
1286                /* shift headers layer */
1287                for (i = proto_hdrs->count - 1 + 1; i > 0; i--)
1288                        proto_hdrs->proto_hdr[i] = proto_hdrs->proto_hdr[i - 1];
1289
1290                /* adding outer ip header at layer 0 */
1291                hdr1 = &proto_hdrs->proto_hdr[0];
1292                hdr1->field_selector = 0;
1293                proto_hdrs->count++;
1294                proto_hdrs->tunnel_level = TUNNEL_LEVEL_OUTER;
1295                if (phint & IAVF_PHINT_OUTER_IPV4)
1296                        VIRTCHNL_SET_PROTO_HDR_TYPE(hdr1, IPV4);
1297                else if (phint & IAVF_PHINT_OUTER_IPV6)
1298                        VIRTCHNL_SET_PROTO_HDR_TYPE(hdr1, IPV6);
1299        } else {
1300                for (i = 0; i < proto_hdrs->count; i++) {
1301                        hdr = &proto_hdrs->proto_hdr[i];
1302                        if (hdr->type == VIRTCHNL_PROTO_HDR_L2TPV2) {
1303                                if (phint & IAVF_PHINT_L2TPV2) {
1304                                        REFINE_PROTO_FLD(DEL, L2TPV2_LEN_SESS_ID);
1305                                } else if (phint & IAVF_PHINT_L2TPV2_LEN) {
1306                                        REFINE_PROTO_FLD(DEL, L2TPV2_SESS_ID);
1307                                }
1308                        }
1309                }
1310        }
1311
1312}
1313
1314static void iavf_refine_proto_hdrs(struct virtchnl_proto_hdrs *proto_hdrs,
1315                                   uint64_t rss_type, uint64_t phint)
1316{
1317        iavf_refine_proto_hdrs_l234(proto_hdrs, rss_type);
1318        iavf_refine_proto_hdrs_by_pattern(proto_hdrs, phint);
1319        iavf_refine_proto_hdrs_gtpu(proto_hdrs, rss_type);
1320        iavf_refine_proto_hdrs_l2tpv2(proto_hdrs, phint);
1321}
1322
1323static uint64_t invalid_rss_comb[] = {
1324        RTE_ETH_RSS_IPV4 | RTE_ETH_RSS_NONFRAG_IPV4_UDP,
1325        RTE_ETH_RSS_IPV4 | RTE_ETH_RSS_NONFRAG_IPV4_TCP,
1326        RTE_ETH_RSS_IPV6 | RTE_ETH_RSS_NONFRAG_IPV6_UDP,
1327        RTE_ETH_RSS_IPV6 | RTE_ETH_RSS_NONFRAG_IPV6_TCP,
1328        RTE_ETH_RSS_L3_PRE32 | RTE_ETH_RSS_L3_PRE40 |
1329        RTE_ETH_RSS_L3_PRE48 | RTE_ETH_RSS_L3_PRE56 |
1330        RTE_ETH_RSS_L3_PRE96
1331};
1332
1333struct rss_attr_type {
1334        uint64_t attr;
1335        uint64_t type;
1336};
1337
1338#define VALID_RSS_IPV4_L4       (RTE_ETH_RSS_NONFRAG_IPV4_UDP   | \
1339                                 RTE_ETH_RSS_NONFRAG_IPV4_TCP   | \
1340                                 RTE_ETH_RSS_NONFRAG_IPV4_SCTP)
1341
1342#define VALID_RSS_IPV6_L4       (RTE_ETH_RSS_NONFRAG_IPV6_UDP   | \
1343                                 RTE_ETH_RSS_NONFRAG_IPV6_TCP   | \
1344                                 RTE_ETH_RSS_NONFRAG_IPV6_SCTP)
1345
1346#define VALID_RSS_IPV4          (RTE_ETH_RSS_IPV4 | RTE_ETH_RSS_FRAG_IPV4 | \
1347                                 VALID_RSS_IPV4_L4)
1348#define VALID_RSS_IPV6          (RTE_ETH_RSS_IPV6 | RTE_ETH_RSS_FRAG_IPV6 | \
1349                                 VALID_RSS_IPV6_L4)
1350#define VALID_RSS_L3            (VALID_RSS_IPV4 | VALID_RSS_IPV6)
1351#define VALID_RSS_L4            (VALID_RSS_IPV4_L4 | VALID_RSS_IPV6_L4)
1352
1353#define VALID_RSS_ATTR          (RTE_ETH_RSS_L3_SRC_ONLY        | \
1354                                 RTE_ETH_RSS_L3_DST_ONLY        | \
1355                                 RTE_ETH_RSS_L4_SRC_ONLY        | \
1356                                 RTE_ETH_RSS_L4_DST_ONLY        | \
1357                                 RTE_ETH_RSS_L2_SRC_ONLY        | \
1358                                 RTE_ETH_RSS_L2_DST_ONLY        | \
1359                                 RTE_ETH_RSS_L3_PRE64)
1360
1361#define INVALID_RSS_ATTR        (RTE_ETH_RSS_L3_PRE32   | \
1362                                 RTE_ETH_RSS_L3_PRE40   | \
1363                                 RTE_ETH_RSS_L3_PRE48   | \
1364                                 RTE_ETH_RSS_L3_PRE56   | \
1365                                 RTE_ETH_RSS_L3_PRE96)
1366
1367static struct rss_attr_type rss_attr_to_valid_type[] = {
1368        {RTE_ETH_RSS_L2_SRC_ONLY | RTE_ETH_RSS_L2_DST_ONLY,     RTE_ETH_RSS_ETH},
1369        {RTE_ETH_RSS_L3_SRC_ONLY | RTE_ETH_RSS_L3_DST_ONLY,     VALID_RSS_L3},
1370        {RTE_ETH_RSS_L4_SRC_ONLY | RTE_ETH_RSS_L4_DST_ONLY,     VALID_RSS_L4},
1371        /* current ipv6 prefix only supports prefix 64 bits*/
1372        {RTE_ETH_RSS_L3_PRE64,                          VALID_RSS_IPV6},
1373        {INVALID_RSS_ATTR,                              0}
1374};
1375
1376static bool
1377iavf_any_invalid_rss_type(enum rte_eth_hash_function rss_func,
1378                          uint64_t rss_type, uint64_t allow_rss_type)
1379{
1380        uint32_t i;
1381
1382        /**
1383         * Check if l3/l4 SRC/DST_ONLY is set for SYMMETRIC_TOEPLITZ
1384         * hash function.
1385         */
1386        if (rss_func == RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ) {
1387                if (rss_type & (RTE_ETH_RSS_L3_SRC_ONLY | RTE_ETH_RSS_L3_DST_ONLY |
1388                    RTE_ETH_RSS_L4_SRC_ONLY | RTE_ETH_RSS_L4_DST_ONLY))
1389                        return true;
1390
1391                if (!(rss_type &
1392                   (RTE_ETH_RSS_IPV4 | RTE_ETH_RSS_IPV6 |
1393                    RTE_ETH_RSS_NONFRAG_IPV4_UDP | RTE_ETH_RSS_NONFRAG_IPV6_UDP |
1394                    RTE_ETH_RSS_NONFRAG_IPV4_TCP | RTE_ETH_RSS_NONFRAG_IPV6_TCP |
1395                    RTE_ETH_RSS_NONFRAG_IPV4_SCTP | RTE_ETH_RSS_NONFRAG_IPV6_SCTP)))
1396                        return true;
1397        }
1398
1399        /* check invalid combination */
1400        for (i = 0; i < RTE_DIM(invalid_rss_comb); i++) {
1401                if (__builtin_popcountll(rss_type & invalid_rss_comb[i]) > 1)
1402                        return true;
1403        }
1404
1405        /* check invalid RSS attribute */
1406        for (i = 0; i < RTE_DIM(rss_attr_to_valid_type); i++) {
1407                struct rss_attr_type *rat = &rss_attr_to_valid_type[i];
1408
1409                if (rat->attr & rss_type && !(rat->type & rss_type))
1410                        return true;
1411        }
1412
1413        /* check not allowed RSS type */
1414        rss_type &= ~VALID_RSS_ATTR;
1415
1416        return ((rss_type & allow_rss_type) != rss_type);
1417}
1418
1419static int
1420iavf_hash_parse_action(struct iavf_pattern_match_item *match_item,
1421                       const struct rte_flow_action actions[],
1422                       uint64_t pattern_hint, struct iavf_rss_meta *rss_meta,
1423                       struct rte_flow_error *error)
1424{
1425        struct virtchnl_proto_hdrs *proto_hdrs;
1426        enum rte_flow_action_type action_type;
1427        const struct rte_flow_action_rss *rss;
1428        const struct rte_flow_action *action;
1429        uint64_t rss_type;
1430
1431        /* Supported action is RSS. */
1432        for (action = actions; action->type !=
1433                RTE_FLOW_ACTION_TYPE_END; action++) {
1434                action_type = action->type;
1435                switch (action_type) {
1436                case RTE_FLOW_ACTION_TYPE_RSS:
1437                        rss = action->conf;
1438                        rss_type = rss->types;
1439
1440                        if (rss->func ==
1441                            RTE_ETH_HASH_FUNCTION_SIMPLE_XOR){
1442                                rss_meta->rss_algorithm =
1443                                        VIRTCHNL_RSS_ALG_XOR_ASYMMETRIC;
1444                                return rte_flow_error_set(error, ENOTSUP,
1445                                        RTE_FLOW_ERROR_TYPE_ACTION, action,
1446                                        "function simple_xor is not supported");
1447                        } else if (rss->func ==
1448                                   RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ) {
1449                                rss_meta->rss_algorithm =
1450                                        VIRTCHNL_RSS_ALG_TOEPLITZ_SYMMETRIC;
1451                        } else {
1452                                rss_meta->rss_algorithm =
1453                                        VIRTCHNL_RSS_ALG_TOEPLITZ_ASYMMETRIC;
1454                        }
1455
1456                        if (rss->level)
1457                                return rte_flow_error_set(error, ENOTSUP,
1458                                        RTE_FLOW_ERROR_TYPE_ACTION, action,
1459                                        "a nonzero RSS encapsulation level is not supported");
1460
1461                        if (rss->key_len)
1462                                return rte_flow_error_set(error, ENOTSUP,
1463                                        RTE_FLOW_ERROR_TYPE_ACTION, action,
1464                                        "a nonzero RSS key_len is not supported");
1465
1466                        if (rss->queue_num)
1467                                return rte_flow_error_set(error, ENOTSUP,
1468                                        RTE_FLOW_ERROR_TYPE_ACTION, action,
1469                                        "a non-NULL RSS queue is not supported");
1470
1471                        /* If pattern type is raw, no need to refine rss type */
1472                        if (pattern_hint == IAVF_PHINT_RAW)
1473                                break;
1474
1475                        /**
1476                         * Check simultaneous use of SRC_ONLY and DST_ONLY
1477                         * of the same level.
1478                         */
1479                        rss_type = rte_eth_rss_hf_refine(rss_type);
1480
1481                        if (iavf_any_invalid_rss_type(rss->func, rss_type,
1482                                        match_item->input_set_mask))
1483                                return rte_flow_error_set(error, ENOTSUP,
1484                                                RTE_FLOW_ERROR_TYPE_ACTION,
1485                                                action, "RSS type not supported");
1486                        proto_hdrs = match_item->meta;
1487                        rss_meta->proto_hdrs = *proto_hdrs;
1488                        iavf_refine_proto_hdrs(&rss_meta->proto_hdrs,
1489                                               rss_type, pattern_hint);
1490                        break;
1491
1492                case RTE_FLOW_ACTION_TYPE_END:
1493                        break;
1494
1495                default:
1496                        rte_flow_error_set(error, EINVAL,
1497                                           RTE_FLOW_ERROR_TYPE_ACTION, action,
1498                                           "Invalid action.");
1499                        return -rte_errno;
1500                }
1501        }
1502
1503        return 0;
1504}
1505
1506static int
1507iavf_hash_parse_pattern_action(__rte_unused struct iavf_adapter *ad,
1508                               struct iavf_pattern_match_item *array,
1509                               uint32_t array_len,
1510                               const struct rte_flow_item pattern[],
1511                               const struct rte_flow_action actions[],
1512                               void **meta,
1513                               struct rte_flow_error *error)
1514{
1515        struct iavf_pattern_match_item *pattern_match_item;
1516        struct iavf_rss_meta *rss_meta_ptr;
1517        uint64_t phint = IAVF_PHINT_NONE;
1518        int ret = 0;
1519
1520        rss_meta_ptr = rte_zmalloc(NULL, sizeof(*rss_meta_ptr), 0);
1521        if (!rss_meta_ptr) {
1522                rte_flow_error_set(error, EINVAL,
1523                                   RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
1524                                   "No memory for rss_meta_ptr");
1525                return -ENOMEM;
1526        }
1527
1528        /* Check rss supported pattern and find matched pattern. */
1529        pattern_match_item =
1530                iavf_search_pattern_match_item(pattern, array, array_len,
1531                                               error);
1532        if (!pattern_match_item) {
1533                ret = -rte_errno;
1534                goto error;
1535        }
1536
1537        ret = iavf_hash_parse_pattern(pattern, &phint, error);
1538        if (ret)
1539                goto error;
1540
1541        if (phint == IAVF_PHINT_RAW) {
1542                rss_meta_ptr->raw_ena = true;
1543                ret = iavf_hash_parse_raw_pattern(pattern, rss_meta_ptr);
1544                if (ret) {
1545                        rte_flow_error_set(error, EINVAL,
1546                                           RTE_FLOW_ERROR_TYPE_ITEM, NULL,
1547                                           "Parse raw pattern failed");
1548                        goto error;
1549                }
1550        }
1551
1552        ret = iavf_hash_parse_action(pattern_match_item, actions, phint,
1553                                     rss_meta_ptr, error);
1554
1555error:
1556        if (!ret && meta)
1557                *meta = rss_meta_ptr;
1558        else
1559                rte_free(rss_meta_ptr);
1560
1561        rte_free(pattern_match_item);
1562
1563        return ret;
1564}
1565
1566static int
1567iavf_hash_create(__rte_unused struct iavf_adapter *ad,
1568                 __rte_unused struct rte_flow *flow, void *meta,
1569                 __rte_unused struct rte_flow_error *error)
1570{
1571        struct iavf_rss_meta *rss_meta = (struct iavf_rss_meta *)meta;
1572        struct virtchnl_rss_cfg *rss_cfg;
1573        int ret = 0;
1574
1575        rss_cfg = rte_zmalloc("iavf rss rule",
1576                              sizeof(struct virtchnl_rss_cfg), 0);
1577        if (!rss_cfg) {
1578                rte_flow_error_set(error, EINVAL,
1579                                   RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
1580                                   "No memory for rss rule");
1581                return -ENOMEM;
1582        }
1583
1584        rss_cfg->proto_hdrs = rss_meta->proto_hdrs;
1585        rss_cfg->rss_algorithm = rss_meta->rss_algorithm;
1586
1587        ret = iavf_add_del_rss_cfg(ad, rss_cfg, true);
1588        if (!ret) {
1589                flow->rule = rss_cfg;
1590        } else {
1591                PMD_DRV_LOG(ERR, "fail to add RSS configure");
1592                rte_flow_error_set(error, -ret,
1593                                   RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
1594                                   "Failed to add rss rule.");
1595                rte_free(rss_cfg);
1596                return -rte_errno;
1597        }
1598
1599        rte_free(meta);
1600
1601        return ret;
1602}
1603
1604static int
1605iavf_hash_destroy(__rte_unused struct iavf_adapter *ad,
1606                  struct rte_flow *flow,
1607                  __rte_unused struct rte_flow_error *error)
1608{
1609        struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(ad);
1610        struct virtchnl_rss_cfg *rss_cfg;
1611        int ret = 0;
1612
1613        if (vf->vf_reset)
1614                return 0;
1615
1616        rss_cfg = (struct virtchnl_rss_cfg *)flow->rule;
1617
1618        ret = iavf_add_del_rss_cfg(ad, rss_cfg, false);
1619        if (ret) {
1620                PMD_DRV_LOG(ERR, "fail to del RSS configure");
1621                rte_flow_error_set(error, -ret,
1622                                   RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
1623                                   "Failed to delete rss rule.");
1624                return -rte_errno;
1625        }
1626        return ret;
1627}
1628
1629static void
1630iavf_hash_uninit(struct iavf_adapter *ad)
1631{
1632        struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(ad);
1633        struct rte_eth_rss_conf *rss_conf;
1634
1635        if (vf->vf_reset)
1636                return;
1637
1638        if (!vf->vf_res)
1639                return;
1640
1641        if (!(vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_ADV_RSS_PF))
1642                return;
1643
1644        rss_conf = &ad->dev_data->dev_conf.rx_adv_conf.rss_conf;
1645        if (iavf_rss_hash_set(ad, rss_conf->rss_hf, false))
1646                PMD_DRV_LOG(ERR, "fail to delete default RSS");
1647
1648        iavf_unregister_parser(&iavf_hash_parser, ad);
1649}
1650
1651static void
1652iavf_hash_free(struct rte_flow *flow)
1653{
1654        rte_free(flow->rule);
1655}
1656