dpdk/drivers/net/ice/ice_hash.c
<<
>>
Prefs
   1/* SPDX-License-Identifier: BSD-3-Clause
   2 * Copyright(c) 2019 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 "ice_logs.h"
  23#include "base/ice_type.h"
  24#include "base/ice_flow.h"
  25#include "ice_ethdev.h"
  26#include "ice_generic_flow.h"
  27
  28#define ICE_PHINT_NONE                          0
  29#define ICE_PHINT_VLAN                          BIT_ULL(0)
  30#define ICE_PHINT_PPPOE                         BIT_ULL(1)
  31#define ICE_PHINT_GTPU                          BIT_ULL(2)
  32#define ICE_PHINT_GTPU_EH                       BIT_ULL(3)
  33#define ICE_PHINT_GTPU_EH_DWN                   BIT_ULL(4)
  34#define ICE_PHINT_GTPU_EH_UP                    BIT_ULL(5)
  35#define ICE_PHINT_RAW                           BIT_ULL(6)
  36
  37#define ICE_GTPU_EH_DWNLINK     0
  38#define ICE_GTPU_EH_UPLINK      1
  39
  40#define ICE_IPV4_PROT           BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_PROT)
  41#define ICE_IPV6_PROT           BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_PROT)
  42
  43#define VALID_RSS_IPV4_L4       (RTE_ETH_RSS_NONFRAG_IPV4_UDP   | \
  44                                 RTE_ETH_RSS_NONFRAG_IPV4_TCP   | \
  45                                 RTE_ETH_RSS_NONFRAG_IPV4_SCTP)
  46
  47#define VALID_RSS_IPV6_L4       (RTE_ETH_RSS_NONFRAG_IPV6_UDP   | \
  48                                 RTE_ETH_RSS_NONFRAG_IPV6_TCP   | \
  49                                 RTE_ETH_RSS_NONFRAG_IPV6_SCTP)
  50
  51#define VALID_RSS_IPV4          (RTE_ETH_RSS_IPV4 | RTE_ETH_RSS_FRAG_IPV4 | \
  52                                 VALID_RSS_IPV4_L4)
  53#define VALID_RSS_IPV6          (RTE_ETH_RSS_IPV6 | RTE_ETH_RSS_FRAG_IPV6 | \
  54                                 VALID_RSS_IPV6_L4)
  55#define VALID_RSS_L3            (VALID_RSS_IPV4 | VALID_RSS_IPV6)
  56#define VALID_RSS_L4            (VALID_RSS_IPV4_L4 | VALID_RSS_IPV6_L4)
  57
  58#define VALID_RSS_ATTR          (RTE_ETH_RSS_L3_SRC_ONLY        | \
  59                                 RTE_ETH_RSS_L3_DST_ONLY        | \
  60                                 RTE_ETH_RSS_L4_SRC_ONLY        | \
  61                                 RTE_ETH_RSS_L4_DST_ONLY        | \
  62                                 RTE_ETH_RSS_L2_SRC_ONLY        | \
  63                                 RTE_ETH_RSS_L2_DST_ONLY        | \
  64                                 RTE_ETH_RSS_L3_PRE32   | \
  65                                 RTE_ETH_RSS_L3_PRE48   | \
  66                                 RTE_ETH_RSS_L3_PRE64)
  67
  68#define INVALID_RSS_ATTR        (RTE_ETH_RSS_L3_PRE40   | \
  69                                 RTE_ETH_RSS_L3_PRE56   | \
  70                                 RTE_ETH_RSS_L3_PRE96)
  71
  72struct ice_rss_meta {
  73        uint8_t hash_function;
  74        struct ice_rss_hash_cfg cfg;
  75        struct ice_rss_raw_cfg raw;
  76};
  77
  78struct ice_hash_flow_cfg {
  79        bool simple_xor;
  80        struct ice_rss_cfg rss_cfg;
  81};
  82
  83static int
  84ice_hash_init(struct ice_adapter *ad);
  85
  86static int
  87ice_hash_create(struct ice_adapter *ad,
  88                struct rte_flow *flow,
  89                void *meta,
  90                struct rte_flow_error *error);
  91
  92static int
  93ice_hash_destroy(struct ice_adapter *ad,
  94                struct rte_flow *flow,
  95                struct rte_flow_error *error);
  96
  97static void
  98ice_hash_uninit(struct ice_adapter *ad);
  99
 100static void
 101ice_hash_free(struct rte_flow *flow);
 102
 103static int
 104ice_hash_parse_pattern_action(struct ice_adapter *ad,
 105                        struct ice_pattern_match_item *array,
 106                        uint32_t array_len,
 107                        const struct rte_flow_item pattern[],
 108                        const struct rte_flow_action actions[],
 109                        uint32_t priority,
 110                        void **meta,
 111                        struct rte_flow_error *error);
 112
 113/* Rss configuration template */
 114struct ice_rss_hash_cfg ipv4_tmplt = {
 115        ICE_FLOW_SEG_HDR_ETH | ICE_FLOW_SEG_HDR_IPV4 |
 116        ICE_FLOW_SEG_HDR_IPV_OTHER,
 117        ICE_FLOW_HASH_ETH | ICE_FLOW_HASH_IPV4,
 118        ICE_RSS_OUTER_HEADERS,
 119        0
 120};
 121
 122struct ice_rss_hash_cfg ipv4_udp_tmplt = {
 123        ICE_FLOW_SEG_HDR_ETH | ICE_FLOW_SEG_HDR_IPV4 |
 124        ICE_FLOW_SEG_HDR_IPV_OTHER | ICE_FLOW_SEG_HDR_UDP,
 125        ICE_FLOW_HASH_ETH | ICE_HASH_UDP_IPV4 | ICE_IPV4_PROT,
 126        ICE_RSS_OUTER_HEADERS,
 127        0
 128};
 129
 130struct ice_rss_hash_cfg ipv4_tcp_tmplt = {
 131        ICE_FLOW_SEG_HDR_ETH | ICE_FLOW_SEG_HDR_IPV4 |
 132        ICE_FLOW_SEG_HDR_IPV_OTHER | ICE_FLOW_SEG_HDR_TCP,
 133        ICE_FLOW_HASH_ETH | ICE_HASH_TCP_IPV4 | ICE_IPV4_PROT,
 134        ICE_RSS_OUTER_HEADERS,
 135        0
 136};
 137
 138struct ice_rss_hash_cfg ipv4_sctp_tmplt = {
 139        ICE_FLOW_SEG_HDR_ETH | ICE_FLOW_SEG_HDR_IPV4 |
 140        ICE_FLOW_SEG_HDR_IPV_OTHER | ICE_FLOW_SEG_HDR_SCTP,
 141        ICE_FLOW_HASH_ETH | ICE_HASH_SCTP_IPV4 | ICE_IPV4_PROT,
 142        ICE_RSS_OUTER_HEADERS,
 143        0
 144};
 145
 146struct ice_rss_hash_cfg ipv6_tmplt = {
 147        ICE_FLOW_SEG_HDR_ETH | ICE_FLOW_SEG_HDR_IPV6 |
 148        ICE_FLOW_SEG_HDR_IPV_OTHER,
 149        ICE_FLOW_HASH_ETH | ICE_FLOW_HASH_IPV6,
 150        ICE_RSS_OUTER_HEADERS,
 151        0
 152};
 153
 154struct ice_rss_hash_cfg ipv6_frag_tmplt = {
 155        ICE_FLOW_SEG_HDR_ETH | ICE_FLOW_SEG_HDR_IPV6 |
 156        ICE_FLOW_SEG_HDR_IPV_FRAG,
 157        ICE_FLOW_HASH_ETH | ICE_FLOW_HASH_IPV6,
 158        ICE_RSS_OUTER_HEADERS,
 159        0
 160};
 161
 162struct ice_rss_hash_cfg ipv6_udp_tmplt = {
 163        ICE_FLOW_SEG_HDR_ETH | ICE_FLOW_SEG_HDR_IPV6 |
 164        ICE_FLOW_SEG_HDR_IPV_OTHER | ICE_FLOW_SEG_HDR_UDP,
 165        ICE_FLOW_HASH_ETH | ICE_HASH_UDP_IPV6 | ICE_IPV6_PROT,
 166        ICE_RSS_OUTER_HEADERS,
 167        0
 168};
 169
 170struct ice_rss_hash_cfg ipv6_tcp_tmplt = {
 171        ICE_FLOW_SEG_HDR_ETH | ICE_FLOW_SEG_HDR_IPV6 |
 172        ICE_FLOW_SEG_HDR_IPV_OTHER | ICE_FLOW_SEG_HDR_TCP,
 173        ICE_FLOW_HASH_ETH | ICE_HASH_TCP_IPV6 | ICE_IPV6_PROT,
 174        ICE_RSS_OUTER_HEADERS,
 175        0
 176};
 177
 178struct ice_rss_hash_cfg ipv6_sctp_tmplt = {
 179        ICE_FLOW_SEG_HDR_ETH | ICE_FLOW_SEG_HDR_IPV6 |
 180        ICE_FLOW_SEG_HDR_IPV_OTHER | ICE_FLOW_SEG_HDR_SCTP,
 181        ICE_FLOW_HASH_ETH | ICE_HASH_SCTP_IPV6 | ICE_IPV6_PROT,
 182        ICE_RSS_OUTER_HEADERS,
 183        0
 184};
 185
 186struct ice_rss_hash_cfg outer_ipv4_inner_ipv4_tmplt = {
 187        ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_IPV_OTHER,
 188        ICE_FLOW_HASH_IPV4,
 189        ICE_RSS_INNER_HEADERS_W_OUTER_IPV4,
 190        0
 191};
 192struct ice_rss_hash_cfg outer_ipv4_inner_ipv4_udp_tmplt = {
 193        ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_IPV_OTHER |
 194        ICE_FLOW_SEG_HDR_UDP,
 195        ICE_HASH_UDP_IPV4 | ICE_IPV4_PROT,
 196        ICE_RSS_INNER_HEADERS_W_OUTER_IPV4,
 197        0
 198};
 199
 200struct ice_rss_hash_cfg outer_ipv4_inner_ipv4_tcp_tmplt = {
 201        ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_IPV_OTHER |
 202        ICE_FLOW_SEG_HDR_TCP,
 203        ICE_HASH_TCP_IPV4 | ICE_IPV4_PROT,
 204        ICE_RSS_INNER_HEADERS_W_OUTER_IPV4,
 205        0
 206};
 207
 208struct ice_rss_hash_cfg outer_ipv6_inner_ipv4_tmplt = {
 209        ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_IPV_OTHER,
 210        ICE_FLOW_HASH_IPV4,
 211        ICE_RSS_INNER_HEADERS_W_OUTER_IPV6,
 212        0
 213};
 214
 215struct ice_rss_hash_cfg outer_ipv6_inner_ipv4_udp_tmplt = {
 216        ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_IPV_OTHER |
 217        ICE_FLOW_SEG_HDR_UDP,
 218        ICE_HASH_UDP_IPV4 | ICE_IPV4_PROT,
 219        ICE_RSS_INNER_HEADERS_W_OUTER_IPV6,
 220        0
 221};
 222
 223struct ice_rss_hash_cfg outer_ipv6_inner_ipv4_tcp_tmplt = {
 224        ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_IPV_OTHER |
 225        ICE_FLOW_SEG_HDR_TCP,
 226        ICE_HASH_TCP_IPV4 | ICE_IPV4_PROT,
 227        ICE_RSS_INNER_HEADERS_W_OUTER_IPV6,
 228        0
 229};
 230
 231struct ice_rss_hash_cfg outer_ipv4_inner_ipv6_tmplt = {
 232        ICE_FLOW_SEG_HDR_IPV6 | ICE_FLOW_SEG_HDR_IPV_OTHER,
 233        ICE_FLOW_HASH_IPV6,
 234        ICE_RSS_INNER_HEADERS_W_OUTER_IPV4,
 235        0
 236};
 237
 238struct ice_rss_hash_cfg outer_ipv4_inner_ipv6_udp_tmplt = {
 239        ICE_FLOW_SEG_HDR_IPV6 | ICE_FLOW_SEG_HDR_IPV_OTHER |
 240        ICE_FLOW_SEG_HDR_UDP,
 241        ICE_HASH_UDP_IPV6 | ICE_IPV6_PROT,
 242        ICE_RSS_INNER_HEADERS_W_OUTER_IPV4,
 243        0
 244};
 245
 246struct ice_rss_hash_cfg outer_ipv4_inner_ipv6_tcp_tmplt = {
 247        ICE_FLOW_SEG_HDR_IPV6 | ICE_FLOW_SEG_HDR_IPV_OTHER |
 248        ICE_FLOW_SEG_HDR_TCP,
 249        ICE_HASH_TCP_IPV6 | ICE_IPV6_PROT,
 250        ICE_RSS_INNER_HEADERS_W_OUTER_IPV4,
 251        0
 252};
 253
 254struct ice_rss_hash_cfg outer_ipv6_inner_ipv6_tmplt = {
 255        ICE_FLOW_SEG_HDR_IPV6 | ICE_FLOW_SEG_HDR_IPV_OTHER,
 256        ICE_FLOW_HASH_IPV6,
 257        ICE_RSS_INNER_HEADERS_W_OUTER_IPV6,
 258        0
 259};
 260struct ice_rss_hash_cfg outer_ipv6_inner_ipv6_udp_tmplt = {
 261        ICE_FLOW_SEG_HDR_IPV6 | ICE_FLOW_SEG_HDR_IPV_OTHER |
 262        ICE_FLOW_SEG_HDR_UDP,
 263        ICE_HASH_UDP_IPV6 | ICE_IPV6_PROT,
 264        ICE_RSS_INNER_HEADERS_W_OUTER_IPV6,
 265        0
 266};
 267
 268struct ice_rss_hash_cfg outer_ipv6_inner_ipv6_tcp_tmplt = {
 269        ICE_FLOW_SEG_HDR_IPV6 | ICE_FLOW_SEG_HDR_IPV_OTHER |
 270        ICE_FLOW_SEG_HDR_TCP,
 271        ICE_HASH_TCP_IPV6 | ICE_IPV6_PROT,
 272        ICE_RSS_INNER_HEADERS_W_OUTER_IPV6,
 273        0
 274};
 275
 276struct ice_rss_hash_cfg eth_ipv4_esp_tmplt = {
 277        ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_IPV_OTHER |
 278        ICE_FLOW_SEG_HDR_ESP,
 279        ICE_FLOW_HASH_ESP_SPI,
 280        ICE_RSS_OUTER_HEADERS,
 281        0
 282};
 283
 284struct ice_rss_hash_cfg eth_ipv4_udp_esp_tmplt = {
 285        ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_IPV_OTHER |
 286        ICE_FLOW_SEG_HDR_NAT_T_ESP,
 287        ICE_FLOW_HASH_NAT_T_ESP_SPI,
 288        ICE_RSS_OUTER_HEADERS,
 289        0
 290};
 291
 292struct ice_rss_hash_cfg eth_ipv4_ah_tmplt = {
 293        ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_IPV_OTHER |
 294        ICE_FLOW_SEG_HDR_AH,
 295        ICE_FLOW_HASH_AH_SPI,
 296        ICE_RSS_OUTER_HEADERS,
 297        0
 298};
 299
 300struct ice_rss_hash_cfg eth_ipv4_l2tpv3_tmplt = {
 301        ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_IPV_OTHER |
 302        ICE_FLOW_SEG_HDR_L2TPV3,
 303        ICE_FLOW_HASH_L2TPV3_SESS_ID,
 304        ICE_RSS_OUTER_HEADERS,
 305        0
 306};
 307
 308struct ice_rss_hash_cfg eth_ipv4_pfcp_tmplt = {
 309        ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_IPV_OTHER |
 310        ICE_FLOW_SEG_HDR_PFCP_SESSION,
 311        ICE_FLOW_HASH_PFCP_SEID,
 312        ICE_RSS_OUTER_HEADERS,
 313        0
 314};
 315
 316struct ice_rss_hash_cfg eth_ipv6_esp_tmplt = {
 317        ICE_FLOW_SEG_HDR_IPV6 | ICE_FLOW_SEG_HDR_IPV_OTHER |
 318        ICE_FLOW_SEG_HDR_ESP,
 319        ICE_FLOW_HASH_ESP_SPI,
 320        ICE_RSS_OUTER_HEADERS,
 321        0
 322};
 323
 324struct ice_rss_hash_cfg eth_ipv6_udp_esp_tmplt = {
 325        ICE_FLOW_SEG_HDR_IPV6 | ICE_FLOW_SEG_HDR_IPV_OTHER |
 326        ICE_FLOW_SEG_HDR_NAT_T_ESP,
 327        ICE_FLOW_HASH_NAT_T_ESP_SPI,
 328        ICE_RSS_OUTER_HEADERS,
 329        0
 330};
 331
 332struct ice_rss_hash_cfg eth_ipv6_ah_tmplt = {
 333        ICE_FLOW_SEG_HDR_IPV6 | ICE_FLOW_SEG_HDR_IPV_OTHER |
 334        ICE_FLOW_SEG_HDR_AH,
 335        ICE_FLOW_HASH_AH_SPI,
 336        ICE_RSS_OUTER_HEADERS,
 337        0
 338};
 339
 340struct ice_rss_hash_cfg eth_ipv6_l2tpv3_tmplt = {
 341        ICE_FLOW_SEG_HDR_IPV6 | ICE_FLOW_SEG_HDR_IPV_OTHER |
 342        ICE_FLOW_SEG_HDR_L2TPV3,
 343        ICE_FLOW_HASH_L2TPV3_SESS_ID,
 344        ICE_RSS_OUTER_HEADERS,
 345        0
 346};
 347
 348struct ice_rss_hash_cfg eth_ipv6_pfcp_tmplt = {
 349        ICE_FLOW_SEG_HDR_IPV6 | ICE_FLOW_SEG_HDR_IPV_OTHER |
 350        ICE_FLOW_SEG_HDR_PFCP_SESSION,
 351        ICE_FLOW_HASH_PFCP_SEID,
 352        ICE_RSS_OUTER_HEADERS,
 353        0
 354};
 355
 356struct ice_rss_hash_cfg pppoe_tmplt = {
 357        ICE_FLOW_SEG_HDR_ETH,
 358        ICE_FLOW_HASH_ETH | ICE_FLOW_HASH_PPPOE_SESS_ID,
 359        ICE_RSS_OUTER_HEADERS,
 360        0
 361};
 362
 363struct ice_rss_hash_cfg empty_tmplt = {
 364        ICE_FLOW_SEG_HDR_NONE,
 365        0,
 366        ICE_RSS_ANY_HEADERS,
 367        0
 368};
 369
 370struct ice_rss_hash_cfg eth_tmplt = {
 371        ICE_FLOW_SEG_HDR_ETH | ICE_FLOW_SEG_HDR_ETH_NON_IP,
 372        ICE_FLOW_HASH_ETH,
 373        ICE_RSS_OUTER_HEADERS,
 374        0
 375};
 376
 377/* IPv4 */
 378#define ICE_RSS_TYPE_ETH_IPV4           (RTE_ETH_RSS_ETH | RTE_ETH_RSS_IPV4 | \
 379                                         RTE_ETH_RSS_FRAG_IPV4 | \
 380                                         RTE_ETH_RSS_IPV4_CHKSUM)
 381#define ICE_RSS_TYPE_ETH_IPV4_UDP       (ICE_RSS_TYPE_ETH_IPV4 | \
 382                                         RTE_ETH_RSS_NONFRAG_IPV4_UDP | \
 383                                         RTE_ETH_RSS_L4_CHKSUM)
 384#define ICE_RSS_TYPE_ETH_IPV4_TCP       (ICE_RSS_TYPE_ETH_IPV4 | \
 385                                         RTE_ETH_RSS_NONFRAG_IPV4_TCP | \
 386                                         RTE_ETH_RSS_L4_CHKSUM)
 387#define ICE_RSS_TYPE_ETH_IPV4_SCTP      (ICE_RSS_TYPE_ETH_IPV4 | \
 388                                         RTE_ETH_RSS_NONFRAG_IPV4_SCTP | \
 389                                         RTE_ETH_RSS_L4_CHKSUM)
 390#define ICE_RSS_TYPE_IPV4               RTE_ETH_RSS_IPV4
 391#define ICE_RSS_TYPE_IPV4_UDP           (RTE_ETH_RSS_IPV4 | \
 392                                         RTE_ETH_RSS_NONFRAG_IPV4_UDP)
 393#define ICE_RSS_TYPE_IPV4_TCP           (RTE_ETH_RSS_IPV4 | \
 394                                         RTE_ETH_RSS_NONFRAG_IPV4_TCP)
 395#define ICE_RSS_TYPE_IPV4_SCTP          (RTE_ETH_RSS_IPV4 | \
 396                                         RTE_ETH_RSS_NONFRAG_IPV4_SCTP)
 397
 398/* IPv6 */
 399#define ICE_RSS_TYPE_ETH_IPV6           (RTE_ETH_RSS_ETH | RTE_ETH_RSS_IPV6)
 400#define ICE_RSS_TYPE_ETH_IPV6_FRAG      (RTE_ETH_RSS_ETH | RTE_ETH_RSS_IPV6 | \
 401                                         RTE_ETH_RSS_FRAG_IPV6)
 402#define ICE_RSS_TYPE_ETH_IPV6_UDP       (ICE_RSS_TYPE_ETH_IPV6 | \
 403                                         RTE_ETH_RSS_NONFRAG_IPV6_UDP | \
 404                                         RTE_ETH_RSS_L4_CHKSUM)
 405#define ICE_RSS_TYPE_ETH_IPV6_TCP       (ICE_RSS_TYPE_ETH_IPV6 | \
 406                                         RTE_ETH_RSS_NONFRAG_IPV6_TCP | \
 407                                         RTE_ETH_RSS_L4_CHKSUM)
 408#define ICE_RSS_TYPE_ETH_IPV6_SCTP      (ICE_RSS_TYPE_ETH_IPV6 | \
 409                                         RTE_ETH_RSS_NONFRAG_IPV6_SCTP | \
 410                                         RTE_ETH_RSS_L4_CHKSUM)
 411#define ICE_RSS_TYPE_IPV6               RTE_ETH_RSS_IPV6
 412#define ICE_RSS_TYPE_IPV6_UDP           (RTE_ETH_RSS_IPV6 | \
 413                                         RTE_ETH_RSS_NONFRAG_IPV6_UDP)
 414#define ICE_RSS_TYPE_IPV6_TCP           (RTE_ETH_RSS_IPV6 | \
 415                                         RTE_ETH_RSS_NONFRAG_IPV6_TCP)
 416#define ICE_RSS_TYPE_IPV6_SCTP          (RTE_ETH_RSS_IPV6 | \
 417                                         RTE_ETH_RSS_NONFRAG_IPV6_SCTP)
 418
 419/* VLAN IPV4 */
 420#define ICE_RSS_TYPE_VLAN_IPV4          (ICE_RSS_TYPE_IPV4 | \
 421                                         RTE_ETH_RSS_S_VLAN | RTE_ETH_RSS_C_VLAN | \
 422                                         RTE_ETH_RSS_FRAG_IPV4)
 423#define ICE_RSS_TYPE_VLAN_IPV4_UDP      (ICE_RSS_TYPE_IPV4_UDP | \
 424                                         RTE_ETH_RSS_S_VLAN | RTE_ETH_RSS_C_VLAN)
 425#define ICE_RSS_TYPE_VLAN_IPV4_TCP      (ICE_RSS_TYPE_IPV4_TCP | \
 426                                         RTE_ETH_RSS_S_VLAN | RTE_ETH_RSS_C_VLAN)
 427#define ICE_RSS_TYPE_VLAN_IPV4_SCTP     (ICE_RSS_TYPE_IPV4_SCTP | \
 428                                         RTE_ETH_RSS_S_VLAN | RTE_ETH_RSS_C_VLAN)
 429/* VLAN IPv6 */
 430#define ICE_RSS_TYPE_VLAN_IPV6          (ICE_RSS_TYPE_IPV6 | \
 431                                         RTE_ETH_RSS_S_VLAN | RTE_ETH_RSS_C_VLAN)
 432#define ICE_RSS_TYPE_VLAN_IPV6_FRAG     (ICE_RSS_TYPE_IPV6 | \
 433                                         RTE_ETH_RSS_S_VLAN | RTE_ETH_RSS_C_VLAN | \
 434                                         RTE_ETH_RSS_FRAG_IPV6)
 435#define ICE_RSS_TYPE_VLAN_IPV6_UDP      (ICE_RSS_TYPE_IPV6_UDP | \
 436                                         RTE_ETH_RSS_S_VLAN | RTE_ETH_RSS_C_VLAN)
 437#define ICE_RSS_TYPE_VLAN_IPV6_TCP      (ICE_RSS_TYPE_IPV6_TCP | \
 438                                         RTE_ETH_RSS_S_VLAN | RTE_ETH_RSS_C_VLAN)
 439#define ICE_RSS_TYPE_VLAN_IPV6_SCTP     (ICE_RSS_TYPE_IPV6_SCTP | \
 440                                         RTE_ETH_RSS_S_VLAN | RTE_ETH_RSS_C_VLAN)
 441
 442/* GTPU IPv4 */
 443#define ICE_RSS_TYPE_GTPU_IPV4          (ICE_RSS_TYPE_IPV4 | \
 444                                         RTE_ETH_RSS_GTPU)
 445#define ICE_RSS_TYPE_GTPU_IPV4_UDP      (ICE_RSS_TYPE_IPV4_UDP | \
 446                                         RTE_ETH_RSS_GTPU)
 447#define ICE_RSS_TYPE_GTPU_IPV4_TCP      (ICE_RSS_TYPE_IPV4_TCP | \
 448                                         RTE_ETH_RSS_GTPU)
 449/* GTPU IPv6 */
 450#define ICE_RSS_TYPE_GTPU_IPV6          (ICE_RSS_TYPE_IPV6 | \
 451                                         RTE_ETH_RSS_GTPU)
 452#define ICE_RSS_TYPE_GTPU_IPV6_UDP      (ICE_RSS_TYPE_IPV6_UDP | \
 453                                         RTE_ETH_RSS_GTPU)
 454#define ICE_RSS_TYPE_GTPU_IPV6_TCP      (ICE_RSS_TYPE_IPV6_TCP | \
 455                                         RTE_ETH_RSS_GTPU)
 456
 457/* PPPOE */
 458#define ICE_RSS_TYPE_PPPOE              (RTE_ETH_RSS_ETH | RTE_ETH_RSS_PPPOE)
 459
 460/* PPPOE IPv4 */
 461#define ICE_RSS_TYPE_PPPOE_IPV4         (ICE_RSS_TYPE_IPV4 | \
 462                                         ICE_RSS_TYPE_PPPOE)
 463#define ICE_RSS_TYPE_PPPOE_IPV4_UDP     (ICE_RSS_TYPE_IPV4_UDP | \
 464                                         ICE_RSS_TYPE_PPPOE)
 465#define ICE_RSS_TYPE_PPPOE_IPV4_TCP     (ICE_RSS_TYPE_IPV4_TCP | \
 466                                         ICE_RSS_TYPE_PPPOE)
 467
 468/* PPPOE IPv6 */
 469#define ICE_RSS_TYPE_PPPOE_IPV6         (ICE_RSS_TYPE_IPV6 | \
 470                                         ICE_RSS_TYPE_PPPOE)
 471#define ICE_RSS_TYPE_PPPOE_IPV6_UDP     (ICE_RSS_TYPE_IPV6_UDP | \
 472                                         ICE_RSS_TYPE_PPPOE)
 473#define ICE_RSS_TYPE_PPPOE_IPV6_TCP     (ICE_RSS_TYPE_IPV6_TCP | \
 474                                         ICE_RSS_TYPE_PPPOE)
 475
 476/* ESP, AH, L2TPV3 and PFCP */
 477#define ICE_RSS_TYPE_IPV4_ESP           (RTE_ETH_RSS_ESP | RTE_ETH_RSS_IPV4)
 478#define ICE_RSS_TYPE_IPV6_ESP           (RTE_ETH_RSS_ESP | RTE_ETH_RSS_IPV6)
 479#define ICE_RSS_TYPE_IPV4_AH            (RTE_ETH_RSS_AH | RTE_ETH_RSS_IPV4)
 480#define ICE_RSS_TYPE_IPV6_AH            (RTE_ETH_RSS_AH | RTE_ETH_RSS_IPV6)
 481#define ICE_RSS_TYPE_IPV4_L2TPV3        (RTE_ETH_RSS_L2TPV3 | RTE_ETH_RSS_IPV4)
 482#define ICE_RSS_TYPE_IPV6_L2TPV3        (RTE_ETH_RSS_L2TPV3 | RTE_ETH_RSS_IPV6)
 483#define ICE_RSS_TYPE_IPV4_PFCP          (RTE_ETH_RSS_PFCP | RTE_ETH_RSS_IPV4)
 484#define ICE_RSS_TYPE_IPV6_PFCP          (RTE_ETH_RSS_PFCP | RTE_ETH_RSS_IPV6)
 485
 486/* MAC */
 487#define ICE_RSS_TYPE_ETH                RTE_ETH_RSS_ETH
 488
 489/**
 490 * Supported pattern for hash.
 491 * The first member is pattern item type,
 492 * the second member is input set mask,
 493 * the third member is ice_rss_hash_cfg template.
 494 */
 495static struct ice_pattern_match_item ice_hash_pattern_list[] = {
 496        /* IPV4 */
 497        {pattern_raw,                           ICE_INSET_NONE,                         ICE_INSET_NONE, NULL},
 498        {pattern_eth_ipv4,                      ICE_RSS_TYPE_ETH_IPV4,          ICE_INSET_NONE, &ipv4_tmplt},
 499        {pattern_eth_ipv4_udp,                  ICE_RSS_TYPE_ETH_IPV4_UDP,      ICE_INSET_NONE, &ipv4_udp_tmplt},
 500        {pattern_eth_ipv4_tcp,                  ICE_RSS_TYPE_ETH_IPV4_TCP,      ICE_INSET_NONE, &ipv4_tcp_tmplt},
 501        {pattern_eth_ipv4_sctp,                 ICE_RSS_TYPE_ETH_IPV4_SCTP,     ICE_INSET_NONE, &ipv4_sctp_tmplt},
 502        {pattern_eth_vlan_ipv4,                 ICE_RSS_TYPE_VLAN_IPV4,         ICE_INSET_NONE, &ipv4_tmplt},
 503        {pattern_eth_vlan_ipv4_udp,             ICE_RSS_TYPE_VLAN_IPV4_UDP,     ICE_INSET_NONE, &ipv4_udp_tmplt},
 504        {pattern_eth_vlan_ipv4_tcp,             ICE_RSS_TYPE_VLAN_IPV4_TCP,     ICE_INSET_NONE, &ipv4_tcp_tmplt},
 505        {pattern_eth_vlan_ipv4_sctp,            ICE_RSS_TYPE_VLAN_IPV4_SCTP,    ICE_INSET_NONE, &ipv4_sctp_tmplt},
 506        {pattern_eth_ipv4_gtpu_ipv4,            ICE_RSS_TYPE_GTPU_IPV4,         ICE_INSET_NONE, &outer_ipv4_inner_ipv4_tmplt},
 507        {pattern_eth_ipv4_gtpu_ipv4_udp,        ICE_RSS_TYPE_GTPU_IPV4_UDP,     ICE_INSET_NONE, &outer_ipv4_inner_ipv4_udp_tmplt},
 508        {pattern_eth_ipv4_gtpu_ipv4_tcp,        ICE_RSS_TYPE_GTPU_IPV4_TCP,     ICE_INSET_NONE, &outer_ipv4_inner_ipv4_tcp_tmplt},
 509        {pattern_eth_ipv6_gtpu_ipv4,            ICE_RSS_TYPE_GTPU_IPV4,         ICE_INSET_NONE, &outer_ipv6_inner_ipv4_tmplt},
 510        {pattern_eth_ipv6_gtpu_ipv4_udp,        ICE_RSS_TYPE_GTPU_IPV4_UDP,     ICE_INSET_NONE, &outer_ipv6_inner_ipv4_udp_tmplt},
 511        {pattern_eth_ipv6_gtpu_ipv4_tcp,        ICE_RSS_TYPE_GTPU_IPV4_TCP,     ICE_INSET_NONE, &outer_ipv6_inner_ipv4_tcp_tmplt},
 512        {pattern_eth_ipv4_gtpu_eh_ipv4,         ICE_RSS_TYPE_GTPU_IPV4,         ICE_INSET_NONE, &outer_ipv4_inner_ipv4_tmplt},
 513        {pattern_eth_ipv4_gtpu_eh_ipv4_udp,     ICE_RSS_TYPE_GTPU_IPV4_UDP,     ICE_INSET_NONE, &outer_ipv4_inner_ipv4_udp_tmplt},
 514        {pattern_eth_ipv4_gtpu_eh_ipv4_tcp,     ICE_RSS_TYPE_GTPU_IPV4_TCP,     ICE_INSET_NONE, &outer_ipv4_inner_ipv4_tcp_tmplt},
 515        {pattern_eth_ipv6_gtpu_eh_ipv4,         ICE_RSS_TYPE_GTPU_IPV4,         ICE_INSET_NONE, &outer_ipv6_inner_ipv4_tmplt},
 516        {pattern_eth_ipv6_gtpu_eh_ipv4_udp,     ICE_RSS_TYPE_GTPU_IPV4_UDP,     ICE_INSET_NONE, &outer_ipv6_inner_ipv4_udp_tmplt},
 517        {pattern_eth_ipv6_gtpu_eh_ipv4_tcp,     ICE_RSS_TYPE_GTPU_IPV4_TCP,     ICE_INSET_NONE, &outer_ipv6_inner_ipv4_tcp_tmplt},
 518        {pattern_eth_pppoes_ipv4,               ICE_RSS_TYPE_PPPOE_IPV4,        ICE_INSET_NONE, &ipv4_tmplt},
 519        {pattern_eth_pppoes_ipv4_udp,           ICE_RSS_TYPE_PPPOE_IPV4_UDP,    ICE_INSET_NONE, &ipv4_udp_tmplt},
 520        {pattern_eth_pppoes_ipv4_tcp,           ICE_RSS_TYPE_PPPOE_IPV4_TCP,    ICE_INSET_NONE, &ipv4_tcp_tmplt},
 521        {pattern_eth_ipv4_esp,                  ICE_RSS_TYPE_IPV4_ESP,          ICE_INSET_NONE, &eth_ipv4_esp_tmplt},
 522        {pattern_eth_ipv4_udp_esp,              ICE_RSS_TYPE_IPV4_ESP,          ICE_INSET_NONE, &eth_ipv4_udp_esp_tmplt},
 523        {pattern_eth_ipv4_ah,                   ICE_RSS_TYPE_IPV4_AH,           ICE_INSET_NONE, &eth_ipv4_ah_tmplt},
 524        {pattern_eth_ipv4_l2tp,                 ICE_RSS_TYPE_IPV4_L2TPV3,       ICE_INSET_NONE, &eth_ipv4_l2tpv3_tmplt},
 525        {pattern_eth_ipv4_pfcp,                 ICE_RSS_TYPE_IPV4_PFCP,         ICE_INSET_NONE, &eth_ipv4_pfcp_tmplt},
 526        /* IPV6 */
 527        {pattern_eth_ipv6,                      ICE_RSS_TYPE_ETH_IPV6,          ICE_INSET_NONE, &ipv6_tmplt},
 528        {pattern_eth_ipv6_frag_ext,             ICE_RSS_TYPE_ETH_IPV6_FRAG,     ICE_INSET_NONE, &ipv6_frag_tmplt},
 529        {pattern_eth_ipv6_udp,                  ICE_RSS_TYPE_ETH_IPV6_UDP,      ICE_INSET_NONE, &ipv6_udp_tmplt},
 530        {pattern_eth_ipv6_tcp,                  ICE_RSS_TYPE_ETH_IPV6_TCP,      ICE_INSET_NONE, &ipv6_tcp_tmplt},
 531        {pattern_eth_ipv6_sctp,                 ICE_RSS_TYPE_ETH_IPV6_SCTP,     ICE_INSET_NONE, &ipv6_sctp_tmplt},
 532        {pattern_eth_vlan_ipv6,                 ICE_RSS_TYPE_VLAN_IPV6,         ICE_INSET_NONE, &ipv6_tmplt},
 533        {pattern_eth_vlan_ipv6_frag_ext,        ICE_RSS_TYPE_VLAN_IPV6_FRAG,    ICE_INSET_NONE, &ipv6_frag_tmplt},
 534        {pattern_eth_vlan_ipv6_udp,             ICE_RSS_TYPE_VLAN_IPV6_UDP,     ICE_INSET_NONE, &ipv6_udp_tmplt},
 535        {pattern_eth_vlan_ipv6_tcp,             ICE_RSS_TYPE_VLAN_IPV6_TCP,     ICE_INSET_NONE, &ipv6_tcp_tmplt},
 536        {pattern_eth_vlan_ipv6_sctp,            ICE_RSS_TYPE_VLAN_IPV6_SCTP,    ICE_INSET_NONE, &ipv6_sctp_tmplt},
 537        {pattern_eth_ipv4_gtpu_ipv6,            ICE_RSS_TYPE_GTPU_IPV6,         ICE_INSET_NONE, &outer_ipv4_inner_ipv6_tmplt},
 538        {pattern_eth_ipv4_gtpu_ipv6_udp,        ICE_RSS_TYPE_GTPU_IPV6_UDP,     ICE_INSET_NONE, &outer_ipv4_inner_ipv6_udp_tmplt},
 539        {pattern_eth_ipv4_gtpu_ipv6_tcp,        ICE_RSS_TYPE_GTPU_IPV6_TCP,     ICE_INSET_NONE, &outer_ipv4_inner_ipv6_tcp_tmplt},
 540        {pattern_eth_ipv6_gtpu_ipv6,            ICE_RSS_TYPE_GTPU_IPV6,         ICE_INSET_NONE, &outer_ipv6_inner_ipv6_tmplt},
 541        {pattern_eth_ipv6_gtpu_ipv6_udp,        ICE_RSS_TYPE_GTPU_IPV6_UDP,     ICE_INSET_NONE, &outer_ipv6_inner_ipv6_udp_tmplt},
 542        {pattern_eth_ipv6_gtpu_ipv6_tcp,        ICE_RSS_TYPE_GTPU_IPV6_TCP,     ICE_INSET_NONE, &outer_ipv6_inner_ipv6_tcp_tmplt},
 543        {pattern_eth_ipv4_gtpu_eh_ipv6,         ICE_RSS_TYPE_GTPU_IPV6,         ICE_INSET_NONE, &outer_ipv4_inner_ipv6_tmplt},
 544        {pattern_eth_ipv4_gtpu_eh_ipv6_udp,     ICE_RSS_TYPE_GTPU_IPV6_UDP,     ICE_INSET_NONE, &outer_ipv4_inner_ipv6_udp_tmplt},
 545        {pattern_eth_ipv4_gtpu_eh_ipv6_tcp,     ICE_RSS_TYPE_GTPU_IPV6_TCP,     ICE_INSET_NONE, &outer_ipv4_inner_ipv6_tcp_tmplt},
 546        {pattern_eth_ipv6_gtpu_eh_ipv6,         ICE_RSS_TYPE_GTPU_IPV6,         ICE_INSET_NONE, &outer_ipv6_inner_ipv6_tmplt},
 547        {pattern_eth_ipv6_gtpu_eh_ipv6_udp,     ICE_RSS_TYPE_GTPU_IPV6_UDP,     ICE_INSET_NONE, &outer_ipv6_inner_ipv6_udp_tmplt},
 548        {pattern_eth_ipv6_gtpu_eh_ipv6_tcp,     ICE_RSS_TYPE_GTPU_IPV6_TCP,     ICE_INSET_NONE, &outer_ipv6_inner_ipv6_tcp_tmplt},
 549        {pattern_eth_pppoes_ipv6,               ICE_RSS_TYPE_PPPOE_IPV6,        ICE_INSET_NONE, &ipv6_tmplt},
 550        {pattern_eth_pppoes_ipv6_udp,           ICE_RSS_TYPE_PPPOE_IPV6_UDP,    ICE_INSET_NONE, &ipv6_udp_tmplt},
 551        {pattern_eth_pppoes_ipv6_tcp,           ICE_RSS_TYPE_PPPOE_IPV6_TCP,    ICE_INSET_NONE, &ipv6_tcp_tmplt},
 552        {pattern_eth_ipv6_esp,                  ICE_RSS_TYPE_IPV6_ESP,          ICE_INSET_NONE, &eth_ipv6_esp_tmplt},
 553        {pattern_eth_ipv6_udp_esp,              ICE_RSS_TYPE_IPV6_ESP,          ICE_INSET_NONE, &eth_ipv6_udp_esp_tmplt},
 554        {pattern_eth_ipv6_ah,                   ICE_RSS_TYPE_IPV6_AH,           ICE_INSET_NONE, &eth_ipv6_ah_tmplt},
 555        {pattern_eth_ipv6_l2tp,                 ICE_RSS_TYPE_IPV6_L2TPV3,       ICE_INSET_NONE, &eth_ipv6_l2tpv3_tmplt},
 556        {pattern_eth_ipv6_pfcp,                 ICE_RSS_TYPE_IPV6_PFCP,         ICE_INSET_NONE, &eth_ipv6_pfcp_tmplt},
 557        /* PPPOE */
 558        {pattern_eth_pppoes,                    ICE_RSS_TYPE_PPPOE,             ICE_INSET_NONE, &pppoe_tmplt},
 559        /* MAC */
 560        {pattern_ethertype,                     ICE_RSS_TYPE_ETH,               ICE_INSET_NONE, &eth_tmplt},
 561        /* EMPTY */
 562        {pattern_empty,                         ICE_INSET_NONE,                 ICE_INSET_NONE, &empty_tmplt},
 563};
 564
 565static struct ice_flow_engine ice_hash_engine = {
 566        .init = ice_hash_init,
 567        .create = ice_hash_create,
 568        .destroy = ice_hash_destroy,
 569        .uninit = ice_hash_uninit,
 570        .free = ice_hash_free,
 571        .type = ICE_FLOW_ENGINE_HASH,
 572};
 573
 574/* Register parser for os package. */
 575static struct ice_flow_parser ice_hash_parser = {
 576        .engine = &ice_hash_engine,
 577        .array = ice_hash_pattern_list,
 578        .array_len = RTE_DIM(ice_hash_pattern_list),
 579        .parse_pattern_action = ice_hash_parse_pattern_action,
 580        .stage = ICE_FLOW_STAGE_RSS,
 581};
 582
 583RTE_INIT(ice_hash_engine_init)
 584{
 585        struct ice_flow_engine *engine = &ice_hash_engine;
 586        ice_register_flow_engine(engine);
 587}
 588
 589static int
 590ice_hash_init(struct ice_adapter *ad)
 591{
 592        struct ice_flow_parser *parser = NULL;
 593
 594        if (ad->hw.dcf_enabled)
 595                return 0;
 596
 597        parser = &ice_hash_parser;
 598
 599        return ice_register_parser(parser, ad);
 600}
 601
 602static int
 603ice_hash_parse_pattern(const struct rte_flow_item pattern[], uint64_t *phint,
 604                       struct rte_flow_error *error)
 605{
 606        const struct rte_flow_item *item = pattern;
 607        const struct rte_flow_item_gtp_psc *psc;
 608
 609        for (item = pattern; item->type != RTE_FLOW_ITEM_TYPE_END; item++) {
 610                if (item->last) {
 611                        rte_flow_error_set(error, EINVAL,
 612                                        RTE_FLOW_ERROR_TYPE_ITEM, item,
 613                                        "Not support range");
 614                        return -rte_errno;
 615                }
 616
 617                switch (item->type) {
 618                case RTE_FLOW_ITEM_TYPE_RAW:
 619                        *phint |= ICE_PHINT_RAW;
 620                        break;
 621                case RTE_FLOW_ITEM_TYPE_VLAN:
 622                        *phint |= ICE_PHINT_VLAN;
 623                        break;
 624                case RTE_FLOW_ITEM_TYPE_PPPOES:
 625                        *phint |= ICE_PHINT_PPPOE;
 626                        break;
 627                case RTE_FLOW_ITEM_TYPE_GTPU:
 628                        *phint |= ICE_PHINT_GTPU;
 629                        break;
 630                case RTE_FLOW_ITEM_TYPE_GTP_PSC:
 631                        *phint |= ICE_PHINT_GTPU_EH;
 632                        psc = item->spec;
 633                        if (!psc)
 634                                break;
 635                        else if (psc->hdr.type == ICE_GTPU_EH_UPLINK)
 636                                *phint |= ICE_PHINT_GTPU_EH_UP;
 637                        else if (psc->hdr.type == ICE_GTPU_EH_DWNLINK)
 638                                *phint |= ICE_PHINT_GTPU_EH_DWN;
 639                        break;
 640                default:
 641                        break;
 642                }
 643        }
 644
 645        return 0;
 646}
 647
 648static int
 649ice_hash_parse_raw_pattern(struct ice_adapter *ad,
 650                                const struct rte_flow_item *item,
 651                                struct ice_rss_meta *meta)
 652{
 653        const struct rte_flow_item_raw *raw_spec, *raw_mask;
 654        struct ice_parser_profile prof;
 655        struct ice_parser_result rslt;
 656        struct ice_parser *psr;
 657        uint8_t *pkt_buf, *msk_buf;
 658        uint8_t spec_len, pkt_len;
 659        uint8_t tmp_val = 0;
 660        uint8_t tmp_c = 0;
 661        int i, j;
 662
 663        raw_spec = item->spec;
 664        raw_mask = item->mask;
 665
 666        spec_len = strlen((char *)(uintptr_t)raw_spec->pattern);
 667        if (strlen((char *)(uintptr_t)raw_mask->pattern) !=
 668                spec_len)
 669                return -rte_errno;
 670
 671        pkt_len = spec_len / 2;
 672
 673        pkt_buf = rte_zmalloc(NULL, pkt_len, 0);
 674        if (!pkt_buf)
 675                return -ENOMEM;
 676
 677        msk_buf = rte_zmalloc(NULL, pkt_len, 0);
 678        if (!msk_buf)
 679                return -ENOMEM;
 680
 681        /* convert string to int array */
 682        for (i = 0, j = 0; i < spec_len; i += 2, j++) {
 683                tmp_c = raw_spec->pattern[i];
 684                if (tmp_c >= 'a' && tmp_c <= 'f')
 685                        tmp_val = tmp_c - 'a' + 10;
 686                if (tmp_c >= 'A' && tmp_c <= 'F')
 687                        tmp_val = tmp_c - 'A' + 10;
 688                if (tmp_c >= '0' && tmp_c <= '9')
 689                        tmp_val = tmp_c - '0';
 690
 691                tmp_c = raw_spec->pattern[i + 1];
 692                if (tmp_c >= 'a' && tmp_c <= 'f')
 693                        pkt_buf[j] = tmp_val * 16 + tmp_c - 'a' + 10;
 694                if (tmp_c >= 'A' && tmp_c <= 'F')
 695                        pkt_buf[j] = tmp_val * 16 + tmp_c - 'A' + 10;
 696                if (tmp_c >= '0' && tmp_c <= '9')
 697                        pkt_buf[j] = tmp_val * 16 + tmp_c - '0';
 698
 699                tmp_c = raw_mask->pattern[i];
 700                if (tmp_c >= 'a' && tmp_c <= 'f')
 701                        tmp_val = tmp_c - 0x57;
 702                if (tmp_c >= 'A' && tmp_c <= 'F')
 703                        tmp_val = tmp_c - 0x37;
 704                if (tmp_c >= '0' && tmp_c <= '9')
 705                        tmp_val = tmp_c - '0';
 706
 707                tmp_c = raw_mask->pattern[i + 1];
 708                if (tmp_c >= 'a' && tmp_c <= 'f')
 709                        msk_buf[j] = tmp_val * 16 + tmp_c - 'a' + 10;
 710                if (tmp_c >= 'A' && tmp_c <= 'F')
 711                        msk_buf[j] = tmp_val * 16 + tmp_c - 'A' + 10;
 712                if (tmp_c >= '0' && tmp_c <= '9')
 713                        msk_buf[j] = tmp_val * 16 + tmp_c - '0';
 714        }
 715
 716        if (ice_parser_create(&ad->hw, &psr))
 717                return -rte_errno;
 718        if (ice_parser_run(psr, pkt_buf, pkt_len, &rslt))
 719                return -rte_errno;
 720        ice_parser_destroy(psr);
 721
 722        if (ice_parser_profile_init(&rslt, pkt_buf, msk_buf,
 723                pkt_len, ICE_BLK_RSS, true, &prof))
 724                return -rte_errno;
 725
 726        rte_memcpy(&meta->raw.prof, &prof, sizeof(prof));
 727
 728        rte_free(pkt_buf);
 729        rte_free(msk_buf);
 730        return 0;
 731}
 732
 733static void
 734ice_refine_hash_cfg_l234(struct ice_rss_hash_cfg *hash_cfg,
 735                         uint64_t rss_type)
 736{
 737        uint32_t *addl_hdrs = &hash_cfg->addl_hdrs;
 738        uint64_t *hash_flds = &hash_cfg->hash_flds;
 739
 740        if (*addl_hdrs & ICE_FLOW_SEG_HDR_ETH) {
 741                if (!(rss_type & RTE_ETH_RSS_ETH))
 742                        *hash_flds &= ~ICE_FLOW_HASH_ETH;
 743                if (rss_type & RTE_ETH_RSS_L2_SRC_ONLY)
 744                        *hash_flds &= ~(BIT_ULL(ICE_FLOW_FIELD_IDX_ETH_DA));
 745                else if (rss_type & RTE_ETH_RSS_L2_DST_ONLY)
 746                        *hash_flds &= ~(BIT_ULL(ICE_FLOW_FIELD_IDX_ETH_SA));
 747                *addl_hdrs &= ~ICE_FLOW_SEG_HDR_ETH;
 748        }
 749
 750        if (*addl_hdrs & ICE_FLOW_SEG_HDR_ETH_NON_IP) {
 751                if (rss_type & RTE_ETH_RSS_ETH)
 752                        *hash_flds |= BIT_ULL(ICE_FLOW_FIELD_IDX_ETH_TYPE);
 753        }
 754
 755        if (*addl_hdrs & ICE_FLOW_SEG_HDR_VLAN) {
 756                if (rss_type & RTE_ETH_RSS_C_VLAN)
 757                        *hash_flds |= BIT_ULL(ICE_FLOW_FIELD_IDX_C_VLAN);
 758                else if (rss_type & RTE_ETH_RSS_S_VLAN)
 759                        *hash_flds |= BIT_ULL(ICE_FLOW_FIELD_IDX_S_VLAN);
 760        }
 761
 762        if (*addl_hdrs & ICE_FLOW_SEG_HDR_PPPOE) {
 763                if (!(rss_type & RTE_ETH_RSS_PPPOE))
 764                        *hash_flds &= ~ICE_FLOW_HASH_PPPOE_SESS_ID;
 765        }
 766
 767        if (*addl_hdrs & ICE_FLOW_SEG_HDR_IPV4) {
 768                if (rss_type &
 769                   (RTE_ETH_RSS_IPV4 | RTE_ETH_RSS_FRAG_IPV4 |
 770                    RTE_ETH_RSS_NONFRAG_IPV4_UDP |
 771                    RTE_ETH_RSS_NONFRAG_IPV4_TCP |
 772                    RTE_ETH_RSS_NONFRAG_IPV4_SCTP)) {
 773                        if (rss_type & RTE_ETH_RSS_FRAG_IPV4) {
 774                                *addl_hdrs |= ICE_FLOW_SEG_HDR_IPV_FRAG;
 775                                *addl_hdrs &= ~(ICE_FLOW_SEG_HDR_IPV_OTHER);
 776                                *hash_flds |=
 777                                        BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_ID);
 778                        }
 779                        if (rss_type & RTE_ETH_RSS_L3_SRC_ONLY)
 780                                *hash_flds &= ~(BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_DA));
 781                        else if (rss_type & RTE_ETH_RSS_L3_DST_ONLY)
 782                                *hash_flds &= ~(BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_SA));
 783                        else if (rss_type &
 784                                (RTE_ETH_RSS_L4_SRC_ONLY |
 785                                RTE_ETH_RSS_L4_DST_ONLY))
 786                                *hash_flds &= ~ICE_FLOW_HASH_IPV4;
 787                } else {
 788                        *hash_flds &= ~ICE_FLOW_HASH_IPV4;
 789                }
 790
 791                if (rss_type & RTE_ETH_RSS_IPV4_CHKSUM)
 792                        *hash_flds |= BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_CHKSUM);
 793        }
 794
 795        if (*addl_hdrs & ICE_FLOW_SEG_HDR_IPV6) {
 796                if (rss_type &
 797                   (RTE_ETH_RSS_IPV6 | RTE_ETH_RSS_FRAG_IPV6 |
 798                    RTE_ETH_RSS_NONFRAG_IPV6_UDP |
 799                    RTE_ETH_RSS_NONFRAG_IPV6_TCP |
 800                    RTE_ETH_RSS_NONFRAG_IPV6_SCTP)) {
 801                        if (rss_type & RTE_ETH_RSS_FRAG_IPV6)
 802                                *hash_flds |=
 803                                        BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_ID);
 804                        if (rss_type & RTE_ETH_RSS_L3_SRC_ONLY)
 805                                *hash_flds &= ~(BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_DA));
 806                        else if (rss_type & RTE_ETH_RSS_L3_DST_ONLY)
 807                                *hash_flds &= ~(BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_SA));
 808                        else if (rss_type &
 809                                (RTE_ETH_RSS_L4_SRC_ONLY |
 810                                RTE_ETH_RSS_L4_DST_ONLY))
 811                                *hash_flds &= ~ICE_FLOW_HASH_IPV6;
 812                } else {
 813                        *hash_flds &= ~ICE_FLOW_HASH_IPV6;
 814                }
 815
 816                if (rss_type & RTE_ETH_RSS_L3_PRE32) {
 817                        if (rss_type & RTE_ETH_RSS_L3_SRC_ONLY) {
 818                                *hash_flds &= ~(BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_SA));
 819                                *hash_flds |= (BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_PRE32_SA));
 820                        } else if (rss_type & RTE_ETH_RSS_L3_DST_ONLY) {
 821                                *hash_flds &= ~(BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_DA));
 822                                *hash_flds |= (BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_PRE32_DA));
 823                        } else {
 824                                *hash_flds &= ~ICE_FLOW_HASH_IPV6;
 825                                *hash_flds |= ICE_FLOW_HASH_IPV6_PRE32;
 826                        }
 827                }
 828                if (rss_type & RTE_ETH_RSS_L3_PRE48) {
 829                        if (rss_type & RTE_ETH_RSS_L3_SRC_ONLY) {
 830                                *hash_flds &= ~(BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_SA));
 831                                *hash_flds |= (BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_PRE48_SA));
 832                        } else if (rss_type & RTE_ETH_RSS_L3_DST_ONLY) {
 833                                *hash_flds &= ~(BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_DA));
 834                                *hash_flds |= (BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_PRE48_DA));
 835                        } else {
 836                                *hash_flds &= ~ICE_FLOW_HASH_IPV6;
 837                                *hash_flds |= ICE_FLOW_HASH_IPV6_PRE48;
 838                        }
 839                }
 840                if (rss_type & RTE_ETH_RSS_L3_PRE64) {
 841                        if (rss_type & RTE_ETH_RSS_L3_SRC_ONLY) {
 842                                *hash_flds &= ~(BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_SA));
 843                                *hash_flds |= (BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_PRE64_SA));
 844                        } else if (rss_type & RTE_ETH_RSS_L3_DST_ONLY) {
 845                                *hash_flds &= ~(BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_DA));
 846                                *hash_flds |= (BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_PRE64_DA));
 847                        } else {
 848                                *hash_flds &= ~ICE_FLOW_HASH_IPV6;
 849                                *hash_flds |= ICE_FLOW_HASH_IPV6_PRE64;
 850                        }
 851                }
 852        }
 853
 854        if (*addl_hdrs & ICE_FLOW_SEG_HDR_UDP) {
 855                if (rss_type &
 856                   (RTE_ETH_RSS_NONFRAG_IPV4_UDP |
 857                    RTE_ETH_RSS_NONFRAG_IPV6_UDP)) {
 858                        if (rss_type & RTE_ETH_RSS_L4_SRC_ONLY)
 859                                *hash_flds &= ~(BIT_ULL(ICE_FLOW_FIELD_IDX_UDP_DST_PORT));
 860                        else if (rss_type & RTE_ETH_RSS_L4_DST_ONLY)
 861                                *hash_flds &= ~(BIT_ULL(ICE_FLOW_FIELD_IDX_UDP_SRC_PORT));
 862                        else if (rss_type &
 863                                (RTE_ETH_RSS_L3_SRC_ONLY |
 864                                  RTE_ETH_RSS_L3_DST_ONLY))
 865                                *hash_flds &= ~ICE_FLOW_HASH_UDP_PORT;
 866                } else {
 867                        *hash_flds &= ~ICE_FLOW_HASH_UDP_PORT;
 868                }
 869
 870                if (rss_type & RTE_ETH_RSS_L4_CHKSUM)
 871                        *hash_flds |= BIT_ULL(ICE_FLOW_FIELD_IDX_UDP_CHKSUM);
 872        }
 873
 874        if (*addl_hdrs & ICE_FLOW_SEG_HDR_TCP) {
 875                if (rss_type &
 876                   (RTE_ETH_RSS_NONFRAG_IPV4_TCP |
 877                    RTE_ETH_RSS_NONFRAG_IPV6_TCP)) {
 878                        if (rss_type & RTE_ETH_RSS_L4_SRC_ONLY)
 879                                *hash_flds &= ~(BIT_ULL(ICE_FLOW_FIELD_IDX_TCP_DST_PORT));
 880                        else if (rss_type & RTE_ETH_RSS_L4_DST_ONLY)
 881                                *hash_flds &= ~(BIT_ULL(ICE_FLOW_FIELD_IDX_TCP_SRC_PORT));
 882                        else if (rss_type &
 883                                (RTE_ETH_RSS_L3_SRC_ONLY |
 884                                  RTE_ETH_RSS_L3_DST_ONLY))
 885                                *hash_flds &= ~ICE_FLOW_HASH_TCP_PORT;
 886                } else {
 887                        *hash_flds &= ~ICE_FLOW_HASH_TCP_PORT;
 888                }
 889
 890                if (rss_type & RTE_ETH_RSS_L4_CHKSUM)
 891                        *hash_flds |= BIT_ULL(ICE_FLOW_FIELD_IDX_TCP_CHKSUM);
 892        }
 893
 894        if (*addl_hdrs & ICE_FLOW_SEG_HDR_SCTP) {
 895                if (rss_type &
 896                   (RTE_ETH_RSS_NONFRAG_IPV4_SCTP |
 897                    RTE_ETH_RSS_NONFRAG_IPV6_SCTP)) {
 898                        if (rss_type & RTE_ETH_RSS_L4_SRC_ONLY)
 899                                *hash_flds &= ~(BIT_ULL(ICE_FLOW_FIELD_IDX_SCTP_DST_PORT));
 900                        else if (rss_type & RTE_ETH_RSS_L4_DST_ONLY)
 901                                *hash_flds &= ~(BIT_ULL(ICE_FLOW_FIELD_IDX_SCTP_SRC_PORT));
 902                        else if (rss_type &
 903                                (RTE_ETH_RSS_L3_SRC_ONLY |
 904                                  RTE_ETH_RSS_L3_DST_ONLY))
 905                                *hash_flds &= ~ICE_FLOW_HASH_SCTP_PORT;
 906                } else {
 907                        *hash_flds &= ~ICE_FLOW_HASH_SCTP_PORT;
 908                }
 909
 910                if (rss_type & RTE_ETH_RSS_L4_CHKSUM)
 911                        *hash_flds |= BIT_ULL(ICE_FLOW_FIELD_IDX_SCTP_CHKSUM);
 912        }
 913
 914        if (*addl_hdrs & ICE_FLOW_SEG_HDR_L2TPV3) {
 915                if (!(rss_type & RTE_ETH_RSS_L2TPV3))
 916                        *hash_flds &= ~ICE_FLOW_HASH_L2TPV3_SESS_ID;
 917        }
 918
 919        if (*addl_hdrs & ICE_FLOW_SEG_HDR_ESP) {
 920                if (!(rss_type & RTE_ETH_RSS_ESP))
 921                        *hash_flds &= ~ICE_FLOW_HASH_ESP_SPI;
 922        }
 923
 924        if (*addl_hdrs & ICE_FLOW_SEG_HDR_AH) {
 925                if (!(rss_type & RTE_ETH_RSS_AH))
 926                        *hash_flds &= ~ICE_FLOW_HASH_AH_SPI;
 927        }
 928
 929        if (*addl_hdrs & ICE_FLOW_SEG_HDR_PFCP_SESSION) {
 930                if (!(rss_type & RTE_ETH_RSS_PFCP))
 931                        *hash_flds &= ~ICE_FLOW_HASH_PFCP_SEID;
 932        }
 933}
 934
 935static void
 936ice_refine_proto_hdrs_by_pattern(struct ice_rss_hash_cfg *hash_cfg,
 937                                 uint64_t phint)
 938{
 939        uint32_t *addl_hdrs = &hash_cfg->addl_hdrs;
 940        if (phint & ICE_PHINT_VLAN)
 941                *addl_hdrs |= ICE_FLOW_SEG_HDR_VLAN;
 942
 943        if (phint & ICE_PHINT_PPPOE)
 944                *addl_hdrs |= ICE_FLOW_SEG_HDR_PPPOE;
 945
 946        if (phint & ICE_PHINT_GTPU_EH_DWN)
 947                *addl_hdrs |= ICE_FLOW_SEG_HDR_GTPU_DWN;
 948        else if (phint & ICE_PHINT_GTPU_EH_UP)
 949                *addl_hdrs |= ICE_FLOW_SEG_HDR_GTPU_UP;
 950        else if (phint & ICE_PHINT_GTPU_EH)
 951                *addl_hdrs |= ICE_FLOW_SEG_HDR_GTPU_EH;
 952        else if (phint & ICE_PHINT_GTPU)
 953                *addl_hdrs |= ICE_FLOW_SEG_HDR_GTPU_IP;
 954}
 955
 956static void
 957ice_refine_hash_cfg_gtpu(struct ice_rss_hash_cfg *hash_cfg,
 958                         uint64_t rss_type)
 959{
 960        uint32_t *addl_hdrs = &hash_cfg->addl_hdrs;
 961        uint64_t *hash_flds = &hash_cfg->hash_flds;
 962
 963        /* update hash field for gtpu eh/gtpu dwn/gtpu up. */
 964        if (!(rss_type & RTE_ETH_RSS_GTPU))
 965                return;
 966
 967        if (*addl_hdrs & ICE_FLOW_SEG_HDR_GTPU_DWN)
 968                *hash_flds |= BIT_ULL(ICE_FLOW_FIELD_IDX_GTPU_DWN_TEID);
 969        else if (*addl_hdrs & ICE_FLOW_SEG_HDR_GTPU_UP)
 970                *hash_flds |= BIT_ULL(ICE_FLOW_FIELD_IDX_GTPU_UP_TEID);
 971        else if (*addl_hdrs & ICE_FLOW_SEG_HDR_GTPU_EH)
 972                *hash_flds |= BIT_ULL(ICE_FLOW_FIELD_IDX_GTPU_EH_TEID);
 973        else if (*addl_hdrs & ICE_FLOW_SEG_HDR_GTPU_IP)
 974                *hash_flds |= BIT_ULL(ICE_FLOW_FIELD_IDX_GTPU_IP_TEID);
 975}
 976
 977static void ice_refine_hash_cfg(struct ice_rss_hash_cfg *hash_cfg,
 978                                uint64_t rss_type, uint64_t phint)
 979{
 980        ice_refine_proto_hdrs_by_pattern(hash_cfg, phint);
 981        ice_refine_hash_cfg_l234(hash_cfg, rss_type);
 982        ice_refine_hash_cfg_gtpu(hash_cfg, rss_type);
 983}
 984
 985static uint64_t invalid_rss_comb[] = {
 986        RTE_ETH_RSS_IPV4 | RTE_ETH_RSS_NONFRAG_IPV4_UDP,
 987        RTE_ETH_RSS_IPV4 | RTE_ETH_RSS_NONFRAG_IPV4_TCP,
 988        RTE_ETH_RSS_IPV6 | RTE_ETH_RSS_NONFRAG_IPV6_UDP,
 989        RTE_ETH_RSS_IPV6 | RTE_ETH_RSS_NONFRAG_IPV6_TCP,
 990        RTE_ETH_RSS_L3_PRE40 |
 991        RTE_ETH_RSS_L3_PRE56 |
 992        RTE_ETH_RSS_L3_PRE96
 993};
 994
 995struct rss_attr_type {
 996        uint64_t attr;
 997        uint64_t type;
 998};
 999
1000static struct rss_attr_type rss_attr_to_valid_type[] = {
1001        {RTE_ETH_RSS_L2_SRC_ONLY | RTE_ETH_RSS_L2_DST_ONLY,     RTE_ETH_RSS_ETH},
1002        {RTE_ETH_RSS_L3_SRC_ONLY | RTE_ETH_RSS_L3_DST_ONLY,     VALID_RSS_L3},
1003        {RTE_ETH_RSS_L4_SRC_ONLY | RTE_ETH_RSS_L4_DST_ONLY,     VALID_RSS_L4},
1004        /* current ipv6 prefix only supports prefix 64 bits*/
1005        {RTE_ETH_RSS_L3_PRE32,                          VALID_RSS_IPV6},
1006        {RTE_ETH_RSS_L3_PRE48,                          VALID_RSS_IPV6},
1007        {RTE_ETH_RSS_L3_PRE64,                          VALID_RSS_IPV6},
1008        {INVALID_RSS_ATTR,                              0}
1009};
1010
1011static bool
1012ice_any_invalid_rss_type(enum rte_eth_hash_function rss_func,
1013                         uint64_t rss_type, uint64_t allow_rss_type)
1014{
1015        uint32_t i;
1016
1017        /**
1018         * Check if l3/l4 SRC/DST_ONLY is set for SYMMETRIC_TOEPLITZ
1019         * hash function.
1020         */
1021        if (rss_func == RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ) {
1022                if (rss_type & (RTE_ETH_RSS_L3_SRC_ONLY | RTE_ETH_RSS_L3_DST_ONLY |
1023                    RTE_ETH_RSS_L4_SRC_ONLY | RTE_ETH_RSS_L4_DST_ONLY))
1024                        return true;
1025
1026                if (!(rss_type &
1027                   (RTE_ETH_RSS_IPV4 | RTE_ETH_RSS_IPV6 |
1028                    RTE_ETH_RSS_FRAG_IPV4 | RTE_ETH_RSS_FRAG_IPV6 |
1029                    RTE_ETH_RSS_NONFRAG_IPV4_UDP | RTE_ETH_RSS_NONFRAG_IPV6_UDP |
1030                    RTE_ETH_RSS_NONFRAG_IPV4_TCP | RTE_ETH_RSS_NONFRAG_IPV6_TCP |
1031                    RTE_ETH_RSS_NONFRAG_IPV4_SCTP | RTE_ETH_RSS_NONFRAG_IPV6_SCTP)))
1032                        return true;
1033        }
1034
1035        /* check invalid combination */
1036        for (i = 0; i < RTE_DIM(invalid_rss_comb); i++) {
1037                if (__builtin_popcountll(rss_type & invalid_rss_comb[i]) > 1)
1038                        return true;
1039        }
1040
1041        /* check invalid RSS attribute */
1042        for (i = 0; i < RTE_DIM(rss_attr_to_valid_type); i++) {
1043                struct rss_attr_type *rat = &rss_attr_to_valid_type[i];
1044
1045                if (rat->attr & rss_type && !(rat->type & rss_type))
1046                        return true;
1047        }
1048
1049        /* check not allowed RSS type */
1050        rss_type &= ~VALID_RSS_ATTR;
1051
1052        return ((rss_type & allow_rss_type) != rss_type);
1053}
1054
1055static int
1056ice_hash_parse_action(struct ice_pattern_match_item *pattern_match_item,
1057                const struct rte_flow_action actions[],
1058                uint64_t pattern_hint, struct ice_rss_meta *rss_meta,
1059                struct rte_flow_error *error)
1060{
1061        struct ice_rss_hash_cfg *cfg = pattern_match_item->meta;
1062        enum rte_flow_action_type action_type;
1063        const struct rte_flow_action_rss *rss;
1064        const struct rte_flow_action *action;
1065        uint64_t rss_type;
1066
1067        /* Supported action is RSS. */
1068        for (action = actions; action->type !=
1069                RTE_FLOW_ACTION_TYPE_END; action++) {
1070                action_type = action->type;
1071                switch (action_type) {
1072                case RTE_FLOW_ACTION_TYPE_RSS:
1073                        rss = action->conf;
1074                        rss_type = rss->types;
1075
1076                        /* Check hash function and save it to rss_meta. */
1077                        if (pattern_match_item->pattern_list !=
1078                            pattern_empty && rss->func ==
1079                            RTE_ETH_HASH_FUNCTION_SIMPLE_XOR) {
1080                                return rte_flow_error_set(error, ENOTSUP,
1081                                        RTE_FLOW_ERROR_TYPE_ACTION, action,
1082                                        "Not supported flow");
1083                        } else if (rss->func ==
1084                                   RTE_ETH_HASH_FUNCTION_SIMPLE_XOR){
1085                                rss_meta->hash_function =
1086                                RTE_ETH_HASH_FUNCTION_SIMPLE_XOR;
1087                                return 0;
1088                        } else if (rss->func ==
1089                                   RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ) {
1090                                rss_meta->hash_function =
1091                                RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ;
1092                                if (pattern_hint == ICE_PHINT_RAW)
1093                                        rss_meta->raw.symm = true;
1094                                else
1095                                        cfg->symm = true;
1096                        }
1097
1098                        if (rss->level)
1099                                return rte_flow_error_set(error, ENOTSUP,
1100                                        RTE_FLOW_ERROR_TYPE_ACTION, action,
1101                                        "a nonzero RSS encapsulation level is not supported");
1102
1103                        if (rss->key_len)
1104                                return rte_flow_error_set(error, ENOTSUP,
1105                                        RTE_FLOW_ERROR_TYPE_ACTION, action,
1106                                        "a nonzero RSS key_len is not supported");
1107
1108                        if (rss->queue)
1109                                return rte_flow_error_set(error, ENOTSUP,
1110                                        RTE_FLOW_ERROR_TYPE_ACTION, action,
1111                                        "a non-NULL RSS queue is not supported");
1112
1113                        /* If pattern type is raw, no need to refine rss type */
1114                        if (pattern_hint == ICE_PHINT_RAW)
1115                                break;
1116
1117                        /**
1118                         * Check simultaneous use of SRC_ONLY and DST_ONLY
1119                         * of the same level.
1120                         */
1121                        rss_type = rte_eth_rss_hf_refine(rss_type);
1122
1123                        if (ice_any_invalid_rss_type(rss->func, rss_type,
1124                                        pattern_match_item->input_set_mask_o))
1125                                return rte_flow_error_set(error, ENOTSUP,
1126                                        RTE_FLOW_ERROR_TYPE_ACTION,
1127                                        action, "RSS type not supported");
1128
1129                        rss_meta->cfg = *cfg;
1130                        ice_refine_hash_cfg(&rss_meta->cfg,
1131                                            rss_type, pattern_hint);
1132                        break;
1133                case RTE_FLOW_ACTION_TYPE_END:
1134                        break;
1135
1136                default:
1137                        rte_flow_error_set(error, EINVAL,
1138                                        RTE_FLOW_ERROR_TYPE_ACTION, action,
1139                                        "Invalid action.");
1140                        return -rte_errno;
1141                }
1142        }
1143
1144        return 0;
1145}
1146
1147static int
1148ice_hash_parse_pattern_action(__rte_unused struct ice_adapter *ad,
1149                        struct ice_pattern_match_item *array,
1150                        uint32_t array_len,
1151                        const struct rte_flow_item pattern[],
1152                        const struct rte_flow_action actions[],
1153                        uint32_t priority,
1154                        void **meta,
1155                        struct rte_flow_error *error)
1156{
1157        int ret = 0;
1158        struct ice_pattern_match_item *pattern_match_item;
1159        struct ice_rss_meta *rss_meta_ptr;
1160        uint64_t phint = ICE_PHINT_NONE;
1161
1162        if (priority >= 1)
1163                return -rte_errno;
1164
1165        rss_meta_ptr = rte_zmalloc(NULL, sizeof(*rss_meta_ptr), 0);
1166        if (!rss_meta_ptr) {
1167                rte_flow_error_set(error, EINVAL,
1168                                RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
1169                                "No memory for rss_meta_ptr");
1170                return -ENOMEM;
1171        }
1172
1173        /* Check rss supported pattern and find matched pattern. */
1174        pattern_match_item = ice_search_pattern_match_item(ad, pattern, array,
1175                                                           array_len, error);
1176        if (!pattern_match_item) {
1177                ret = -rte_errno;
1178                goto error;
1179        }
1180
1181        ret = ice_hash_parse_pattern(pattern, &phint, error);
1182        if (ret)
1183                goto error;
1184
1185        if (phint == ICE_PHINT_RAW) {
1186                rss_meta_ptr->raw.raw_ena = true;
1187                ret = ice_hash_parse_raw_pattern(ad, pattern, rss_meta_ptr);
1188                if (ret) {
1189                        rte_flow_error_set(error, EINVAL,
1190                                           RTE_FLOW_ERROR_TYPE_ITEM, NULL,
1191                                           "Parse raw pattern failed");
1192                        goto error;
1193                }
1194        }
1195
1196        /* Check rss action. */
1197        ret = ice_hash_parse_action(pattern_match_item, actions, phint,
1198                                    rss_meta_ptr, error);
1199
1200error:
1201        if (!ret && meta)
1202                *meta = rss_meta_ptr;
1203        else
1204                rte_free(rss_meta_ptr);
1205        rte_free(pattern_match_item);
1206
1207        return ret;
1208}
1209
1210static int
1211ice_hash_add_raw_cfg(struct ice_adapter *ad,
1212                struct ice_rss_raw_cfg *cfg, u16 vsi_handle)
1213{
1214        struct ice_parser_profile *prof = &cfg->prof;
1215        struct ice_rss_prof_info *rss_prof;
1216        struct ice_hw *hw = &ad->hw;
1217        int i, ptg, ret;
1218        u64 id;
1219
1220        id = (u64)ice_find_first_bit(prof->ptypes, UINT16_MAX);
1221
1222        ptg = hw->blk[ICE_BLK_RSS].xlt1.t[id];
1223        rss_prof = &ad->rss_prof_info[ptg];
1224        /* check if ptg already has profile */
1225        if (rss_prof->prof.fv_num) {
1226                for (i = 0; i < ICE_MAX_FV_WORDS; i++) {
1227                        if (rss_prof->prof.fv[i].proto_id !=
1228                            prof->fv[i].proto_id ||
1229                            rss_prof->prof.fv[i].offset !=
1230                            prof->fv[i].offset)
1231                                break;
1232                }
1233
1234                /* current profile is matched, check symmetric hash */
1235                if (i == ICE_MAX_FV_WORDS) {
1236                        if (rss_prof->symm != cfg->symm)
1237                                goto update_symm;
1238
1239                        return 0;
1240                }
1241
1242                /* current profile is not matched, remove it */
1243                ret = ice_rem_prof_id_flow(hw, ICE_BLK_RSS,
1244                                           ice_get_hw_vsi_num(hw, vsi_handle),
1245                                           id);
1246                if (ret) {
1247                        PMD_DRV_LOG(ERR, "remove RSS flow failed\n");
1248                        return ret;
1249                }
1250
1251                ret = ice_rem_prof(hw, ICE_BLK_RSS, id);
1252                if (ret) {
1253                        PMD_DRV_LOG(ERR, "remove RSS profile failed\n");
1254                        return ret;
1255                }
1256        }
1257
1258        /* add new profile */
1259        ret = ice_flow_set_hw_prof(hw, vsi_handle, 0, prof, ICE_BLK_RSS);
1260        if (ret) {
1261                PMD_DRV_LOG(ERR, "HW profile add failed\n");
1262                return ret;
1263        }
1264
1265        rss_prof->symm = cfg->symm;
1266        ice_memcpy(&rss_prof->prof, prof,
1267                   sizeof(struct ice_parser_profile),
1268                   ICE_NONDMA_TO_NONDMA);
1269
1270update_symm:
1271        ice_rss_update_raw_symm(hw, cfg, id);
1272        return 0;
1273}
1274
1275static int
1276ice_hash_create(struct ice_adapter *ad,
1277                struct rte_flow *flow,
1278                void *meta,
1279                struct rte_flow_error *error)
1280{
1281        struct ice_pf *pf = &ad->pf;
1282        struct ice_hw *hw = ICE_PF_TO_HW(pf);
1283        struct ice_vsi *vsi = pf->main_vsi;
1284        int ret;
1285        uint32_t reg;
1286        struct ice_hash_flow_cfg *filter_ptr;
1287        struct ice_rss_meta *rss_meta = (struct ice_rss_meta *)meta;
1288        uint8_t hash_function = rss_meta->hash_function;
1289
1290        filter_ptr = rte_zmalloc("ice_rss_filter",
1291                                sizeof(struct ice_hash_flow_cfg), 0);
1292        if (!filter_ptr) {
1293                rte_flow_error_set(error, EINVAL,
1294                                RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
1295                                "No memory for filter_ptr");
1296                return -ENOMEM;
1297        }
1298
1299        if (hash_function == RTE_ETH_HASH_FUNCTION_SIMPLE_XOR) {
1300                /* Enable registers for simple_xor hash function. */
1301                reg = ICE_READ_REG(hw, VSIQF_HASH_CTL(vsi->vsi_id));
1302                reg = (reg & (~VSIQF_HASH_CTL_HASH_SCHEME_M)) |
1303                        (2 << VSIQF_HASH_CTL_HASH_SCHEME_S);
1304                ICE_WRITE_REG(hw, VSIQF_HASH_CTL(vsi->vsi_id), reg);
1305
1306                filter_ptr->simple_xor = 1;
1307
1308                goto out;
1309        } else {
1310                if (rss_meta->raw.raw_ena) {
1311                        memcpy(&filter_ptr->rss_cfg.raw, &rss_meta->raw,
1312                               sizeof(struct ice_rss_raw_cfg));
1313                        ret = ice_hash_add_raw_cfg(ad, &rss_meta->raw,
1314                                                   pf->main_vsi->idx);
1315                        if (ret) {
1316                                rte_flow_error_set(error, EINVAL,
1317                                                   RTE_FLOW_ERROR_TYPE_HANDLE,
1318                                                   NULL,
1319                                                   "rss flow create fail");
1320                                goto error;
1321                        }
1322                } else {
1323                        memcpy(&filter_ptr->rss_cfg.hash, &rss_meta->cfg,
1324                               sizeof(struct ice_rss_hash_cfg));
1325                        ret = ice_add_rss_cfg_wrap(pf, vsi->idx,
1326                                                   &filter_ptr->rss_cfg.hash);
1327                        if (ret) {
1328                                rte_flow_error_set(error, EINVAL,
1329                                                   RTE_FLOW_ERROR_TYPE_HANDLE,
1330                                                   NULL,
1331                                                   "rss flow create fail");
1332                                goto error;
1333                        }
1334                }
1335        }
1336
1337out:
1338        flow->rule = filter_ptr;
1339        rte_free(meta);
1340        return 0;
1341
1342error:
1343        rte_free(filter_ptr);
1344        rte_free(meta);
1345        return -rte_errno;
1346}
1347
1348static int
1349ice_hash_rem_raw_cfg(struct ice_adapter *ad,
1350                        struct ice_parser_profile *prof,
1351                    u16 vsi_handle)
1352{
1353        struct ice_hw *hw = &ad->hw;
1354        int ptg, ret;
1355        u16 vsig;
1356        u64 id;
1357
1358        id = (u64)ice_find_first_bit(prof->ptypes, 0xFFFF);
1359
1360        ptg = hw->blk[ICE_BLK_RSS].xlt1.t[id];
1361
1362        memset(&ad->rss_prof_info[ptg], 0,
1363                sizeof(struct ice_rss_prof_info));
1364
1365        /* check if vsig is already removed */
1366        ret = ice_vsig_find_vsi(hw, ICE_BLK_RSS,
1367                ice_get_hw_vsi_num(hw, vsi_handle), &vsig);
1368        if (!ret && vsig) {
1369                ret = ice_rem_prof_id_flow(hw, ICE_BLK_RSS,
1370                                           ice_get_hw_vsi_num(hw, vsi_handle),
1371                                           id);
1372                if (ret)
1373                        goto err;
1374
1375                ret = ice_rem_prof(hw, ICE_BLK_RSS, id);
1376                if (ret)
1377                        goto err;
1378        }
1379
1380        return 0;
1381
1382err:
1383        PMD_DRV_LOG(ERR, "HW profile remove failed\n");
1384        return ret;
1385}
1386
1387static int
1388ice_hash_destroy(struct ice_adapter *ad,
1389                struct rte_flow *flow,
1390                struct rte_flow_error *error)
1391{
1392        struct ice_pf *pf = ICE_DEV_PRIVATE_TO_PF(ad);
1393        struct ice_hw *hw = ICE_PF_TO_HW(pf);
1394        struct ice_vsi *vsi = pf->main_vsi;
1395        int ret;
1396        uint32_t reg;
1397        struct ice_hash_flow_cfg *filter_ptr;
1398
1399        filter_ptr = (struct ice_hash_flow_cfg *)flow->rule;
1400
1401        if (filter_ptr->simple_xor == 1) {
1402                /* Return to symmetric_toeplitz state. */
1403                reg = ICE_READ_REG(hw, VSIQF_HASH_CTL(vsi->vsi_id));
1404                reg = (reg & (~VSIQF_HASH_CTL_HASH_SCHEME_M)) |
1405                        (1 << VSIQF_HASH_CTL_HASH_SCHEME_S);
1406                ICE_WRITE_REG(hw, VSIQF_HASH_CTL(vsi->vsi_id), reg);
1407        } else {
1408                if (filter_ptr->rss_cfg.raw.raw_ena) {
1409                        ret =
1410                        ice_hash_rem_raw_cfg(ad, &filter_ptr->rss_cfg.raw.prof,
1411                                             pf->main_vsi->idx);
1412                        if (ret) {
1413                                rte_flow_error_set(error, EINVAL,
1414                                                   RTE_FLOW_ERROR_TYPE_HANDLE,
1415                                                   NULL,
1416                                                   "rss flow destroy fail");
1417                                goto error;
1418                        }
1419                } else {
1420                        ret = ice_rem_rss_cfg_wrap(pf, vsi->idx,
1421                                                   &filter_ptr->rss_cfg.hash);
1422                        /* Fixme: Ignore the error if a rule does not exist.
1423                         * Currently a rule for inputset change or symm turn
1424                         * on/off will overwrite an exist rule, while
1425                         * application still have 2 rte_flow handles.
1426                         **/
1427                        if (ret && ret != ICE_ERR_DOES_NOT_EXIST) {
1428                                rte_flow_error_set(error, EINVAL,
1429                                                   RTE_FLOW_ERROR_TYPE_HANDLE,
1430                                                   NULL,
1431                                                   "rss flow destroy fail");
1432                                goto error;
1433                        }
1434                }
1435        }
1436
1437        rte_free(filter_ptr);
1438        return 0;
1439
1440error:
1441        rte_free(filter_ptr);
1442        return -rte_errno;
1443}
1444
1445static void
1446ice_hash_uninit(struct ice_adapter *ad)
1447{
1448        if (ad->hw.dcf_enabled)
1449                return;
1450
1451        ice_unregister_parser(&ice_hash_parser, ad);
1452}
1453
1454static void
1455ice_hash_free(struct rte_flow *flow)
1456{
1457        rte_free(flow->rule);
1458}
1459