Linux Audio

Check our new training course

Linux kernel drivers training

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