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        uint8_t *pkt_buf, *msk_buf;
 657        uint8_t spec_len, pkt_len;
 658        uint8_t tmp_val = 0;
 659        uint8_t tmp_c = 0;
 660        int i, j;
 661
 662        if (ad->psr == NULL)
 663                return -rte_errno;
 664
 665        raw_spec = item->spec;
 666        raw_mask = item->mask;
 667
 668        spec_len = strlen((char *)(uintptr_t)raw_spec->pattern);
 669        if (strlen((char *)(uintptr_t)raw_mask->pattern) !=
 670                spec_len)
 671                return -rte_errno;
 672
 673        pkt_len = spec_len / 2;
 674
 675        pkt_buf = rte_zmalloc(NULL, pkt_len, 0);
 676        if (!pkt_buf)
 677                return -ENOMEM;
 678
 679        msk_buf = rte_zmalloc(NULL, pkt_len, 0);
 680        if (!msk_buf)
 681                return -ENOMEM;
 682
 683        /* convert string to int array */
 684        for (i = 0, j = 0; i < spec_len; i += 2, j++) {
 685                tmp_c = raw_spec->pattern[i];
 686                if (tmp_c >= 'a' && tmp_c <= 'f')
 687                        tmp_val = tmp_c - 'a' + 10;
 688                if (tmp_c >= 'A' && tmp_c <= 'F')
 689                        tmp_val = tmp_c - 'A' + 10;
 690                if (tmp_c >= '0' && tmp_c <= '9')
 691                        tmp_val = tmp_c - '0';
 692
 693                tmp_c = raw_spec->pattern[i + 1];
 694                if (tmp_c >= 'a' && tmp_c <= 'f')
 695                        pkt_buf[j] = tmp_val * 16 + tmp_c - 'a' + 10;
 696                if (tmp_c >= 'A' && tmp_c <= 'F')
 697                        pkt_buf[j] = tmp_val * 16 + tmp_c - 'A' + 10;
 698                if (tmp_c >= '0' && tmp_c <= '9')
 699                        pkt_buf[j] = tmp_val * 16 + tmp_c - '0';
 700
 701                tmp_c = raw_mask->pattern[i];
 702                if (tmp_c >= 'a' && tmp_c <= 'f')
 703                        tmp_val = tmp_c - 0x57;
 704                if (tmp_c >= 'A' && tmp_c <= 'F')
 705                        tmp_val = tmp_c - 0x37;
 706                if (tmp_c >= '0' && tmp_c <= '9')
 707                        tmp_val = tmp_c - '0';
 708
 709                tmp_c = raw_mask->pattern[i + 1];
 710                if (tmp_c >= 'a' && tmp_c <= 'f')
 711                        msk_buf[j] = tmp_val * 16 + tmp_c - 'a' + 10;
 712                if (tmp_c >= 'A' && tmp_c <= 'F')
 713                        msk_buf[j] = tmp_val * 16 + tmp_c - 'A' + 10;
 714                if (tmp_c >= '0' && tmp_c <= '9')
 715                        msk_buf[j] = tmp_val * 16 + tmp_c - '0';
 716        }
 717
 718        if (ice_parser_run(ad->psr, pkt_buf, pkt_len, &rslt))
 719                return -rte_errno;
 720
 721        if (ice_parser_profile_init(&rslt, pkt_buf, msk_buf,
 722                pkt_len, ICE_BLK_RSS, true, &prof))
 723                return -rte_errno;
 724
 725        rte_memcpy(&meta->raw.prof, &prof, sizeof(prof));
 726
 727        rte_free(pkt_buf);
 728        rte_free(msk_buf);
 729        return 0;
 730}
 731
 732static void
 733ice_refine_hash_cfg_l234(struct ice_rss_hash_cfg *hash_cfg,
 734                         uint64_t rss_type)
 735{
 736        uint32_t *addl_hdrs = &hash_cfg->addl_hdrs;
 737        uint64_t *hash_flds = &hash_cfg->hash_flds;
 738
 739        if (*addl_hdrs & ICE_FLOW_SEG_HDR_ETH) {
 740                if (!(rss_type & RTE_ETH_RSS_ETH))
 741                        *hash_flds &= ~ICE_FLOW_HASH_ETH;
 742                if (rss_type & RTE_ETH_RSS_L2_SRC_ONLY)
 743                        *hash_flds &= ~(BIT_ULL(ICE_FLOW_FIELD_IDX_ETH_DA));
 744                else if (rss_type & RTE_ETH_RSS_L2_DST_ONLY)
 745                        *hash_flds &= ~(BIT_ULL(ICE_FLOW_FIELD_IDX_ETH_SA));
 746                *addl_hdrs &= ~ICE_FLOW_SEG_HDR_ETH;
 747        }
 748
 749        if (*addl_hdrs & ICE_FLOW_SEG_HDR_ETH_NON_IP) {
 750                if (rss_type & RTE_ETH_RSS_ETH)
 751                        *hash_flds |= BIT_ULL(ICE_FLOW_FIELD_IDX_ETH_TYPE);
 752        }
 753
 754        if (*addl_hdrs & ICE_FLOW_SEG_HDR_VLAN) {
 755                if (rss_type & RTE_ETH_RSS_C_VLAN)
 756                        *hash_flds |= BIT_ULL(ICE_FLOW_FIELD_IDX_C_VLAN);
 757                else if (rss_type & RTE_ETH_RSS_S_VLAN)
 758                        *hash_flds |= BIT_ULL(ICE_FLOW_FIELD_IDX_S_VLAN);
 759        }
 760
 761        if (*addl_hdrs & ICE_FLOW_SEG_HDR_PPPOE) {
 762                if (!(rss_type & RTE_ETH_RSS_PPPOE))
 763                        *hash_flds &= ~ICE_FLOW_HASH_PPPOE_SESS_ID;
 764        }
 765
 766        if (*addl_hdrs & ICE_FLOW_SEG_HDR_IPV4) {
 767                if (rss_type &
 768                   (RTE_ETH_RSS_IPV4 | RTE_ETH_RSS_FRAG_IPV4 |
 769                    RTE_ETH_RSS_NONFRAG_IPV4_UDP |
 770                    RTE_ETH_RSS_NONFRAG_IPV4_TCP |
 771                    RTE_ETH_RSS_NONFRAG_IPV4_SCTP)) {
 772                        if (rss_type & RTE_ETH_RSS_FRAG_IPV4) {
 773                                *addl_hdrs |= ICE_FLOW_SEG_HDR_IPV_FRAG;
 774                                *addl_hdrs &= ~(ICE_FLOW_SEG_HDR_IPV_OTHER);
 775                                *hash_flds |=
 776                                        BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_ID);
 777                        }
 778                        if (rss_type & RTE_ETH_RSS_L3_SRC_ONLY)
 779                                *hash_flds &= ~(BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_DA));
 780                        else if (rss_type & RTE_ETH_RSS_L3_DST_ONLY)
 781                                *hash_flds &= ~(BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_SA));
 782                        else if (rss_type &
 783                                (RTE_ETH_RSS_L4_SRC_ONLY |
 784                                RTE_ETH_RSS_L4_DST_ONLY))
 785                                *hash_flds &= ~ICE_FLOW_HASH_IPV4;
 786                } else {
 787                        *hash_flds &= ~ICE_FLOW_HASH_IPV4;
 788                }
 789
 790                if (rss_type & RTE_ETH_RSS_IPV4_CHKSUM)
 791                        *hash_flds |= BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_CHKSUM);
 792        }
 793
 794        if (*addl_hdrs & ICE_FLOW_SEG_HDR_IPV6) {
 795                if (rss_type &
 796                   (RTE_ETH_RSS_IPV6 | RTE_ETH_RSS_FRAG_IPV6 |
 797                    RTE_ETH_RSS_NONFRAG_IPV6_UDP |
 798                    RTE_ETH_RSS_NONFRAG_IPV6_TCP |
 799                    RTE_ETH_RSS_NONFRAG_IPV6_SCTP)) {
 800                        if (rss_type & RTE_ETH_RSS_FRAG_IPV6)
 801                                *hash_flds |=
 802                                        BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_ID);
 803                        if (rss_type & RTE_ETH_RSS_L3_SRC_ONLY)
 804                                *hash_flds &= ~(BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_DA));
 805                        else if (rss_type & RTE_ETH_RSS_L3_DST_ONLY)
 806                                *hash_flds &= ~(BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_SA));
 807                        else if (rss_type &
 808                                (RTE_ETH_RSS_L4_SRC_ONLY |
 809                                RTE_ETH_RSS_L4_DST_ONLY))
 810                                *hash_flds &= ~ICE_FLOW_HASH_IPV6;
 811                } else {
 812                        *hash_flds &= ~ICE_FLOW_HASH_IPV6;
 813                }
 814
 815                if (rss_type & RTE_ETH_RSS_L3_PRE32) {
 816                        if (rss_type & RTE_ETH_RSS_L3_SRC_ONLY) {
 817                                *hash_flds &= ~(BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_SA));
 818                                *hash_flds |= (BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_PRE32_SA));
 819                        } else if (rss_type & RTE_ETH_RSS_L3_DST_ONLY) {
 820                                *hash_flds &= ~(BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_DA));
 821                                *hash_flds |= (BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_PRE32_DA));
 822                        } else {
 823                                *hash_flds &= ~ICE_FLOW_HASH_IPV6;
 824                                *hash_flds |= ICE_FLOW_HASH_IPV6_PRE32;
 825                        }
 826                }
 827                if (rss_type & RTE_ETH_RSS_L3_PRE48) {
 828                        if (rss_type & RTE_ETH_RSS_L3_SRC_ONLY) {
 829                                *hash_flds &= ~(BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_SA));
 830                                *hash_flds |= (BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_PRE48_SA));
 831                        } else if (rss_type & RTE_ETH_RSS_L3_DST_ONLY) {
 832                                *hash_flds &= ~(BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_DA));
 833                                *hash_flds |= (BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_PRE48_DA));
 834                        } else {
 835                                *hash_flds &= ~ICE_FLOW_HASH_IPV6;
 836                                *hash_flds |= ICE_FLOW_HASH_IPV6_PRE48;
 837                        }
 838                }
 839                if (rss_type & RTE_ETH_RSS_L3_PRE64) {
 840                        if (rss_type & RTE_ETH_RSS_L3_SRC_ONLY) {
 841                                *hash_flds &= ~(BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_SA));
 842                                *hash_flds |= (BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_PRE64_SA));
 843                        } else if (rss_type & RTE_ETH_RSS_L3_DST_ONLY) {
 844                                *hash_flds &= ~(BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_DA));
 845                                *hash_flds |= (BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_PRE64_DA));
 846                        } else {
 847                                *hash_flds &= ~ICE_FLOW_HASH_IPV6;
 848                                *hash_flds |= ICE_FLOW_HASH_IPV6_PRE64;
 849                        }
 850                }
 851        }
 852
 853        if (*addl_hdrs & ICE_FLOW_SEG_HDR_UDP) {
 854                if (rss_type &
 855                   (RTE_ETH_RSS_NONFRAG_IPV4_UDP |
 856                    RTE_ETH_RSS_NONFRAG_IPV6_UDP)) {
 857                        if (rss_type & RTE_ETH_RSS_L4_SRC_ONLY)
 858                                *hash_flds &= ~(BIT_ULL(ICE_FLOW_FIELD_IDX_UDP_DST_PORT));
 859                        else if (rss_type & RTE_ETH_RSS_L4_DST_ONLY)
 860                                *hash_flds &= ~(BIT_ULL(ICE_FLOW_FIELD_IDX_UDP_SRC_PORT));
 861                        else if (rss_type &
 862                                (RTE_ETH_RSS_L3_SRC_ONLY |
 863                                  RTE_ETH_RSS_L3_DST_ONLY))
 864                                *hash_flds &= ~ICE_FLOW_HASH_UDP_PORT;
 865                } else {
 866                        *hash_flds &= ~ICE_FLOW_HASH_UDP_PORT;
 867                }
 868
 869                if (rss_type & RTE_ETH_RSS_L4_CHKSUM)
 870                        *hash_flds |= BIT_ULL(ICE_FLOW_FIELD_IDX_UDP_CHKSUM);
 871        }
 872
 873        if (*addl_hdrs & ICE_FLOW_SEG_HDR_TCP) {
 874                if (rss_type &
 875                   (RTE_ETH_RSS_NONFRAG_IPV4_TCP |
 876                    RTE_ETH_RSS_NONFRAG_IPV6_TCP)) {
 877                        if (rss_type & RTE_ETH_RSS_L4_SRC_ONLY)
 878                                *hash_flds &= ~(BIT_ULL(ICE_FLOW_FIELD_IDX_TCP_DST_PORT));
 879                        else if (rss_type & RTE_ETH_RSS_L4_DST_ONLY)
 880                                *hash_flds &= ~(BIT_ULL(ICE_FLOW_FIELD_IDX_TCP_SRC_PORT));
 881                        else if (rss_type &
 882                                (RTE_ETH_RSS_L3_SRC_ONLY |
 883                                  RTE_ETH_RSS_L3_DST_ONLY))
 884                                *hash_flds &= ~ICE_FLOW_HASH_TCP_PORT;
 885                } else {
 886                        *hash_flds &= ~ICE_FLOW_HASH_TCP_PORT;
 887                }
 888
 889                if (rss_type & RTE_ETH_RSS_L4_CHKSUM)
 890                        *hash_flds |= BIT_ULL(ICE_FLOW_FIELD_IDX_TCP_CHKSUM);
 891        }
 892
 893        if (*addl_hdrs & ICE_FLOW_SEG_HDR_SCTP) {
 894                if (rss_type &
 895                   (RTE_ETH_RSS_NONFRAG_IPV4_SCTP |
 896                    RTE_ETH_RSS_NONFRAG_IPV6_SCTP)) {
 897                        if (rss_type & RTE_ETH_RSS_L4_SRC_ONLY)
 898                                *hash_flds &= ~(BIT_ULL(ICE_FLOW_FIELD_IDX_SCTP_DST_PORT));
 899                        else if (rss_type & RTE_ETH_RSS_L4_DST_ONLY)
 900                                *hash_flds &= ~(BIT_ULL(ICE_FLOW_FIELD_IDX_SCTP_SRC_PORT));
 901                        else if (rss_type &
 902                                (RTE_ETH_RSS_L3_SRC_ONLY |
 903                                  RTE_ETH_RSS_L3_DST_ONLY))
 904                                *hash_flds &= ~ICE_FLOW_HASH_SCTP_PORT;
 905                } else {
 906                        *hash_flds &= ~ICE_FLOW_HASH_SCTP_PORT;
 907                }
 908
 909                if (rss_type & RTE_ETH_RSS_L4_CHKSUM)
 910                        *hash_flds |= BIT_ULL(ICE_FLOW_FIELD_IDX_SCTP_CHKSUM);
 911        }
 912
 913        if (*addl_hdrs & ICE_FLOW_SEG_HDR_L2TPV3) {
 914                if (!(rss_type & RTE_ETH_RSS_L2TPV3))
 915                        *hash_flds &= ~ICE_FLOW_HASH_L2TPV3_SESS_ID;
 916        }
 917
 918        if (*addl_hdrs & ICE_FLOW_SEG_HDR_ESP) {
 919                if (!(rss_type & RTE_ETH_RSS_ESP))
 920                        *hash_flds &= ~ICE_FLOW_HASH_ESP_SPI;
 921        }
 922
 923        if (*addl_hdrs & ICE_FLOW_SEG_HDR_AH) {
 924                if (!(rss_type & RTE_ETH_RSS_AH))
 925                        *hash_flds &= ~ICE_FLOW_HASH_AH_SPI;
 926        }
 927
 928        if (*addl_hdrs & ICE_FLOW_SEG_HDR_PFCP_SESSION) {
 929                if (!(rss_type & RTE_ETH_RSS_PFCP))
 930                        *hash_flds &= ~ICE_FLOW_HASH_PFCP_SEID;
 931        }
 932}
 933
 934static void
 935ice_refine_proto_hdrs_by_pattern(struct ice_rss_hash_cfg *hash_cfg,
 936                                 uint64_t phint)
 937{
 938        uint32_t *addl_hdrs = &hash_cfg->addl_hdrs;
 939        if (phint & ICE_PHINT_VLAN)
 940                *addl_hdrs |= ICE_FLOW_SEG_HDR_VLAN;
 941
 942        if (phint & ICE_PHINT_PPPOE)
 943                *addl_hdrs |= ICE_FLOW_SEG_HDR_PPPOE;
 944
 945        if (phint & ICE_PHINT_GTPU_EH_DWN)
 946                *addl_hdrs |= ICE_FLOW_SEG_HDR_GTPU_DWN;
 947        else if (phint & ICE_PHINT_GTPU_EH_UP)
 948                *addl_hdrs |= ICE_FLOW_SEG_HDR_GTPU_UP;
 949        else if (phint & ICE_PHINT_GTPU_EH)
 950                *addl_hdrs |= ICE_FLOW_SEG_HDR_GTPU_EH;
 951        else if (phint & ICE_PHINT_GTPU)
 952                *addl_hdrs |= ICE_FLOW_SEG_HDR_GTPU_IP;
 953}
 954
 955static void
 956ice_refine_hash_cfg_gtpu(struct ice_rss_hash_cfg *hash_cfg,
 957                         uint64_t rss_type)
 958{
 959        uint32_t *addl_hdrs = &hash_cfg->addl_hdrs;
 960        uint64_t *hash_flds = &hash_cfg->hash_flds;
 961
 962        /* update hash field for gtpu eh/gtpu dwn/gtpu up. */
 963        if (!(rss_type & RTE_ETH_RSS_GTPU))
 964                return;
 965
 966        if (*addl_hdrs & ICE_FLOW_SEG_HDR_GTPU_DWN)
 967                *hash_flds |= BIT_ULL(ICE_FLOW_FIELD_IDX_GTPU_DWN_TEID);
 968        else if (*addl_hdrs & ICE_FLOW_SEG_HDR_GTPU_UP)
 969                *hash_flds |= BIT_ULL(ICE_FLOW_FIELD_IDX_GTPU_UP_TEID);
 970        else if (*addl_hdrs & ICE_FLOW_SEG_HDR_GTPU_EH)
 971                *hash_flds |= BIT_ULL(ICE_FLOW_FIELD_IDX_GTPU_EH_TEID);
 972        else if (*addl_hdrs & ICE_FLOW_SEG_HDR_GTPU_IP)
 973                *hash_flds |= BIT_ULL(ICE_FLOW_FIELD_IDX_GTPU_IP_TEID);
 974}
 975
 976static void ice_refine_hash_cfg(struct ice_rss_hash_cfg *hash_cfg,
 977                                uint64_t rss_type, uint64_t phint)
 978{
 979        ice_refine_proto_hdrs_by_pattern(hash_cfg, phint);
 980        ice_refine_hash_cfg_l234(hash_cfg, rss_type);
 981        ice_refine_hash_cfg_gtpu(hash_cfg, rss_type);
 982}
 983
 984static uint64_t invalid_rss_comb[] = {
 985        RTE_ETH_RSS_IPV4 | RTE_ETH_RSS_NONFRAG_IPV4_UDP,
 986        RTE_ETH_RSS_IPV4 | RTE_ETH_RSS_NONFRAG_IPV4_TCP,
 987        RTE_ETH_RSS_IPV6 | RTE_ETH_RSS_NONFRAG_IPV6_UDP,
 988        RTE_ETH_RSS_IPV6 | RTE_ETH_RSS_NONFRAG_IPV6_TCP,
 989        RTE_ETH_RSS_L3_PRE40 |
 990        RTE_ETH_RSS_L3_PRE56 |
 991        RTE_ETH_RSS_L3_PRE96
 992};
 993
 994struct rss_attr_type {
 995        uint64_t attr;
 996        uint64_t type;
 997};
 998
 999static struct rss_attr_type rss_attr_to_valid_type[] = {
1000        {RTE_ETH_RSS_L2_SRC_ONLY | RTE_ETH_RSS_L2_DST_ONLY,     RTE_ETH_RSS_ETH},
1001        {RTE_ETH_RSS_L3_SRC_ONLY | RTE_ETH_RSS_L3_DST_ONLY,     VALID_RSS_L3},
1002        {RTE_ETH_RSS_L4_SRC_ONLY | RTE_ETH_RSS_L4_DST_ONLY,     VALID_RSS_L4},
1003        /* current ipv6 prefix only supports prefix 64 bits*/
1004        {RTE_ETH_RSS_L3_PRE32,                          VALID_RSS_IPV6},
1005        {RTE_ETH_RSS_L3_PRE48,                          VALID_RSS_IPV6},
1006        {RTE_ETH_RSS_L3_PRE64,                          VALID_RSS_IPV6},
1007        {INVALID_RSS_ATTR,                              0}
1008};
1009
1010static bool
1011ice_any_invalid_rss_type(enum rte_eth_hash_function rss_func,
1012                         uint64_t rss_type, uint64_t allow_rss_type)
1013{
1014        uint32_t i;
1015
1016        /**
1017         * Check if l3/l4 SRC/DST_ONLY is set for SYMMETRIC_TOEPLITZ
1018         * hash function.
1019         */
1020        if (rss_func == RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ) {
1021                if (rss_type & (RTE_ETH_RSS_L3_SRC_ONLY | RTE_ETH_RSS_L3_DST_ONLY |
1022                    RTE_ETH_RSS_L4_SRC_ONLY | RTE_ETH_RSS_L4_DST_ONLY))
1023                        return true;
1024
1025                if (!(rss_type &
1026                   (RTE_ETH_RSS_IPV4 | RTE_ETH_RSS_IPV6 |
1027                    RTE_ETH_RSS_FRAG_IPV4 | RTE_ETH_RSS_FRAG_IPV6 |
1028                    RTE_ETH_RSS_NONFRAG_IPV4_UDP | RTE_ETH_RSS_NONFRAG_IPV6_UDP |
1029                    RTE_ETH_RSS_NONFRAG_IPV4_TCP | RTE_ETH_RSS_NONFRAG_IPV6_TCP |
1030                    RTE_ETH_RSS_NONFRAG_IPV4_SCTP | RTE_ETH_RSS_NONFRAG_IPV6_SCTP)))
1031                        return true;
1032        }
1033
1034        /* check invalid combination */
1035        for (i = 0; i < RTE_DIM(invalid_rss_comb); i++) {
1036                if (__builtin_popcountll(rss_type & invalid_rss_comb[i]) > 1)
1037                        return true;
1038        }
1039
1040        /* check invalid RSS attribute */
1041        for (i = 0; i < RTE_DIM(rss_attr_to_valid_type); i++) {
1042                struct rss_attr_type *rat = &rss_attr_to_valid_type[i];
1043
1044                if (rat->attr & rss_type && !(rat->type & rss_type))
1045                        return true;
1046        }
1047
1048        /* check not allowed RSS type */
1049        rss_type &= ~VALID_RSS_ATTR;
1050
1051        return ((rss_type & allow_rss_type) != rss_type);
1052}
1053
1054static int
1055ice_hash_parse_action(struct ice_pattern_match_item *pattern_match_item,
1056                const struct rte_flow_action actions[],
1057                uint64_t pattern_hint, struct ice_rss_meta *rss_meta,
1058                struct rte_flow_error *error)
1059{
1060        struct ice_rss_hash_cfg *cfg = pattern_match_item->meta;
1061        enum rte_flow_action_type action_type;
1062        const struct rte_flow_action_rss *rss;
1063        const struct rte_flow_action *action;
1064        uint64_t rss_type;
1065
1066        /* Supported action is RSS. */
1067        for (action = actions; action->type !=
1068                RTE_FLOW_ACTION_TYPE_END; action++) {
1069                action_type = action->type;
1070                switch (action_type) {
1071                case RTE_FLOW_ACTION_TYPE_RSS:
1072                        rss = action->conf;
1073                        rss_type = rss->types;
1074
1075                        /* Check hash function and save it to rss_meta. */
1076                        if (pattern_match_item->pattern_list !=
1077                            pattern_empty && rss->func ==
1078                            RTE_ETH_HASH_FUNCTION_SIMPLE_XOR) {
1079                                return rte_flow_error_set(error, ENOTSUP,
1080                                        RTE_FLOW_ERROR_TYPE_ACTION, action,
1081                                        "Not supported flow");
1082                        } else if (rss->func ==
1083                                   RTE_ETH_HASH_FUNCTION_SIMPLE_XOR){
1084                                rss_meta->hash_function =
1085                                RTE_ETH_HASH_FUNCTION_SIMPLE_XOR;
1086                                return 0;
1087                        } else if (rss->func ==
1088                                   RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ) {
1089                                rss_meta->hash_function =
1090                                RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ;
1091                                if (pattern_hint == ICE_PHINT_RAW)
1092                                        rss_meta->raw.symm = true;
1093                                else
1094                                        cfg->symm = true;
1095                        }
1096
1097                        if (rss->level)
1098                                return rte_flow_error_set(error, ENOTSUP,
1099                                        RTE_FLOW_ERROR_TYPE_ACTION, action,
1100                                        "a nonzero RSS encapsulation level is not supported");
1101
1102                        if (rss->key_len)
1103                                return rte_flow_error_set(error, ENOTSUP,
1104                                        RTE_FLOW_ERROR_TYPE_ACTION, action,
1105                                        "a nonzero RSS key_len is not supported");
1106
1107                        if (rss->queue)
1108                                return rte_flow_error_set(error, ENOTSUP,
1109                                        RTE_FLOW_ERROR_TYPE_ACTION, action,
1110                                        "a non-NULL RSS queue is not supported");
1111
1112                        /* If pattern type is raw, no need to refine rss type */
1113                        if (pattern_hint == ICE_PHINT_RAW)
1114                                break;
1115
1116                        /**
1117                         * Check simultaneous use of SRC_ONLY and DST_ONLY
1118                         * of the same level.
1119                         */
1120                        rss_type = rte_eth_rss_hf_refine(rss_type);
1121
1122                        if (ice_any_invalid_rss_type(rss->func, rss_type,
1123                                        pattern_match_item->input_set_mask_o))
1124                                return rte_flow_error_set(error, ENOTSUP,
1125                                        RTE_FLOW_ERROR_TYPE_ACTION,
1126                                        action, "RSS type not supported");
1127
1128                        rss_meta->cfg = *cfg;
1129                        ice_refine_hash_cfg(&rss_meta->cfg,
1130                                            rss_type, pattern_hint);
1131                        break;
1132                case RTE_FLOW_ACTION_TYPE_END:
1133                        break;
1134
1135                default:
1136                        rte_flow_error_set(error, EINVAL,
1137                                        RTE_FLOW_ERROR_TYPE_ACTION, action,
1138                                        "Invalid action.");
1139                        return -rte_errno;
1140                }
1141        }
1142
1143        return 0;
1144}
1145
1146static int
1147ice_hash_parse_pattern_action(__rte_unused struct ice_adapter *ad,
1148                        struct ice_pattern_match_item *array,
1149                        uint32_t array_len,
1150                        const struct rte_flow_item pattern[],
1151                        const struct rte_flow_action actions[],
1152                        uint32_t priority,
1153                        void **meta,
1154                        struct rte_flow_error *error)
1155{
1156        int ret = 0;
1157        struct ice_pattern_match_item *pattern_match_item;
1158        struct ice_rss_meta *rss_meta_ptr;
1159        uint64_t phint = ICE_PHINT_NONE;
1160
1161        if (priority >= 1)
1162                return -rte_errno;
1163
1164        rss_meta_ptr = rte_zmalloc(NULL, sizeof(*rss_meta_ptr), 0);
1165        if (!rss_meta_ptr) {
1166                rte_flow_error_set(error, EINVAL,
1167                                RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
1168                                "No memory for rss_meta_ptr");
1169                return -ENOMEM;
1170        }
1171
1172        /* Check rss supported pattern and find matched pattern. */
1173        pattern_match_item = ice_search_pattern_match_item(ad, pattern, array,
1174                                                           array_len, error);
1175        if (!pattern_match_item) {
1176                ret = -rte_errno;
1177                goto error;
1178        }
1179
1180        ret = ice_hash_parse_pattern(pattern, &phint, error);
1181        if (ret)
1182                goto error;
1183
1184        if (phint == ICE_PHINT_RAW) {
1185                rss_meta_ptr->raw.raw_ena = true;
1186                ret = ice_hash_parse_raw_pattern(ad, pattern, rss_meta_ptr);
1187                if (ret) {
1188                        rte_flow_error_set(error, EINVAL,
1189                                           RTE_FLOW_ERROR_TYPE_ITEM, NULL,
1190                                           "Parse raw pattern failed");
1191                        goto error;
1192                }
1193        }
1194
1195        /* Check rss action. */
1196        ret = ice_hash_parse_action(pattern_match_item, actions, phint,
1197                                    rss_meta_ptr, error);
1198
1199error:
1200        if (!ret && meta)
1201                *meta = rss_meta_ptr;
1202        else
1203                rte_free(rss_meta_ptr);
1204        rte_free(pattern_match_item);
1205
1206        return ret;
1207}
1208
1209static int
1210ice_hash_add_raw_cfg(struct ice_adapter *ad,
1211                struct ice_rss_raw_cfg *cfg, u16 vsi_handle)
1212{
1213        struct ice_parser_profile *prof = &cfg->prof;
1214        struct ice_rss_prof_info *rss_prof;
1215        struct ice_hw *hw = &ad->hw;
1216        int i, ptg, ret;
1217        u64 id;
1218
1219        id = (u64)ice_find_first_bit(prof->ptypes, UINT16_MAX);
1220
1221        ptg = hw->blk[ICE_BLK_RSS].xlt1.t[id];
1222        rss_prof = &ad->rss_prof_info[ptg];
1223        /* check if ptg already has profile */
1224        if (rss_prof->prof.fv_num) {
1225                for (i = 0; i < ICE_MAX_FV_WORDS; i++) {
1226                        if (rss_prof->prof.fv[i].proto_id !=
1227                            prof->fv[i].proto_id ||
1228                            rss_prof->prof.fv[i].offset !=
1229                            prof->fv[i].offset)
1230                                break;
1231                }
1232
1233                /* current profile is matched, check symmetric hash */
1234                if (i == ICE_MAX_FV_WORDS) {
1235                        if (rss_prof->symm != cfg->symm)
1236                                goto update_symm;
1237
1238                        return 0;
1239                }
1240
1241                /* current profile is not matched, remove it */
1242                ret = ice_rem_prof_id_flow(hw, ICE_BLK_RSS,
1243                                           ice_get_hw_vsi_num(hw, vsi_handle),
1244                                           id);
1245                if (ret) {
1246                        PMD_DRV_LOG(ERR, "remove RSS flow failed\n");
1247                        return ret;
1248                }
1249
1250                ret = ice_rem_prof(hw, ICE_BLK_RSS, id);
1251                if (ret) {
1252                        PMD_DRV_LOG(ERR, "remove RSS profile failed\n");
1253                        return ret;
1254                }
1255        }
1256
1257        /* add new profile */
1258        ret = ice_flow_set_hw_prof(hw, vsi_handle, 0, prof, ICE_BLK_RSS);
1259        if (ret) {
1260                PMD_DRV_LOG(ERR, "HW profile add failed\n");
1261                return ret;
1262        }
1263
1264        rss_prof->symm = cfg->symm;
1265        ice_memcpy(&rss_prof->prof, prof,
1266                   sizeof(struct ice_parser_profile),
1267                   ICE_NONDMA_TO_NONDMA);
1268
1269update_symm:
1270        ice_rss_update_raw_symm(hw, cfg, id);
1271        return 0;
1272}
1273
1274static int
1275ice_hash_create(struct ice_adapter *ad,
1276                struct rte_flow *flow,
1277                void *meta,
1278                struct rte_flow_error *error)
1279{
1280        struct ice_pf *pf = &ad->pf;
1281        struct ice_hw *hw = ICE_PF_TO_HW(pf);
1282        struct ice_vsi *vsi = pf->main_vsi;
1283        int ret;
1284        uint32_t reg;
1285        struct ice_hash_flow_cfg *filter_ptr;
1286        struct ice_rss_meta *rss_meta = (struct ice_rss_meta *)meta;
1287        uint8_t hash_function = rss_meta->hash_function;
1288
1289        filter_ptr = rte_zmalloc("ice_rss_filter",
1290                                sizeof(struct ice_hash_flow_cfg), 0);
1291        if (!filter_ptr) {
1292                rte_flow_error_set(error, EINVAL,
1293                                RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
1294                                "No memory for filter_ptr");
1295                return -ENOMEM;
1296        }
1297
1298        if (hash_function == RTE_ETH_HASH_FUNCTION_SIMPLE_XOR) {
1299                /* Enable registers for simple_xor hash function. */
1300                reg = ICE_READ_REG(hw, VSIQF_HASH_CTL(vsi->vsi_id));
1301                reg = (reg & (~VSIQF_HASH_CTL_HASH_SCHEME_M)) |
1302                        (2 << VSIQF_HASH_CTL_HASH_SCHEME_S);
1303                ICE_WRITE_REG(hw, VSIQF_HASH_CTL(vsi->vsi_id), reg);
1304
1305                filter_ptr->simple_xor = 1;
1306
1307                goto out;
1308        } else {
1309                if (rss_meta->raw.raw_ena) {
1310                        memcpy(&filter_ptr->rss_cfg.raw, &rss_meta->raw,
1311                               sizeof(struct ice_rss_raw_cfg));
1312                        ret = ice_hash_add_raw_cfg(ad, &rss_meta->raw,
1313                                                   pf->main_vsi->idx);
1314                        if (ret) {
1315                                rte_flow_error_set(error, EINVAL,
1316                                                   RTE_FLOW_ERROR_TYPE_HANDLE,
1317                                                   NULL,
1318                                                   "rss flow create fail");
1319                                goto error;
1320                        }
1321                } else {
1322                        memcpy(&filter_ptr->rss_cfg.hash, &rss_meta->cfg,
1323                               sizeof(struct ice_rss_hash_cfg));
1324                        ret = ice_add_rss_cfg_wrap(pf, vsi->idx,
1325                                                   &filter_ptr->rss_cfg.hash);
1326                        if (ret) {
1327                                rte_flow_error_set(error, EINVAL,
1328                                                   RTE_FLOW_ERROR_TYPE_HANDLE,
1329                                                   NULL,
1330                                                   "rss flow create fail");
1331                                goto error;
1332                        }
1333                }
1334        }
1335
1336out:
1337        flow->rule = filter_ptr;
1338        rte_free(meta);
1339        return 0;
1340
1341error:
1342        rte_free(filter_ptr);
1343        rte_free(meta);
1344        return -rte_errno;
1345}
1346
1347static int
1348ice_hash_rem_raw_cfg(struct ice_adapter *ad,
1349                        struct ice_parser_profile *prof,
1350                    u16 vsi_handle)
1351{
1352        struct ice_hw *hw = &ad->hw;
1353        int ptg, ret;
1354        u16 vsig;
1355        u64 id;
1356
1357        id = (u64)ice_find_first_bit(prof->ptypes, 0xFFFF);
1358
1359        ptg = hw->blk[ICE_BLK_RSS].xlt1.t[id];
1360
1361        memset(&ad->rss_prof_info[ptg], 0,
1362                sizeof(struct ice_rss_prof_info));
1363
1364        /* check if vsig is already removed */
1365        ret = ice_vsig_find_vsi(hw, ICE_BLK_RSS,
1366                ice_get_hw_vsi_num(hw, vsi_handle), &vsig);
1367        if (!ret && vsig) {
1368                ret = ice_rem_prof_id_flow(hw, ICE_BLK_RSS,
1369                                           ice_get_hw_vsi_num(hw, vsi_handle),
1370                                           id);
1371                if (ret)
1372                        goto err;
1373
1374                ret = ice_rem_prof(hw, ICE_BLK_RSS, id);
1375                if (ret)
1376                        goto err;
1377        }
1378
1379        return 0;
1380
1381err:
1382        PMD_DRV_LOG(ERR, "HW profile remove failed\n");
1383        return ret;
1384}
1385
1386static int
1387ice_hash_destroy(struct ice_adapter *ad,
1388                struct rte_flow *flow,
1389                struct rte_flow_error *error)
1390{
1391        struct ice_pf *pf = ICE_DEV_PRIVATE_TO_PF(ad);
1392        struct ice_hw *hw = ICE_PF_TO_HW(pf);
1393        struct ice_vsi *vsi = pf->main_vsi;
1394        int ret;
1395        uint32_t reg;
1396        struct ice_hash_flow_cfg *filter_ptr;
1397
1398        filter_ptr = (struct ice_hash_flow_cfg *)flow->rule;
1399
1400        if (filter_ptr->simple_xor == 1) {
1401                /* Return to symmetric_toeplitz state. */
1402                reg = ICE_READ_REG(hw, VSIQF_HASH_CTL(vsi->vsi_id));
1403                reg = (reg & (~VSIQF_HASH_CTL_HASH_SCHEME_M)) |
1404                        (1 << VSIQF_HASH_CTL_HASH_SCHEME_S);
1405                ICE_WRITE_REG(hw, VSIQF_HASH_CTL(vsi->vsi_id), reg);
1406        } else {
1407                if (filter_ptr->rss_cfg.raw.raw_ena) {
1408                        ret =
1409                        ice_hash_rem_raw_cfg(ad, &filter_ptr->rss_cfg.raw.prof,
1410                                             pf->main_vsi->idx);
1411                        if (ret) {
1412                                rte_flow_error_set(error, EINVAL,
1413                                                   RTE_FLOW_ERROR_TYPE_HANDLE,
1414                                                   NULL,
1415                                                   "rss flow destroy fail");
1416                                goto error;
1417                        }
1418                } else {
1419                        ret = ice_rem_rss_cfg_wrap(pf, vsi->idx,
1420                                                   &filter_ptr->rss_cfg.hash);
1421                        /* Fixme: Ignore the error if a rule does not exist.
1422                         * Currently a rule for inputset change or symm turn
1423                         * on/off will overwrite an exist rule, while
1424                         * application still have 2 rte_flow handles.
1425                         **/
1426                        if (ret && ret != ICE_ERR_DOES_NOT_EXIST) {
1427                                rte_flow_error_set(error, EINVAL,
1428                                                   RTE_FLOW_ERROR_TYPE_HANDLE,
1429                                                   NULL,
1430                                                   "rss flow destroy fail");
1431                                goto error;
1432                        }
1433                }
1434        }
1435
1436        rte_free(filter_ptr);
1437        return 0;
1438
1439error:
1440        rte_free(filter_ptr);
1441        return -rte_errno;
1442}
1443
1444static void
1445ice_hash_uninit(struct ice_adapter *ad)
1446{
1447        if (ad->hw.dcf_enabled)
1448                return;
1449
1450        ice_unregister_parser(&ice_hash_parser, ad);
1451}
1452
1453static void
1454ice_hash_free(struct rte_flow *flow)
1455{
1456        rte_free(flow->rule);
1457}
1458