linux/drivers/net/ethernet/intel/ice/ice_flow.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/* Copyright (c) 2019, Intel Corporation. */
   3
   4#include "ice_common.h"
   5#include "ice_flow.h"
   6
   7/* Describe properties of a protocol header field */
   8struct ice_flow_field_info {
   9        enum ice_flow_seg_hdr hdr;
  10        s16 off;        /* Offset from start of a protocol header, in bits */
  11        u16 size;       /* Size of fields in bits */
  12        u16 mask;       /* 16-bit mask for field */
  13};
  14
  15#define ICE_FLOW_FLD_INFO(_hdr, _offset_bytes, _size_bytes) { \
  16        .hdr = _hdr, \
  17        .off = (_offset_bytes) * BITS_PER_BYTE, \
  18        .size = (_size_bytes) * BITS_PER_BYTE, \
  19        .mask = 0, \
  20}
  21
  22#define ICE_FLOW_FLD_INFO_MSK(_hdr, _offset_bytes, _size_bytes, _mask) { \
  23        .hdr = _hdr, \
  24        .off = (_offset_bytes) * BITS_PER_BYTE, \
  25        .size = (_size_bytes) * BITS_PER_BYTE, \
  26        .mask = _mask, \
  27}
  28
  29/* Table containing properties of supported protocol header fields */
  30static const
  31struct ice_flow_field_info ice_flds_info[ICE_FLOW_FIELD_IDX_MAX] = {
  32        /* Ether */
  33        /* ICE_FLOW_FIELD_IDX_ETH_DA */
  34        ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ETH, 0, ETH_ALEN),
  35        /* ICE_FLOW_FIELD_IDX_ETH_SA */
  36        ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ETH, ETH_ALEN, ETH_ALEN),
  37        /* ICE_FLOW_FIELD_IDX_S_VLAN */
  38        ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_VLAN, 12, sizeof(__be16)),
  39        /* ICE_FLOW_FIELD_IDX_C_VLAN */
  40        ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_VLAN, 14, sizeof(__be16)),
  41        /* ICE_FLOW_FIELD_IDX_ETH_TYPE */
  42        ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ETH, 0, sizeof(__be16)),
  43        /* IPv4 / IPv6 */
  44        /* ICE_FLOW_FIELD_IDX_IPV4_DSCP */
  45        ICE_FLOW_FLD_INFO_MSK(ICE_FLOW_SEG_HDR_IPV4, 0, 1, 0x00fc),
  46        /* ICE_FLOW_FIELD_IDX_IPV6_DSCP */
  47        ICE_FLOW_FLD_INFO_MSK(ICE_FLOW_SEG_HDR_IPV6, 0, 1, 0x0ff0),
  48        /* ICE_FLOW_FIELD_IDX_IPV4_TTL */
  49        ICE_FLOW_FLD_INFO_MSK(ICE_FLOW_SEG_HDR_NONE, 8, 1, 0xff00),
  50        /* ICE_FLOW_FIELD_IDX_IPV4_PROT */
  51        ICE_FLOW_FLD_INFO_MSK(ICE_FLOW_SEG_HDR_NONE, 8, 1, 0x00ff),
  52        /* ICE_FLOW_FIELD_IDX_IPV6_TTL */
  53        ICE_FLOW_FLD_INFO_MSK(ICE_FLOW_SEG_HDR_NONE, 6, 1, 0x00ff),
  54        /* ICE_FLOW_FIELD_IDX_IPV6_PROT */
  55        ICE_FLOW_FLD_INFO_MSK(ICE_FLOW_SEG_HDR_NONE, 6, 1, 0xff00),
  56        /* ICE_FLOW_FIELD_IDX_IPV4_SA */
  57        ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV4, 12, sizeof(struct in_addr)),
  58        /* ICE_FLOW_FIELD_IDX_IPV4_DA */
  59        ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV4, 16, sizeof(struct in_addr)),
  60        /* ICE_FLOW_FIELD_IDX_IPV6_SA */
  61        ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV6, 8, sizeof(struct in6_addr)),
  62        /* ICE_FLOW_FIELD_IDX_IPV6_DA */
  63        ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV6, 24, sizeof(struct in6_addr)),
  64        /* Transport */
  65        /* ICE_FLOW_FIELD_IDX_TCP_SRC_PORT */
  66        ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_TCP, 0, sizeof(__be16)),
  67        /* ICE_FLOW_FIELD_IDX_TCP_DST_PORT */
  68        ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_TCP, 2, sizeof(__be16)),
  69        /* ICE_FLOW_FIELD_IDX_UDP_SRC_PORT */
  70        ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_UDP, 0, sizeof(__be16)),
  71        /* ICE_FLOW_FIELD_IDX_UDP_DST_PORT */
  72        ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_UDP, 2, sizeof(__be16)),
  73        /* ICE_FLOW_FIELD_IDX_SCTP_SRC_PORT */
  74        ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_SCTP, 0, sizeof(__be16)),
  75        /* ICE_FLOW_FIELD_IDX_SCTP_DST_PORT */
  76        ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_SCTP, 2, sizeof(__be16)),
  77        /* ICE_FLOW_FIELD_IDX_TCP_FLAGS */
  78        ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_TCP, 13, 1),
  79        /* ARP */
  80        /* ICE_FLOW_FIELD_IDX_ARP_SIP */
  81        ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ARP, 14, sizeof(struct in_addr)),
  82        /* ICE_FLOW_FIELD_IDX_ARP_DIP */
  83        ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ARP, 24, sizeof(struct in_addr)),
  84        /* ICE_FLOW_FIELD_IDX_ARP_SHA */
  85        ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ARP, 8, ETH_ALEN),
  86        /* ICE_FLOW_FIELD_IDX_ARP_DHA */
  87        ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ARP, 18, ETH_ALEN),
  88        /* ICE_FLOW_FIELD_IDX_ARP_OP */
  89        ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ARP, 6, sizeof(__be16)),
  90        /* ICMP */
  91        /* ICE_FLOW_FIELD_IDX_ICMP_TYPE */
  92        ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ICMP, 0, 1),
  93        /* ICE_FLOW_FIELD_IDX_ICMP_CODE */
  94        ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ICMP, 1, 1),
  95        /* GRE */
  96        /* ICE_FLOW_FIELD_IDX_GRE_KEYID */
  97        ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_GRE, 12,
  98                          sizeof_field(struct gre_full_hdr, key)),
  99        /* GTP */
 100        /* ICE_FLOW_FIELD_IDX_GTPC_TEID */
 101        ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_GTPC_TEID, 12, sizeof(__be32)),
 102        /* ICE_FLOW_FIELD_IDX_GTPU_IP_TEID */
 103        ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_GTPU_IP, 12, sizeof(__be32)),
 104        /* ICE_FLOW_FIELD_IDX_GTPU_EH_TEID */
 105        ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_GTPU_EH, 12, sizeof(__be32)),
 106        /* ICE_FLOW_FIELD_IDX_GTPU_EH_QFI */
 107        ICE_FLOW_FLD_INFO_MSK(ICE_FLOW_SEG_HDR_GTPU_EH, 22, sizeof(__be16),
 108                              0x3f00),
 109        /* ICE_FLOW_FIELD_IDX_GTPU_UP_TEID */
 110        ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_GTPU_UP, 12, sizeof(__be32)),
 111        /* ICE_FLOW_FIELD_IDX_GTPU_DWN_TEID */
 112        ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_GTPU_DWN, 12, sizeof(__be32)),
 113        /* PPPoE */
 114        /* ICE_FLOW_FIELD_IDX_PPPOE_SESS_ID */
 115        ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_PPPOE, 2, sizeof(__be16)),
 116        /* PFCP */
 117        /* ICE_FLOW_FIELD_IDX_PFCP_SEID */
 118        ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_PFCP_SESSION, 12, sizeof(__be64)),
 119        /* L2TPv3 */
 120        /* ICE_FLOW_FIELD_IDX_L2TPV3_SESS_ID */
 121        ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_L2TPV3, 0, sizeof(__be32)),
 122        /* ESP */
 123        /* ICE_FLOW_FIELD_IDX_ESP_SPI */
 124        ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ESP, 0, sizeof(__be32)),
 125        /* AH */
 126        /* ICE_FLOW_FIELD_IDX_AH_SPI */
 127        ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_AH, 4, sizeof(__be32)),
 128        /* NAT_T_ESP */
 129        /* ICE_FLOW_FIELD_IDX_NAT_T_ESP_SPI */
 130        ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_NAT_T_ESP, 8, sizeof(__be32)),
 131};
 132
 133/* Bitmaps indicating relevant packet types for a particular protocol header
 134 *
 135 * Packet types for packets with an Outer/First/Single MAC header
 136 */
 137static const u32 ice_ptypes_mac_ofos[] = {
 138        0xFDC00846, 0xBFBF7F7E, 0xF70001DF, 0xFEFDFDFB,
 139        0x0000077E, 0x00000000, 0x00000000, 0x00000000,
 140        0x00400000, 0x03FFF000, 0x7FFFFFE0, 0x00000000,
 141        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 142        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 143        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 144        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 145        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 146};
 147
 148/* Packet types for packets with an Innermost/Last MAC VLAN header */
 149static const u32 ice_ptypes_macvlan_il[] = {
 150        0x00000000, 0xBC000000, 0x000001DF, 0xF0000000,
 151        0x0000077E, 0x00000000, 0x00000000, 0x00000000,
 152        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 153        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 154        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 155        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 156        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 157        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 158};
 159
 160/* Packet types for packets with an Outer/First/Single IPv4 header, does NOT
 161 * include IPv4 other PTYPEs
 162 */
 163static const u32 ice_ptypes_ipv4_ofos[] = {
 164        0x1DC00000, 0x04000800, 0x00000000, 0x00000000,
 165        0x00000000, 0x00000155, 0x00000000, 0x00000000,
 166        0x00000000, 0x000FC000, 0x00000000, 0x00000000,
 167        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 168        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 169        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 170        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 171        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 172};
 173
 174/* Packet types for packets with an Outer/First/Single IPv4 header, includes
 175 * IPv4 other PTYPEs
 176 */
 177static const u32 ice_ptypes_ipv4_ofos_all[] = {
 178        0x1DC00000, 0x04000800, 0x00000000, 0x00000000,
 179        0x00000000, 0x00000155, 0x00000000, 0x00000000,
 180        0x00000000, 0x000FC000, 0x83E0F800, 0x00000101,
 181        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 182        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 183        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 184        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 185        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 186};
 187
 188/* Packet types for packets with an Innermost/Last IPv4 header */
 189static const u32 ice_ptypes_ipv4_il[] = {
 190        0xE0000000, 0xB807700E, 0x80000003, 0xE01DC03B,
 191        0x0000000E, 0x00000000, 0x00000000, 0x00000000,
 192        0x00000000, 0x00000000, 0x001FF800, 0x00000000,
 193        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 194        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 195        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 196        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 197        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 198};
 199
 200/* Packet types for packets with an Outer/First/Single IPv6 header, does NOT
 201 * include IPv6 other PTYPEs
 202 */
 203static const u32 ice_ptypes_ipv6_ofos[] = {
 204        0x00000000, 0x00000000, 0x77000000, 0x10002000,
 205        0x00000000, 0x000002AA, 0x00000000, 0x00000000,
 206        0x00000000, 0x03F00000, 0x00000000, 0x00000000,
 207        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 208        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 209        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 210        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 211        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 212};
 213
 214/* Packet types for packets with an Outer/First/Single IPv6 header, includes
 215 * IPv6 other PTYPEs
 216 */
 217static const u32 ice_ptypes_ipv6_ofos_all[] = {
 218        0x00000000, 0x00000000, 0x77000000, 0x10002000,
 219        0x00000000, 0x000002AA, 0x00000000, 0x00000000,
 220        0x00080F00, 0x03F00000, 0x7C1F0000, 0x00000206,
 221        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 222        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 223        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 224        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 225        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 226};
 227
 228/* Packet types for packets with an Innermost/Last IPv6 header */
 229static const u32 ice_ptypes_ipv6_il[] = {
 230        0x00000000, 0x03B80770, 0x000001DC, 0x0EE00000,
 231        0x00000770, 0x00000000, 0x00000000, 0x00000000,
 232        0x00000000, 0x00000000, 0x7FE00000, 0x00000000,
 233        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 234        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 235        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 236        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 237        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 238};
 239
 240/* Packet types for packets with an Outer/First/Single IPv4 header - no L4 */
 241static const u32 ice_ptypes_ipv4_ofos_no_l4[] = {
 242        0x10C00000, 0x04000800, 0x00000000, 0x00000000,
 243        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 244        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 245        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 246        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 247        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 248        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 249        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 250};
 251
 252/* Packet types for packets with an Outermost/First ARP header */
 253static const u32 ice_ptypes_arp_of[] = {
 254        0x00000800, 0x00000000, 0x00000000, 0x00000000,
 255        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 256        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 257        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 258        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 259        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 260        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 261        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 262};
 263
 264/* Packet types for packets with an Innermost/Last IPv4 header - no L4 */
 265static const u32 ice_ptypes_ipv4_il_no_l4[] = {
 266        0x60000000, 0x18043008, 0x80000002, 0x6010c021,
 267        0x00000008, 0x00000000, 0x00000000, 0x00000000,
 268        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 269        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 270        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 271        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 272        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 273        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 274};
 275
 276/* Packet types for packets with an Outer/First/Single IPv6 header - no L4 */
 277static const u32 ice_ptypes_ipv6_ofos_no_l4[] = {
 278        0x00000000, 0x00000000, 0x43000000, 0x10002000,
 279        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 280        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 281        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 282        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 283        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 284        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 285        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 286};
 287
 288/* Packet types for packets with an Innermost/Last IPv6 header - no L4 */
 289static const u32 ice_ptypes_ipv6_il_no_l4[] = {
 290        0x00000000, 0x02180430, 0x0000010c, 0x086010c0,
 291        0x00000430, 0x00000000, 0x00000000, 0x00000000,
 292        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 293        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 294        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 295        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 296        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 297        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 298};
 299
 300/* UDP Packet types for non-tunneled packets or tunneled
 301 * packets with inner UDP.
 302 */
 303static const u32 ice_ptypes_udp_il[] = {
 304        0x81000000, 0x20204040, 0x04000010, 0x80810102,
 305        0x00000040, 0x00000000, 0x00000000, 0x00000000,
 306        0x00000000, 0x00410000, 0x90842000, 0x00000007,
 307        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 308        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 309        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 310        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 311        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 312};
 313
 314/* Packet types for packets with an Innermost/Last TCP header */
 315static const u32 ice_ptypes_tcp_il[] = {
 316        0x04000000, 0x80810102, 0x10000040, 0x02040408,
 317        0x00000102, 0x00000000, 0x00000000, 0x00000000,
 318        0x00000000, 0x00820000, 0x21084000, 0x00000000,
 319        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 320        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 321        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 322        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 323        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 324};
 325
 326/* Packet types for packets with an Innermost/Last SCTP header */
 327static const u32 ice_ptypes_sctp_il[] = {
 328        0x08000000, 0x01020204, 0x20000081, 0x04080810,
 329        0x00000204, 0x00000000, 0x00000000, 0x00000000,
 330        0x00000000, 0x01040000, 0x00000000, 0x00000000,
 331        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 332        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 333        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 334        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 335        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 336};
 337
 338/* Packet types for packets with an Outermost/First ICMP header */
 339static const u32 ice_ptypes_icmp_of[] = {
 340        0x10000000, 0x00000000, 0x00000000, 0x00000000,
 341        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 342        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 343        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 344        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 345        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 346        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 347        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 348};
 349
 350/* Packet types for packets with an Innermost/Last ICMP header */
 351static const u32 ice_ptypes_icmp_il[] = {
 352        0x00000000, 0x02040408, 0x40000102, 0x08101020,
 353        0x00000408, 0x00000000, 0x00000000, 0x00000000,
 354        0x00000000, 0x00000000, 0x42108000, 0x00000000,
 355        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 356        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 357        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 358        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 359        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 360};
 361
 362/* Packet types for packets with an Outermost/First GRE header */
 363static const u32 ice_ptypes_gre_of[] = {
 364        0x00000000, 0xBFBF7800, 0x000001DF, 0xFEFDE000,
 365        0x0000017E, 0x00000000, 0x00000000, 0x00000000,
 366        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 367        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 368        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 369        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 370        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 371        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 372};
 373
 374/* Packet types for packets with an Innermost/Last MAC header */
 375static const u32 ice_ptypes_mac_il[] = {
 376        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 377        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 378        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 379        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 380        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 381        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 382        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 383        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 384};
 385
 386/* Packet types for GTPC */
 387static const u32 ice_ptypes_gtpc[] = {
 388        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 389        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 390        0x00000000, 0x00000000, 0x00000180, 0x00000000,
 391        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 392        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 393        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 394        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 395        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 396};
 397
 398/* Packet types for GTPC with TEID */
 399static const u32 ice_ptypes_gtpc_tid[] = {
 400        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 401        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 402        0x00000000, 0x00000000, 0x00000060, 0x00000000,
 403        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 404        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 405        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 406        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 407        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 408};
 409
 410/* Packet types for GTPU */
 411static const struct ice_ptype_attributes ice_attr_gtpu_eh[] = {
 412        { ICE_MAC_IPV4_GTPU_IPV4_FRAG,    ICE_PTYPE_ATTR_GTP_PDU_EH },
 413        { ICE_MAC_IPV4_GTPU_IPV4_PAY,     ICE_PTYPE_ATTR_GTP_PDU_EH },
 414        { ICE_MAC_IPV4_GTPU_IPV4_UDP_PAY, ICE_PTYPE_ATTR_GTP_PDU_EH },
 415        { ICE_MAC_IPV4_GTPU_IPV4_TCP,     ICE_PTYPE_ATTR_GTP_PDU_EH },
 416        { ICE_MAC_IPV4_GTPU_IPV4_ICMP,    ICE_PTYPE_ATTR_GTP_PDU_EH },
 417        { ICE_MAC_IPV6_GTPU_IPV4_FRAG,    ICE_PTYPE_ATTR_GTP_PDU_EH },
 418        { ICE_MAC_IPV6_GTPU_IPV4_PAY,     ICE_PTYPE_ATTR_GTP_PDU_EH },
 419        { ICE_MAC_IPV6_GTPU_IPV4_UDP_PAY, ICE_PTYPE_ATTR_GTP_PDU_EH },
 420        { ICE_MAC_IPV6_GTPU_IPV4_TCP,     ICE_PTYPE_ATTR_GTP_PDU_EH },
 421        { ICE_MAC_IPV6_GTPU_IPV4_ICMP,    ICE_PTYPE_ATTR_GTP_PDU_EH },
 422        { ICE_MAC_IPV4_GTPU_IPV6_FRAG,    ICE_PTYPE_ATTR_GTP_PDU_EH },
 423        { ICE_MAC_IPV4_GTPU_IPV6_PAY,     ICE_PTYPE_ATTR_GTP_PDU_EH },
 424        { ICE_MAC_IPV4_GTPU_IPV6_UDP_PAY, ICE_PTYPE_ATTR_GTP_PDU_EH },
 425        { ICE_MAC_IPV4_GTPU_IPV6_TCP,     ICE_PTYPE_ATTR_GTP_PDU_EH },
 426        { ICE_MAC_IPV4_GTPU_IPV6_ICMPV6,  ICE_PTYPE_ATTR_GTP_PDU_EH },
 427        { ICE_MAC_IPV6_GTPU_IPV6_FRAG,    ICE_PTYPE_ATTR_GTP_PDU_EH },
 428        { ICE_MAC_IPV6_GTPU_IPV6_PAY,     ICE_PTYPE_ATTR_GTP_PDU_EH },
 429        { ICE_MAC_IPV6_GTPU_IPV6_UDP_PAY, ICE_PTYPE_ATTR_GTP_PDU_EH },
 430        { ICE_MAC_IPV6_GTPU_IPV6_TCP,     ICE_PTYPE_ATTR_GTP_PDU_EH },
 431        { ICE_MAC_IPV6_GTPU_IPV6_ICMPV6,  ICE_PTYPE_ATTR_GTP_PDU_EH },
 432};
 433
 434static const struct ice_ptype_attributes ice_attr_gtpu_down[] = {
 435        { ICE_MAC_IPV4_GTPU_IPV4_FRAG,    ICE_PTYPE_ATTR_GTP_DOWNLINK },
 436        { ICE_MAC_IPV4_GTPU_IPV4_PAY,     ICE_PTYPE_ATTR_GTP_DOWNLINK },
 437        { ICE_MAC_IPV4_GTPU_IPV4_UDP_PAY, ICE_PTYPE_ATTR_GTP_DOWNLINK },
 438        { ICE_MAC_IPV4_GTPU_IPV4_TCP,     ICE_PTYPE_ATTR_GTP_DOWNLINK },
 439        { ICE_MAC_IPV4_GTPU_IPV4_ICMP,    ICE_PTYPE_ATTR_GTP_DOWNLINK },
 440        { ICE_MAC_IPV6_GTPU_IPV4_FRAG,    ICE_PTYPE_ATTR_GTP_DOWNLINK },
 441        { ICE_MAC_IPV6_GTPU_IPV4_PAY,     ICE_PTYPE_ATTR_GTP_DOWNLINK },
 442        { ICE_MAC_IPV6_GTPU_IPV4_UDP_PAY, ICE_PTYPE_ATTR_GTP_DOWNLINK },
 443        { ICE_MAC_IPV6_GTPU_IPV4_TCP,     ICE_PTYPE_ATTR_GTP_DOWNLINK },
 444        { ICE_MAC_IPV6_GTPU_IPV4_ICMP,    ICE_PTYPE_ATTR_GTP_DOWNLINK },
 445        { ICE_MAC_IPV4_GTPU_IPV6_FRAG,    ICE_PTYPE_ATTR_GTP_DOWNLINK },
 446        { ICE_MAC_IPV4_GTPU_IPV6_PAY,     ICE_PTYPE_ATTR_GTP_DOWNLINK },
 447        { ICE_MAC_IPV4_GTPU_IPV6_UDP_PAY, ICE_PTYPE_ATTR_GTP_DOWNLINK },
 448        { ICE_MAC_IPV4_GTPU_IPV6_TCP,     ICE_PTYPE_ATTR_GTP_DOWNLINK },
 449        { ICE_MAC_IPV4_GTPU_IPV6_ICMPV6,  ICE_PTYPE_ATTR_GTP_DOWNLINK },
 450        { ICE_MAC_IPV6_GTPU_IPV6_FRAG,    ICE_PTYPE_ATTR_GTP_DOWNLINK },
 451        { ICE_MAC_IPV6_GTPU_IPV6_PAY,     ICE_PTYPE_ATTR_GTP_DOWNLINK },
 452        { ICE_MAC_IPV6_GTPU_IPV6_UDP_PAY, ICE_PTYPE_ATTR_GTP_DOWNLINK },
 453        { ICE_MAC_IPV6_GTPU_IPV6_TCP,     ICE_PTYPE_ATTR_GTP_DOWNLINK },
 454        { ICE_MAC_IPV6_GTPU_IPV6_ICMPV6,  ICE_PTYPE_ATTR_GTP_DOWNLINK },
 455};
 456
 457static const struct ice_ptype_attributes ice_attr_gtpu_up[] = {
 458        { ICE_MAC_IPV4_GTPU_IPV4_FRAG,    ICE_PTYPE_ATTR_GTP_UPLINK },
 459        { ICE_MAC_IPV4_GTPU_IPV4_PAY,     ICE_PTYPE_ATTR_GTP_UPLINK },
 460        { ICE_MAC_IPV4_GTPU_IPV4_UDP_PAY, ICE_PTYPE_ATTR_GTP_UPLINK },
 461        { ICE_MAC_IPV4_GTPU_IPV4_TCP,     ICE_PTYPE_ATTR_GTP_UPLINK },
 462        { ICE_MAC_IPV4_GTPU_IPV4_ICMP,    ICE_PTYPE_ATTR_GTP_UPLINK },
 463        { ICE_MAC_IPV6_GTPU_IPV4_FRAG,    ICE_PTYPE_ATTR_GTP_UPLINK },
 464        { ICE_MAC_IPV6_GTPU_IPV4_PAY,     ICE_PTYPE_ATTR_GTP_UPLINK },
 465        { ICE_MAC_IPV6_GTPU_IPV4_UDP_PAY, ICE_PTYPE_ATTR_GTP_UPLINK },
 466        { ICE_MAC_IPV6_GTPU_IPV4_TCP,     ICE_PTYPE_ATTR_GTP_UPLINK },
 467        { ICE_MAC_IPV6_GTPU_IPV4_ICMP,    ICE_PTYPE_ATTR_GTP_UPLINK },
 468        { ICE_MAC_IPV4_GTPU_IPV6_FRAG,    ICE_PTYPE_ATTR_GTP_UPLINK },
 469        { ICE_MAC_IPV4_GTPU_IPV6_PAY,     ICE_PTYPE_ATTR_GTP_UPLINK },
 470        { ICE_MAC_IPV4_GTPU_IPV6_UDP_PAY, ICE_PTYPE_ATTR_GTP_UPLINK },
 471        { ICE_MAC_IPV4_GTPU_IPV6_TCP,     ICE_PTYPE_ATTR_GTP_UPLINK },
 472        { ICE_MAC_IPV4_GTPU_IPV6_ICMPV6,  ICE_PTYPE_ATTR_GTP_UPLINK },
 473        { ICE_MAC_IPV6_GTPU_IPV6_FRAG,    ICE_PTYPE_ATTR_GTP_UPLINK },
 474        { ICE_MAC_IPV6_GTPU_IPV6_PAY,     ICE_PTYPE_ATTR_GTP_UPLINK },
 475        { ICE_MAC_IPV6_GTPU_IPV6_UDP_PAY, ICE_PTYPE_ATTR_GTP_UPLINK },
 476        { ICE_MAC_IPV6_GTPU_IPV6_TCP,     ICE_PTYPE_ATTR_GTP_UPLINK },
 477        { ICE_MAC_IPV6_GTPU_IPV6_ICMPV6,  ICE_PTYPE_ATTR_GTP_UPLINK },
 478};
 479
 480static const u32 ice_ptypes_gtpu[] = {
 481        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 482        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 483        0x00000000, 0x00000000, 0x7FFFFE00, 0x00000000,
 484        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 485        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 486        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 487        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 488        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 489};
 490
 491/* Packet types for PPPoE */
 492static const u32 ice_ptypes_pppoe[] = {
 493        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 494        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 495        0x00000000, 0x03ffe000, 0x00000000, 0x00000000,
 496        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 497        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 498        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 499        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 500        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 501};
 502
 503/* Packet types for packets with PFCP NODE header */
 504static const u32 ice_ptypes_pfcp_node[] = {
 505        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 506        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 507        0x00000000, 0x00000000, 0x80000000, 0x00000002,
 508        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 509        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 510        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 511        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 512        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 513};
 514
 515/* Packet types for packets with PFCP SESSION header */
 516static const u32 ice_ptypes_pfcp_session[] = {
 517        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 518        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 519        0x00000000, 0x00000000, 0x00000000, 0x00000005,
 520        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 521        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 522        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 523        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 524        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 525};
 526
 527/* Packet types for L2TPv3 */
 528static const u32 ice_ptypes_l2tpv3[] = {
 529        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 530        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 531        0x00000000, 0x00000000, 0x00000000, 0x00000300,
 532        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 533        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 534        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 535        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 536        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 537};
 538
 539/* Packet types for ESP */
 540static const u32 ice_ptypes_esp[] = {
 541        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 542        0x00000000, 0x00000003, 0x00000000, 0x00000000,
 543        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 544        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 545        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 546        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 547        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 548        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 549};
 550
 551/* Packet types for AH */
 552static const u32 ice_ptypes_ah[] = {
 553        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 554        0x00000000, 0x0000000C, 0x00000000, 0x00000000,
 555        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 556        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 557        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 558        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 559        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 560        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 561};
 562
 563/* Packet types for packets with NAT_T ESP header */
 564static const u32 ice_ptypes_nat_t_esp[] = {
 565        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 566        0x00000000, 0x00000030, 0x00000000, 0x00000000,
 567        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 568        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 569        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 570        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 571        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 572        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 573};
 574
 575static const u32 ice_ptypes_mac_non_ip_ofos[] = {
 576        0x00000846, 0x00000000, 0x00000000, 0x00000000,
 577        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 578        0x00400000, 0x03FFF000, 0x00000000, 0x00000000,
 579        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 580        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 581        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 582        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 583        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 584};
 585
 586/* Manage parameters and info. used during the creation of a flow profile */
 587struct ice_flow_prof_params {
 588        enum ice_block blk;
 589        u16 entry_length; /* # of bytes formatted entry will require */
 590        u8 es_cnt;
 591        struct ice_flow_prof *prof;
 592
 593        /* For ACL, the es[0] will have the data of ICE_RX_MDID_PKT_FLAGS_15_0
 594         * This will give us the direction flags.
 595         */
 596        struct ice_fv_word es[ICE_MAX_FV_WORDS];
 597        /* attributes can be used to add attributes to a particular PTYPE */
 598        const struct ice_ptype_attributes *attr;
 599        u16 attr_cnt;
 600
 601        u16 mask[ICE_MAX_FV_WORDS];
 602        DECLARE_BITMAP(ptypes, ICE_FLOW_PTYPE_MAX);
 603};
 604
 605#define ICE_FLOW_RSS_HDRS_INNER_MASK \
 606        (ICE_FLOW_SEG_HDR_PPPOE | ICE_FLOW_SEG_HDR_GTPC | \
 607        ICE_FLOW_SEG_HDR_GTPC_TEID | ICE_FLOW_SEG_HDR_GTPU | \
 608        ICE_FLOW_SEG_HDR_PFCP_SESSION | ICE_FLOW_SEG_HDR_L2TPV3 | \
 609        ICE_FLOW_SEG_HDR_ESP | ICE_FLOW_SEG_HDR_AH | \
 610        ICE_FLOW_SEG_HDR_NAT_T_ESP)
 611
 612#define ICE_FLOW_SEG_HDRS_L3_MASK       \
 613        (ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_IPV6 | ICE_FLOW_SEG_HDR_ARP)
 614#define ICE_FLOW_SEG_HDRS_L4_MASK       \
 615        (ICE_FLOW_SEG_HDR_ICMP | ICE_FLOW_SEG_HDR_TCP | ICE_FLOW_SEG_HDR_UDP | \
 616         ICE_FLOW_SEG_HDR_SCTP)
 617/* mask for L4 protocols that are NOT part of IPv4/6 OTHER PTYPE groups */
 618#define ICE_FLOW_SEG_HDRS_L4_MASK_NO_OTHER      \
 619        (ICE_FLOW_SEG_HDR_TCP | ICE_FLOW_SEG_HDR_UDP | ICE_FLOW_SEG_HDR_SCTP)
 620
 621/**
 622 * ice_flow_val_hdrs - validates packet segments for valid protocol headers
 623 * @segs: array of one or more packet segments that describe the flow
 624 * @segs_cnt: number of packet segments provided
 625 */
 626static int ice_flow_val_hdrs(struct ice_flow_seg_info *segs, u8 segs_cnt)
 627{
 628        u8 i;
 629
 630        for (i = 0; i < segs_cnt; i++) {
 631                /* Multiple L3 headers */
 632                if (segs[i].hdrs & ICE_FLOW_SEG_HDRS_L3_MASK &&
 633                    !is_power_of_2(segs[i].hdrs & ICE_FLOW_SEG_HDRS_L3_MASK))
 634                        return -EINVAL;
 635
 636                /* Multiple L4 headers */
 637                if (segs[i].hdrs & ICE_FLOW_SEG_HDRS_L4_MASK &&
 638                    !is_power_of_2(segs[i].hdrs & ICE_FLOW_SEG_HDRS_L4_MASK))
 639                        return -EINVAL;
 640        }
 641
 642        return 0;
 643}
 644
 645/* Sizes of fixed known protocol headers without header options */
 646#define ICE_FLOW_PROT_HDR_SZ_MAC        14
 647#define ICE_FLOW_PROT_HDR_SZ_MAC_VLAN   (ICE_FLOW_PROT_HDR_SZ_MAC + 2)
 648#define ICE_FLOW_PROT_HDR_SZ_IPV4       20
 649#define ICE_FLOW_PROT_HDR_SZ_IPV6       40
 650#define ICE_FLOW_PROT_HDR_SZ_ARP        28
 651#define ICE_FLOW_PROT_HDR_SZ_ICMP       8
 652#define ICE_FLOW_PROT_HDR_SZ_TCP        20
 653#define ICE_FLOW_PROT_HDR_SZ_UDP        8
 654#define ICE_FLOW_PROT_HDR_SZ_SCTP       12
 655
 656/**
 657 * ice_flow_calc_seg_sz - calculates size of a packet segment based on headers
 658 * @params: information about the flow to be processed
 659 * @seg: index of packet segment whose header size is to be determined
 660 */
 661static u16 ice_flow_calc_seg_sz(struct ice_flow_prof_params *params, u8 seg)
 662{
 663        u16 sz;
 664
 665        /* L2 headers */
 666        sz = (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_VLAN) ?
 667                ICE_FLOW_PROT_HDR_SZ_MAC_VLAN : ICE_FLOW_PROT_HDR_SZ_MAC;
 668
 669        /* L3 headers */
 670        if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_IPV4)
 671                sz += ICE_FLOW_PROT_HDR_SZ_IPV4;
 672        else if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_IPV6)
 673                sz += ICE_FLOW_PROT_HDR_SZ_IPV6;
 674        else if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_ARP)
 675                sz += ICE_FLOW_PROT_HDR_SZ_ARP;
 676        else if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDRS_L4_MASK)
 677                /* An L3 header is required if L4 is specified */
 678                return 0;
 679
 680        /* L4 headers */
 681        if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_ICMP)
 682                sz += ICE_FLOW_PROT_HDR_SZ_ICMP;
 683        else if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_TCP)
 684                sz += ICE_FLOW_PROT_HDR_SZ_TCP;
 685        else if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_UDP)
 686                sz += ICE_FLOW_PROT_HDR_SZ_UDP;
 687        else if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_SCTP)
 688                sz += ICE_FLOW_PROT_HDR_SZ_SCTP;
 689
 690        return sz;
 691}
 692
 693/**
 694 * ice_flow_proc_seg_hdrs - process protocol headers present in pkt segments
 695 * @params: information about the flow to be processed
 696 *
 697 * This function identifies the packet types associated with the protocol
 698 * headers being present in packet segments of the specified flow profile.
 699 */
 700static int ice_flow_proc_seg_hdrs(struct ice_flow_prof_params *params)
 701{
 702        struct ice_flow_prof *prof;
 703        u8 i;
 704
 705        memset(params->ptypes, 0xff, sizeof(params->ptypes));
 706
 707        prof = params->prof;
 708
 709        for (i = 0; i < params->prof->segs_cnt; i++) {
 710                const unsigned long *src;
 711                u32 hdrs;
 712
 713                hdrs = prof->segs[i].hdrs;
 714
 715                if (hdrs & ICE_FLOW_SEG_HDR_ETH) {
 716                        src = !i ? (const unsigned long *)ice_ptypes_mac_ofos :
 717                                (const unsigned long *)ice_ptypes_mac_il;
 718                        bitmap_and(params->ptypes, params->ptypes, src,
 719                                   ICE_FLOW_PTYPE_MAX);
 720                }
 721
 722                if (i && hdrs & ICE_FLOW_SEG_HDR_VLAN) {
 723                        src = (const unsigned long *)ice_ptypes_macvlan_il;
 724                        bitmap_and(params->ptypes, params->ptypes, src,
 725                                   ICE_FLOW_PTYPE_MAX);
 726                }
 727
 728                if (!i && hdrs & ICE_FLOW_SEG_HDR_ARP) {
 729                        bitmap_and(params->ptypes, params->ptypes,
 730                                   (const unsigned long *)ice_ptypes_arp_of,
 731                                   ICE_FLOW_PTYPE_MAX);
 732                }
 733
 734                if ((hdrs & ICE_FLOW_SEG_HDR_IPV4) &&
 735                    (hdrs & ICE_FLOW_SEG_HDR_IPV_OTHER)) {
 736                        src = i ? (const unsigned long *)ice_ptypes_ipv4_il :
 737                                (const unsigned long *)ice_ptypes_ipv4_ofos_all;
 738                        bitmap_and(params->ptypes, params->ptypes, src,
 739                                   ICE_FLOW_PTYPE_MAX);
 740                } else if ((hdrs & ICE_FLOW_SEG_HDR_IPV6) &&
 741                           (hdrs & ICE_FLOW_SEG_HDR_IPV_OTHER)) {
 742                        src = i ? (const unsigned long *)ice_ptypes_ipv6_il :
 743                                (const unsigned long *)ice_ptypes_ipv6_ofos_all;
 744                        bitmap_and(params->ptypes, params->ptypes, src,
 745                                   ICE_FLOW_PTYPE_MAX);
 746                } else if ((hdrs & ICE_FLOW_SEG_HDR_IPV4) &&
 747                           !(hdrs & ICE_FLOW_SEG_HDRS_L4_MASK_NO_OTHER)) {
 748                        src = !i ? (const unsigned long *)ice_ptypes_ipv4_ofos_no_l4 :
 749                                (const unsigned long *)ice_ptypes_ipv4_il_no_l4;
 750                        bitmap_and(params->ptypes, params->ptypes, src,
 751                                   ICE_FLOW_PTYPE_MAX);
 752                } else if (hdrs & ICE_FLOW_SEG_HDR_IPV4) {
 753                        src = !i ? (const unsigned long *)ice_ptypes_ipv4_ofos :
 754                                (const unsigned long *)ice_ptypes_ipv4_il;
 755                        bitmap_and(params->ptypes, params->ptypes, src,
 756                                   ICE_FLOW_PTYPE_MAX);
 757                } else if ((hdrs & ICE_FLOW_SEG_HDR_IPV6) &&
 758                           !(hdrs & ICE_FLOW_SEG_HDRS_L4_MASK_NO_OTHER)) {
 759                        src = !i ? (const unsigned long *)ice_ptypes_ipv6_ofos_no_l4 :
 760                                (const unsigned long *)ice_ptypes_ipv6_il_no_l4;
 761                        bitmap_and(params->ptypes, params->ptypes, src,
 762                                   ICE_FLOW_PTYPE_MAX);
 763                } else if (hdrs & ICE_FLOW_SEG_HDR_IPV6) {
 764                        src = !i ? (const unsigned long *)ice_ptypes_ipv6_ofos :
 765                                (const unsigned long *)ice_ptypes_ipv6_il;
 766                        bitmap_and(params->ptypes, params->ptypes, src,
 767                                   ICE_FLOW_PTYPE_MAX);
 768                }
 769
 770                if (hdrs & ICE_FLOW_SEG_HDR_ETH_NON_IP) {
 771                        src = (const unsigned long *)ice_ptypes_mac_non_ip_ofos;
 772                        bitmap_and(params->ptypes, params->ptypes, src,
 773                                   ICE_FLOW_PTYPE_MAX);
 774                } else if (hdrs & ICE_FLOW_SEG_HDR_PPPOE) {
 775                        src = (const unsigned long *)ice_ptypes_pppoe;
 776                        bitmap_and(params->ptypes, params->ptypes, src,
 777                                   ICE_FLOW_PTYPE_MAX);
 778                } else {
 779                        src = (const unsigned long *)ice_ptypes_pppoe;
 780                        bitmap_andnot(params->ptypes, params->ptypes, src,
 781                                      ICE_FLOW_PTYPE_MAX);
 782                }
 783
 784                if (hdrs & ICE_FLOW_SEG_HDR_UDP) {
 785                        src = (const unsigned long *)ice_ptypes_udp_il;
 786                        bitmap_and(params->ptypes, params->ptypes, src,
 787                                   ICE_FLOW_PTYPE_MAX);
 788                } else if (hdrs & ICE_FLOW_SEG_HDR_TCP) {
 789                        bitmap_and(params->ptypes, params->ptypes,
 790                                   (const unsigned long *)ice_ptypes_tcp_il,
 791                                   ICE_FLOW_PTYPE_MAX);
 792                } else if (hdrs & ICE_FLOW_SEG_HDR_SCTP) {
 793                        src = (const unsigned long *)ice_ptypes_sctp_il;
 794                        bitmap_and(params->ptypes, params->ptypes, src,
 795                                   ICE_FLOW_PTYPE_MAX);
 796                }
 797
 798                if (hdrs & ICE_FLOW_SEG_HDR_ICMP) {
 799                        src = !i ? (const unsigned long *)ice_ptypes_icmp_of :
 800                                (const unsigned long *)ice_ptypes_icmp_il;
 801                        bitmap_and(params->ptypes, params->ptypes, src,
 802                                   ICE_FLOW_PTYPE_MAX);
 803                } else if (hdrs & ICE_FLOW_SEG_HDR_GRE) {
 804                        if (!i) {
 805                                src = (const unsigned long *)ice_ptypes_gre_of;
 806                                bitmap_and(params->ptypes, params->ptypes,
 807                                           src, ICE_FLOW_PTYPE_MAX);
 808                        }
 809                } else if (hdrs & ICE_FLOW_SEG_HDR_GTPC) {
 810                        src = (const unsigned long *)ice_ptypes_gtpc;
 811                        bitmap_and(params->ptypes, params->ptypes, src,
 812                                   ICE_FLOW_PTYPE_MAX);
 813                } else if (hdrs & ICE_FLOW_SEG_HDR_GTPC_TEID) {
 814                        src = (const unsigned long *)ice_ptypes_gtpc_tid;
 815                        bitmap_and(params->ptypes, params->ptypes, src,
 816                                   ICE_FLOW_PTYPE_MAX);
 817                } else if (hdrs & ICE_FLOW_SEG_HDR_GTPU_DWN) {
 818                        src = (const unsigned long *)ice_ptypes_gtpu;
 819                        bitmap_and(params->ptypes, params->ptypes, src,
 820                                   ICE_FLOW_PTYPE_MAX);
 821
 822                        /* Attributes for GTP packet with downlink */
 823                        params->attr = ice_attr_gtpu_down;
 824                        params->attr_cnt = ARRAY_SIZE(ice_attr_gtpu_down);
 825                } else if (hdrs & ICE_FLOW_SEG_HDR_GTPU_UP) {
 826                        src = (const unsigned long *)ice_ptypes_gtpu;
 827                        bitmap_and(params->ptypes, params->ptypes, src,
 828                                   ICE_FLOW_PTYPE_MAX);
 829
 830                        /* Attributes for GTP packet with uplink */
 831                        params->attr = ice_attr_gtpu_up;
 832                        params->attr_cnt = ARRAY_SIZE(ice_attr_gtpu_up);
 833                } else if (hdrs & ICE_FLOW_SEG_HDR_GTPU_EH) {
 834                        src = (const unsigned long *)ice_ptypes_gtpu;
 835                        bitmap_and(params->ptypes, params->ptypes, src,
 836                                   ICE_FLOW_PTYPE_MAX);
 837
 838                        /* Attributes for GTP packet with Extension Header */
 839                        params->attr = ice_attr_gtpu_eh;
 840                        params->attr_cnt = ARRAY_SIZE(ice_attr_gtpu_eh);
 841                } else if (hdrs & ICE_FLOW_SEG_HDR_GTPU_IP) {
 842                        src = (const unsigned long *)ice_ptypes_gtpu;
 843                        bitmap_and(params->ptypes, params->ptypes, src,
 844                                   ICE_FLOW_PTYPE_MAX);
 845                } else if (hdrs & ICE_FLOW_SEG_HDR_L2TPV3) {
 846                        src = (const unsigned long *)ice_ptypes_l2tpv3;
 847                        bitmap_and(params->ptypes, params->ptypes, src,
 848                                   ICE_FLOW_PTYPE_MAX);
 849                } else if (hdrs & ICE_FLOW_SEG_HDR_ESP) {
 850                        src = (const unsigned long *)ice_ptypes_esp;
 851                        bitmap_and(params->ptypes, params->ptypes, src,
 852                                   ICE_FLOW_PTYPE_MAX);
 853                } else if (hdrs & ICE_FLOW_SEG_HDR_AH) {
 854                        src = (const unsigned long *)ice_ptypes_ah;
 855                        bitmap_and(params->ptypes, params->ptypes, src,
 856                                   ICE_FLOW_PTYPE_MAX);
 857                } else if (hdrs & ICE_FLOW_SEG_HDR_NAT_T_ESP) {
 858                        src = (const unsigned long *)ice_ptypes_nat_t_esp;
 859                        bitmap_and(params->ptypes, params->ptypes, src,
 860                                   ICE_FLOW_PTYPE_MAX);
 861                }
 862
 863                if (hdrs & ICE_FLOW_SEG_HDR_PFCP) {
 864                        if (hdrs & ICE_FLOW_SEG_HDR_PFCP_NODE)
 865                                src = (const unsigned long *)ice_ptypes_pfcp_node;
 866                        else
 867                                src = (const unsigned long *)ice_ptypes_pfcp_session;
 868
 869                        bitmap_and(params->ptypes, params->ptypes, src,
 870                                   ICE_FLOW_PTYPE_MAX);
 871                } else {
 872                        src = (const unsigned long *)ice_ptypes_pfcp_node;
 873                        bitmap_andnot(params->ptypes, params->ptypes, src,
 874                                      ICE_FLOW_PTYPE_MAX);
 875
 876                        src = (const unsigned long *)ice_ptypes_pfcp_session;
 877                        bitmap_andnot(params->ptypes, params->ptypes, src,
 878                                      ICE_FLOW_PTYPE_MAX);
 879                }
 880        }
 881
 882        return 0;
 883}
 884
 885/**
 886 * ice_flow_xtract_fld - Create an extraction sequence entry for the given field
 887 * @hw: pointer to the HW struct
 888 * @params: information about the flow to be processed
 889 * @seg: packet segment index of the field to be extracted
 890 * @fld: ID of field to be extracted
 891 * @match: bit field of all fields
 892 *
 893 * This function determines the protocol ID, offset, and size of the given
 894 * field. It then allocates one or more extraction sequence entries for the
 895 * given field, and fill the entries with protocol ID and offset information.
 896 */
 897static int
 898ice_flow_xtract_fld(struct ice_hw *hw, struct ice_flow_prof_params *params,
 899                    u8 seg, enum ice_flow_field fld, u64 match)
 900{
 901        enum ice_flow_field sib = ICE_FLOW_FIELD_IDX_MAX;
 902        enum ice_prot_id prot_id = ICE_PROT_ID_INVAL;
 903        u8 fv_words = hw->blk[params->blk].es.fvw;
 904        struct ice_flow_fld_info *flds;
 905        u16 cnt, ese_bits, i;
 906        u16 sib_mask = 0;
 907        u16 mask;
 908        u16 off;
 909
 910        flds = params->prof->segs[seg].fields;
 911
 912        switch (fld) {
 913        case ICE_FLOW_FIELD_IDX_ETH_DA:
 914        case ICE_FLOW_FIELD_IDX_ETH_SA:
 915        case ICE_FLOW_FIELD_IDX_S_VLAN:
 916        case ICE_FLOW_FIELD_IDX_C_VLAN:
 917                prot_id = seg == 0 ? ICE_PROT_MAC_OF_OR_S : ICE_PROT_MAC_IL;
 918                break;
 919        case ICE_FLOW_FIELD_IDX_ETH_TYPE:
 920                prot_id = seg == 0 ? ICE_PROT_ETYPE_OL : ICE_PROT_ETYPE_IL;
 921                break;
 922        case ICE_FLOW_FIELD_IDX_IPV4_DSCP:
 923                prot_id = seg == 0 ? ICE_PROT_IPV4_OF_OR_S : ICE_PROT_IPV4_IL;
 924                break;
 925        case ICE_FLOW_FIELD_IDX_IPV6_DSCP:
 926                prot_id = seg == 0 ? ICE_PROT_IPV6_OF_OR_S : ICE_PROT_IPV6_IL;
 927                break;
 928        case ICE_FLOW_FIELD_IDX_IPV4_TTL:
 929        case ICE_FLOW_FIELD_IDX_IPV4_PROT:
 930                prot_id = seg == 0 ? ICE_PROT_IPV4_OF_OR_S : ICE_PROT_IPV4_IL;
 931
 932                /* TTL and PROT share the same extraction seq. entry.
 933                 * Each is considered a sibling to the other in terms of sharing
 934                 * the same extraction sequence entry.
 935                 */
 936                if (fld == ICE_FLOW_FIELD_IDX_IPV4_TTL)
 937                        sib = ICE_FLOW_FIELD_IDX_IPV4_PROT;
 938                else if (fld == ICE_FLOW_FIELD_IDX_IPV4_PROT)
 939                        sib = ICE_FLOW_FIELD_IDX_IPV4_TTL;
 940
 941                /* If the sibling field is also included, that field's
 942                 * mask needs to be included.
 943                 */
 944                if (match & BIT(sib))
 945                        sib_mask = ice_flds_info[sib].mask;
 946                break;
 947        case ICE_FLOW_FIELD_IDX_IPV6_TTL:
 948        case ICE_FLOW_FIELD_IDX_IPV6_PROT:
 949                prot_id = seg == 0 ? ICE_PROT_IPV6_OF_OR_S : ICE_PROT_IPV6_IL;
 950
 951                /* TTL and PROT share the same extraction seq. entry.
 952                 * Each is considered a sibling to the other in terms of sharing
 953                 * the same extraction sequence entry.
 954                 */
 955                if (fld == ICE_FLOW_FIELD_IDX_IPV6_TTL)
 956                        sib = ICE_FLOW_FIELD_IDX_IPV6_PROT;
 957                else if (fld == ICE_FLOW_FIELD_IDX_IPV6_PROT)
 958                        sib = ICE_FLOW_FIELD_IDX_IPV6_TTL;
 959
 960                /* If the sibling field is also included, that field's
 961                 * mask needs to be included.
 962                 */
 963                if (match & BIT(sib))
 964                        sib_mask = ice_flds_info[sib].mask;
 965                break;
 966        case ICE_FLOW_FIELD_IDX_IPV4_SA:
 967        case ICE_FLOW_FIELD_IDX_IPV4_DA:
 968                prot_id = seg == 0 ? ICE_PROT_IPV4_OF_OR_S : ICE_PROT_IPV4_IL;
 969                break;
 970        case ICE_FLOW_FIELD_IDX_IPV6_SA:
 971        case ICE_FLOW_FIELD_IDX_IPV6_DA:
 972                prot_id = seg == 0 ? ICE_PROT_IPV6_OF_OR_S : ICE_PROT_IPV6_IL;
 973                break;
 974        case ICE_FLOW_FIELD_IDX_TCP_SRC_PORT:
 975        case ICE_FLOW_FIELD_IDX_TCP_DST_PORT:
 976        case ICE_FLOW_FIELD_IDX_TCP_FLAGS:
 977                prot_id = ICE_PROT_TCP_IL;
 978                break;
 979        case ICE_FLOW_FIELD_IDX_UDP_SRC_PORT:
 980        case ICE_FLOW_FIELD_IDX_UDP_DST_PORT:
 981                prot_id = ICE_PROT_UDP_IL_OR_S;
 982                break;
 983        case ICE_FLOW_FIELD_IDX_SCTP_SRC_PORT:
 984        case ICE_FLOW_FIELD_IDX_SCTP_DST_PORT:
 985                prot_id = ICE_PROT_SCTP_IL;
 986                break;
 987        case ICE_FLOW_FIELD_IDX_GTPC_TEID:
 988        case ICE_FLOW_FIELD_IDX_GTPU_IP_TEID:
 989        case ICE_FLOW_FIELD_IDX_GTPU_UP_TEID:
 990        case ICE_FLOW_FIELD_IDX_GTPU_DWN_TEID:
 991        case ICE_FLOW_FIELD_IDX_GTPU_EH_TEID:
 992        case ICE_FLOW_FIELD_IDX_GTPU_EH_QFI:
 993                /* GTP is accessed through UDP OF protocol */
 994                prot_id = ICE_PROT_UDP_OF;
 995                break;
 996        case ICE_FLOW_FIELD_IDX_PPPOE_SESS_ID:
 997                prot_id = ICE_PROT_PPPOE;
 998                break;
 999        case ICE_FLOW_FIELD_IDX_PFCP_SEID:
1000                prot_id = ICE_PROT_UDP_IL_OR_S;
1001                break;
1002        case ICE_FLOW_FIELD_IDX_L2TPV3_SESS_ID:
1003                prot_id = ICE_PROT_L2TPV3;
1004                break;
1005        case ICE_FLOW_FIELD_IDX_ESP_SPI:
1006                prot_id = ICE_PROT_ESP_F;
1007                break;
1008        case ICE_FLOW_FIELD_IDX_AH_SPI:
1009                prot_id = ICE_PROT_ESP_2;
1010                break;
1011        case ICE_FLOW_FIELD_IDX_NAT_T_ESP_SPI:
1012                prot_id = ICE_PROT_UDP_IL_OR_S;
1013                break;
1014        case ICE_FLOW_FIELD_IDX_ARP_SIP:
1015        case ICE_FLOW_FIELD_IDX_ARP_DIP:
1016        case ICE_FLOW_FIELD_IDX_ARP_SHA:
1017        case ICE_FLOW_FIELD_IDX_ARP_DHA:
1018        case ICE_FLOW_FIELD_IDX_ARP_OP:
1019                prot_id = ICE_PROT_ARP_OF;
1020                break;
1021        case ICE_FLOW_FIELD_IDX_ICMP_TYPE:
1022        case ICE_FLOW_FIELD_IDX_ICMP_CODE:
1023                /* ICMP type and code share the same extraction seq. entry */
1024                prot_id = (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_IPV4) ?
1025                                ICE_PROT_ICMP_IL : ICE_PROT_ICMPV6_IL;
1026                sib = fld == ICE_FLOW_FIELD_IDX_ICMP_TYPE ?
1027                        ICE_FLOW_FIELD_IDX_ICMP_CODE :
1028                        ICE_FLOW_FIELD_IDX_ICMP_TYPE;
1029                break;
1030        case ICE_FLOW_FIELD_IDX_GRE_KEYID:
1031                prot_id = ICE_PROT_GRE_OF;
1032                break;
1033        default:
1034                return -EOPNOTSUPP;
1035        }
1036
1037        /* Each extraction sequence entry is a word in size, and extracts a
1038         * word-aligned offset from a protocol header.
1039         */
1040        ese_bits = ICE_FLOW_FV_EXTRACT_SZ * BITS_PER_BYTE;
1041
1042        flds[fld].xtrct.prot_id = prot_id;
1043        flds[fld].xtrct.off = (ice_flds_info[fld].off / ese_bits) *
1044                ICE_FLOW_FV_EXTRACT_SZ;
1045        flds[fld].xtrct.disp = (u8)(ice_flds_info[fld].off % ese_bits);
1046        flds[fld].xtrct.idx = params->es_cnt;
1047        flds[fld].xtrct.mask = ice_flds_info[fld].mask;
1048
1049        /* Adjust the next field-entry index after accommodating the number of
1050         * entries this field consumes
1051         */
1052        cnt = DIV_ROUND_UP(flds[fld].xtrct.disp + ice_flds_info[fld].size,
1053                           ese_bits);
1054
1055        /* Fill in the extraction sequence entries needed for this field */
1056        off = flds[fld].xtrct.off;
1057        mask = flds[fld].xtrct.mask;
1058        for (i = 0; i < cnt; i++) {
1059                /* Only consume an extraction sequence entry if there is no
1060                 * sibling field associated with this field or the sibling entry
1061                 * already extracts the word shared with this field.
1062                 */
1063                if (sib == ICE_FLOW_FIELD_IDX_MAX ||
1064                    flds[sib].xtrct.prot_id == ICE_PROT_ID_INVAL ||
1065                    flds[sib].xtrct.off != off) {
1066                        u8 idx;
1067
1068                        /* Make sure the number of extraction sequence required
1069                         * does not exceed the block's capability
1070                         */
1071                        if (params->es_cnt >= fv_words)
1072                                return -ENOSPC;
1073
1074                        /* some blocks require a reversed field vector layout */
1075                        if (hw->blk[params->blk].es.reverse)
1076                                idx = fv_words - params->es_cnt - 1;
1077                        else
1078                                idx = params->es_cnt;
1079
1080                        params->es[idx].prot_id = prot_id;
1081                        params->es[idx].off = off;
1082                        params->mask[idx] = mask | sib_mask;
1083                        params->es_cnt++;
1084                }
1085
1086                off += ICE_FLOW_FV_EXTRACT_SZ;
1087        }
1088
1089        return 0;
1090}
1091
1092/**
1093 * ice_flow_xtract_raws - Create extract sequence entries for raw bytes
1094 * @hw: pointer to the HW struct
1095 * @params: information about the flow to be processed
1096 * @seg: index of packet segment whose raw fields are to be extracted
1097 */
1098static int
1099ice_flow_xtract_raws(struct ice_hw *hw, struct ice_flow_prof_params *params,
1100                     u8 seg)
1101{
1102        u16 fv_words;
1103        u16 hdrs_sz;
1104        u8 i;
1105
1106        if (!params->prof->segs[seg].raws_cnt)
1107                return 0;
1108
1109        if (params->prof->segs[seg].raws_cnt >
1110            ARRAY_SIZE(params->prof->segs[seg].raws))
1111                return -ENOSPC;
1112
1113        /* Offsets within the segment headers are not supported */
1114        hdrs_sz = ice_flow_calc_seg_sz(params, seg);
1115        if (!hdrs_sz)
1116                return -EINVAL;
1117
1118        fv_words = hw->blk[params->blk].es.fvw;
1119
1120        for (i = 0; i < params->prof->segs[seg].raws_cnt; i++) {
1121                struct ice_flow_seg_fld_raw *raw;
1122                u16 off, cnt, j;
1123
1124                raw = &params->prof->segs[seg].raws[i];
1125
1126                /* Storing extraction information */
1127                raw->info.xtrct.prot_id = ICE_PROT_MAC_OF_OR_S;
1128                raw->info.xtrct.off = (raw->off / ICE_FLOW_FV_EXTRACT_SZ) *
1129                        ICE_FLOW_FV_EXTRACT_SZ;
1130                raw->info.xtrct.disp = (raw->off % ICE_FLOW_FV_EXTRACT_SZ) *
1131                        BITS_PER_BYTE;
1132                raw->info.xtrct.idx = params->es_cnt;
1133
1134                /* Determine the number of field vector entries this raw field
1135                 * consumes.
1136                 */
1137                cnt = DIV_ROUND_UP(raw->info.xtrct.disp +
1138                                   (raw->info.src.last * BITS_PER_BYTE),
1139                                   (ICE_FLOW_FV_EXTRACT_SZ * BITS_PER_BYTE));
1140                off = raw->info.xtrct.off;
1141                for (j = 0; j < cnt; j++) {
1142                        u16 idx;
1143
1144                        /* Make sure the number of extraction sequence required
1145                         * does not exceed the block's capability
1146                         */
1147                        if (params->es_cnt >= hw->blk[params->blk].es.count ||
1148                            params->es_cnt >= ICE_MAX_FV_WORDS)
1149                                return -ENOSPC;
1150
1151                        /* some blocks require a reversed field vector layout */
1152                        if (hw->blk[params->blk].es.reverse)
1153                                idx = fv_words - params->es_cnt - 1;
1154                        else
1155                                idx = params->es_cnt;
1156
1157                        params->es[idx].prot_id = raw->info.xtrct.prot_id;
1158                        params->es[idx].off = off;
1159                        params->es_cnt++;
1160                        off += ICE_FLOW_FV_EXTRACT_SZ;
1161                }
1162        }
1163
1164        return 0;
1165}
1166
1167/**
1168 * ice_flow_create_xtrct_seq - Create an extraction sequence for given segments
1169 * @hw: pointer to the HW struct
1170 * @params: information about the flow to be processed
1171 *
1172 * This function iterates through all matched fields in the given segments, and
1173 * creates an extraction sequence for the fields.
1174 */
1175static int
1176ice_flow_create_xtrct_seq(struct ice_hw *hw,
1177                          struct ice_flow_prof_params *params)
1178{
1179        struct ice_flow_prof *prof = params->prof;
1180        int status = 0;
1181        u8 i;
1182
1183        for (i = 0; i < prof->segs_cnt; i++) {
1184                u64 match = params->prof->segs[i].match;
1185                enum ice_flow_field j;
1186
1187                for_each_set_bit(j, (unsigned long *)&match,
1188                                 ICE_FLOW_FIELD_IDX_MAX) {
1189                        status = ice_flow_xtract_fld(hw, params, i, j, match);
1190                        if (status)
1191                                return status;
1192                        clear_bit(j, (unsigned long *)&match);
1193                }
1194
1195                /* Process raw matching bytes */
1196                status = ice_flow_xtract_raws(hw, params, i);
1197                if (status)
1198                        return status;
1199        }
1200
1201        return status;
1202}
1203
1204/**
1205 * ice_flow_proc_segs - process all packet segments associated with a profile
1206 * @hw: pointer to the HW struct
1207 * @params: information about the flow to be processed
1208 */
1209static int
1210ice_flow_proc_segs(struct ice_hw *hw, struct ice_flow_prof_params *params)
1211{
1212        int status;
1213
1214        status = ice_flow_proc_seg_hdrs(params);
1215        if (status)
1216                return status;
1217
1218        status = ice_flow_create_xtrct_seq(hw, params);
1219        if (status)
1220                return status;
1221
1222        switch (params->blk) {
1223        case ICE_BLK_FD:
1224        case ICE_BLK_RSS:
1225                status = 0;
1226                break;
1227        default:
1228                return -EOPNOTSUPP;
1229        }
1230
1231        return status;
1232}
1233
1234#define ICE_FLOW_FIND_PROF_CHK_FLDS     0x00000001
1235#define ICE_FLOW_FIND_PROF_CHK_VSI      0x00000002
1236#define ICE_FLOW_FIND_PROF_NOT_CHK_DIR  0x00000004
1237
1238/**
1239 * ice_flow_find_prof_conds - Find a profile matching headers and conditions
1240 * @hw: pointer to the HW struct
1241 * @blk: classification stage
1242 * @dir: flow direction
1243 * @segs: array of one or more packet segments that describe the flow
1244 * @segs_cnt: number of packet segments provided
1245 * @vsi_handle: software VSI handle to check VSI (ICE_FLOW_FIND_PROF_CHK_VSI)
1246 * @conds: additional conditions to be checked (ICE_FLOW_FIND_PROF_CHK_*)
1247 */
1248static struct ice_flow_prof *
1249ice_flow_find_prof_conds(struct ice_hw *hw, enum ice_block blk,
1250                         enum ice_flow_dir dir, struct ice_flow_seg_info *segs,
1251                         u8 segs_cnt, u16 vsi_handle, u32 conds)
1252{
1253        struct ice_flow_prof *p, *prof = NULL;
1254
1255        mutex_lock(&hw->fl_profs_locks[blk]);
1256        list_for_each_entry(p, &hw->fl_profs[blk], l_entry)
1257                if ((p->dir == dir || conds & ICE_FLOW_FIND_PROF_NOT_CHK_DIR) &&
1258                    segs_cnt && segs_cnt == p->segs_cnt) {
1259                        u8 i;
1260
1261                        /* Check for profile-VSI association if specified */
1262                        if ((conds & ICE_FLOW_FIND_PROF_CHK_VSI) &&
1263                            ice_is_vsi_valid(hw, vsi_handle) &&
1264                            !test_bit(vsi_handle, p->vsis))
1265                                continue;
1266
1267                        /* Protocol headers must be checked. Matched fields are
1268                         * checked if specified.
1269                         */
1270                        for (i = 0; i < segs_cnt; i++)
1271                                if (segs[i].hdrs != p->segs[i].hdrs ||
1272                                    ((conds & ICE_FLOW_FIND_PROF_CHK_FLDS) &&
1273                                     segs[i].match != p->segs[i].match))
1274                                        break;
1275
1276                        /* A match is found if all segments are matched */
1277                        if (i == segs_cnt) {
1278                                prof = p;
1279                                break;
1280                        }
1281                }
1282        mutex_unlock(&hw->fl_profs_locks[blk]);
1283
1284        return prof;
1285}
1286
1287/**
1288 * ice_flow_find_prof_id - Look up a profile with given profile ID
1289 * @hw: pointer to the HW struct
1290 * @blk: classification stage
1291 * @prof_id: unique ID to identify this flow profile
1292 */
1293static struct ice_flow_prof *
1294ice_flow_find_prof_id(struct ice_hw *hw, enum ice_block blk, u64 prof_id)
1295{
1296        struct ice_flow_prof *p;
1297
1298        list_for_each_entry(p, &hw->fl_profs[blk], l_entry)
1299                if (p->id == prof_id)
1300                        return p;
1301
1302        return NULL;
1303}
1304
1305/**
1306 * ice_dealloc_flow_entry - Deallocate flow entry memory
1307 * @hw: pointer to the HW struct
1308 * @entry: flow entry to be removed
1309 */
1310static void
1311ice_dealloc_flow_entry(struct ice_hw *hw, struct ice_flow_entry *entry)
1312{
1313        if (!entry)
1314                return;
1315
1316        if (entry->entry)
1317                devm_kfree(ice_hw_to_dev(hw), entry->entry);
1318
1319        devm_kfree(ice_hw_to_dev(hw), entry);
1320}
1321
1322/**
1323 * ice_flow_rem_entry_sync - Remove a flow entry
1324 * @hw: pointer to the HW struct
1325 * @blk: classification stage
1326 * @entry: flow entry to be removed
1327 */
1328static int
1329ice_flow_rem_entry_sync(struct ice_hw *hw, enum ice_block __always_unused blk,
1330                        struct ice_flow_entry *entry)
1331{
1332        if (!entry)
1333                return -EINVAL;
1334
1335        list_del(&entry->l_entry);
1336
1337        ice_dealloc_flow_entry(hw, entry);
1338
1339        return 0;
1340}
1341
1342/**
1343 * ice_flow_add_prof_sync - Add a flow profile for packet segments and fields
1344 * @hw: pointer to the HW struct
1345 * @blk: classification stage
1346 * @dir: flow direction
1347 * @prof_id: unique ID to identify this flow profile
1348 * @segs: array of one or more packet segments that describe the flow
1349 * @segs_cnt: number of packet segments provided
1350 * @prof: stores the returned flow profile added
1351 *
1352 * Assumption: the caller has acquired the lock to the profile list
1353 */
1354static int
1355ice_flow_add_prof_sync(struct ice_hw *hw, enum ice_block blk,
1356                       enum ice_flow_dir dir, u64 prof_id,
1357                       struct ice_flow_seg_info *segs, u8 segs_cnt,
1358                       struct ice_flow_prof **prof)
1359{
1360        struct ice_flow_prof_params *params;
1361        int status;
1362        u8 i;
1363
1364        if (!prof)
1365                return -EINVAL;
1366
1367        params = kzalloc(sizeof(*params), GFP_KERNEL);
1368        if (!params)
1369                return -ENOMEM;
1370
1371        params->prof = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*params->prof),
1372                                    GFP_KERNEL);
1373        if (!params->prof) {
1374                status = -ENOMEM;
1375                goto free_params;
1376        }
1377
1378        /* initialize extraction sequence to all invalid (0xff) */
1379        for (i = 0; i < ICE_MAX_FV_WORDS; i++) {
1380                params->es[i].prot_id = ICE_PROT_INVALID;
1381                params->es[i].off = ICE_FV_OFFSET_INVAL;
1382        }
1383
1384        params->blk = blk;
1385        params->prof->id = prof_id;
1386        params->prof->dir = dir;
1387        params->prof->segs_cnt = segs_cnt;
1388
1389        /* Make a copy of the segments that need to be persistent in the flow
1390         * profile instance
1391         */
1392        for (i = 0; i < segs_cnt; i++)
1393                memcpy(&params->prof->segs[i], &segs[i], sizeof(*segs));
1394
1395        status = ice_flow_proc_segs(hw, params);
1396        if (status) {
1397                ice_debug(hw, ICE_DBG_FLOW, "Error processing a flow's packet segments\n");
1398                goto out;
1399        }
1400
1401        /* Add a HW profile for this flow profile */
1402        status = ice_add_prof(hw, blk, prof_id, (u8 *)params->ptypes,
1403                              params->attr, params->attr_cnt, params->es,
1404                              params->mask);
1405        if (status) {
1406                ice_debug(hw, ICE_DBG_FLOW, "Error adding a HW flow profile\n");
1407                goto out;
1408        }
1409
1410        INIT_LIST_HEAD(&params->prof->entries);
1411        mutex_init(&params->prof->entries_lock);
1412        *prof = params->prof;
1413
1414out:
1415        if (status)
1416                devm_kfree(ice_hw_to_dev(hw), params->prof);
1417free_params:
1418        kfree(params);
1419
1420        return status;
1421}
1422
1423/**
1424 * ice_flow_rem_prof_sync - remove a flow profile
1425 * @hw: pointer to the hardware structure
1426 * @blk: classification stage
1427 * @prof: pointer to flow profile to remove
1428 *
1429 * Assumption: the caller has acquired the lock to the profile list
1430 */
1431static int
1432ice_flow_rem_prof_sync(struct ice_hw *hw, enum ice_block blk,
1433                       struct ice_flow_prof *prof)
1434{
1435        int status;
1436
1437        /* Remove all remaining flow entries before removing the flow profile */
1438        if (!list_empty(&prof->entries)) {
1439                struct ice_flow_entry *e, *t;
1440
1441                mutex_lock(&prof->entries_lock);
1442
1443                list_for_each_entry_safe(e, t, &prof->entries, l_entry) {
1444                        status = ice_flow_rem_entry_sync(hw, blk, e);
1445                        if (status)
1446                                break;
1447                }
1448
1449                mutex_unlock(&prof->entries_lock);
1450        }
1451
1452        /* Remove all hardware profiles associated with this flow profile */
1453        status = ice_rem_prof(hw, blk, prof->id);
1454        if (!status) {
1455                list_del(&prof->l_entry);
1456                mutex_destroy(&prof->entries_lock);
1457                devm_kfree(ice_hw_to_dev(hw), prof);
1458        }
1459
1460        return status;
1461}
1462
1463/**
1464 * ice_flow_assoc_prof - associate a VSI with a flow profile
1465 * @hw: pointer to the hardware structure
1466 * @blk: classification stage
1467 * @prof: pointer to flow profile
1468 * @vsi_handle: software VSI handle
1469 *
1470 * Assumption: the caller has acquired the lock to the profile list
1471 * and the software VSI handle has been validated
1472 */
1473static int
1474ice_flow_assoc_prof(struct ice_hw *hw, enum ice_block blk,
1475                    struct ice_flow_prof *prof, u16 vsi_handle)
1476{
1477        int status = 0;
1478
1479        if (!test_bit(vsi_handle, prof->vsis)) {
1480                status = ice_add_prof_id_flow(hw, blk,
1481                                              ice_get_hw_vsi_num(hw,
1482                                                                 vsi_handle),
1483                                              prof->id);
1484                if (!status)
1485                        set_bit(vsi_handle, prof->vsis);
1486                else
1487                        ice_debug(hw, ICE_DBG_FLOW, "HW profile add failed, %d\n",
1488                                  status);
1489        }
1490
1491        return status;
1492}
1493
1494/**
1495 * ice_flow_disassoc_prof - disassociate a VSI from a flow profile
1496 * @hw: pointer to the hardware structure
1497 * @blk: classification stage
1498 * @prof: pointer to flow profile
1499 * @vsi_handle: software VSI handle
1500 *
1501 * Assumption: the caller has acquired the lock to the profile list
1502 * and the software VSI handle has been validated
1503 */
1504static int
1505ice_flow_disassoc_prof(struct ice_hw *hw, enum ice_block blk,
1506                       struct ice_flow_prof *prof, u16 vsi_handle)
1507{
1508        int status = 0;
1509
1510        if (test_bit(vsi_handle, prof->vsis)) {
1511                status = ice_rem_prof_id_flow(hw, blk,
1512                                              ice_get_hw_vsi_num(hw,
1513                                                                 vsi_handle),
1514                                              prof->id);
1515                if (!status)
1516                        clear_bit(vsi_handle, prof->vsis);
1517                else
1518                        ice_debug(hw, ICE_DBG_FLOW, "HW profile remove failed, %d\n",
1519                                  status);
1520        }
1521
1522        return status;
1523}
1524
1525/**
1526 * ice_flow_add_prof - Add a flow profile for packet segments and matched fields
1527 * @hw: pointer to the HW struct
1528 * @blk: classification stage
1529 * @dir: flow direction
1530 * @prof_id: unique ID to identify this flow profile
1531 * @segs: array of one or more packet segments that describe the flow
1532 * @segs_cnt: number of packet segments provided
1533 * @prof: stores the returned flow profile added
1534 */
1535int
1536ice_flow_add_prof(struct ice_hw *hw, enum ice_block blk, enum ice_flow_dir dir,
1537                  u64 prof_id, struct ice_flow_seg_info *segs, u8 segs_cnt,
1538                  struct ice_flow_prof **prof)
1539{
1540        int status;
1541
1542        if (segs_cnt > ICE_FLOW_SEG_MAX)
1543                return -ENOSPC;
1544
1545        if (!segs_cnt)
1546                return -EINVAL;
1547
1548        if (!segs)
1549                return -EINVAL;
1550
1551        status = ice_flow_val_hdrs(segs, segs_cnt);
1552        if (status)
1553                return status;
1554
1555        mutex_lock(&hw->fl_profs_locks[blk]);
1556
1557        status = ice_flow_add_prof_sync(hw, blk, dir, prof_id, segs, segs_cnt,
1558                                        prof);
1559        if (!status)
1560                list_add(&(*prof)->l_entry, &hw->fl_profs[blk]);
1561
1562        mutex_unlock(&hw->fl_profs_locks[blk]);
1563
1564        return status;
1565}
1566
1567/**
1568 * ice_flow_rem_prof - Remove a flow profile and all entries associated with it
1569 * @hw: pointer to the HW struct
1570 * @blk: the block for which the flow profile is to be removed
1571 * @prof_id: unique ID of the flow profile to be removed
1572 */
1573int ice_flow_rem_prof(struct ice_hw *hw, enum ice_block blk, u64 prof_id)
1574{
1575        struct ice_flow_prof *prof;
1576        int status;
1577
1578        mutex_lock(&hw->fl_profs_locks[blk]);
1579
1580        prof = ice_flow_find_prof_id(hw, blk, prof_id);
1581        if (!prof) {
1582                status = -ENOENT;
1583                goto out;
1584        }
1585
1586        /* prof becomes invalid after the call */
1587        status = ice_flow_rem_prof_sync(hw, blk, prof);
1588
1589out:
1590        mutex_unlock(&hw->fl_profs_locks[blk]);
1591
1592        return status;
1593}
1594
1595/**
1596 * ice_flow_add_entry - Add a flow entry
1597 * @hw: pointer to the HW struct
1598 * @blk: classification stage
1599 * @prof_id: ID of the profile to add a new flow entry to
1600 * @entry_id: unique ID to identify this flow entry
1601 * @vsi_handle: software VSI handle for the flow entry
1602 * @prio: priority of the flow entry
1603 * @data: pointer to a data buffer containing flow entry's match values/masks
1604 * @entry_h: pointer to buffer that receives the new flow entry's handle
1605 */
1606int
1607ice_flow_add_entry(struct ice_hw *hw, enum ice_block blk, u64 prof_id,
1608                   u64 entry_id, u16 vsi_handle, enum ice_flow_priority prio,
1609                   void *data, u64 *entry_h)
1610{
1611        struct ice_flow_entry *e = NULL;
1612        struct ice_flow_prof *prof;
1613        int status;
1614
1615        /* No flow entry data is expected for RSS */
1616        if (!entry_h || (!data && blk != ICE_BLK_RSS))
1617                return -EINVAL;
1618
1619        if (!ice_is_vsi_valid(hw, vsi_handle))
1620                return -EINVAL;
1621
1622        mutex_lock(&hw->fl_profs_locks[blk]);
1623
1624        prof = ice_flow_find_prof_id(hw, blk, prof_id);
1625        if (!prof) {
1626                status = -ENOENT;
1627        } else {
1628                /* Allocate memory for the entry being added and associate
1629                 * the VSI to the found flow profile
1630                 */
1631                e = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*e), GFP_KERNEL);
1632                if (!e)
1633                        status = -ENOMEM;
1634                else
1635                        status = ice_flow_assoc_prof(hw, blk, prof, vsi_handle);
1636        }
1637
1638        mutex_unlock(&hw->fl_profs_locks[blk]);
1639        if (status)
1640                goto out;
1641
1642        e->id = entry_id;
1643        e->vsi_handle = vsi_handle;
1644        e->prof = prof;
1645        e->priority = prio;
1646
1647        switch (blk) {
1648        case ICE_BLK_FD:
1649        case ICE_BLK_RSS:
1650                break;
1651        default:
1652                status = -EOPNOTSUPP;
1653                goto out;
1654        }
1655
1656        mutex_lock(&prof->entries_lock);
1657        list_add(&e->l_entry, &prof->entries);
1658        mutex_unlock(&prof->entries_lock);
1659
1660        *entry_h = ICE_FLOW_ENTRY_HNDL(e);
1661
1662out:
1663        if (status && e) {
1664                if (e->entry)
1665                        devm_kfree(ice_hw_to_dev(hw), e->entry);
1666                devm_kfree(ice_hw_to_dev(hw), e);
1667        }
1668
1669        return status;
1670}
1671
1672/**
1673 * ice_flow_rem_entry - Remove a flow entry
1674 * @hw: pointer to the HW struct
1675 * @blk: classification stage
1676 * @entry_h: handle to the flow entry to be removed
1677 */
1678int ice_flow_rem_entry(struct ice_hw *hw, enum ice_block blk, u64 entry_h)
1679{
1680        struct ice_flow_entry *entry;
1681        struct ice_flow_prof *prof;
1682        int status = 0;
1683
1684        if (entry_h == ICE_FLOW_ENTRY_HANDLE_INVAL)
1685                return -EINVAL;
1686
1687        entry = ICE_FLOW_ENTRY_PTR(entry_h);
1688
1689        /* Retain the pointer to the flow profile as the entry will be freed */
1690        prof = entry->prof;
1691
1692        if (prof) {
1693                mutex_lock(&prof->entries_lock);
1694                status = ice_flow_rem_entry_sync(hw, blk, entry);
1695                mutex_unlock(&prof->entries_lock);
1696        }
1697
1698        return status;
1699}
1700
1701/**
1702 * ice_flow_set_fld_ext - specifies locations of field from entry's input buffer
1703 * @seg: packet segment the field being set belongs to
1704 * @fld: field to be set
1705 * @field_type: type of the field
1706 * @val_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of the value to match from
1707 *           entry's input buffer
1708 * @mask_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of mask value from entry's
1709 *            input buffer
1710 * @last_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of last/upper value from
1711 *            entry's input buffer
1712 *
1713 * This helper function stores information of a field being matched, including
1714 * the type of the field and the locations of the value to match, the mask, and
1715 * the upper-bound value in the start of the input buffer for a flow entry.
1716 * This function should only be used for fixed-size data structures.
1717 *
1718 * This function also opportunistically determines the protocol headers to be
1719 * present based on the fields being set. Some fields cannot be used alone to
1720 * determine the protocol headers present. Sometimes, fields for particular
1721 * protocol headers are not matched. In those cases, the protocol headers
1722 * must be explicitly set.
1723 */
1724static void
1725ice_flow_set_fld_ext(struct ice_flow_seg_info *seg, enum ice_flow_field fld,
1726                     enum ice_flow_fld_match_type field_type, u16 val_loc,
1727                     u16 mask_loc, u16 last_loc)
1728{
1729        u64 bit = BIT_ULL(fld);
1730
1731        seg->match |= bit;
1732        if (field_type == ICE_FLOW_FLD_TYPE_RANGE)
1733                seg->range |= bit;
1734
1735        seg->fields[fld].type = field_type;
1736        seg->fields[fld].src.val = val_loc;
1737        seg->fields[fld].src.mask = mask_loc;
1738        seg->fields[fld].src.last = last_loc;
1739
1740        ICE_FLOW_SET_HDRS(seg, ice_flds_info[fld].hdr);
1741}
1742
1743/**
1744 * ice_flow_set_fld - specifies locations of field from entry's input buffer
1745 * @seg: packet segment the field being set belongs to
1746 * @fld: field to be set
1747 * @val_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of the value to match from
1748 *           entry's input buffer
1749 * @mask_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of mask value from entry's
1750 *            input buffer
1751 * @last_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of last/upper value from
1752 *            entry's input buffer
1753 * @range: indicate if field being matched is to be in a range
1754 *
1755 * This function specifies the locations, in the form of byte offsets from the
1756 * start of the input buffer for a flow entry, from where the value to match,
1757 * the mask value, and upper value can be extracted. These locations are then
1758 * stored in the flow profile. When adding a flow entry associated with the
1759 * flow profile, these locations will be used to quickly extract the values and
1760 * create the content of a match entry. This function should only be used for
1761 * fixed-size data structures.
1762 */
1763void
1764ice_flow_set_fld(struct ice_flow_seg_info *seg, enum ice_flow_field fld,
1765                 u16 val_loc, u16 mask_loc, u16 last_loc, bool range)
1766{
1767        enum ice_flow_fld_match_type t = range ?
1768                ICE_FLOW_FLD_TYPE_RANGE : ICE_FLOW_FLD_TYPE_REG;
1769
1770        ice_flow_set_fld_ext(seg, fld, t, val_loc, mask_loc, last_loc);
1771}
1772
1773/**
1774 * ice_flow_add_fld_raw - sets locations of a raw field from entry's input buf
1775 * @seg: packet segment the field being set belongs to
1776 * @off: offset of the raw field from the beginning of the segment in bytes
1777 * @len: length of the raw pattern to be matched
1778 * @val_loc: location of the value to match from entry's input buffer
1779 * @mask_loc: location of mask value from entry's input buffer
1780 *
1781 * This function specifies the offset of the raw field to be match from the
1782 * beginning of the specified packet segment, and the locations, in the form of
1783 * byte offsets from the start of the input buffer for a flow entry, from where
1784 * the value to match and the mask value to be extracted. These locations are
1785 * then stored in the flow profile. When adding flow entries to the associated
1786 * flow profile, these locations can be used to quickly extract the values to
1787 * create the content of a match entry. This function should only be used for
1788 * fixed-size data structures.
1789 */
1790void
1791ice_flow_add_fld_raw(struct ice_flow_seg_info *seg, u16 off, u8 len,
1792                     u16 val_loc, u16 mask_loc)
1793{
1794        if (seg->raws_cnt < ICE_FLOW_SEG_RAW_FLD_MAX) {
1795                seg->raws[seg->raws_cnt].off = off;
1796                seg->raws[seg->raws_cnt].info.type = ICE_FLOW_FLD_TYPE_SIZE;
1797                seg->raws[seg->raws_cnt].info.src.val = val_loc;
1798                seg->raws[seg->raws_cnt].info.src.mask = mask_loc;
1799                /* The "last" field is used to store the length of the field */
1800                seg->raws[seg->raws_cnt].info.src.last = len;
1801        }
1802
1803        /* Overflows of "raws" will be handled as an error condition later in
1804         * the flow when this information is processed.
1805         */
1806        seg->raws_cnt++;
1807}
1808
1809/**
1810 * ice_flow_rem_vsi_prof - remove VSI from flow profile
1811 * @hw: pointer to the hardware structure
1812 * @vsi_handle: software VSI handle
1813 * @prof_id: unique ID to identify this flow profile
1814 *
1815 * This function removes the flow entries associated to the input
1816 * VSI handle and disassociate the VSI from the flow profile.
1817 */
1818int ice_flow_rem_vsi_prof(struct ice_hw *hw, u16 vsi_handle, u64 prof_id)
1819{
1820        struct ice_flow_prof *prof;
1821        int status = 0;
1822
1823        if (!ice_is_vsi_valid(hw, vsi_handle))
1824                return -EINVAL;
1825
1826        /* find flow profile pointer with input package block and profile ID */
1827        prof = ice_flow_find_prof_id(hw, ICE_BLK_FD, prof_id);
1828        if (!prof) {
1829                ice_debug(hw, ICE_DBG_PKG, "Cannot find flow profile id=%llu\n",
1830                          prof_id);
1831                return -ENOENT;
1832        }
1833
1834        /* Remove all remaining flow entries before removing the flow profile */
1835        if (!list_empty(&prof->entries)) {
1836                struct ice_flow_entry *e, *t;
1837
1838                mutex_lock(&prof->entries_lock);
1839                list_for_each_entry_safe(e, t, &prof->entries, l_entry) {
1840                        if (e->vsi_handle != vsi_handle)
1841                                continue;
1842
1843                        status = ice_flow_rem_entry_sync(hw, ICE_BLK_FD, e);
1844                        if (status)
1845                                break;
1846                }
1847                mutex_unlock(&prof->entries_lock);
1848        }
1849        if (status)
1850                return status;
1851
1852        /* disassociate the flow profile from sw VSI handle */
1853        status = ice_flow_disassoc_prof(hw, ICE_BLK_FD, prof, vsi_handle);
1854        if (status)
1855                ice_debug(hw, ICE_DBG_PKG, "ice_flow_disassoc_prof() failed with status=%d\n",
1856                          status);
1857        return status;
1858}
1859
1860#define ICE_FLOW_RSS_SEG_HDR_L2_MASKS \
1861        (ICE_FLOW_SEG_HDR_ETH | ICE_FLOW_SEG_HDR_VLAN)
1862
1863#define ICE_FLOW_RSS_SEG_HDR_L3_MASKS \
1864        (ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_IPV6)
1865
1866#define ICE_FLOW_RSS_SEG_HDR_L4_MASKS \
1867        (ICE_FLOW_SEG_HDR_TCP | ICE_FLOW_SEG_HDR_UDP | ICE_FLOW_SEG_HDR_SCTP)
1868
1869#define ICE_FLOW_RSS_SEG_HDR_VAL_MASKS \
1870        (ICE_FLOW_RSS_SEG_HDR_L2_MASKS | \
1871         ICE_FLOW_RSS_SEG_HDR_L3_MASKS | \
1872         ICE_FLOW_RSS_SEG_HDR_L4_MASKS)
1873
1874/**
1875 * ice_flow_set_rss_seg_info - setup packet segments for RSS
1876 * @segs: pointer to the flow field segment(s)
1877 * @hash_fields: fields to be hashed on for the segment(s)
1878 * @flow_hdr: protocol header fields within a packet segment
1879 *
1880 * Helper function to extract fields from hash bitmap and use flow
1881 * header value to set flow field segment for further use in flow
1882 * profile entry or removal.
1883 */
1884static int
1885ice_flow_set_rss_seg_info(struct ice_flow_seg_info *segs, u64 hash_fields,
1886                          u32 flow_hdr)
1887{
1888        u64 val;
1889        u8 i;
1890
1891        for_each_set_bit(i, (unsigned long *)&hash_fields,
1892                         ICE_FLOW_FIELD_IDX_MAX)
1893                ice_flow_set_fld(segs, (enum ice_flow_field)i,
1894                                 ICE_FLOW_FLD_OFF_INVAL, ICE_FLOW_FLD_OFF_INVAL,
1895                                 ICE_FLOW_FLD_OFF_INVAL, false);
1896
1897        ICE_FLOW_SET_HDRS(segs, flow_hdr);
1898
1899        if (segs->hdrs & ~ICE_FLOW_RSS_SEG_HDR_VAL_MASKS &
1900            ~ICE_FLOW_RSS_HDRS_INNER_MASK & ~ICE_FLOW_SEG_HDR_IPV_OTHER)
1901                return -EINVAL;
1902
1903        val = (u64)(segs->hdrs & ICE_FLOW_RSS_SEG_HDR_L3_MASKS);
1904        if (val && !is_power_of_2(val))
1905                return -EIO;
1906
1907        val = (u64)(segs->hdrs & ICE_FLOW_RSS_SEG_HDR_L4_MASKS);
1908        if (val && !is_power_of_2(val))
1909                return -EIO;
1910
1911        return 0;
1912}
1913
1914/**
1915 * ice_rem_vsi_rss_list - remove VSI from RSS list
1916 * @hw: pointer to the hardware structure
1917 * @vsi_handle: software VSI handle
1918 *
1919 * Remove the VSI from all RSS configurations in the list.
1920 */
1921void ice_rem_vsi_rss_list(struct ice_hw *hw, u16 vsi_handle)
1922{
1923        struct ice_rss_cfg *r, *tmp;
1924
1925        if (list_empty(&hw->rss_list_head))
1926                return;
1927
1928        mutex_lock(&hw->rss_locks);
1929        list_for_each_entry_safe(r, tmp, &hw->rss_list_head, l_entry)
1930                if (test_and_clear_bit(vsi_handle, r->vsis))
1931                        if (bitmap_empty(r->vsis, ICE_MAX_VSI)) {
1932                                list_del(&r->l_entry);
1933                                devm_kfree(ice_hw_to_dev(hw), r);
1934                        }
1935        mutex_unlock(&hw->rss_locks);
1936}
1937
1938/**
1939 * ice_rem_vsi_rss_cfg - remove RSS configurations associated with VSI
1940 * @hw: pointer to the hardware structure
1941 * @vsi_handle: software VSI handle
1942 *
1943 * This function will iterate through all flow profiles and disassociate
1944 * the VSI from that profile. If the flow profile has no VSIs it will
1945 * be removed.
1946 */
1947int ice_rem_vsi_rss_cfg(struct ice_hw *hw, u16 vsi_handle)
1948{
1949        const enum ice_block blk = ICE_BLK_RSS;
1950        struct ice_flow_prof *p, *t;
1951        int status = 0;
1952
1953        if (!ice_is_vsi_valid(hw, vsi_handle))
1954                return -EINVAL;
1955
1956        if (list_empty(&hw->fl_profs[blk]))
1957                return 0;
1958
1959        mutex_lock(&hw->rss_locks);
1960        list_for_each_entry_safe(p, t, &hw->fl_profs[blk], l_entry)
1961                if (test_bit(vsi_handle, p->vsis)) {
1962                        status = ice_flow_disassoc_prof(hw, blk, p, vsi_handle);
1963                        if (status)
1964                                break;
1965
1966                        if (bitmap_empty(p->vsis, ICE_MAX_VSI)) {
1967                                status = ice_flow_rem_prof(hw, blk, p->id);
1968                                if (status)
1969                                        break;
1970                        }
1971                }
1972        mutex_unlock(&hw->rss_locks);
1973
1974        return status;
1975}
1976
1977/**
1978 * ice_rem_rss_list - remove RSS configuration from list
1979 * @hw: pointer to the hardware structure
1980 * @vsi_handle: software VSI handle
1981 * @prof: pointer to flow profile
1982 *
1983 * Assumption: lock has already been acquired for RSS list
1984 */
1985static void
1986ice_rem_rss_list(struct ice_hw *hw, u16 vsi_handle, struct ice_flow_prof *prof)
1987{
1988        struct ice_rss_cfg *r, *tmp;
1989
1990        /* Search for RSS hash fields associated to the VSI that match the
1991         * hash configurations associated to the flow profile. If found
1992         * remove from the RSS entry list of the VSI context and delete entry.
1993         */
1994        list_for_each_entry_safe(r, tmp, &hw->rss_list_head, l_entry)
1995                if (r->hashed_flds == prof->segs[prof->segs_cnt - 1].match &&
1996                    r->packet_hdr == prof->segs[prof->segs_cnt - 1].hdrs) {
1997                        clear_bit(vsi_handle, r->vsis);
1998                        if (bitmap_empty(r->vsis, ICE_MAX_VSI)) {
1999                                list_del(&r->l_entry);
2000                                devm_kfree(ice_hw_to_dev(hw), r);
2001                        }
2002                        return;
2003                }
2004}
2005
2006/**
2007 * ice_add_rss_list - add RSS configuration to list
2008 * @hw: pointer to the hardware structure
2009 * @vsi_handle: software VSI handle
2010 * @prof: pointer to flow profile
2011 *
2012 * Assumption: lock has already been acquired for RSS list
2013 */
2014static int
2015ice_add_rss_list(struct ice_hw *hw, u16 vsi_handle, struct ice_flow_prof *prof)
2016{
2017        struct ice_rss_cfg *r, *rss_cfg;
2018
2019        list_for_each_entry(r, &hw->rss_list_head, l_entry)
2020                if (r->hashed_flds == prof->segs[prof->segs_cnt - 1].match &&
2021                    r->packet_hdr == prof->segs[prof->segs_cnt - 1].hdrs) {
2022                        set_bit(vsi_handle, r->vsis);
2023                        return 0;
2024                }
2025
2026        rss_cfg = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*rss_cfg),
2027                               GFP_KERNEL);
2028        if (!rss_cfg)
2029                return -ENOMEM;
2030
2031        rss_cfg->hashed_flds = prof->segs[prof->segs_cnt - 1].match;
2032        rss_cfg->packet_hdr = prof->segs[prof->segs_cnt - 1].hdrs;
2033        set_bit(vsi_handle, rss_cfg->vsis);
2034
2035        list_add_tail(&rss_cfg->l_entry, &hw->rss_list_head);
2036
2037        return 0;
2038}
2039
2040#define ICE_FLOW_PROF_HASH_S    0
2041#define ICE_FLOW_PROF_HASH_M    (0xFFFFFFFFULL << ICE_FLOW_PROF_HASH_S)
2042#define ICE_FLOW_PROF_HDR_S     32
2043#define ICE_FLOW_PROF_HDR_M     (0x3FFFFFFFULL << ICE_FLOW_PROF_HDR_S)
2044#define ICE_FLOW_PROF_ENCAP_S   63
2045#define ICE_FLOW_PROF_ENCAP_M   (BIT_ULL(ICE_FLOW_PROF_ENCAP_S))
2046
2047#define ICE_RSS_OUTER_HEADERS   1
2048#define ICE_RSS_INNER_HEADERS   2
2049
2050/* Flow profile ID format:
2051 * [0:31] - Packet match fields
2052 * [32:62] - Protocol header
2053 * [63] - Encapsulation flag, 0 if non-tunneled, 1 if tunneled
2054 */
2055#define ICE_FLOW_GEN_PROFID(hash, hdr, segs_cnt) \
2056        ((u64)(((u64)(hash) & ICE_FLOW_PROF_HASH_M) | \
2057               (((u64)(hdr) << ICE_FLOW_PROF_HDR_S) & ICE_FLOW_PROF_HDR_M) | \
2058               ((u8)((segs_cnt) - 1) ? ICE_FLOW_PROF_ENCAP_M : 0)))
2059
2060/**
2061 * ice_add_rss_cfg_sync - add an RSS configuration
2062 * @hw: pointer to the hardware structure
2063 * @vsi_handle: software VSI handle
2064 * @hashed_flds: hash bit fields (ICE_FLOW_HASH_*) to configure
2065 * @addl_hdrs: protocol header fields
2066 * @segs_cnt: packet segment count
2067 *
2068 * Assumption: lock has already been acquired for RSS list
2069 */
2070static int
2071ice_add_rss_cfg_sync(struct ice_hw *hw, u16 vsi_handle, u64 hashed_flds,
2072                     u32 addl_hdrs, u8 segs_cnt)
2073{
2074        const enum ice_block blk = ICE_BLK_RSS;
2075        struct ice_flow_prof *prof = NULL;
2076        struct ice_flow_seg_info *segs;
2077        int status;
2078
2079        if (!segs_cnt || segs_cnt > ICE_FLOW_SEG_MAX)
2080                return -EINVAL;
2081
2082        segs = kcalloc(segs_cnt, sizeof(*segs), GFP_KERNEL);
2083        if (!segs)
2084                return -ENOMEM;
2085
2086        /* Construct the packet segment info from the hashed fields */
2087        status = ice_flow_set_rss_seg_info(&segs[segs_cnt - 1], hashed_flds,
2088                                           addl_hdrs);
2089        if (status)
2090                goto exit;
2091
2092        /* Search for a flow profile that has matching headers, hash fields
2093         * and has the input VSI associated to it. If found, no further
2094         * operations required and exit.
2095         */
2096        prof = ice_flow_find_prof_conds(hw, blk, ICE_FLOW_RX, segs, segs_cnt,
2097                                        vsi_handle,
2098                                        ICE_FLOW_FIND_PROF_CHK_FLDS |
2099                                        ICE_FLOW_FIND_PROF_CHK_VSI);
2100        if (prof)
2101                goto exit;
2102
2103        /* Check if a flow profile exists with the same protocol headers and
2104         * associated with the input VSI. If so disassociate the VSI from
2105         * this profile. The VSI will be added to a new profile created with
2106         * the protocol header and new hash field configuration.
2107         */
2108        prof = ice_flow_find_prof_conds(hw, blk, ICE_FLOW_RX, segs, segs_cnt,
2109                                        vsi_handle, ICE_FLOW_FIND_PROF_CHK_VSI);
2110        if (prof) {
2111                status = ice_flow_disassoc_prof(hw, blk, prof, vsi_handle);
2112                if (!status)
2113                        ice_rem_rss_list(hw, vsi_handle, prof);
2114                else
2115                        goto exit;
2116
2117                /* Remove profile if it has no VSIs associated */
2118                if (bitmap_empty(prof->vsis, ICE_MAX_VSI)) {
2119                        status = ice_flow_rem_prof(hw, blk, prof->id);
2120                        if (status)
2121                                goto exit;
2122                }
2123        }
2124
2125        /* Search for a profile that has same match fields only. If this
2126         * exists then associate the VSI to this profile.
2127         */
2128        prof = ice_flow_find_prof_conds(hw, blk, ICE_FLOW_RX, segs, segs_cnt,
2129                                        vsi_handle,
2130                                        ICE_FLOW_FIND_PROF_CHK_FLDS);
2131        if (prof) {
2132                status = ice_flow_assoc_prof(hw, blk, prof, vsi_handle);
2133                if (!status)
2134                        status = ice_add_rss_list(hw, vsi_handle, prof);
2135                goto exit;
2136        }
2137
2138        /* Create a new flow profile with generated profile and packet
2139         * segment information.
2140         */
2141        status = ice_flow_add_prof(hw, blk, ICE_FLOW_RX,
2142                                   ICE_FLOW_GEN_PROFID(hashed_flds,
2143                                                       segs[segs_cnt - 1].hdrs,
2144                                                       segs_cnt),
2145                                   segs, segs_cnt, &prof);
2146        if (status)
2147                goto exit;
2148
2149        status = ice_flow_assoc_prof(hw, blk, prof, vsi_handle);
2150        /* If association to a new flow profile failed then this profile can
2151         * be removed.
2152         */
2153        if (status) {
2154                ice_flow_rem_prof(hw, blk, prof->id);
2155                goto exit;
2156        }
2157
2158        status = ice_add_rss_list(hw, vsi_handle, prof);
2159
2160exit:
2161        kfree(segs);
2162        return status;
2163}
2164
2165/**
2166 * ice_add_rss_cfg - add an RSS configuration with specified hashed fields
2167 * @hw: pointer to the hardware structure
2168 * @vsi_handle: software VSI handle
2169 * @hashed_flds: hash bit fields (ICE_FLOW_HASH_*) to configure
2170 * @addl_hdrs: protocol header fields
2171 *
2172 * This function will generate a flow profile based on fields associated with
2173 * the input fields to hash on, the flow type and use the VSI number to add
2174 * a flow entry to the profile.
2175 */
2176int
2177ice_add_rss_cfg(struct ice_hw *hw, u16 vsi_handle, u64 hashed_flds,
2178                u32 addl_hdrs)
2179{
2180        int status;
2181
2182        if (hashed_flds == ICE_HASH_INVALID ||
2183            !ice_is_vsi_valid(hw, vsi_handle))
2184                return -EINVAL;
2185
2186        mutex_lock(&hw->rss_locks);
2187        status = ice_add_rss_cfg_sync(hw, vsi_handle, hashed_flds, addl_hdrs,
2188                                      ICE_RSS_OUTER_HEADERS);
2189        if (!status)
2190                status = ice_add_rss_cfg_sync(hw, vsi_handle, hashed_flds,
2191                                              addl_hdrs, ICE_RSS_INNER_HEADERS);
2192        mutex_unlock(&hw->rss_locks);
2193
2194        return status;
2195}
2196
2197/**
2198 * ice_rem_rss_cfg_sync - remove an existing RSS configuration
2199 * @hw: pointer to the hardware structure
2200 * @vsi_handle: software VSI handle
2201 * @hashed_flds: Packet hash types (ICE_FLOW_HASH_*) to remove
2202 * @addl_hdrs: Protocol header fields within a packet segment
2203 * @segs_cnt: packet segment count
2204 *
2205 * Assumption: lock has already been acquired for RSS list
2206 */
2207static int
2208ice_rem_rss_cfg_sync(struct ice_hw *hw, u16 vsi_handle, u64 hashed_flds,
2209                     u32 addl_hdrs, u8 segs_cnt)
2210{
2211        const enum ice_block blk = ICE_BLK_RSS;
2212        struct ice_flow_seg_info *segs;
2213        struct ice_flow_prof *prof;
2214        int status;
2215
2216        segs = kcalloc(segs_cnt, sizeof(*segs), GFP_KERNEL);
2217        if (!segs)
2218                return -ENOMEM;
2219
2220        /* Construct the packet segment info from the hashed fields */
2221        status = ice_flow_set_rss_seg_info(&segs[segs_cnt - 1], hashed_flds,
2222                                           addl_hdrs);
2223        if (status)
2224                goto out;
2225
2226        prof = ice_flow_find_prof_conds(hw, blk, ICE_FLOW_RX, segs, segs_cnt,
2227                                        vsi_handle,
2228                                        ICE_FLOW_FIND_PROF_CHK_FLDS);
2229        if (!prof) {
2230                status = -ENOENT;
2231                goto out;
2232        }
2233
2234        status = ice_flow_disassoc_prof(hw, blk, prof, vsi_handle);
2235        if (status)
2236                goto out;
2237
2238        /* Remove RSS configuration from VSI context before deleting
2239         * the flow profile.
2240         */
2241        ice_rem_rss_list(hw, vsi_handle, prof);
2242
2243        if (bitmap_empty(prof->vsis, ICE_MAX_VSI))
2244                status = ice_flow_rem_prof(hw, blk, prof->id);
2245
2246out:
2247        kfree(segs);
2248        return status;
2249}
2250
2251/**
2252 * ice_rem_rss_cfg - remove an existing RSS config with matching hashed fields
2253 * @hw: pointer to the hardware structure
2254 * @vsi_handle: software VSI handle
2255 * @hashed_flds: Packet hash types (ICE_FLOW_HASH_*) to remove
2256 * @addl_hdrs: Protocol header fields within a packet segment
2257 *
2258 * This function will lookup the flow profile based on the input
2259 * hash field bitmap, iterate through the profile entry list of
2260 * that profile and find entry associated with input VSI to be
2261 * removed. Calls are made to underlying flow s which will APIs
2262 * turn build or update buffers for RSS XLT1 section.
2263 */
2264int __maybe_unused
2265ice_rem_rss_cfg(struct ice_hw *hw, u16 vsi_handle, u64 hashed_flds,
2266                u32 addl_hdrs)
2267{
2268        int status;
2269
2270        if (hashed_flds == ICE_HASH_INVALID ||
2271            !ice_is_vsi_valid(hw, vsi_handle))
2272                return -EINVAL;
2273
2274        mutex_lock(&hw->rss_locks);
2275        status = ice_rem_rss_cfg_sync(hw, vsi_handle, hashed_flds, addl_hdrs,
2276                                      ICE_RSS_OUTER_HEADERS);
2277        if (!status)
2278                status = ice_rem_rss_cfg_sync(hw, vsi_handle, hashed_flds,
2279                                              addl_hdrs, ICE_RSS_INNER_HEADERS);
2280        mutex_unlock(&hw->rss_locks);
2281
2282        return status;
2283}
2284
2285/* Mapping of AVF hash bit fields to an L3-L4 hash combination.
2286 * As the ice_flow_avf_hdr_field represent individual bit shifts in a hash,
2287 * convert its values to their appropriate flow L3, L4 values.
2288 */
2289#define ICE_FLOW_AVF_RSS_IPV4_MASKS \
2290        (BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_OTHER) | \
2291         BIT_ULL(ICE_AVF_FLOW_FIELD_FRAG_IPV4))
2292#define ICE_FLOW_AVF_RSS_TCP_IPV4_MASKS \
2293        (BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_TCP_SYN_NO_ACK) | \
2294         BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_TCP))
2295#define ICE_FLOW_AVF_RSS_UDP_IPV4_MASKS \
2296        (BIT_ULL(ICE_AVF_FLOW_FIELD_UNICAST_IPV4_UDP) | \
2297         BIT_ULL(ICE_AVF_FLOW_FIELD_MULTICAST_IPV4_UDP) | \
2298         BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_UDP))
2299#define ICE_FLOW_AVF_RSS_ALL_IPV4_MASKS \
2300        (ICE_FLOW_AVF_RSS_TCP_IPV4_MASKS | ICE_FLOW_AVF_RSS_UDP_IPV4_MASKS | \
2301         ICE_FLOW_AVF_RSS_IPV4_MASKS | BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_SCTP))
2302
2303#define ICE_FLOW_AVF_RSS_IPV6_MASKS \
2304        (BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_OTHER) | \
2305         BIT_ULL(ICE_AVF_FLOW_FIELD_FRAG_IPV6))
2306#define ICE_FLOW_AVF_RSS_UDP_IPV6_MASKS \
2307        (BIT_ULL(ICE_AVF_FLOW_FIELD_UNICAST_IPV6_UDP) | \
2308         BIT_ULL(ICE_AVF_FLOW_FIELD_MULTICAST_IPV6_UDP) | \
2309         BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_UDP))
2310#define ICE_FLOW_AVF_RSS_TCP_IPV6_MASKS \
2311        (BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_TCP_SYN_NO_ACK) | \
2312         BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_TCP))
2313#define ICE_FLOW_AVF_RSS_ALL_IPV6_MASKS \
2314        (ICE_FLOW_AVF_RSS_TCP_IPV6_MASKS | ICE_FLOW_AVF_RSS_UDP_IPV6_MASKS | \
2315         ICE_FLOW_AVF_RSS_IPV6_MASKS | BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_SCTP))
2316
2317/**
2318 * ice_add_avf_rss_cfg - add an RSS configuration for AVF driver
2319 * @hw: pointer to the hardware structure
2320 * @vsi_handle: software VSI handle
2321 * @avf_hash: hash bit fields (ICE_AVF_FLOW_FIELD_*) to configure
2322 *
2323 * This function will take the hash bitmap provided by the AVF driver via a
2324 * message, convert it to ICE-compatible values, and configure RSS flow
2325 * profiles.
2326 */
2327int ice_add_avf_rss_cfg(struct ice_hw *hw, u16 vsi_handle, u64 avf_hash)
2328{
2329        int status = 0;
2330        u64 hash_flds;
2331
2332        if (avf_hash == ICE_AVF_FLOW_FIELD_INVALID ||
2333            !ice_is_vsi_valid(hw, vsi_handle))
2334                return -EINVAL;
2335
2336        /* Make sure no unsupported bits are specified */
2337        if (avf_hash & ~(ICE_FLOW_AVF_RSS_ALL_IPV4_MASKS |
2338                         ICE_FLOW_AVF_RSS_ALL_IPV6_MASKS))
2339                return -EIO;
2340
2341        hash_flds = avf_hash;
2342
2343        /* Always create an L3 RSS configuration for any L4 RSS configuration */
2344        if (hash_flds & ICE_FLOW_AVF_RSS_ALL_IPV4_MASKS)
2345                hash_flds |= ICE_FLOW_AVF_RSS_IPV4_MASKS;
2346
2347        if (hash_flds & ICE_FLOW_AVF_RSS_ALL_IPV6_MASKS)
2348                hash_flds |= ICE_FLOW_AVF_RSS_IPV6_MASKS;
2349
2350        /* Create the corresponding RSS configuration for each valid hash bit */
2351        while (hash_flds) {
2352                u64 rss_hash = ICE_HASH_INVALID;
2353
2354                if (hash_flds & ICE_FLOW_AVF_RSS_ALL_IPV4_MASKS) {
2355                        if (hash_flds & ICE_FLOW_AVF_RSS_IPV4_MASKS) {
2356                                rss_hash = ICE_FLOW_HASH_IPV4;
2357                                hash_flds &= ~ICE_FLOW_AVF_RSS_IPV4_MASKS;
2358                        } else if (hash_flds &
2359                                   ICE_FLOW_AVF_RSS_TCP_IPV4_MASKS) {
2360                                rss_hash = ICE_FLOW_HASH_IPV4 |
2361                                        ICE_FLOW_HASH_TCP_PORT;
2362                                hash_flds &= ~ICE_FLOW_AVF_RSS_TCP_IPV4_MASKS;
2363                        } else if (hash_flds &
2364                                   ICE_FLOW_AVF_RSS_UDP_IPV4_MASKS) {
2365                                rss_hash = ICE_FLOW_HASH_IPV4 |
2366                                        ICE_FLOW_HASH_UDP_PORT;
2367                                hash_flds &= ~ICE_FLOW_AVF_RSS_UDP_IPV4_MASKS;
2368                        } else if (hash_flds &
2369                                   BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_SCTP)) {
2370                                rss_hash = ICE_FLOW_HASH_IPV4 |
2371                                        ICE_FLOW_HASH_SCTP_PORT;
2372                                hash_flds &=
2373                                        ~BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_SCTP);
2374                        }
2375                } else if (hash_flds & ICE_FLOW_AVF_RSS_ALL_IPV6_MASKS) {
2376                        if (hash_flds & ICE_FLOW_AVF_RSS_IPV6_MASKS) {
2377                                rss_hash = ICE_FLOW_HASH_IPV6;
2378                                hash_flds &= ~ICE_FLOW_AVF_RSS_IPV6_MASKS;
2379                        } else if (hash_flds &
2380                                   ICE_FLOW_AVF_RSS_TCP_IPV6_MASKS) {
2381                                rss_hash = ICE_FLOW_HASH_IPV6 |
2382                                        ICE_FLOW_HASH_TCP_PORT;
2383                                hash_flds &= ~ICE_FLOW_AVF_RSS_TCP_IPV6_MASKS;
2384                        } else if (hash_flds &
2385                                   ICE_FLOW_AVF_RSS_UDP_IPV6_MASKS) {
2386                                rss_hash = ICE_FLOW_HASH_IPV6 |
2387                                        ICE_FLOW_HASH_UDP_PORT;
2388                                hash_flds &= ~ICE_FLOW_AVF_RSS_UDP_IPV6_MASKS;
2389                        } else if (hash_flds &
2390                                   BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_SCTP)) {
2391                                rss_hash = ICE_FLOW_HASH_IPV6 |
2392                                        ICE_FLOW_HASH_SCTP_PORT;
2393                                hash_flds &=
2394                                        ~BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_SCTP);
2395                        }
2396                }
2397
2398                if (rss_hash == ICE_HASH_INVALID)
2399                        return -EIO;
2400
2401                status = ice_add_rss_cfg(hw, vsi_handle, rss_hash,
2402                                         ICE_FLOW_SEG_HDR_NONE);
2403                if (status)
2404                        break;
2405        }
2406
2407        return status;
2408}
2409
2410/**
2411 * ice_replay_rss_cfg - replay RSS configurations associated with VSI
2412 * @hw: pointer to the hardware structure
2413 * @vsi_handle: software VSI handle
2414 */
2415int ice_replay_rss_cfg(struct ice_hw *hw, u16 vsi_handle)
2416{
2417        struct ice_rss_cfg *r;
2418        int status = 0;
2419
2420        if (!ice_is_vsi_valid(hw, vsi_handle))
2421                return -EINVAL;
2422
2423        mutex_lock(&hw->rss_locks);
2424        list_for_each_entry(r, &hw->rss_list_head, l_entry) {
2425                if (test_bit(vsi_handle, r->vsis)) {
2426                        status = ice_add_rss_cfg_sync(hw, vsi_handle,
2427                                                      r->hashed_flds,
2428                                                      r->packet_hdr,
2429                                                      ICE_RSS_OUTER_HEADERS);
2430                        if (status)
2431                                break;
2432                        status = ice_add_rss_cfg_sync(hw, vsi_handle,
2433                                                      r->hashed_flds,
2434                                                      r->packet_hdr,
2435                                                      ICE_RSS_INNER_HEADERS);
2436                        if (status)
2437                                break;
2438                }
2439        }
2440        mutex_unlock(&hw->rss_locks);
2441
2442        return status;
2443}
2444
2445/**
2446 * ice_get_rss_cfg - returns hashed fields for the given header types
2447 * @hw: pointer to the hardware structure
2448 * @vsi_handle: software VSI handle
2449 * @hdrs: protocol header type
2450 *
2451 * This function will return the match fields of the first instance of flow
2452 * profile having the given header types and containing input VSI
2453 */
2454u64 ice_get_rss_cfg(struct ice_hw *hw, u16 vsi_handle, u32 hdrs)
2455{
2456        u64 rss_hash = ICE_HASH_INVALID;
2457        struct ice_rss_cfg *r;
2458
2459        /* verify if the protocol header is non zero and VSI is valid */
2460        if (hdrs == ICE_FLOW_SEG_HDR_NONE || !ice_is_vsi_valid(hw, vsi_handle))
2461                return ICE_HASH_INVALID;
2462
2463        mutex_lock(&hw->rss_locks);
2464        list_for_each_entry(r, &hw->rss_list_head, l_entry)
2465                if (test_bit(vsi_handle, r->vsis) &&
2466                    r->packet_hdr == hdrs) {
2467                        rss_hash = r->hashed_flds;
2468                        break;
2469                }
2470        mutex_unlock(&hw->rss_locks);
2471
2472        return rss_hash;
2473}
2474