File Index
Files and directories
Sign in
FILE

ice_switch.c

File preview with syntax highlighting.

linux-6.19.14/drivers/net/ethernet/intel/ice/ice_switch.c C
   1// SPDX-License-Identifier: GPL-2.0
   2/* Copyright (c) 2018, Intel Corporation. */
   3
   4#include "ice_lib.h"
   5#include "ice_switch.h"
   6#include "ice_trace.h"
   7
   8#define ICE_ETH_DA_OFFSET		0
   9#define ICE_ETH_ETHTYPE_OFFSET		12
  10#define ICE_ETH_VLAN_TCI_OFFSET		14
  11#define ICE_MAX_VLAN_ID			0xFFF
  12#define ICE_IPV6_ETHER_ID		0x86DD
  13
  14/* Dummy ethernet header needed in the ice_aqc_sw_rules_elem
  15 * struct to configure any switch filter rules.
  16 * {DA (6 bytes), SA(6 bytes),
  17 * Ether type (2 bytes for header without VLAN tag) OR
  18 * VLAN tag (4 bytes for header with VLAN tag) }
  19 *
  20 * Word on Hardcoded values
  21 * byte 0 = 0x2: to identify it as locally administered DA MAC
  22 * byte 6 = 0x2: to identify it as locally administered SA MAC
  23 * byte 12 = 0x81 & byte 13 = 0x00:
  24 *      In case of VLAN filter first two bytes defines ether type (0x8100)
  25 *      and remaining two bytes are placeholder for programming a given VLAN ID
  26 *      In case of Ether type filter it is treated as header without VLAN tag
  27 *      and byte 12 and 13 is used to program a given Ether type instead
  28 */
  29static const u8 dummy_eth_header[DUMMY_ETH_HDR_LEN] = { 0x2, 0, 0, 0, 0, 0,
  30							0x2, 0, 0, 0, 0, 0,
  31							0x81, 0, 0, 0};
  32
  33enum {
  34	ICE_PKT_OUTER_IPV6	= BIT(0),
  35	ICE_PKT_TUN_GTPC	= BIT(1),
  36	ICE_PKT_TUN_GTPU	= BIT(2),
  37	ICE_PKT_TUN_NVGRE	= BIT(3),
  38	ICE_PKT_TUN_UDP		= BIT(4),
  39	ICE_PKT_INNER_IPV6	= BIT(5),
  40	ICE_PKT_INNER_TCP	= BIT(6),
  41	ICE_PKT_INNER_UDP	= BIT(7),
  42	ICE_PKT_GTP_NOPAY	= BIT(8),
  43	ICE_PKT_KMALLOC		= BIT(9),
  44	ICE_PKT_PPPOE		= BIT(10),
  45	ICE_PKT_L2TPV3		= BIT(11),
  46	ICE_PKT_PFCP		= BIT(12),
  47};
  48
  49struct ice_dummy_pkt_offsets {
  50	enum ice_protocol_type type;
  51	u16 offset; /* ICE_PROTOCOL_LAST indicates end of list */
  52};
  53
  54struct ice_dummy_pkt_profile {
  55	const struct ice_dummy_pkt_offsets *offsets;
  56	const u8 *pkt;
  57	u32 match;
  58	u16 pkt_len;
  59	u16 offsets_len;
  60};
  61
  62#define ICE_DECLARE_PKT_OFFSETS(type)					\
  63	static const struct ice_dummy_pkt_offsets			\
  64	ice_dummy_##type##_packet_offsets[]
  65
  66#define ICE_DECLARE_PKT_TEMPLATE(type)					\
  67	static const u8 ice_dummy_##type##_packet[]
  68
  69#define ICE_PKT_PROFILE(type, m) {					\
  70	.match		= (m),						\
  71	.pkt		= ice_dummy_##type##_packet,			\
  72	.pkt_len	= sizeof(ice_dummy_##type##_packet),		\
  73	.offsets	= ice_dummy_##type##_packet_offsets,		\
  74	.offsets_len	= sizeof(ice_dummy_##type##_packet_offsets),	\
  75}
  76
  77ICE_DECLARE_PKT_OFFSETS(vlan) = {
  78	{ ICE_VLAN_OFOS,        12 },
  79};
  80
  81ICE_DECLARE_PKT_TEMPLATE(vlan) = {
  82	0x81, 0x00, 0x00, 0x00, /* ICE_VLAN_OFOS 12 */
  83};
  84
  85ICE_DECLARE_PKT_OFFSETS(qinq) = {
  86	{ ICE_VLAN_EX,          12 },
  87	{ ICE_VLAN_IN,          16 },
  88};
  89
  90ICE_DECLARE_PKT_TEMPLATE(qinq) = {
  91	0x91, 0x00, 0x00, 0x00, /* ICE_VLAN_EX 12 */
  92	0x81, 0x00, 0x00, 0x00, /* ICE_VLAN_IN 16 */
  93};
  94
  95ICE_DECLARE_PKT_OFFSETS(gre_tcp) = {
  96	{ ICE_MAC_OFOS,		0 },
  97	{ ICE_ETYPE_OL,		12 },
  98	{ ICE_IPV4_OFOS,	14 },
  99	{ ICE_NVGRE,		34 },
 100	{ ICE_MAC_IL,		42 },
 101	{ ICE_ETYPE_IL,		54 },
 102	{ ICE_IPV4_IL,		56 },
 103	{ ICE_TCP_IL,		76 },
 104	{ ICE_PROTOCOL_LAST,	0 },
 105};
 106
 107ICE_DECLARE_PKT_TEMPLATE(gre_tcp) = {
 108	0x00, 0x00, 0x00, 0x00,	/* ICE_MAC_OFOS 0 */
 109	0x00, 0x00, 0x00, 0x00,
 110	0x00, 0x00, 0x00, 0x00,
 111
 112	0x08, 0x00,		/* ICE_ETYPE_OL 12 */
 113
 114	0x45, 0x00, 0x00, 0x3E,	/* ICE_IPV4_OFOS 14 */
 115	0x00, 0x00, 0x00, 0x00,
 116	0x00, 0x2F, 0x00, 0x00,
 117	0x00, 0x00, 0x00, 0x00,
 118	0x00, 0x00, 0x00, 0x00,
 119
 120	0x80, 0x00, 0x65, 0x58,	/* ICE_NVGRE 34 */
 121	0x00, 0x00, 0x00, 0x00,
 122
 123	0x00, 0x00, 0x00, 0x00,	/* ICE_MAC_IL 42 */
 124	0x00, 0x00, 0x00, 0x00,
 125	0x00, 0x00, 0x00, 0x00,
 126
 127	0x08, 0x00,		/* ICE_ETYPE_IL 54 */
 128
 129	0x45, 0x00, 0x00, 0x14,	/* ICE_IPV4_IL 56 */
 130	0x00, 0x00, 0x00, 0x00,
 131	0x00, 0x06, 0x00, 0x00,
 132	0x00, 0x00, 0x00, 0x00,
 133	0x00, 0x00, 0x00, 0x00,
 134
 135	0x00, 0x00, 0x00, 0x00,	/* ICE_TCP_IL 76 */
 136	0x00, 0x00, 0x00, 0x00,
 137	0x00, 0x00, 0x00, 0x00,
 138	0x50, 0x02, 0x20, 0x00,
 139	0x00, 0x00, 0x00, 0x00
 140};
 141
 142ICE_DECLARE_PKT_OFFSETS(gre_udp) = {
 143	{ ICE_MAC_OFOS,		0 },
 144	{ ICE_ETYPE_OL,		12 },
 145	{ ICE_IPV4_OFOS,	14 },
 146	{ ICE_NVGRE,		34 },
 147	{ ICE_MAC_IL,		42 },
 148	{ ICE_ETYPE_IL,		54 },
 149	{ ICE_IPV4_IL,		56 },
 150	{ ICE_UDP_ILOS,		76 },
 151	{ ICE_PROTOCOL_LAST,	0 },
 152};
 153
 154ICE_DECLARE_PKT_TEMPLATE(gre_udp) = {
 155	0x00, 0x00, 0x00, 0x00,	/* ICE_MAC_OFOS 0 */
 156	0x00, 0x00, 0x00, 0x00,
 157	0x00, 0x00, 0x00, 0x00,
 158
 159	0x08, 0x00,		/* ICE_ETYPE_OL 12 */
 160
 161	0x45, 0x00, 0x00, 0x3E,	/* ICE_IPV4_OFOS 14 */
 162	0x00, 0x00, 0x00, 0x00,
 163	0x00, 0x2F, 0x00, 0x00,
 164	0x00, 0x00, 0x00, 0x00,
 165	0x00, 0x00, 0x00, 0x00,
 166
 167	0x80, 0x00, 0x65, 0x58,	/* ICE_NVGRE 34 */
 168	0x00, 0x00, 0x00, 0x00,
 169
 170	0x00, 0x00, 0x00, 0x00,	/* ICE_MAC_IL 42 */
 171	0x00, 0x00, 0x00, 0x00,
 172	0x00, 0x00, 0x00, 0x00,
 173
 174	0x08, 0x00,		/* ICE_ETYPE_IL 54 */
 175
 176	0x45, 0x00, 0x00, 0x14,	/* ICE_IPV4_IL 56 */
 177	0x00, 0x00, 0x00, 0x00,
 178	0x00, 0x11, 0x00, 0x00,
 179	0x00, 0x00, 0x00, 0x00,
 180	0x00, 0x00, 0x00, 0x00,
 181
 182	0x00, 0x00, 0x00, 0x00,	/* ICE_UDP_ILOS 76 */
 183	0x00, 0x08, 0x00, 0x00,
 184};
 185
 186ICE_DECLARE_PKT_OFFSETS(udp_tun_tcp) = {
 187	{ ICE_MAC_OFOS,		0 },
 188	{ ICE_ETYPE_OL,		12 },
 189	{ ICE_IPV4_OFOS,	14 },
 190	{ ICE_UDP_OF,		34 },
 191	{ ICE_VXLAN,		42 },
 192	{ ICE_GENEVE,		42 },
 193	{ ICE_VXLAN_GPE,	42 },
 194	{ ICE_MAC_IL,		50 },
 195	{ ICE_ETYPE_IL,		62 },
 196	{ ICE_IPV4_IL,		64 },
 197	{ ICE_TCP_IL,		84 },
 198	{ ICE_PROTOCOL_LAST,	0 },
 199};
 200
 201ICE_DECLARE_PKT_TEMPLATE(udp_tun_tcp) = {
 202	0x00, 0x00, 0x00, 0x00,  /* ICE_MAC_OFOS 0 */
 203	0x00, 0x00, 0x00, 0x00,
 204	0x00, 0x00, 0x00, 0x00,
 205
 206	0x08, 0x00,		/* ICE_ETYPE_OL 12 */
 207
 208	0x45, 0x00, 0x00, 0x5a, /* ICE_IPV4_OFOS 14 */
 209	0x00, 0x01, 0x00, 0x00,
 210	0x40, 0x11, 0x00, 0x00,
 211	0x00, 0x00, 0x00, 0x00,
 212	0x00, 0x00, 0x00, 0x00,
 213
 214	0x00, 0x00, 0x12, 0xb5, /* ICE_UDP_OF 34 */
 215	0x00, 0x46, 0x00, 0x00,
 216
 217	0x00, 0x00, 0x65, 0x58, /* ICE_VXLAN 42 */
 218	0x00, 0x00, 0x00, 0x00,
 219
 220	0x00, 0x00, 0x00, 0x00, /* ICE_MAC_IL 50 */
 221	0x00, 0x00, 0x00, 0x00,
 222	0x00, 0x00, 0x00, 0x00,
 223
 224	0x08, 0x00,		/* ICE_ETYPE_IL 62 */
 225
 226	0x45, 0x00, 0x00, 0x28, /* ICE_IPV4_IL 64 */
 227	0x00, 0x01, 0x00, 0x00,
 228	0x40, 0x06, 0x00, 0x00,
 229	0x00, 0x00, 0x00, 0x00,
 230	0x00, 0x00, 0x00, 0x00,
 231
 232	0x00, 0x00, 0x00, 0x00, /* ICE_TCP_IL 84 */
 233	0x00, 0x00, 0x00, 0x00,
 234	0x00, 0x00, 0x00, 0x00,
 235	0x50, 0x02, 0x20, 0x00,
 236	0x00, 0x00, 0x00, 0x00
 237};
 238
 239ICE_DECLARE_PKT_OFFSETS(udp_tun_udp) = {
 240	{ ICE_MAC_OFOS,		0 },
 241	{ ICE_ETYPE_OL,		12 },
 242	{ ICE_IPV4_OFOS,	14 },
 243	{ ICE_UDP_OF,		34 },
 244	{ ICE_VXLAN,		42 },
 245	{ ICE_GENEVE,		42 },
 246	{ ICE_VXLAN_GPE,	42 },
 247	{ ICE_MAC_IL,		50 },
 248	{ ICE_ETYPE_IL,		62 },
 249	{ ICE_IPV4_IL,		64 },
 250	{ ICE_UDP_ILOS,		84 },
 251	{ ICE_PROTOCOL_LAST,	0 },
 252};
 253
 254ICE_DECLARE_PKT_TEMPLATE(udp_tun_udp) = {
 255	0x00, 0x00, 0x00, 0x00,  /* ICE_MAC_OFOS 0 */
 256	0x00, 0x00, 0x00, 0x00,
 257	0x00, 0x00, 0x00, 0x00,
 258
 259	0x08, 0x00,		/* ICE_ETYPE_OL 12 */
 260
 261	0x45, 0x00, 0x00, 0x4e, /* ICE_IPV4_OFOS 14 */
 262	0x00, 0x01, 0x00, 0x00,
 263	0x00, 0x11, 0x00, 0x00,
 264	0x00, 0x00, 0x00, 0x00,
 265	0x00, 0x00, 0x00, 0x00,
 266
 267	0x00, 0x00, 0x12, 0xb5, /* ICE_UDP_OF 34 */
 268	0x00, 0x3a, 0x00, 0x00,
 269
 270	0x00, 0x00, 0x65, 0x58, /* ICE_VXLAN 42 */
 271	0x00, 0x00, 0x00, 0x00,
 272
 273	0x00, 0x00, 0x00, 0x00, /* ICE_MAC_IL 50 */
 274	0x00, 0x00, 0x00, 0x00,
 275	0x00, 0x00, 0x00, 0x00,
 276
 277	0x08, 0x00,		/* ICE_ETYPE_IL 62 */
 278
 279	0x45, 0x00, 0x00, 0x1c, /* ICE_IPV4_IL 64 */
 280	0x00, 0x01, 0x00, 0x00,
 281	0x00, 0x11, 0x00, 0x00,
 282	0x00, 0x00, 0x00, 0x00,
 283	0x00, 0x00, 0x00, 0x00,
 284
 285	0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 84 */
 286	0x00, 0x08, 0x00, 0x00,
 287};
 288
 289ICE_DECLARE_PKT_OFFSETS(gre_ipv6_tcp) = {
 290	{ ICE_MAC_OFOS,		0 },
 291	{ ICE_ETYPE_OL,		12 },
 292	{ ICE_IPV4_OFOS,	14 },
 293	{ ICE_NVGRE,		34 },
 294	{ ICE_MAC_IL,		42 },
 295	{ ICE_ETYPE_IL,		54 },
 296	{ ICE_IPV6_IL,		56 },
 297	{ ICE_TCP_IL,		96 },
 298	{ ICE_PROTOCOL_LAST,	0 },
 299};
 300
 301ICE_DECLARE_PKT_TEMPLATE(gre_ipv6_tcp) = {
 302	0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
 303	0x00, 0x00, 0x00, 0x00,
 304	0x00, 0x00, 0x00, 0x00,
 305
 306	0x08, 0x00,		/* ICE_ETYPE_OL 12 */
 307
 308	0x45, 0x00, 0x00, 0x66, /* ICE_IPV4_OFOS 14 */
 309	0x00, 0x00, 0x00, 0x00,
 310	0x00, 0x2F, 0x00, 0x00,
 311	0x00, 0x00, 0x00, 0x00,
 312	0x00, 0x00, 0x00, 0x00,
 313
 314	0x80, 0x00, 0x65, 0x58, /* ICE_NVGRE 34 */
 315	0x00, 0x00, 0x00, 0x00,
 316
 317	0x00, 0x00, 0x00, 0x00, /* ICE_MAC_IL 42 */
 318	0x00, 0x00, 0x00, 0x00,
 319	0x00, 0x00, 0x00, 0x00,
 320
 321	0x86, 0xdd,		/* ICE_ETYPE_IL 54 */
 322
 323	0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_IL 56 */
 324	0x00, 0x08, 0x06, 0x40,
 325	0x00, 0x00, 0x00, 0x00,
 326	0x00, 0x00, 0x00, 0x00,
 327	0x00, 0x00, 0x00, 0x00,
 328	0x00, 0x00, 0x00, 0x00,
 329	0x00, 0x00, 0x00, 0x00,
 330	0x00, 0x00, 0x00, 0x00,
 331	0x00, 0x00, 0x00, 0x00,
 332	0x00, 0x00, 0x00, 0x00,
 333
 334	0x00, 0x00, 0x00, 0x00, /* ICE_TCP_IL 96 */
 335	0x00, 0x00, 0x00, 0x00,
 336	0x00, 0x00, 0x00, 0x00,
 337	0x50, 0x02, 0x20, 0x00,
 338	0x00, 0x00, 0x00, 0x00
 339};
 340
 341ICE_DECLARE_PKT_OFFSETS(gre_ipv6_udp) = {
 342	{ ICE_MAC_OFOS,		0 },
 343	{ ICE_ETYPE_OL,		12 },
 344	{ ICE_IPV4_OFOS,	14 },
 345	{ ICE_NVGRE,		34 },
 346	{ ICE_MAC_IL,		42 },
 347	{ ICE_ETYPE_IL,		54 },
 348	{ ICE_IPV6_IL,		56 },
 349	{ ICE_UDP_ILOS,		96 },
 350	{ ICE_PROTOCOL_LAST,	0 },
 351};
 352
 353ICE_DECLARE_PKT_TEMPLATE(gre_ipv6_udp) = {
 354	0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
 355	0x00, 0x00, 0x00, 0x00,
 356	0x00, 0x00, 0x00, 0x00,
 357
 358	0x08, 0x00,		/* ICE_ETYPE_OL 12 */
 359
 360	0x45, 0x00, 0x00, 0x5a, /* ICE_IPV4_OFOS 14 */
 361	0x00, 0x00, 0x00, 0x00,
 362	0x00, 0x2F, 0x00, 0x00,
 363	0x00, 0x00, 0x00, 0x00,
 364	0x00, 0x00, 0x00, 0x00,
 365
 366	0x80, 0x00, 0x65, 0x58, /* ICE_NVGRE 34 */
 367	0x00, 0x00, 0x00, 0x00,
 368
 369	0x00, 0x00, 0x00, 0x00, /* ICE_MAC_IL 42 */
 370	0x00, 0x00, 0x00, 0x00,
 371	0x00, 0x00, 0x00, 0x00,
 372
 373	0x86, 0xdd,		/* ICE_ETYPE_IL 54 */
 374
 375	0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_IL 56 */
 376	0x00, 0x08, 0x11, 0x40,
 377	0x00, 0x00, 0x00, 0x00,
 378	0x00, 0x00, 0x00, 0x00,
 379	0x00, 0x00, 0x00, 0x00,
 380	0x00, 0x00, 0x00, 0x00,
 381	0x00, 0x00, 0x00, 0x00,
 382	0x00, 0x00, 0x00, 0x00,
 383	0x00, 0x00, 0x00, 0x00,
 384	0x00, 0x00, 0x00, 0x00,
 385
 386	0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 96 */
 387	0x00, 0x08, 0x00, 0x00,
 388};
 389
 390ICE_DECLARE_PKT_OFFSETS(udp_tun_ipv6_tcp) = {
 391	{ ICE_MAC_OFOS,		0 },
 392	{ ICE_ETYPE_OL,		12 },
 393	{ ICE_IPV4_OFOS,	14 },
 394	{ ICE_UDP_OF,		34 },
 395	{ ICE_VXLAN,		42 },
 396	{ ICE_GENEVE,		42 },
 397	{ ICE_VXLAN_GPE,	42 },
 398	{ ICE_MAC_IL,		50 },
 399	{ ICE_ETYPE_IL,		62 },
 400	{ ICE_IPV6_IL,		64 },
 401	{ ICE_TCP_IL,		104 },
 402	{ ICE_PROTOCOL_LAST,	0 },
 403};
 404
 405ICE_DECLARE_PKT_TEMPLATE(udp_tun_ipv6_tcp) = {
 406	0x00, 0x00, 0x00, 0x00,  /* ICE_MAC_OFOS 0 */
 407	0x00, 0x00, 0x00, 0x00,
 408	0x00, 0x00, 0x00, 0x00,
 409
 410	0x08, 0x00,		/* ICE_ETYPE_OL 12 */
 411
 412	0x45, 0x00, 0x00, 0x6e, /* ICE_IPV4_OFOS 14 */
 413	0x00, 0x01, 0x00, 0x00,
 414	0x40, 0x11, 0x00, 0x00,
 415	0x00, 0x00, 0x00, 0x00,
 416	0x00, 0x00, 0x00, 0x00,
 417
 418	0x00, 0x00, 0x12, 0xb5, /* ICE_UDP_OF 34 */
 419	0x00, 0x5a, 0x00, 0x00,
 420
 421	0x00, 0x00, 0x65, 0x58, /* ICE_VXLAN 42 */
 422	0x00, 0x00, 0x00, 0x00,
 423
 424	0x00, 0x00, 0x00, 0x00, /* ICE_MAC_IL 50 */
 425	0x00, 0x00, 0x00, 0x00,
 426	0x00, 0x00, 0x00, 0x00,
 427
 428	0x86, 0xdd,		/* ICE_ETYPE_IL 62 */
 429
 430	0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_IL 64 */
 431	0x00, 0x08, 0x06, 0x40,
 432	0x00, 0x00, 0x00, 0x00,
 433	0x00, 0x00, 0x00, 0x00,
 434	0x00, 0x00, 0x00, 0x00,
 435	0x00, 0x00, 0x00, 0x00,
 436	0x00, 0x00, 0x00, 0x00,
 437	0x00, 0x00, 0x00, 0x00,
 438	0x00, 0x00, 0x00, 0x00,
 439	0x00, 0x00, 0x00, 0x00,
 440
 441	0x00, 0x00, 0x00, 0x00, /* ICE_TCP_IL 104 */
 442	0x00, 0x00, 0x00, 0x00,
 443	0x00, 0x00, 0x00, 0x00,
 444	0x50, 0x02, 0x20, 0x00,
 445	0x00, 0x00, 0x00, 0x00
 446};
 447
 448ICE_DECLARE_PKT_OFFSETS(udp_tun_ipv6_udp) = {
 449	{ ICE_MAC_OFOS,		0 },
 450	{ ICE_ETYPE_OL,		12 },
 451	{ ICE_IPV4_OFOS,	14 },
 452	{ ICE_UDP_OF,		34 },
 453	{ ICE_VXLAN,		42 },
 454	{ ICE_GENEVE,		42 },
 455	{ ICE_VXLAN_GPE,	42 },
 456	{ ICE_MAC_IL,		50 },
 457	{ ICE_ETYPE_IL,		62 },
 458	{ ICE_IPV6_IL,		64 },
 459	{ ICE_UDP_ILOS,		104 },
 460	{ ICE_PROTOCOL_LAST,	0 },
 461};
 462
 463ICE_DECLARE_PKT_TEMPLATE(udp_tun_ipv6_udp) = {
 464	0x00, 0x00, 0x00, 0x00,  /* ICE_MAC_OFOS 0 */
 465	0x00, 0x00, 0x00, 0x00,
 466	0x00, 0x00, 0x00, 0x00,
 467
 468	0x08, 0x00,		/* ICE_ETYPE_OL 12 */
 469
 470	0x45, 0x00, 0x00, 0x62, /* ICE_IPV4_OFOS 14 */
 471	0x00, 0x01, 0x00, 0x00,
 472	0x00, 0x11, 0x00, 0x00,
 473	0x00, 0x00, 0x00, 0x00,
 474	0x00, 0x00, 0x00, 0x00,
 475
 476	0x00, 0x00, 0x12, 0xb5, /* ICE_UDP_OF 34 */
 477	0x00, 0x4e, 0x00, 0x00,
 478
 479	0x00, 0x00, 0x65, 0x58, /* ICE_VXLAN 42 */
 480	0x00, 0x00, 0x00, 0x00,
 481
 482	0x00, 0x00, 0x00, 0x00, /* ICE_MAC_IL 50 */
 483	0x00, 0x00, 0x00, 0x00,
 484	0x00, 0x00, 0x00, 0x00,
 485
 486	0x86, 0xdd,		/* ICE_ETYPE_IL 62 */
 487
 488	0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_IL 64 */
 489	0x00, 0x08, 0x11, 0x40,
 490	0x00, 0x00, 0x00, 0x00,
 491	0x00, 0x00, 0x00, 0x00,
 492	0x00, 0x00, 0x00, 0x00,
 493	0x00, 0x00, 0x00, 0x00,
 494	0x00, 0x00, 0x00, 0x00,
 495	0x00, 0x00, 0x00, 0x00,
 496	0x00, 0x00, 0x00, 0x00,
 497	0x00, 0x00, 0x00, 0x00,
 498
 499	0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 104 */
 500	0x00, 0x08, 0x00, 0x00,
 501};
 502
 503/* offset info for MAC + IPv4 + UDP dummy packet */
 504ICE_DECLARE_PKT_OFFSETS(udp) = {
 505	{ ICE_MAC_OFOS,		0 },
 506	{ ICE_ETYPE_OL,		12 },
 507	{ ICE_IPV4_OFOS,	14 },
 508	{ ICE_UDP_ILOS,		34 },
 509	{ ICE_PROTOCOL_LAST,	0 },
 510};
 511
 512/* Dummy packet for MAC + IPv4 + UDP */
 513ICE_DECLARE_PKT_TEMPLATE(udp) = {
 514	0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
 515	0x00, 0x00, 0x00, 0x00,
 516	0x00, 0x00, 0x00, 0x00,
 517
 518	0x08, 0x00,		/* ICE_ETYPE_OL 12 */
 519
 520	0x45, 0x00, 0x00, 0x1c, /* ICE_IPV4_OFOS 14 */
 521	0x00, 0x01, 0x00, 0x00,
 522	0x00, 0x11, 0x00, 0x00,
 523	0x00, 0x00, 0x00, 0x00,
 524	0x00, 0x00, 0x00, 0x00,
 525
 526	0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 34 */
 527	0x00, 0x08, 0x00, 0x00,
 528
 529	0x00, 0x00,	/* 2 bytes for 4 byte alignment */
 530};
 531
 532/* offset info for MAC + IPv4 + TCP dummy packet */
 533ICE_DECLARE_PKT_OFFSETS(tcp) = {
 534	{ ICE_MAC_OFOS,		0 },
 535	{ ICE_ETYPE_OL,		12 },
 536	{ ICE_IPV4_OFOS,	14 },
 537	{ ICE_TCP_IL,		34 },
 538	{ ICE_PROTOCOL_LAST,	0 },
 539};
 540
 541/* Dummy packet for MAC + IPv4 + TCP */
 542ICE_DECLARE_PKT_TEMPLATE(tcp) = {
 543	0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
 544	0x00, 0x00, 0x00, 0x00,
 545	0x00, 0x00, 0x00, 0x00,
 546
 547	0x08, 0x00,		/* ICE_ETYPE_OL 12 */
 548
 549	0x45, 0x00, 0x00, 0x28, /* ICE_IPV4_OFOS 14 */
 550	0x00, 0x01, 0x00, 0x00,
 551	0x00, 0x06, 0x00, 0x00,
 552	0x00, 0x00, 0x00, 0x00,
 553	0x00, 0x00, 0x00, 0x00,
 554
 555	0x00, 0x00, 0x00, 0x00, /* ICE_TCP_IL 34 */
 556	0x00, 0x00, 0x00, 0x00,
 557	0x00, 0x00, 0x00, 0x00,
 558	0x50, 0x00, 0x00, 0x00,
 559	0x00, 0x00, 0x00, 0x00,
 560
 561	0x00, 0x00,	/* 2 bytes for 4 byte alignment */
 562};
 563
 564ICE_DECLARE_PKT_OFFSETS(tcp_ipv6) = {
 565	{ ICE_MAC_OFOS,		0 },
 566	{ ICE_ETYPE_OL,		12 },
 567	{ ICE_IPV6_OFOS,	14 },
 568	{ ICE_TCP_IL,		54 },
 569	{ ICE_PROTOCOL_LAST,	0 },
 570};
 571
 572ICE_DECLARE_PKT_TEMPLATE(tcp_ipv6) = {
 573	0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
 574	0x00, 0x00, 0x00, 0x00,
 575	0x00, 0x00, 0x00, 0x00,
 576
 577	0x86, 0xDD,		/* ICE_ETYPE_OL 12 */
 578
 579	0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 40 */
 580	0x00, 0x14, 0x06, 0x00, /* Next header is TCP */
 581	0x00, 0x00, 0x00, 0x00,
 582	0x00, 0x00, 0x00, 0x00,
 583	0x00, 0x00, 0x00, 0x00,
 584	0x00, 0x00, 0x00, 0x00,
 585	0x00, 0x00, 0x00, 0x00,
 586	0x00, 0x00, 0x00, 0x00,
 587	0x00, 0x00, 0x00, 0x00,
 588	0x00, 0x00, 0x00, 0x00,
 589
 590	0x00, 0x00, 0x00, 0x00, /* ICE_TCP_IL 54 */
 591	0x00, 0x00, 0x00, 0x00,
 592	0x00, 0x00, 0x00, 0x00,
 593	0x50, 0x00, 0x00, 0x00,
 594	0x00, 0x00, 0x00, 0x00,
 595
 596	0x00, 0x00, /* 2 bytes for 4 byte alignment */
 597};
 598
 599/* IPv6 + UDP */
 600ICE_DECLARE_PKT_OFFSETS(udp_ipv6) = {
 601	{ ICE_MAC_OFOS,		0 },
 602	{ ICE_ETYPE_OL,		12 },
 603	{ ICE_IPV6_OFOS,	14 },
 604	{ ICE_UDP_ILOS,		54 },
 605	{ ICE_PROTOCOL_LAST,	0 },
 606};
 607
 608/* IPv6 + UDP dummy packet */
 609ICE_DECLARE_PKT_TEMPLATE(udp_ipv6) = {
 610	0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
 611	0x00, 0x00, 0x00, 0x00,
 612	0x00, 0x00, 0x00, 0x00,
 613
 614	0x86, 0xDD,		/* ICE_ETYPE_OL 12 */
 615
 616	0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 40 */
 617	0x00, 0x10, 0x11, 0x00, /* Next header UDP */
 618	0x00, 0x00, 0x00, 0x00,
 619	0x00, 0x00, 0x00, 0x00,
 620	0x00, 0x00, 0x00, 0x00,
 621	0x00, 0x00, 0x00, 0x00,
 622	0x00, 0x00, 0x00, 0x00,
 623	0x00, 0x00, 0x00, 0x00,
 624	0x00, 0x00, 0x00, 0x00,
 625	0x00, 0x00, 0x00, 0x00,
 626
 627	0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 54 */
 628	0x00, 0x10, 0x00, 0x00,
 629
 630	0x00, 0x00, 0x00, 0x00, /* needed for ESP packets */
 631	0x00, 0x00, 0x00, 0x00,
 632
 633	0x00, 0x00, /* 2 bytes for 4 byte alignment */
 634};
 635
 636/* Outer IPv4 + Outer UDP + GTP + Inner IPv4 + Inner TCP */
 637ICE_DECLARE_PKT_OFFSETS(ipv4_gtpu_ipv4_tcp) = {
 638	{ ICE_MAC_OFOS,		0 },
 639	{ ICE_IPV4_OFOS,	14 },
 640	{ ICE_UDP_OF,		34 },
 641	{ ICE_GTP,		42 },
 642	{ ICE_IPV4_IL,		62 },
 643	{ ICE_TCP_IL,		82 },
 644	{ ICE_PROTOCOL_LAST,	0 },
 645};
 646
 647ICE_DECLARE_PKT_TEMPLATE(ipv4_gtpu_ipv4_tcp) = {
 648	0x00, 0x00, 0x00, 0x00, /* Ethernet 0 */
 649	0x00, 0x00, 0x00, 0x00,
 650	0x00, 0x00, 0x00, 0x00,
 651	0x08, 0x00,
 652
 653	0x45, 0x00, 0x00, 0x58, /* IP 14 */
 654	0x00, 0x00, 0x00, 0x00,
 655	0x00, 0x11, 0x00, 0x00,
 656	0x00, 0x00, 0x00, 0x00,
 657	0x00, 0x00, 0x00, 0x00,
 658
 659	0x00, 0x00, 0x08, 0x68, /* UDP 34 */
 660	0x00, 0x44, 0x00, 0x00,
 661
 662	0x34, 0xff, 0x00, 0x34, /* ICE_GTP Header 42 */
 663	0x00, 0x00, 0x00, 0x00,
 664	0x00, 0x00, 0x00, 0x85,
 665
 666	0x02, 0x00, 0x00, 0x00, /* GTP_PDUSession_ExtensionHeader 54 */
 667	0x00, 0x00, 0x00, 0x00,
 668
 669	0x45, 0x00, 0x00, 0x28, /* IP 62 */
 670	0x00, 0x00, 0x00, 0x00,
 671	0x00, 0x06, 0x00, 0x00,
 672	0x00, 0x00, 0x00, 0x00,
 673	0x00, 0x00, 0x00, 0x00,
 674
 675	0x00, 0x00, 0x00, 0x00, /* TCP 82 */
 676	0x00, 0x00, 0x00, 0x00,
 677	0x00, 0x00, 0x00, 0x00,
 678	0x50, 0x00, 0x00, 0x00,
 679	0x00, 0x00, 0x00, 0x00,
 680
 681	0x00, 0x00, /* 2 bytes for 4 byte alignment */
 682};
 683
 684/* Outer IPv4 + Outer UDP + GTP + Inner IPv4 + Inner UDP */
 685ICE_DECLARE_PKT_OFFSETS(ipv4_gtpu_ipv4_udp) = {
 686	{ ICE_MAC_OFOS,		0 },
 687	{ ICE_IPV4_OFOS,	14 },
 688	{ ICE_UDP_OF,		34 },
 689	{ ICE_GTP,		42 },
 690	{ ICE_IPV4_IL,		62 },
 691	{ ICE_UDP_ILOS,		82 },
 692	{ ICE_PROTOCOL_LAST,	0 },
 693};
 694
 695ICE_DECLARE_PKT_TEMPLATE(ipv4_gtpu_ipv4_udp) = {
 696	0x00, 0x00, 0x00, 0x00, /* Ethernet 0 */
 697	0x00, 0x00, 0x00, 0x00,
 698	0x00, 0x00, 0x00, 0x00,
 699	0x08, 0x00,
 700
 701	0x45, 0x00, 0x00, 0x4c, /* IP 14 */
 702	0x00, 0x00, 0x00, 0x00,
 703	0x00, 0x11, 0x00, 0x00,
 704	0x00, 0x00, 0x00, 0x00,
 705	0x00, 0x00, 0x00, 0x00,
 706
 707	0x00, 0x00, 0x08, 0x68, /* UDP 34 */
 708	0x00, 0x38, 0x00, 0x00,
 709
 710	0x34, 0xff, 0x00, 0x28, /* ICE_GTP Header 42 */
 711	0x00, 0x00, 0x00, 0x00,
 712	0x00, 0x00, 0x00, 0x85,
 713
 714	0x02, 0x00, 0x00, 0x00, /* GTP_PDUSession_ExtensionHeader 54 */
 715	0x00, 0x00, 0x00, 0x00,
 716
 717	0x45, 0x00, 0x00, 0x1c, /* IP 62 */
 718	0x00, 0x00, 0x00, 0x00,
 719	0x00, 0x11, 0x00, 0x00,
 720	0x00, 0x00, 0x00, 0x00,
 721	0x00, 0x00, 0x00, 0x00,
 722
 723	0x00, 0x00, 0x00, 0x00, /* UDP 82 */
 724	0x00, 0x08, 0x00, 0x00,
 725
 726	0x00, 0x00, /* 2 bytes for 4 byte alignment */
 727};
 728
 729/* Outer IPv6 + Outer UDP + GTP + Inner IPv4 + Inner TCP */
 730ICE_DECLARE_PKT_OFFSETS(ipv4_gtpu_ipv6_tcp) = {
 731	{ ICE_MAC_OFOS,		0 },
 732	{ ICE_IPV4_OFOS,	14 },
 733	{ ICE_UDP_OF,		34 },
 734	{ ICE_GTP,		42 },
 735	{ ICE_IPV6_IL,		62 },
 736	{ ICE_TCP_IL,		102 },
 737	{ ICE_PROTOCOL_LAST,	0 },
 738};
 739
 740ICE_DECLARE_PKT_TEMPLATE(ipv4_gtpu_ipv6_tcp) = {
 741	0x00, 0x00, 0x00, 0x00, /* Ethernet 0 */
 742	0x00, 0x00, 0x00, 0x00,
 743	0x00, 0x00, 0x00, 0x00,
 744	0x08, 0x00,
 745
 746	0x45, 0x00, 0x00, 0x6c, /* IP 14 */
 747	0x00, 0x00, 0x00, 0x00,
 748	0x00, 0x11, 0x00, 0x00,
 749	0x00, 0x00, 0x00, 0x00,
 750	0x00, 0x00, 0x00, 0x00,
 751
 752	0x00, 0x00, 0x08, 0x68, /* UDP 34 */
 753	0x00, 0x58, 0x00, 0x00,
 754
 755	0x34, 0xff, 0x00, 0x48, /* ICE_GTP Header 42 */
 756	0x00, 0x00, 0x00, 0x00,
 757	0x00, 0x00, 0x00, 0x85,
 758
 759	0x02, 0x00, 0x00, 0x00, /* GTP_PDUSession_ExtensionHeader 54 */
 760	0x00, 0x00, 0x00, 0x00,
 761
 762	0x60, 0x00, 0x00, 0x00, /* IPv6 62 */
 763	0x00, 0x14, 0x06, 0x00,
 764	0x00, 0x00, 0x00, 0x00,
 765	0x00, 0x00, 0x00, 0x00,
 766	0x00, 0x00, 0x00, 0x00,
 767	0x00, 0x00, 0x00, 0x00,
 768	0x00, 0x00, 0x00, 0x00,
 769	0x00, 0x00, 0x00, 0x00,
 770	0x00, 0x00, 0x00, 0x00,
 771	0x00, 0x00, 0x00, 0x00,
 772
 773	0x00, 0x00, 0x00, 0x00, /* TCP 102 */
 774	0x00, 0x00, 0x00, 0x00,
 775	0x00, 0x00, 0x00, 0x00,
 776	0x50, 0x00, 0x00, 0x00,
 777	0x00, 0x00, 0x00, 0x00,
 778
 779	0x00, 0x00, /* 2 bytes for 4 byte alignment */
 780};
 781
 782ICE_DECLARE_PKT_OFFSETS(ipv4_gtpu_ipv6_udp) = {
 783	{ ICE_MAC_OFOS,		0 },
 784	{ ICE_IPV4_OFOS,	14 },
 785	{ ICE_UDP_OF,		34 },
 786	{ ICE_GTP,		42 },
 787	{ ICE_IPV6_IL,		62 },
 788	{ ICE_UDP_ILOS,		102 },
 789	{ ICE_PROTOCOL_LAST,	0 },
 790};
 791
 792ICE_DECLARE_PKT_TEMPLATE(ipv4_gtpu_ipv6_udp) = {
 793	0x00, 0x00, 0x00, 0x00, /* Ethernet 0 */
 794	0x00, 0x00, 0x00, 0x00,
 795	0x00, 0x00, 0x00, 0x00,
 796	0x08, 0x00,
 797
 798	0x45, 0x00, 0x00, 0x60, /* IP 14 */
 799	0x00, 0x00, 0x00, 0x00,
 800	0x00, 0x11, 0x00, 0x00,
 801	0x00, 0x00, 0x00, 0x00,
 802	0x00, 0x00, 0x00, 0x00,
 803
 804	0x00, 0x00, 0x08, 0x68, /* UDP 34 */
 805	0x00, 0x4c, 0x00, 0x00,
 806
 807	0x34, 0xff, 0x00, 0x3c, /* ICE_GTP Header 42 */
 808	0x00, 0x00, 0x00, 0x00,
 809	0x00, 0x00, 0x00, 0x85,
 810
 811	0x02, 0x00, 0x00, 0x00, /* GTP_PDUSession_ExtensionHeader 54 */
 812	0x00, 0x00, 0x00, 0x00,
 813
 814	0x60, 0x00, 0x00, 0x00, /* IPv6 62 */
 815	0x00, 0x08, 0x11, 0x00,
 816	0x00, 0x00, 0x00, 0x00,
 817	0x00, 0x00, 0x00, 0x00,
 818	0x00, 0x00, 0x00, 0x00,
 819	0x00, 0x00, 0x00, 0x00,
 820	0x00, 0x00, 0x00, 0x00,
 821	0x00, 0x00, 0x00, 0x00,
 822	0x00, 0x00, 0x00, 0x00,
 823	0x00, 0x00, 0x00, 0x00,
 824
 825	0x00, 0x00, 0x00, 0x00, /* UDP 102 */
 826	0x00, 0x08, 0x00, 0x00,
 827
 828	0x00, 0x00, /* 2 bytes for 4 byte alignment */
 829};
 830
 831ICE_DECLARE_PKT_OFFSETS(ipv6_gtpu_ipv4_tcp) = {
 832	{ ICE_MAC_OFOS,		0 },
 833	{ ICE_IPV6_OFOS,	14 },
 834	{ ICE_UDP_OF,		54 },
 835	{ ICE_GTP,		62 },
 836	{ ICE_IPV4_IL,		82 },
 837	{ ICE_TCP_IL,		102 },
 838	{ ICE_PROTOCOL_LAST,	0 },
 839};
 840
 841ICE_DECLARE_PKT_TEMPLATE(ipv6_gtpu_ipv4_tcp) = {
 842	0x00, 0x00, 0x00, 0x00, /* Ethernet 0 */
 843	0x00, 0x00, 0x00, 0x00,
 844	0x00, 0x00, 0x00, 0x00,
 845	0x86, 0xdd,
 846
 847	0x60, 0x00, 0x00, 0x00, /* IPv6 14 */
 848	0x00, 0x44, 0x11, 0x00,
 849	0x00, 0x00, 0x00, 0x00,
 850	0x00, 0x00, 0x00, 0x00,
 851	0x00, 0x00, 0x00, 0x00,
 852	0x00, 0x00, 0x00, 0x00,
 853	0x00, 0x00, 0x00, 0x00,
 854	0x00, 0x00, 0x00, 0x00,
 855	0x00, 0x00, 0x00, 0x00,
 856	0x00, 0x00, 0x00, 0x00,
 857
 858	0x00, 0x00, 0x08, 0x68, /* UDP 54 */
 859	0x00, 0x44, 0x00, 0x00,
 860
 861	0x34, 0xff, 0x00, 0x34, /* ICE_GTP Header 62 */
 862	0x00, 0x00, 0x00, 0x00,
 863	0x00, 0x00, 0x00, 0x85,
 864
 865	0x02, 0x00, 0x00, 0x00, /* GTP_PDUSession_ExtensionHeader 74 */
 866	0x00, 0x00, 0x00, 0x00,
 867
 868	0x45, 0x00, 0x00, 0x28, /* IP 82 */
 869	0x00, 0x00, 0x00, 0x00,
 870	0x00, 0x06, 0x00, 0x00,
 871	0x00, 0x00, 0x00, 0x00,
 872	0x00, 0x00, 0x00, 0x00,
 873
 874	0x00, 0x00, 0x00, 0x00, /* TCP 102 */
 875	0x00, 0x00, 0x00, 0x00,
 876	0x00, 0x00, 0x00, 0x00,
 877	0x50, 0x00, 0x00, 0x00,
 878	0x00, 0x00, 0x00, 0x00,
 879
 880	0x00, 0x00, /* 2 bytes for 4 byte alignment */
 881};
 882
 883ICE_DECLARE_PKT_OFFSETS(ipv6_gtpu_ipv4_udp) = {
 884	{ ICE_MAC_OFOS,		0 },
 885	{ ICE_IPV6_OFOS,	14 },
 886	{ ICE_UDP_OF,		54 },
 887	{ ICE_GTP,		62 },
 888	{ ICE_IPV4_IL,		82 },
 889	{ ICE_UDP_ILOS,		102 },
 890	{ ICE_PROTOCOL_LAST,	0 },
 891};
 892
 893ICE_DECLARE_PKT_TEMPLATE(ipv6_gtpu_ipv4_udp) = {
 894	0x00, 0x00, 0x00, 0x00, /* Ethernet 0 */
 895	0x00, 0x00, 0x00, 0x00,
 896	0x00, 0x00, 0x00, 0x00,
 897	0x86, 0xdd,
 898
 899	0x60, 0x00, 0x00, 0x00, /* IPv6 14 */
 900	0x00, 0x38, 0x11, 0x00,
 901	0x00, 0x00, 0x00, 0x00,
 902	0x00, 0x00, 0x00, 0x00,
 903	0x00, 0x00, 0x00, 0x00,
 904	0x00, 0x00, 0x00, 0x00,
 905	0x00, 0x00, 0x00, 0x00,
 906	0x00, 0x00, 0x00, 0x00,
 907	0x00, 0x00, 0x00, 0x00,
 908	0x00, 0x00, 0x00, 0x00,
 909
 910	0x00, 0x00, 0x08, 0x68, /* UDP 54 */
 911	0x00, 0x38, 0x00, 0x00,
 912
 913	0x34, 0xff, 0x00, 0x28, /* ICE_GTP Header 62 */
 914	0x00, 0x00, 0x00, 0x00,
 915	0x00, 0x00, 0x00, 0x85,
 916
 917	0x02, 0x00, 0x00, 0x00, /* GTP_PDUSession_ExtensionHeader 74 */
 918	0x00, 0x00, 0x00, 0x00,
 919
 920	0x45, 0x00, 0x00, 0x1c, /* IP 82 */
 921	0x00, 0x00, 0x00, 0x00,
 922	0x00, 0x11, 0x00, 0x00,
 923	0x00, 0x00, 0x00, 0x00,
 924	0x00, 0x00, 0x00, 0x00,
 925
 926	0x00, 0x00, 0x00, 0x00, /* UDP 102 */
 927	0x00, 0x08, 0x00, 0x00,
 928
 929	0x00, 0x00, /* 2 bytes for 4 byte alignment */
 930};
 931
 932ICE_DECLARE_PKT_OFFSETS(ipv6_gtpu_ipv6_tcp) = {
 933	{ ICE_MAC_OFOS,		0 },
 934	{ ICE_IPV6_OFOS,	14 },
 935	{ ICE_UDP_OF,		54 },
 936	{ ICE_GTP,		62 },
 937	{ ICE_IPV6_IL,		82 },
 938	{ ICE_TCP_IL,		122 },
 939	{ ICE_PROTOCOL_LAST,	0 },
 940};
 941
 942ICE_DECLARE_PKT_TEMPLATE(ipv6_gtpu_ipv6_tcp) = {
 943	0x00, 0x00, 0x00, 0x00, /* Ethernet 0 */
 944	0x00, 0x00, 0x00, 0x00,
 945	0x00, 0x00, 0x00, 0x00,
 946	0x86, 0xdd,
 947
 948	0x60, 0x00, 0x00, 0x00, /* IPv6 14 */
 949	0x00, 0x58, 0x11, 0x00,
 950	0x00, 0x00, 0x00, 0x00,
 951	0x00, 0x00, 0x00, 0x00,
 952	0x00, 0x00, 0x00, 0x00,
 953	0x00, 0x00, 0x00, 0x00,
 954	0x00, 0x00, 0x00, 0x00,
 955	0x00, 0x00, 0x00, 0x00,
 956	0x00, 0x00, 0x00, 0x00,
 957	0x00, 0x00, 0x00, 0x00,
 958
 959	0x00, 0x00, 0x08, 0x68, /* UDP 54 */
 960	0x00, 0x58, 0x00, 0x00,
 961
 962	0x34, 0xff, 0x00, 0x48, /* ICE_GTP Header 62 */
 963	0x00, 0x00, 0x00, 0x00,
 964	0x00, 0x00, 0x00, 0x85,
 965
 966	0x02, 0x00, 0x00, 0x00, /* GTP_PDUSession_ExtensionHeader 74 */
 967	0x00, 0x00, 0x00, 0x00,
 968
 969	0x60, 0x00, 0x00, 0x00, /* IPv6 82 */
 970	0x00, 0x14, 0x06, 0x00,
 971	0x00, 0x00, 0x00, 0x00,
 972	0x00, 0x00, 0x00, 0x00,
 973	0x00, 0x00, 0x00, 0x00,
 974	0x00, 0x00, 0x00, 0x00,
 975	0x00, 0x00, 0x00, 0x00,
 976	0x00, 0x00, 0x00, 0x00,
 977	0x00, 0x00, 0x00, 0x00,
 978	0x00, 0x00, 0x00, 0x00,
 979
 980	0x00, 0x00, 0x00, 0x00, /* TCP 122 */
 981	0x00, 0x00, 0x00, 0x00,
 982	0x00, 0x00, 0x00, 0x00,
 983	0x50, 0x00, 0x00, 0x00,
 984	0x00, 0x00, 0x00, 0x00,
 985
 986	0x00, 0x00, /* 2 bytes for 4 byte alignment */
 987};
 988
 989ICE_DECLARE_PKT_OFFSETS(ipv6_gtpu_ipv6_udp) = {
 990	{ ICE_MAC_OFOS,		0 },
 991	{ ICE_IPV6_OFOS,	14 },
 992	{ ICE_UDP_OF,		54 },
 993	{ ICE_GTP,		62 },
 994	{ ICE_IPV6_IL,		82 },
 995	{ ICE_UDP_ILOS,		122 },
 996	{ ICE_PROTOCOL_LAST,	0 },
 997};
 998
 999ICE_DECLARE_PKT_TEMPLATE(ipv6_gtpu_ipv6_udp) = {
1000	0x00, 0x00, 0x00, 0x00, /* Ethernet 0 */
1001	0x00, 0x00, 0x00, 0x00,
1002	0x00, 0x00, 0x00, 0x00,
1003	0x86, 0xdd,
1004
1005	0x60, 0x00, 0x00, 0x00, /* IPv6 14 */
1006	0x00, 0x4c, 0x11, 0x00,
1007	0x00, 0x00, 0x00, 0x00,
1008	0x00, 0x00, 0x00, 0x00,
1009	0x00, 0x00, 0x00, 0x00,
1010	0x00, 0x00, 0x00, 0x00,
1011	0x00, 0x00, 0x00, 0x00,
1012	0x00, 0x00, 0x00, 0x00,
1013	0x00, 0x00, 0x00, 0x00,
1014	0x00, 0x00, 0x00, 0x00,
1015
1016	0x00, 0x00, 0x08, 0x68, /* UDP 54 */
1017	0x00, 0x4c, 0x00, 0x00,
1018
1019	0x34, 0xff, 0x00, 0x3c, /* ICE_GTP Header 62 */
1020	0x00, 0x00, 0x00, 0x00,
1021	0x00, 0x00, 0x00, 0x85,
1022
1023	0x02, 0x00, 0x00, 0x00, /* GTP_PDUSession_ExtensionHeader 74 */
1024	0x00, 0x00, 0x00, 0x00,
1025
1026	0x60, 0x00, 0x00, 0x00, /* IPv6 82 */
1027	0x00, 0x08, 0x11, 0x00,
1028	0x00, 0x00, 0x00, 0x00,
1029	0x00, 0x00, 0x00, 0x00,
1030	0x00, 0x00, 0x00, 0x00,
1031	0x00, 0x00, 0x00, 0x00,
1032	0x00, 0x00, 0x00, 0x00,
1033	0x00, 0x00, 0x00, 0x00,
1034	0x00, 0x00, 0x00, 0x00,
1035	0x00, 0x00, 0x00, 0x00,
1036
1037	0x00, 0x00, 0x00, 0x00, /* UDP 122 */
1038	0x00, 0x08, 0x00, 0x00,
1039
1040	0x00, 0x00, /* 2 bytes for 4 byte alignment */
1041};
1042
1043ICE_DECLARE_PKT_OFFSETS(ipv4_gtpu_ipv4) = {
1044	{ ICE_MAC_OFOS,		0 },
1045	{ ICE_IPV4_OFOS,	14 },
1046	{ ICE_UDP_OF,		34 },
1047	{ ICE_GTP_NO_PAY,	42 },
1048	{ ICE_PROTOCOL_LAST,	0 },
1049};
1050
1051ICE_DECLARE_PKT_TEMPLATE(ipv4_gtpu_ipv4) = {
1052	0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1053	0x00, 0x00, 0x00, 0x00,
1054	0x00, 0x00, 0x00, 0x00,
1055	0x08, 0x00,
1056
1057	0x45, 0x00, 0x00, 0x44, /* ICE_IPV4_OFOS 14 */
1058	0x00, 0x00, 0x40, 0x00,
1059	0x40, 0x11, 0x00, 0x00,
1060	0x00, 0x00, 0x00, 0x00,
1061	0x00, 0x00, 0x00, 0x00,
1062
1063	0x08, 0x68, 0x08, 0x68, /* ICE_UDP_OF 34 */
1064	0x00, 0x00, 0x00, 0x00,
1065
1066	0x34, 0xff, 0x00, 0x28, /* ICE_GTP 42 */
1067	0x00, 0x00, 0x00, 0x00,
1068	0x00, 0x00, 0x00, 0x85,
1069
1070	0x02, 0x00, 0x00, 0x00, /* PDU Session extension header */
1071	0x00, 0x00, 0x00, 0x00,
1072
1073	0x45, 0x00, 0x00, 0x14, /* ICE_IPV4_IL 62 */
1074	0x00, 0x00, 0x40, 0x00,
1075	0x40, 0x00, 0x00, 0x00,
1076	0x00, 0x00, 0x00, 0x00,
1077	0x00, 0x00, 0x00, 0x00,
1078	0x00, 0x00,
1079};
1080
1081ICE_DECLARE_PKT_OFFSETS(ipv6_gtp) = {
1082	{ ICE_MAC_OFOS,		0 },
1083	{ ICE_IPV6_OFOS,	14 },
1084	{ ICE_UDP_OF,		54 },
1085	{ ICE_GTP_NO_PAY,	62 },
1086	{ ICE_PROTOCOL_LAST,	0 },
1087};
1088
1089ICE_DECLARE_PKT_TEMPLATE(ipv6_gtp) = {
1090	0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1091	0x00, 0x00, 0x00, 0x00,
1092	0x00, 0x00, 0x00, 0x00,
1093	0x86, 0xdd,
1094
1095	0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 14 */
1096	0x00, 0x6c, 0x11, 0x00, /* Next header UDP*/
1097	0x00, 0x00, 0x00, 0x00,
1098	0x00, 0x00, 0x00, 0x00,
1099	0x00, 0x00, 0x00, 0x00,
1100	0x00, 0x00, 0x00, 0x00,
1101	0x00, 0x00, 0x00, 0x00,
1102	0x00, 0x00, 0x00, 0x00,
1103	0x00, 0x00, 0x00, 0x00,
1104	0x00, 0x00, 0x00, 0x00,
1105
1106	0x08, 0x68, 0x08, 0x68, /* ICE_UDP_OF 54 */
1107	0x00, 0x00, 0x00, 0x00,
1108
1109	0x30, 0x00, 0x00, 0x28, /* ICE_GTP 62 */
1110	0x00, 0x00, 0x00, 0x00,
1111
1112	0x00, 0x00,
1113};
1114
1115ICE_DECLARE_PKT_OFFSETS(pfcp_session_ipv4) = {
1116	{ ICE_MAC_OFOS,		0 },
1117	{ ICE_ETYPE_OL,		12 },
1118	{ ICE_IPV4_OFOS,	14 },
1119	{ ICE_UDP_ILOS,		34 },
1120	{ ICE_PFCP,		42 },
1121	{ ICE_PROTOCOL_LAST,	0 },
1122};
1123
1124ICE_DECLARE_PKT_TEMPLATE(pfcp_session_ipv4) = {
1125	0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1126	0x00, 0x00, 0x00, 0x00,
1127	0x00, 0x00, 0x00, 0x00,
1128
1129	0x08, 0x00,		/* ICE_ETYPE_OL 12 */
1130
1131	0x45, 0x00, 0x00, 0x2c, /* ICE_IPV4_OFOS 14 */
1132	0x00, 0x01, 0x00, 0x00,
1133	0x00, 0x11, 0x00, 0x00,
1134	0x00, 0x00, 0x00, 0x00,
1135	0x00, 0x00, 0x00, 0x00,
1136
1137	0x00, 0x00, 0x22, 0x65, /* ICE_UDP_ILOS 34 */
1138	0x00, 0x18, 0x00, 0x00,
1139
1140	0x21, 0x01, 0x00, 0x0c, /* ICE_PFCP 42 */
1141	0x00, 0x00, 0x00, 0x00,
1142	0x00, 0x00, 0x00, 0x00,
1143	0x00, 0x00, 0x00, 0x00,
1144
1145	0x00, 0x00,		/* 2 bytes for 4 byte alignment */
1146};
1147
1148ICE_DECLARE_PKT_OFFSETS(pfcp_session_ipv6) = {
1149	{ ICE_MAC_OFOS,		0 },
1150	{ ICE_ETYPE_OL,		12 },
1151	{ ICE_IPV6_OFOS,	14 },
1152	{ ICE_UDP_ILOS,		54 },
1153	{ ICE_PFCP,		62 },
1154	{ ICE_PROTOCOL_LAST,	0 },
1155};
1156
1157ICE_DECLARE_PKT_TEMPLATE(pfcp_session_ipv6) = {
1158	0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1159	0x00, 0x00, 0x00, 0x00,
1160	0x00, 0x00, 0x00, 0x00,
1161
1162	0x86, 0xdd,		/* ICE_ETYPE_OL 12 */
1163
1164	0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 14 */
1165	0x00, 0x10, 0x11, 0x00, /* Next header UDP */
1166	0x00, 0x00, 0x00, 0x00,
1167	0x00, 0x00, 0x00, 0x00,
1168	0x00, 0x00, 0x00, 0x00,
1169	0x00, 0x00, 0x00, 0x00,
1170	0x00, 0x00, 0x00, 0x00,
1171	0x00, 0x00, 0x00, 0x00,
1172	0x00, 0x00, 0x00, 0x00,
1173	0x00, 0x00, 0x00, 0x00,
1174
1175	0x00, 0x00, 0x22, 0x65, /* ICE_UDP_ILOS 54 */
1176	0x00, 0x18, 0x00, 0x00,
1177
1178	0x21, 0x01, 0x00, 0x0c, /* ICE_PFCP 62 */
1179	0x00, 0x00, 0x00, 0x00,
1180	0x00, 0x00, 0x00, 0x00,
1181	0x00, 0x00, 0x00, 0x00,
1182
1183	0x00, 0x00,		/* 2 bytes for 4 byte alignment */
1184};
1185
1186ICE_DECLARE_PKT_OFFSETS(pppoe_ipv4_tcp) = {
1187	{ ICE_MAC_OFOS,		0 },
1188	{ ICE_ETYPE_OL,		12 },
1189	{ ICE_PPPOE,		14 },
1190	{ ICE_IPV4_OFOS,	22 },
1191	{ ICE_TCP_IL,		42 },
1192	{ ICE_PROTOCOL_LAST,	0 },
1193};
1194
1195ICE_DECLARE_PKT_TEMPLATE(pppoe_ipv4_tcp) = {
1196	0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1197	0x00, 0x00, 0x00, 0x00,
1198	0x00, 0x00, 0x00, 0x00,
1199
1200	0x88, 0x64,		/* ICE_ETYPE_OL 12 */
1201
1202	0x11, 0x00, 0x00, 0x00, /* ICE_PPPOE 14 */
1203	0x00, 0x16,
1204
1205	0x00, 0x21,		/* PPP Link Layer 20 */
1206
1207	0x45, 0x00, 0x00, 0x28, /* ICE_IPV4_OFOS 22 */
1208	0x00, 0x01, 0x00, 0x00,
1209	0x00, 0x06, 0x00, 0x00,
1210	0x00, 0x00, 0x00, 0x00,
1211	0x00, 0x00, 0x00, 0x00,
1212
1213	0x00, 0x00, 0x00, 0x00, /* ICE_TCP_IL 42 */
1214	0x00, 0x00, 0x00, 0x00,
1215	0x00, 0x00, 0x00, 0x00,
1216	0x50, 0x00, 0x00, 0x00,
1217	0x00, 0x00, 0x00, 0x00,
1218
1219	0x00, 0x00,		/* 2 bytes for 4 bytes alignment */
1220};
1221
1222ICE_DECLARE_PKT_OFFSETS(pppoe_ipv4_udp) = {
1223	{ ICE_MAC_OFOS,		0 },
1224	{ ICE_ETYPE_OL,		12 },
1225	{ ICE_PPPOE,		14 },
1226	{ ICE_IPV4_OFOS,	22 },
1227	{ ICE_UDP_ILOS,		42 },
1228	{ ICE_PROTOCOL_LAST,	0 },
1229};
1230
1231ICE_DECLARE_PKT_TEMPLATE(pppoe_ipv4_udp) = {
1232	0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1233	0x00, 0x00, 0x00, 0x00,
1234	0x00, 0x00, 0x00, 0x00,
1235
1236	0x88, 0x64,		/* ICE_ETYPE_OL 12 */
1237
1238	0x11, 0x00, 0x00, 0x00, /* ICE_PPPOE 14 */
1239	0x00, 0x16,
1240
1241	0x00, 0x21,		/* PPP Link Layer 20 */
1242
1243	0x45, 0x00, 0x00, 0x1c, /* ICE_IPV4_OFOS 22 */
1244	0x00, 0x01, 0x00, 0x00,
1245	0x00, 0x11, 0x00, 0x00,
1246	0x00, 0x00, 0x00, 0x00,
1247	0x00, 0x00, 0x00, 0x00,
1248
1249	0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 42 */
1250	0x00, 0x08, 0x00, 0x00,
1251
1252	0x00, 0x00,		/* 2 bytes for 4 bytes alignment */
1253};
1254
1255ICE_DECLARE_PKT_OFFSETS(pppoe_ipv6_tcp) = {
1256	{ ICE_MAC_OFOS,		0 },
1257	{ ICE_ETYPE_OL,		12 },
1258	{ ICE_PPPOE,		14 },
1259	{ ICE_IPV6_OFOS,	22 },
1260	{ ICE_TCP_IL,		62 },
1261	{ ICE_PROTOCOL_LAST,	0 },
1262};
1263
1264ICE_DECLARE_PKT_TEMPLATE(pppoe_ipv6_tcp) = {
1265	0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1266	0x00, 0x00, 0x00, 0x00,
1267	0x00, 0x00, 0x00, 0x00,
1268
1269	0x88, 0x64,		/* ICE_ETYPE_OL 12 */
1270
1271	0x11, 0x00, 0x00, 0x00, /* ICE_PPPOE 14 */
1272	0x00, 0x2a,
1273
1274	0x00, 0x57,		/* PPP Link Layer 20 */
1275
1276	0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 22 */
1277	0x00, 0x14, 0x06, 0x00, /* Next header is TCP */
1278	0x00, 0x00, 0x00, 0x00,
1279	0x00, 0x00, 0x00, 0x00,
1280	0x00, 0x00, 0x00, 0x00,
1281	0x00, 0x00, 0x00, 0x00,
1282	0x00, 0x00, 0x00, 0x00,
1283	0x00, 0x00, 0x00, 0x00,
1284	0x00, 0x00, 0x00, 0x00,
1285	0x00, 0x00, 0x00, 0x00,
1286
1287	0x00, 0x00, 0x00, 0x00, /* ICE_TCP_IL 62 */
1288	0x00, 0x00, 0x00, 0x00,
1289	0x00, 0x00, 0x00, 0x00,
1290	0x50, 0x00, 0x00, 0x00,
1291	0x00, 0x00, 0x00, 0x00,
1292
1293	0x00, 0x00,		/* 2 bytes for 4 bytes alignment */
1294};
1295
1296ICE_DECLARE_PKT_OFFSETS(pppoe_ipv6_udp) = {
1297	{ ICE_MAC_OFOS,		0 },
1298	{ ICE_ETYPE_OL,		12 },
1299	{ ICE_PPPOE,		14 },
1300	{ ICE_IPV6_OFOS,	22 },
1301	{ ICE_UDP_ILOS,		62 },
1302	{ ICE_PROTOCOL_LAST,	0 },
1303};
1304
1305ICE_DECLARE_PKT_TEMPLATE(pppoe_ipv6_udp) = {
1306	0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1307	0x00, 0x00, 0x00, 0x00,
1308	0x00, 0x00, 0x00, 0x00,
1309
1310	0x88, 0x64,		/* ICE_ETYPE_OL 12 */
1311
1312	0x11, 0x00, 0x00, 0x00, /* ICE_PPPOE 14 */
1313	0x00, 0x2a,
1314
1315	0x00, 0x57,		/* PPP Link Layer 20 */
1316
1317	0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 22 */
1318	0x00, 0x08, 0x11, 0x00, /* Next header UDP*/
1319	0x00, 0x00, 0x00, 0x00,
1320	0x00, 0x00, 0x00, 0x00,
1321	0x00, 0x00, 0x00, 0x00,
1322	0x00, 0x00, 0x00, 0x00,
1323	0x00, 0x00, 0x00, 0x00,
1324	0x00, 0x00, 0x00, 0x00,
1325	0x00, 0x00, 0x00, 0x00,
1326	0x00, 0x00, 0x00, 0x00,
1327
1328	0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 62 */
1329	0x00, 0x08, 0x00, 0x00,
1330
1331	0x00, 0x00,		/* 2 bytes for 4 bytes alignment */
1332};
1333
1334ICE_DECLARE_PKT_OFFSETS(ipv4_l2tpv3) = {
1335	{ ICE_MAC_OFOS,		0 },
1336	{ ICE_ETYPE_OL,		12 },
1337	{ ICE_IPV4_OFOS,	14 },
1338	{ ICE_L2TPV3,		34 },
1339	{ ICE_PROTOCOL_LAST,	0 },
1340};
1341
1342ICE_DECLARE_PKT_TEMPLATE(ipv4_l2tpv3) = {
1343	0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1344	0x00, 0x00, 0x00, 0x00,
1345	0x00, 0x00, 0x00, 0x00,
1346
1347	0x08, 0x00,		/* ICE_ETYPE_OL 12 */
1348
1349	0x45, 0x00, 0x00, 0x20, /* ICE_IPV4_IL 14 */
1350	0x00, 0x00, 0x40, 0x00,
1351	0x40, 0x73, 0x00, 0x00,
1352	0x00, 0x00, 0x00, 0x00,
1353	0x00, 0x00, 0x00, 0x00,
1354
1355	0x00, 0x00, 0x00, 0x00, /* ICE_L2TPV3 34 */
1356	0x00, 0x00, 0x00, 0x00,
1357	0x00, 0x00, 0x00, 0x00,
1358	0x00, 0x00,		/* 2 bytes for 4 bytes alignment */
1359};
1360
1361ICE_DECLARE_PKT_OFFSETS(ipv6_l2tpv3) = {
1362	{ ICE_MAC_OFOS,		0 },
1363	{ ICE_ETYPE_OL,		12 },
1364	{ ICE_IPV6_OFOS,	14 },
1365	{ ICE_L2TPV3,		54 },
1366	{ ICE_PROTOCOL_LAST,	0 },
1367};
1368
1369ICE_DECLARE_PKT_TEMPLATE(ipv6_l2tpv3) = {
1370	0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1371	0x00, 0x00, 0x00, 0x00,
1372	0x00, 0x00, 0x00, 0x00,
1373
1374	0x86, 0xDD,		/* ICE_ETYPE_OL 12 */
1375
1376	0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_IL 14 */
1377	0x00, 0x0c, 0x73, 0x40,
1378	0x00, 0x00, 0x00, 0x00,
1379	0x00, 0x00, 0x00, 0x00,
1380	0x00, 0x00, 0x00, 0x00,
1381	0x00, 0x00, 0x00, 0x00,
1382	0x00, 0x00, 0x00, 0x00,
1383	0x00, 0x00, 0x00, 0x00,
1384	0x00, 0x00, 0x00, 0x00,
1385	0x00, 0x00, 0x00, 0x00,
1386
1387	0x00, 0x00, 0x00, 0x00, /* ICE_L2TPV3 54 */
1388	0x00, 0x00, 0x00, 0x00,
1389	0x00, 0x00, 0x00, 0x00,
1390	0x00, 0x00,		/* 2 bytes for 4 bytes alignment */
1391};
1392
1393static const struct ice_dummy_pkt_profile ice_dummy_pkt_profiles[] = {
1394	ICE_PKT_PROFILE(ipv6_gtp, ICE_PKT_TUN_GTPU | ICE_PKT_OUTER_IPV6 |
1395				  ICE_PKT_GTP_NOPAY),
1396	ICE_PKT_PROFILE(ipv6_gtpu_ipv6_udp, ICE_PKT_TUN_GTPU |
1397					    ICE_PKT_OUTER_IPV6 |
1398					    ICE_PKT_INNER_IPV6 |
1399					    ICE_PKT_INNER_UDP),
1400	ICE_PKT_PROFILE(ipv6_gtpu_ipv6_tcp, ICE_PKT_TUN_GTPU |
1401					    ICE_PKT_OUTER_IPV6 |
1402					    ICE_PKT_INNER_IPV6),
1403	ICE_PKT_PROFILE(ipv6_gtpu_ipv4_udp, ICE_PKT_TUN_GTPU |
1404					    ICE_PKT_OUTER_IPV6 |
1405					    ICE_PKT_INNER_UDP),
1406	ICE_PKT_PROFILE(ipv6_gtpu_ipv4_tcp, ICE_PKT_TUN_GTPU |
1407					    ICE_PKT_OUTER_IPV6),
1408	ICE_PKT_PROFILE(ipv4_gtpu_ipv4, ICE_PKT_TUN_GTPU | ICE_PKT_GTP_NOPAY),
1409	ICE_PKT_PROFILE(ipv4_gtpu_ipv6_udp, ICE_PKT_TUN_GTPU |
1410					    ICE_PKT_INNER_IPV6 |
1411					    ICE_PKT_INNER_UDP),
1412	ICE_PKT_PROFILE(ipv4_gtpu_ipv6_tcp, ICE_PKT_TUN_GTPU |
1413					    ICE_PKT_INNER_IPV6),
1414	ICE_PKT_PROFILE(ipv4_gtpu_ipv4_udp, ICE_PKT_TUN_GTPU |
1415					    ICE_PKT_INNER_UDP),
1416	ICE_PKT_PROFILE(ipv4_gtpu_ipv4_tcp, ICE_PKT_TUN_GTPU),
1417	ICE_PKT_PROFILE(ipv6_gtp, ICE_PKT_TUN_GTPC | ICE_PKT_OUTER_IPV6),
1418	ICE_PKT_PROFILE(ipv4_gtpu_ipv4, ICE_PKT_TUN_GTPC),
1419	ICE_PKT_PROFILE(pfcp_session_ipv6, ICE_PKT_PFCP | ICE_PKT_OUTER_IPV6),
1420	ICE_PKT_PROFILE(pfcp_session_ipv4, ICE_PKT_PFCP),
1421	ICE_PKT_PROFILE(pppoe_ipv6_udp, ICE_PKT_PPPOE | ICE_PKT_OUTER_IPV6 |
1422					ICE_PKT_INNER_UDP),
1423	ICE_PKT_PROFILE(pppoe_ipv6_tcp, ICE_PKT_PPPOE | ICE_PKT_OUTER_IPV6),
1424	ICE_PKT_PROFILE(pppoe_ipv4_udp, ICE_PKT_PPPOE | ICE_PKT_INNER_UDP),
1425	ICE_PKT_PROFILE(pppoe_ipv4_tcp, ICE_PKT_PPPOE),
1426	ICE_PKT_PROFILE(gre_ipv6_tcp, ICE_PKT_TUN_NVGRE | ICE_PKT_INNER_IPV6 |
1427				      ICE_PKT_INNER_TCP),
1428	ICE_PKT_PROFILE(gre_tcp, ICE_PKT_TUN_NVGRE | ICE_PKT_INNER_TCP),
1429	ICE_PKT_PROFILE(gre_ipv6_udp, ICE_PKT_TUN_NVGRE | ICE_PKT_INNER_IPV6),
1430	ICE_PKT_PROFILE(gre_udp, ICE_PKT_TUN_NVGRE),
1431	ICE_PKT_PROFILE(udp_tun_ipv6_tcp, ICE_PKT_TUN_UDP |
1432					  ICE_PKT_INNER_IPV6 |
1433					  ICE_PKT_INNER_TCP),
1434	ICE_PKT_PROFILE(ipv6_l2tpv3, ICE_PKT_L2TPV3 | ICE_PKT_OUTER_IPV6),
1435	ICE_PKT_PROFILE(ipv4_l2tpv3, ICE_PKT_L2TPV3),
1436	ICE_PKT_PROFILE(udp_tun_tcp, ICE_PKT_TUN_UDP | ICE_PKT_INNER_TCP),
1437	ICE_PKT_PROFILE(udp_tun_ipv6_udp, ICE_PKT_TUN_UDP |
1438					  ICE_PKT_INNER_IPV6),
1439	ICE_PKT_PROFILE(udp_tun_udp, ICE_PKT_TUN_UDP),
1440	ICE_PKT_PROFILE(udp_ipv6, ICE_PKT_OUTER_IPV6 | ICE_PKT_INNER_UDP),
1441	ICE_PKT_PROFILE(udp, ICE_PKT_INNER_UDP),
1442	ICE_PKT_PROFILE(tcp_ipv6, ICE_PKT_OUTER_IPV6),
1443	ICE_PKT_PROFILE(tcp, 0),
1444};
1445
1446/* this is a recipe to profile association bitmap */
1447static DECLARE_BITMAP(recipe_to_profile[ICE_MAX_NUM_RECIPES],
1448			  ICE_MAX_NUM_PROFILES);
1449
1450/* this is a profile to recipe association bitmap */
1451static DECLARE_BITMAP(profile_to_recipe[ICE_MAX_NUM_PROFILES],
1452			  ICE_MAX_NUM_RECIPES);
1453
1454/**
1455 * ice_init_def_sw_recp - initialize the recipe book keeping tables
1456 * @hw: pointer to the HW struct
1457 *
1458 * Allocate memory for the entire recipe table and initialize the structures/
1459 * entries corresponding to basic recipes.
1460 */
1461int ice_init_def_sw_recp(struct ice_hw *hw)
1462{
1463	struct ice_sw_recipe *recps;
1464	u8 i;
1465
1466	recps = devm_kcalloc(ice_hw_to_dev(hw), ICE_MAX_NUM_RECIPES,
1467			     sizeof(*recps), GFP_KERNEL);
1468	if (!recps)
1469		return -ENOMEM;
1470
1471	for (i = 0; i < ICE_MAX_NUM_RECIPES; i++) {
1472		recps[i].root_rid = i;
1473		INIT_LIST_HEAD(&recps[i].filt_rules);
1474		INIT_LIST_HEAD(&recps[i].filt_replay_rules);
1475		mutex_init(&recps[i].filt_rule_lock);
1476	}
1477
1478	hw->switch_info->recp_list = recps;
1479
1480	return 0;
1481}
1482
1483/**
1484 * ice_aq_get_sw_cfg - get switch configuration
1485 * @hw: pointer to the hardware structure
1486 * @buf: pointer to the result buffer
1487 * @buf_size: length of the buffer available for response
1488 * @req_desc: pointer to requested descriptor
1489 * @num_elems: pointer to number of elements
1490 * @cd: pointer to command details structure or NULL
1491 *
1492 * Get switch configuration (0x0200) to be placed in buf.
1493 * This admin command returns information such as initial VSI/port number
1494 * and switch ID it belongs to.
1495 *
1496 * NOTE: *req_desc is both an input/output parameter.
1497 * The caller of this function first calls this function with *request_desc set
1498 * to 0. If the response from f/w has *req_desc set to 0, all the switch
1499 * configuration information has been returned; if non-zero (meaning not all
1500 * the information was returned), the caller should call this function again
1501 * with *req_desc set to the previous value returned by f/w to get the
1502 * next block of switch configuration information.
1503 *
1504 * *num_elems is output only parameter. This reflects the number of elements
1505 * in response buffer. The caller of this function to use *num_elems while
1506 * parsing the response buffer.
1507 */
1508static int
1509ice_aq_get_sw_cfg(struct ice_hw *hw, struct ice_aqc_get_sw_cfg_resp_elem *buf,
1510		  u16 buf_size, u16 *req_desc, u16 *num_elems,
1511		  struct ice_sq_cd *cd)
1512{
1513	struct ice_aqc_get_sw_cfg *cmd;
1514	struct libie_aq_desc desc;
1515	int status;
1516
1517	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_sw_cfg);
1518	cmd = libie_aq_raw(&desc);
1519	cmd->element = cpu_to_le16(*req_desc);
1520
1521	status = ice_aq_send_cmd(hw, &desc, buf, buf_size, cd);
1522	if (!status) {
1523		*req_desc = le16_to_cpu(cmd->element);
1524		*num_elems = le16_to_cpu(cmd->num_elems);
1525	}
1526
1527	return status;
1528}
1529
1530/**
1531 * ice_aq_add_vsi
1532 * @hw: pointer to the HW struct
1533 * @vsi_ctx: pointer to a VSI context struct
1534 * @cd: pointer to command details structure or NULL
1535 *
1536 * Add a VSI context to the hardware (0x0210)
1537 */
1538static int
1539ice_aq_add_vsi(struct ice_hw *hw, struct ice_vsi_ctx *vsi_ctx,
1540	       struct ice_sq_cd *cd)
1541{
1542	struct ice_aqc_add_update_free_vsi_resp *res;
1543	struct ice_aqc_add_get_update_free_vsi *cmd;
1544	struct libie_aq_desc desc;
1545	int status;
1546
1547	cmd = libie_aq_raw(&desc);
1548	res = libie_aq_raw(&desc);
1549
1550	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_add_vsi);
1551
1552	if (!vsi_ctx->alloc_from_pool)
1553		cmd->vsi_num = cpu_to_le16(vsi_ctx->vsi_num |
1554					   ICE_AQ_VSI_IS_VALID);
1555	cmd->vf_id = vsi_ctx->vf_num;
1556
1557	cmd->vsi_flags = cpu_to_le16(vsi_ctx->flags);
1558
1559	desc.flags |= cpu_to_le16(LIBIE_AQ_FLAG_RD);
1560
1561	status = ice_aq_send_cmd(hw, &desc, &vsi_ctx->info,
1562				 sizeof(vsi_ctx->info), cd);
1563
1564	if (!status) {
1565		vsi_ctx->vsi_num = le16_to_cpu(res->vsi_num) & ICE_AQ_VSI_NUM_M;
1566		vsi_ctx->vsis_allocd = le16_to_cpu(res->vsi_used);
1567		vsi_ctx->vsis_unallocated = le16_to_cpu(res->vsi_free);
1568	}
1569
1570	return status;
1571}
1572
1573/**
1574 * ice_aq_free_vsi
1575 * @hw: pointer to the HW struct
1576 * @vsi_ctx: pointer to a VSI context struct
1577 * @keep_vsi_alloc: keep VSI allocation as part of this PF's resources
1578 * @cd: pointer to command details structure or NULL
1579 *
1580 * Free VSI context info from hardware (0x0213)
1581 */
1582static int
1583ice_aq_free_vsi(struct ice_hw *hw, struct ice_vsi_ctx *vsi_ctx,
1584		bool keep_vsi_alloc, struct ice_sq_cd *cd)
1585{
1586	struct ice_aqc_add_update_free_vsi_resp *resp;
1587	struct ice_aqc_add_get_update_free_vsi *cmd;
1588	struct libie_aq_desc desc;
1589	int status;
1590
1591	cmd = libie_aq_raw(&desc);
1592	resp = libie_aq_raw(&desc);
1593
1594	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_free_vsi);
1595
1596	cmd->vsi_num = cpu_to_le16(vsi_ctx->vsi_num | ICE_AQ_VSI_IS_VALID);
1597	if (keep_vsi_alloc)
1598		cmd->cmd_flags = cpu_to_le16(ICE_AQ_VSI_KEEP_ALLOC);
1599
1600	status = ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
1601	if (!status) {
1602		vsi_ctx->vsis_allocd = le16_to_cpu(resp->vsi_used);
1603		vsi_ctx->vsis_unallocated = le16_to_cpu(resp->vsi_free);
1604	}
1605
1606	return status;
1607}
1608
1609/**
1610 * ice_aq_update_vsi
1611 * @hw: pointer to the HW struct
1612 * @vsi_ctx: pointer to a VSI context struct
1613 * @cd: pointer to command details structure or NULL
1614 *
1615 * Update VSI context in the hardware (0x0211)
1616 */
1617static int
1618ice_aq_update_vsi(struct ice_hw *hw, struct ice_vsi_ctx *vsi_ctx,
1619		  struct ice_sq_cd *cd)
1620{
1621	struct ice_aqc_add_update_free_vsi_resp *resp;
1622	struct ice_aqc_add_get_update_free_vsi *cmd;
1623	struct libie_aq_desc desc;
1624	int status;
1625
1626	cmd = libie_aq_raw(&desc);
1627	resp = libie_aq_raw(&desc);
1628
1629	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_update_vsi);
1630
1631	cmd->vsi_num = cpu_to_le16(vsi_ctx->vsi_num | ICE_AQ_VSI_IS_VALID);
1632
1633	desc.flags |= cpu_to_le16(LIBIE_AQ_FLAG_RD);
1634
1635	status = ice_aq_send_cmd(hw, &desc, &vsi_ctx->info,
1636				 sizeof(vsi_ctx->info), cd);
1637
1638	if (!status) {
1639		vsi_ctx->vsis_allocd = le16_to_cpu(resp->vsi_used);
1640		vsi_ctx->vsis_unallocated = le16_to_cpu(resp->vsi_free);
1641	}
1642
1643	return status;
1644}
1645
1646/**
1647 * ice_is_vsi_valid - check whether the VSI is valid or not
1648 * @hw: pointer to the HW struct
1649 * @vsi_handle: VSI handle
1650 *
1651 * check whether the VSI is valid or not
1652 */
1653bool ice_is_vsi_valid(struct ice_hw *hw, u16 vsi_handle)
1654{
1655	return vsi_handle < ICE_MAX_VSI && hw->vsi_ctx[vsi_handle];
1656}
1657
1658/**
1659 * ice_get_hw_vsi_num - return the HW VSI number
1660 * @hw: pointer to the HW struct
1661 * @vsi_handle: VSI handle
1662 *
1663 * return the HW VSI number
1664 * Caution: call this function only if VSI is valid (ice_is_vsi_valid)
1665 */
1666u16 ice_get_hw_vsi_num(struct ice_hw *hw, u16 vsi_handle)
1667{
1668	return hw->vsi_ctx[vsi_handle]->vsi_num;
1669}
1670
1671/**
1672 * ice_get_vsi_ctx - return the VSI context entry for a given VSI handle
1673 * @hw: pointer to the HW struct
1674 * @vsi_handle: VSI handle
1675 *
1676 * return the VSI context entry for a given VSI handle
1677 */
1678struct ice_vsi_ctx *ice_get_vsi_ctx(struct ice_hw *hw, u16 vsi_handle)
1679{
1680	return (vsi_handle >= ICE_MAX_VSI) ? NULL : hw->vsi_ctx[vsi_handle];
1681}
1682
1683/**
1684 * ice_save_vsi_ctx - save the VSI context for a given VSI handle
1685 * @hw: pointer to the HW struct
1686 * @vsi_handle: VSI handle
1687 * @vsi: VSI context pointer
1688 *
1689 * save the VSI context entry for a given VSI handle
1690 */
1691static void
1692ice_save_vsi_ctx(struct ice_hw *hw, u16 vsi_handle, struct ice_vsi_ctx *vsi)
1693{
1694	hw->vsi_ctx[vsi_handle] = vsi;
1695}
1696
1697/**
1698 * ice_clear_vsi_q_ctx - clear VSI queue contexts for all TCs
1699 * @hw: pointer to the HW struct
1700 * @vsi_handle: VSI handle
1701 */
1702static void ice_clear_vsi_q_ctx(struct ice_hw *hw, u16 vsi_handle)
1703{
1704	struct ice_vsi_ctx *vsi = ice_get_vsi_ctx(hw, vsi_handle);
1705	u8 i;
1706
1707	if (!vsi)
1708		return;
1709	ice_for_each_traffic_class(i) {
1710		devm_kfree(ice_hw_to_dev(hw), vsi->lan_q_ctx[i]);
1711		vsi->lan_q_ctx[i] = NULL;
1712		devm_kfree(ice_hw_to_dev(hw), vsi->rdma_q_ctx[i]);
1713		vsi->rdma_q_ctx[i] = NULL;
1714	}
1715}
1716
1717/**
1718 * ice_clear_vsi_ctx - clear the VSI context entry
1719 * @hw: pointer to the HW struct
1720 * @vsi_handle: VSI handle
1721 *
1722 * clear the VSI context entry
1723 */
1724static void ice_clear_vsi_ctx(struct ice_hw *hw, u16 vsi_handle)
1725{
1726	struct ice_vsi_ctx *vsi;
1727
1728	vsi = ice_get_vsi_ctx(hw, vsi_handle);
1729	if (vsi) {
1730		ice_clear_vsi_q_ctx(hw, vsi_handle);
1731		devm_kfree(ice_hw_to_dev(hw), vsi);
1732		hw->vsi_ctx[vsi_handle] = NULL;
1733	}
1734}
1735
1736/**
1737 * ice_clear_all_vsi_ctx - clear all the VSI context entries
1738 * @hw: pointer to the HW struct
1739 */
1740void ice_clear_all_vsi_ctx(struct ice_hw *hw)
1741{
1742	u16 i;
1743
1744	for (i = 0; i < ICE_MAX_VSI; i++)
1745		ice_clear_vsi_ctx(hw, i);
1746}
1747
1748/**
1749 * ice_add_vsi - add VSI context to the hardware and VSI handle list
1750 * @hw: pointer to the HW struct
1751 * @vsi_handle: unique VSI handle provided by drivers
1752 * @vsi_ctx: pointer to a VSI context struct
1753 * @cd: pointer to command details structure or NULL
1754 *
1755 * Add a VSI context to the hardware also add it into the VSI handle list.
1756 * If this function gets called after reset for existing VSIs then update
1757 * with the new HW VSI number in the corresponding VSI handle list entry.
1758 */
1759int
1760ice_add_vsi(struct ice_hw *hw, u16 vsi_handle, struct ice_vsi_ctx *vsi_ctx,
1761	    struct ice_sq_cd *cd)
1762{
1763	struct ice_vsi_ctx *tmp_vsi_ctx;
1764	int status;
1765
1766	if (vsi_handle >= ICE_MAX_VSI)
1767		return -EINVAL;
1768	status = ice_aq_add_vsi(hw, vsi_ctx, cd);
1769	if (status)
1770		return status;
1771	tmp_vsi_ctx = ice_get_vsi_ctx(hw, vsi_handle);
1772	if (!tmp_vsi_ctx) {
1773		/* Create a new VSI context */
1774		tmp_vsi_ctx = devm_kzalloc(ice_hw_to_dev(hw),
1775					   sizeof(*tmp_vsi_ctx), GFP_KERNEL);
1776		if (!tmp_vsi_ctx) {
1777			ice_aq_free_vsi(hw, vsi_ctx, false, cd);
1778			return -ENOMEM;
1779		}
1780		*tmp_vsi_ctx = *vsi_ctx;
1781		ice_save_vsi_ctx(hw, vsi_handle, tmp_vsi_ctx);
1782	} else {
1783		/* update with new HW VSI num */
1784		tmp_vsi_ctx->vsi_num = vsi_ctx->vsi_num;
1785	}
1786
1787	return 0;
1788}
1789
1790/**
1791 * ice_free_vsi- free VSI context from hardware and VSI handle list
1792 * @hw: pointer to the HW struct
1793 * @vsi_handle: unique VSI handle
1794 * @vsi_ctx: pointer to a VSI context struct
1795 * @keep_vsi_alloc: keep VSI allocation as part of this PF's resources
1796 * @cd: pointer to command details structure or NULL
1797 *
1798 * Free VSI context info from hardware as well as from VSI handle list
1799 */
1800int
1801ice_free_vsi(struct ice_hw *hw, u16 vsi_handle, struct ice_vsi_ctx *vsi_ctx,
1802	     bool keep_vsi_alloc, struct ice_sq_cd *cd)
1803{
1804	int status;
1805
1806	if (!ice_is_vsi_valid(hw, vsi_handle))
1807		return -EINVAL;
1808	vsi_ctx->vsi_num = ice_get_hw_vsi_num(hw, vsi_handle);
1809	status = ice_aq_free_vsi(hw, vsi_ctx, keep_vsi_alloc, cd);
1810	if (!status)
1811		ice_clear_vsi_ctx(hw, vsi_handle);
1812	return status;
1813}
1814
1815/**
1816 * ice_update_vsi
1817 * @hw: pointer to the HW struct
1818 * @vsi_handle: unique VSI handle
1819 * @vsi_ctx: pointer to a VSI context struct
1820 * @cd: pointer to command details structure or NULL
1821 *
1822 * Update VSI context in the hardware
1823 */
1824int
1825ice_update_vsi(struct ice_hw *hw, u16 vsi_handle, struct ice_vsi_ctx *vsi_ctx,
1826	       struct ice_sq_cd *cd)
1827{
1828	if (!ice_is_vsi_valid(hw, vsi_handle))
1829		return -EINVAL;
1830	vsi_ctx->vsi_num = ice_get_hw_vsi_num(hw, vsi_handle);
1831	return ice_aq_update_vsi(hw, vsi_ctx, cd);
1832}
1833
1834/**
1835 * ice_cfg_rdma_fltr - enable/disable RDMA filtering on VSI
1836 * @hw: pointer to HW struct
1837 * @vsi_handle: VSI SW index
1838 * @enable: boolean for enable/disable
1839 */
1840int
1841ice_cfg_rdma_fltr(struct ice_hw *hw, u16 vsi_handle, bool enable)
1842{
1843	struct ice_vsi_ctx *ctx, *cached_ctx;
1844	int status;
1845
1846	cached_ctx = ice_get_vsi_ctx(hw, vsi_handle);
1847	if (!cached_ctx)
1848		return -ENOENT;
1849
1850	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
1851	if (!ctx)
1852		return -ENOMEM;
1853
1854	ctx->info.q_opt_rss = cached_ctx->info.q_opt_rss;
1855	ctx->info.q_opt_tc = cached_ctx->info.q_opt_tc;
1856	ctx->info.q_opt_flags = cached_ctx->info.q_opt_flags;
1857
1858	ctx->info.valid_sections = cpu_to_le16(ICE_AQ_VSI_PROP_Q_OPT_VALID);
1859
1860	if (enable)
1861		ctx->info.q_opt_flags |= ICE_AQ_VSI_Q_OPT_PE_FLTR_EN;
1862	else
1863		ctx->info.q_opt_flags &= ~ICE_AQ_VSI_Q_OPT_PE_FLTR_EN;
1864
1865	status = ice_update_vsi(hw, vsi_handle, ctx, NULL);
1866	if (!status) {
1867		cached_ctx->info.q_opt_flags = ctx->info.q_opt_flags;
1868		cached_ctx->info.valid_sections |= ctx->info.valid_sections;
1869	}
1870
1871	kfree(ctx);
1872	return status;
1873}
1874
1875/**
1876 * ice_aq_alloc_free_vsi_list
1877 * @hw: pointer to the HW struct
1878 * @vsi_list_id: VSI list ID returned or used for lookup
1879 * @lkup_type: switch rule filter lookup type
1880 * @opc: switch rules population command type - pass in the command opcode
1881 *
1882 * allocates or free a VSI list resource
1883 */
1884static int
1885ice_aq_alloc_free_vsi_list(struct ice_hw *hw, u16 *vsi_list_id,
1886			   enum ice_sw_lkup_type lkup_type,
1887			   enum ice_adminq_opc opc)
1888{
1889	DEFINE_RAW_FLEX(struct ice_aqc_alloc_free_res_elem, sw_buf, elem, 1);
1890	u16 buf_len = __struct_size(sw_buf);
1891	struct ice_aqc_res_elem *vsi_ele;
1892	int status;
1893
1894	sw_buf->num_elems = cpu_to_le16(1);
1895
1896	if (lkup_type == ICE_SW_LKUP_MAC ||
1897	    lkup_type == ICE_SW_LKUP_MAC_VLAN ||
1898	    lkup_type == ICE_SW_LKUP_ETHERTYPE ||
1899	    lkup_type == ICE_SW_LKUP_ETHERTYPE_MAC ||
1900	    lkup_type == ICE_SW_LKUP_PROMISC ||
1901	    lkup_type == ICE_SW_LKUP_PROMISC_VLAN ||
1902	    lkup_type == ICE_SW_LKUP_DFLT ||
1903	    lkup_type == ICE_SW_LKUP_LAST) {
1904		sw_buf->res_type = cpu_to_le16(ICE_AQC_RES_TYPE_VSI_LIST_REP);
1905	} else if (lkup_type == ICE_SW_LKUP_VLAN) {
1906		if (opc == ice_aqc_opc_alloc_res)
1907			sw_buf->res_type =
1908				cpu_to_le16(ICE_AQC_RES_TYPE_VSI_LIST_PRUNE |
1909					    ICE_AQC_RES_TYPE_FLAG_SHARED);
1910		else
1911			sw_buf->res_type =
1912				cpu_to_le16(ICE_AQC_RES_TYPE_VSI_LIST_PRUNE);
1913	} else {
1914		return -EINVAL;
1915	}
1916
1917	if (opc == ice_aqc_opc_free_res)
1918		sw_buf->elem[0].e.sw_resp = cpu_to_le16(*vsi_list_id);
1919
1920	status = ice_aq_alloc_free_res(hw, sw_buf, buf_len, opc);
1921	if (status)
1922		return status;
1923
1924	if (opc == ice_aqc_opc_alloc_res) {
1925		vsi_ele = &sw_buf->elem[0];
1926		*vsi_list_id = le16_to_cpu(vsi_ele->e.sw_resp);
1927	}
1928
1929	return 0;
1930}
1931
1932/**
1933 * ice_aq_sw_rules - add/update/remove switch rules
1934 * @hw: pointer to the HW struct
1935 * @rule_list: pointer to switch rule population list
1936 * @rule_list_sz: total size of the rule list in bytes
1937 * @num_rules: number of switch rules in the rule_list
1938 * @opc: switch rules population command type - pass in the command opcode
1939 * @cd: pointer to command details structure or NULL
1940 *
1941 * Add(0x02a0)/Update(0x02a1)/Remove(0x02a2) switch rules commands to firmware
1942 */
1943int
1944ice_aq_sw_rules(struct ice_hw *hw, void *rule_list, u16 rule_list_sz,
1945		u8 num_rules, enum ice_adminq_opc opc, struct ice_sq_cd *cd)
1946{
1947	struct ice_aqc_sw_rules *cmd;
1948	struct libie_aq_desc desc;
1949	int status;
1950
1951	if (opc != ice_aqc_opc_add_sw_rules &&
1952	    opc != ice_aqc_opc_update_sw_rules &&
1953	    opc != ice_aqc_opc_remove_sw_rules)
1954		return -EINVAL;
1955
1956	ice_fill_dflt_direct_cmd_desc(&desc, opc);
1957	cmd = libie_aq_raw(&desc);
1958
1959	desc.flags |= cpu_to_le16(LIBIE_AQ_FLAG_RD);
1960	cmd->num_rules_fltr_entry_index = cpu_to_le16(num_rules);
1961	status = ice_aq_send_cmd(hw, &desc, rule_list, rule_list_sz, cd);
1962	if (opc != ice_aqc_opc_add_sw_rules &&
1963	    hw->adminq.sq_last_status == LIBIE_AQ_RC_ENOENT)
1964		status = -ENOENT;
1965
1966	if (!status) {
1967		if (opc == ice_aqc_opc_add_sw_rules)
1968			hw->switch_info->rule_cnt += num_rules;
1969		else if (opc == ice_aqc_opc_remove_sw_rules)
1970			hw->switch_info->rule_cnt -= num_rules;
1971	}
1972
1973	trace_ice_aq_sw_rules(hw->switch_info);
1974
1975	return status;
1976}
1977
1978/**
1979 * ice_aq_add_recipe - add switch recipe
1980 * @hw: pointer to the HW struct
1981 * @s_recipe_list: pointer to switch rule population list
1982 * @num_recipes: number of switch recipes in the list
1983 * @cd: pointer to command details structure or NULL
1984 *
1985 * Add(0x0290)
1986 */
1987int
1988ice_aq_add_recipe(struct ice_hw *hw,
1989		  struct ice_aqc_recipe_data_elem *s_recipe_list,
1990		  u16 num_recipes, struct ice_sq_cd *cd)
1991{
1992	struct ice_aqc_add_get_recipe *cmd;
1993	struct libie_aq_desc desc;
1994	u16 buf_size;
1995
1996	cmd = libie_aq_raw(&desc);
1997	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_add_recipe);
1998
1999	cmd->num_sub_recipes = cpu_to_le16(num_recipes);
2000	desc.flags |= cpu_to_le16(LIBIE_AQ_FLAG_RD);
2001
2002	buf_size = num_recipes * sizeof(*s_recipe_list);
2003
2004	return ice_aq_send_cmd(hw, &desc, s_recipe_list, buf_size, cd);
2005}
2006
2007/**
2008 * ice_aq_get_recipe - get switch recipe
2009 * @hw: pointer to the HW struct
2010 * @s_recipe_list: pointer to switch rule population list
2011 * @num_recipes: pointer to the number of recipes (input and output)
2012 * @recipe_root: root recipe number of recipe(s) to retrieve
2013 * @cd: pointer to command details structure or NULL
2014 *
2015 * Get(0x0292)
2016 *
2017 * On input, *num_recipes should equal the number of entries in s_recipe_list.
2018 * On output, *num_recipes will equal the number of entries returned in
2019 * s_recipe_list.
2020 *
2021 * The caller must supply enough space in s_recipe_list to hold all possible
2022 * recipes and *num_recipes must equal ICE_MAX_NUM_RECIPES.
2023 */
2024int
2025ice_aq_get_recipe(struct ice_hw *hw,
2026		  struct ice_aqc_recipe_data_elem *s_recipe_list,
2027		  u16 *num_recipes, u16 recipe_root, struct ice_sq_cd *cd)
2028{
2029	struct ice_aqc_add_get_recipe *cmd;
2030	struct libie_aq_desc desc;
2031	u16 buf_size;
2032	int status;
2033
2034	if (*num_recipes != ICE_MAX_NUM_RECIPES)
2035		return -EINVAL;
2036
2037	cmd = libie_aq_raw(&desc);
2038	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_recipe);
2039
2040	cmd->return_index = cpu_to_le16(recipe_root);
2041	cmd->num_sub_recipes = 0;
2042
2043	buf_size = *num_recipes * sizeof(*s_recipe_list);
2044
2045	status = ice_aq_send_cmd(hw, &desc, s_recipe_list, buf_size, cd);
2046	*num_recipes = le16_to_cpu(cmd->num_sub_recipes);
2047
2048	return status;
2049}
2050
2051/**
2052 * ice_update_recipe_lkup_idx - update a default recipe based on the lkup_idx
2053 * @hw: pointer to the HW struct
2054 * @params: parameters used to update the default recipe
2055 *
2056 * This function only supports updating default recipes and it only supports
2057 * updating a single recipe based on the lkup_idx at a time.
2058 *
2059 * This is done as a read-modify-write operation. First, get the current recipe
2060 * contents based on the recipe's ID. Then modify the field vector index and
2061 * mask if it's valid at the lkup_idx. Finally, use the add recipe AQ to update
2062 * the pre-existing recipe with the modifications.
2063 */
2064int
2065ice_update_recipe_lkup_idx(struct ice_hw *hw,
2066			   struct ice_update_recipe_lkup_idx_params *params)
2067{
2068	struct ice_aqc_recipe_data_elem *rcp_list;
2069	u16 num_recps = ICE_MAX_NUM_RECIPES;
2070	int status;
2071
2072	rcp_list = kcalloc(num_recps, sizeof(*rcp_list), GFP_KERNEL);
2073	if (!rcp_list)
2074		return -ENOMEM;
2075
2076	/* read current recipe list from firmware */
2077	rcp_list->recipe_indx = params->rid;
2078	status = ice_aq_get_recipe(hw, rcp_list, &num_recps, params->rid, NULL);
2079	if (status) {
2080		ice_debug(hw, ICE_DBG_SW, "Failed to get recipe %d, status %d\n",
2081			  params->rid, status);
2082		goto error_out;
2083	}
2084
2085	/* only modify existing recipe's lkup_idx and mask if valid, while
2086	 * leaving all other fields the same, then update the recipe firmware
2087	 */
2088	rcp_list->content.lkup_indx[params->lkup_idx] = params->fv_idx;
2089	if (params->mask_valid)
2090		rcp_list->content.mask[params->lkup_idx] =
2091			cpu_to_le16(params->mask);
2092
2093	if (params->ignore_valid)
2094		rcp_list->content.lkup_indx[params->lkup_idx] |=
2095			ICE_AQ_RECIPE_LKUP_IGNORE;
2096
2097	status = ice_aq_add_recipe(hw, &rcp_list[0], 1, NULL);
2098	if (status)
2099		ice_debug(hw, ICE_DBG_SW, "Failed to update recipe %d lkup_idx %d fv_idx %d mask %d mask_valid %s, status %d\n",
2100			  params->rid, params->lkup_idx, params->fv_idx,
2101			  params->mask, params->mask_valid ? "true" : "false",
2102			  status);
2103
2104error_out:
2105	kfree(rcp_list);
2106	return status;
2107}
2108
2109/**
2110 * ice_aq_map_recipe_to_profile - Map recipe to packet profile
2111 * @hw: pointer to the HW struct
2112 * @profile_id: package profile ID to associate the recipe with
2113 * @r_assoc: Recipe bitmap filled in and need to be returned as response
2114 * @cd: pointer to command details structure or NULL
2115 * Recipe to profile association (0x0291)
2116 */
2117int
2118ice_aq_map_recipe_to_profile(struct ice_hw *hw, u32 profile_id, u64 r_assoc,
2119			     struct ice_sq_cd *cd)
2120{
2121	struct ice_aqc_recipe_to_profile *cmd;
2122	struct libie_aq_desc desc;
2123
2124	cmd = libie_aq_raw(&desc);
2125	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_recipe_to_profile);
2126	cmd->profile_id = cpu_to_le16(profile_id);
2127	/* Set the recipe ID bit in the bitmask to let the device know which
2128	 * profile we are associating the recipe to
2129	 */
2130	cmd->recipe_assoc = cpu_to_le64(r_assoc);
2131
2132	return ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
2133}
2134
2135/**
2136 * ice_aq_get_recipe_to_profile - Map recipe to packet profile
2137 * @hw: pointer to the HW struct
2138 * @profile_id: package profile ID to associate the recipe with
2139 * @r_assoc: Recipe bitmap filled in and need to be returned as response
2140 * @cd: pointer to command details structure or NULL
2141 * Associate profile ID with given recipe (0x0293)
2142 */
2143int
2144ice_aq_get_recipe_to_profile(struct ice_hw *hw, u32 profile_id, u64 *r_assoc,
2145			     struct ice_sq_cd *cd)
2146{
2147	struct ice_aqc_recipe_to_profile *cmd;
2148	struct libie_aq_desc desc;
2149	int status;
2150
2151	cmd = libie_aq_raw(&desc);
2152	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_recipe_to_profile);
2153	cmd->profile_id = cpu_to_le16(profile_id);
2154
2155	status = ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
2156	if (!status)
2157		*r_assoc = le64_to_cpu(cmd->recipe_assoc);
2158
2159	return status;
2160}
2161
2162/**
2163 * ice_init_chk_recipe_reuse_support - check if recipe reuse is supported
2164 * @hw: pointer to the hardware structure
2165 */
2166void ice_init_chk_recipe_reuse_support(struct ice_hw *hw)
2167{
2168	struct ice_nvm_info *nvm = &hw->flash.nvm;
2169
2170	hw->recp_reuse = (nvm->major == 0x4 && nvm->minor >= 0x30) ||
2171			 nvm->major > 0x4;
2172}
2173
2174/**
2175 * ice_alloc_recipe - add recipe resource
2176 * @hw: pointer to the hardware structure
2177 * @rid: recipe ID returned as response to AQ call
2178 */
2179int ice_alloc_recipe(struct ice_hw *hw, u16 *rid)
2180{
2181	DEFINE_RAW_FLEX(struct ice_aqc_alloc_free_res_elem, sw_buf, elem, 1);
2182	u16 buf_len = __struct_size(sw_buf);
2183	u16 res_type;
2184	int status;
2185
2186	sw_buf->num_elems = cpu_to_le16(1);
2187	res_type = FIELD_PREP(ICE_AQC_RES_TYPE_M, ICE_AQC_RES_TYPE_RECIPE);
2188	if (hw->recp_reuse)
2189		res_type |= ICE_AQC_RES_TYPE_FLAG_SUBSCRIBE_SHARED;
2190	else
2191		res_type |= ICE_AQC_RES_TYPE_FLAG_SHARED;
2192	sw_buf->res_type = cpu_to_le16(res_type);
2193	status = ice_aq_alloc_free_res(hw, sw_buf, buf_len,
2194				       ice_aqc_opc_alloc_res);
2195	if (!status) {
2196		*rid = le16_to_cpu(sw_buf->elem[0].e.sw_resp);
2197		hw->switch_info->recp_cnt++;
2198	}
2199
2200	return status;
2201}
2202
2203/**
2204 * ice_free_recipe_res - free recipe resource
2205 * @hw: pointer to the hardware structure
2206 * @rid: recipe ID to free
2207 *
2208 * Return: 0 on success, and others on error
2209 */
2210static int ice_free_recipe_res(struct ice_hw *hw, u16 rid)
2211{
2212	int status;
2213
2214	status = ice_free_hw_res(hw, ICE_AQC_RES_TYPE_RECIPE, 1, &rid);
2215	if (!status)
2216		hw->switch_info->recp_cnt--;
2217
2218	return status;
2219}
2220
2221/**
2222 * ice_release_recipe_res - disassociate and free recipe resource
2223 * @hw: pointer to the hardware structure
2224 * @recp: the recipe struct resource to unassociate and free
2225 *
2226 * Return: 0 on success, and others on error
2227 */
2228static int ice_release_recipe_res(struct ice_hw *hw,
2229				  struct ice_sw_recipe *recp)
2230{
2231	DECLARE_BITMAP(r_bitmap, ICE_MAX_NUM_RECIPES);
2232	struct ice_switch_info *sw = hw->switch_info;
2233	u64 recp_assoc;
2234	u32 rid, prof;
2235	int status;
2236
2237	for_each_set_bit(rid, recp->r_bitmap, ICE_MAX_NUM_RECIPES) {
2238		for_each_set_bit(prof, recipe_to_profile[rid],
2239				 ICE_MAX_NUM_PROFILES) {
2240			status = ice_aq_get_recipe_to_profile(hw, prof,
2241							      &recp_assoc,
2242							      NULL);
2243			if (status)
2244				return status;
2245
2246			bitmap_from_arr64(r_bitmap, &recp_assoc,
2247					  ICE_MAX_NUM_RECIPES);
2248			bitmap_andnot(r_bitmap, r_bitmap, recp->r_bitmap,
2249				      ICE_MAX_NUM_RECIPES);
2250			bitmap_to_arr64(&recp_assoc, r_bitmap,
2251					ICE_MAX_NUM_RECIPES);
2252			ice_aq_map_recipe_to_profile(hw, prof,
2253						     recp_assoc, NULL);
2254
2255			clear_bit(rid, profile_to_recipe[prof]);
2256			clear_bit(prof, recipe_to_profile[rid]);
2257		}
2258
2259		status = ice_free_recipe_res(hw, rid);
2260		if (status)
2261			return status;
2262
2263		sw->recp_list[rid].recp_created = false;
2264		sw->recp_list[rid].adv_rule = false;
2265		memset(&sw->recp_list[rid].lkup_exts, 0,
2266		       sizeof(sw->recp_list[rid].lkup_exts));
2267		clear_bit(rid, recp->r_bitmap);
2268	}
2269
2270	return 0;
2271}
2272
2273/**
2274 * ice_get_recp_to_prof_map - updates recipe to profile mapping
2275 * @hw: pointer to hardware structure
2276 *
2277 * This function is used to populate recipe_to_profile matrix where index to
2278 * this array is the recipe ID and the element is the mapping of which profiles
2279 * is this recipe mapped to.
2280 */
2281static void ice_get_recp_to_prof_map(struct ice_hw *hw)
2282{
2283	DECLARE_BITMAP(r_bitmap, ICE_MAX_NUM_RECIPES);
2284	u64 recp_assoc;
2285	u16 i;
2286
2287	for (i = 0; i < hw->switch_info->max_used_prof_index + 1; i++) {
2288		u16 j;
2289
2290		bitmap_zero(profile_to_recipe[i], ICE_MAX_NUM_RECIPES);
2291		bitmap_zero(r_bitmap, ICE_MAX_NUM_RECIPES);
2292		if (ice_aq_get_recipe_to_profile(hw, i, &recp_assoc, NULL))
2293			continue;
2294		bitmap_from_arr64(r_bitmap, &recp_assoc, ICE_MAX_NUM_RECIPES);
2295		bitmap_copy(profile_to_recipe[i], r_bitmap,
2296			    ICE_MAX_NUM_RECIPES);
2297		for_each_set_bit(j, r_bitmap, ICE_MAX_NUM_RECIPES)
2298			set_bit(i, recipe_to_profile[j]);
2299	}
2300}
2301
2302/**
2303 * ice_get_recp_frm_fw - update SW bookkeeping from FW recipe entries
2304 * @hw: pointer to hardware structure
2305 * @recps: struct that we need to populate
2306 * @rid: recipe ID that we are populating
2307 * @refresh_required: true if we should get recipe to profile mapping from FW
2308 * @is_add: flag of adding recipe
2309 *
2310 * This function is used to populate all the necessary entries into our
2311 * bookkeeping so that we have a current list of all the recipes that are
2312 * programmed in the firmware.
2313 */
2314static int
2315ice_get_recp_frm_fw(struct ice_hw *hw, struct ice_sw_recipe *recps, u8 rid,
2316		    bool *refresh_required, bool is_add)
2317{
2318	DECLARE_BITMAP(result_bm, ICE_MAX_FV_WORDS);
2319	struct ice_aqc_recipe_data_elem *tmp;
2320	u16 num_recps = ICE_MAX_NUM_RECIPES;
2321	struct ice_prot_lkup_ext *lkup_exts;
2322	u8 fv_word_idx = 0;
2323	u16 sub_recps;
2324	int status;
2325
2326	bitmap_zero(result_bm, ICE_MAX_FV_WORDS);
2327
2328	/* we need a buffer big enough to accommodate all the recipes */
2329	tmp = kcalloc(ICE_MAX_NUM_RECIPES, sizeof(*tmp), GFP_KERNEL);
2330	if (!tmp)
2331		return -ENOMEM;
2332
2333	tmp[0].recipe_indx = rid;
2334	status = ice_aq_get_recipe(hw, tmp, &num_recps, rid, NULL);
2335	/* non-zero status meaning recipe doesn't exist */
2336	if (status)
2337		goto err_unroll;
2338
2339	/* Get recipe to profile map so that we can get the fv from lkups that
2340	 * we read for a recipe from FW. Since we want to minimize the number of
2341	 * times we make this FW call, just make one call and cache the copy
2342	 * until a new recipe is added. This operation is only required the
2343	 * first time to get the changes from FW. Then to search existing
2344	 * entries we don't need to update the cache again until another recipe
2345	 * gets added.
2346	 */
2347	if (*refresh_required) {
2348		ice_get_recp_to_prof_map(hw);
2349		*refresh_required = false;
2350	}
2351
2352	/* Start populating all the entries for recps[rid] based on lkups from
2353	 * firmware. Note that we are only creating the root recipe in our
2354	 * database.
2355	 */
2356	lkup_exts = &recps[rid].lkup_exts;
2357
2358	for (sub_recps = 0; sub_recps < num_recps; sub_recps++) {
2359		struct ice_aqc_recipe_data_elem root_bufs = tmp[sub_recps];
2360		u8 i, prof, idx, prot = 0;
2361		bool is_root;
2362		u16 off = 0;
2363
2364		idx = root_bufs.recipe_indx;
2365		is_root = root_bufs.content.rid & ICE_AQ_RECIPE_ID_IS_ROOT;
2366
2367		/* Mark all result indices in this chain */
2368		if (root_bufs.content.result_indx & ICE_AQ_RECIPE_RESULT_EN)
2369			set_bit(root_bufs.content.result_indx & ~ICE_AQ_RECIPE_RESULT_EN,
2370				result_bm);
2371
2372		/* get the first profile that is associated with rid */
2373		prof = find_first_bit(recipe_to_profile[idx],
2374				      ICE_MAX_NUM_PROFILES);
2375		for (i = 0; i < ICE_NUM_WORDS_RECIPE; i++) {
2376			u8 lkup_indx = root_bufs.content.lkup_indx[i];
2377			u16 lkup_mask = le16_to_cpu(root_bufs.content.mask[i]);
2378
2379			/* If the recipe is a chained recipe then all its
2380			 * child recipe's result will have a result index.
2381			 * To fill fv_words we should not use those result
2382			 * index, we only need the protocol ids and offsets.
2383			 * We will skip all the fv_idx which stores result
2384			 * index in them. We also need to skip any fv_idx which
2385			 * has ICE_AQ_RECIPE_LKUP_IGNORE or 0 since it isn't a
2386			 * valid offset value.
2387			 */
2388			if (!lkup_indx ||
2389			    (lkup_indx & ICE_AQ_RECIPE_LKUP_IGNORE) ||
2390			    test_bit(lkup_indx,
2391				     hw->switch_info->prof_res_bm[prof]))
2392				continue;
2393
2394			ice_find_prot_off(hw, ICE_BLK_SW, prof, lkup_indx,
2395					  &prot, &off);
2396			lkup_exts->fv_words[fv_word_idx].prot_id = prot;
2397			lkup_exts->fv_words[fv_word_idx].off = off;
2398			lkup_exts->field_mask[fv_word_idx] = lkup_mask;
2399			fv_word_idx++;
2400		}
2401
2402		/* Propagate some data to the recipe database */
2403		recps[idx].priority = root_bufs.content.act_ctrl_fwd_priority;
2404		recps[idx].need_pass_l2 = !!(root_bufs.content.act_ctrl &
2405					     ICE_AQ_RECIPE_ACT_NEED_PASS_L2);
2406		recps[idx].allow_pass_l2 = !!(root_bufs.content.act_ctrl &
2407					      ICE_AQ_RECIPE_ACT_ALLOW_PASS_L2);
2408		bitmap_zero(recps[idx].res_idxs, ICE_MAX_FV_WORDS);
2409		if (root_bufs.content.result_indx & ICE_AQ_RECIPE_RESULT_EN) {
2410			set_bit(root_bufs.content.result_indx &
2411				~ICE_AQ_RECIPE_RESULT_EN, recps[idx].res_idxs);
2412		}
2413
2414		if (!is_root) {
2415			if (hw->recp_reuse && is_add)
2416				recps[idx].recp_created = true;
2417
2418			continue;
2419		}
2420
2421		/* Only do the following for root recipes entries */
2422		memcpy(recps[idx].r_bitmap, root_bufs.recipe_bitmap,
2423		       sizeof(recps[idx].r_bitmap));
2424		recps[idx].root_rid = root_bufs.content.rid &
2425			~ICE_AQ_RECIPE_ID_IS_ROOT;
2426		recps[idx].priority = root_bufs.content.act_ctrl_fwd_priority;
2427	}
2428
2429	/* Complete initialization of the root recipe entry */
2430	lkup_exts->n_val_words = fv_word_idx;
2431
2432	/* Copy result indexes */
2433	bitmap_copy(recps[rid].res_idxs, result_bm, ICE_MAX_FV_WORDS);
2434	if (is_add)
2435		recps[rid].recp_created = true;
2436
2437err_unroll:
2438	kfree(tmp);
2439	return status;
2440}
2441
2442/* ice_init_port_info - Initialize port_info with switch configuration data
2443 * @pi: pointer to port_info
2444 * @vsi_port_num: VSI number or port number
2445 * @type: Type of switch element (port or VSI)
2446 * @swid: switch ID of the switch the element is attached to
2447 * @pf_vf_num: PF or VF number
2448 * @is_vf: true if the element is a VF, false otherwise
2449 */
2450static void
2451ice_init_port_info(struct ice_port_info *pi, u16 vsi_port_num, u8 type,
2452		   u16 swid, u16 pf_vf_num, bool is_vf)
2453{
2454	switch (type) {
2455	case ICE_AQC_GET_SW_CONF_RESP_PHYS_PORT:
2456		pi->lport = (u8)(vsi_port_num & ICE_LPORT_MASK);
2457		pi->sw_id = swid;
2458		pi->pf_vf_num = pf_vf_num;
2459		pi->is_vf = is_vf;
2460		break;
2461	default:
2462		ice_debug(pi->hw, ICE_DBG_SW, "incorrect VSI/port type received\n");
2463		break;
2464	}
2465}
2466
2467/* ice_get_initial_sw_cfg - Get initial port and default VSI data
2468 * @hw: pointer to the hardware structure
2469 */
2470int ice_get_initial_sw_cfg(struct ice_hw *hw)
2471{
2472	struct ice_aqc_get_sw_cfg_resp_elem *rbuf;
2473	u16 req_desc = 0;
2474	u16 num_elems;
2475	int status;
2476	u16 i;
2477
2478	rbuf = kzalloc(ICE_SW_CFG_MAX_BUF_LEN, GFP_KERNEL);
2479	if (!rbuf)
2480		return -ENOMEM;
2481
2482	/* Multiple calls to ice_aq_get_sw_cfg may be required
2483	 * to get all the switch configuration information. The need
2484	 * for additional calls is indicated by ice_aq_get_sw_cfg
2485	 * writing a non-zero value in req_desc
2486	 */
2487	do {
2488		struct ice_aqc_get_sw_cfg_resp_elem *ele;
2489
2490		status = ice_aq_get_sw_cfg(hw, rbuf, ICE_SW_CFG_MAX_BUF_LEN,
2491					   &req_desc, &num_elems, NULL);
2492
2493		if (status)
2494			break;
2495
2496		for (i = 0, ele = rbuf; i < num_elems; i++, ele++) {
2497			u16 pf_vf_num, swid, vsi_port_num;
2498			bool is_vf = false;
2499			u8 res_type;
2500
2501			vsi_port_num = le16_to_cpu(ele->vsi_port_num) &
2502				ICE_AQC_GET_SW_CONF_RESP_VSI_PORT_NUM_M;
2503
2504			pf_vf_num = le16_to_cpu(ele->pf_vf_num) &
2505				ICE_AQC_GET_SW_CONF_RESP_FUNC_NUM_M;
2506
2507			swid = le16_to_cpu(ele->swid);
2508
2509			if (le16_to_cpu(ele->pf_vf_num) &
2510			    ICE_AQC_GET_SW_CONF_RESP_IS_VF)
2511				is_vf = true;
2512
2513			res_type = (u8)(le16_to_cpu(ele->vsi_port_num) >>
2514					ICE_AQC_GET_SW_CONF_RESP_TYPE_S);
2515
2516			if (res_type == ICE_AQC_GET_SW_CONF_RESP_VSI) {
2517				/* FW VSI is not needed. Just continue. */
2518				continue;
2519			}
2520
2521			ice_init_port_info(hw->port_info, vsi_port_num,
2522					   res_type, swid, pf_vf_num, is_vf);
2523		}
2524	} while (req_desc && !status);
2525
2526	kfree(rbuf);
2527	return status;
2528}
2529
2530/**
2531 * ice_fill_sw_info - Helper function to populate lb_en and lan_en
2532 * @hw: pointer to the hardware structure
2533 * @fi: filter info structure to fill/update
2534 *
2535 * This helper function populates the lb_en and lan_en elements of the provided
2536 * ice_fltr_info struct using the switch's type and characteristics of the
2537 * switch rule being configured.
2538 */
2539static void ice_fill_sw_info(struct ice_hw *hw, struct ice_fltr_info *fi)
2540{
2541	fi->lb_en = false;
2542	fi->lan_en = false;
2543	if ((fi->flag & ICE_FLTR_TX) &&
2544	    (fi->fltr_act == ICE_FWD_TO_VSI ||
2545	     fi->fltr_act == ICE_FWD_TO_VSI_LIST ||
2546	     fi->fltr_act == ICE_FWD_TO_Q ||
2547	     fi->fltr_act == ICE_FWD_TO_QGRP)) {
2548		/* Setting LB for prune actions will result in replicated
2549		 * packets to the internal switch that will be dropped.
2550		 */
2551		if (fi->lkup_type != ICE_SW_LKUP_VLAN)
2552			fi->lb_en = true;
2553
2554		/* Set lan_en to TRUE if
2555		 * 1. The switch is a VEB AND
2556		 * 2
2557		 * 2.1 The lookup is a directional lookup like ethertype,
2558		 * promiscuous, ethertype-MAC, promiscuous-VLAN
2559		 * and default-port OR
2560		 * 2.2 The lookup is VLAN, OR
2561		 * 2.3 The lookup is MAC with mcast or bcast addr for MAC, OR
2562		 * 2.4 The lookup is MAC_VLAN with mcast or bcast addr for MAC.
2563		 *
2564		 * OR
2565		 *
2566		 * The switch is a VEPA.
2567		 *
2568		 * In all other cases, the LAN enable has to be set to false.
2569		 */
2570		if (hw->evb_veb) {
2571			if (fi->lkup_type == ICE_SW_LKUP_ETHERTYPE ||
2572			    fi->lkup_type == ICE_SW_LKUP_PROMISC ||
2573			    fi->lkup_type == ICE_SW_LKUP_ETHERTYPE_MAC ||
2574			    fi->lkup_type == ICE_SW_LKUP_PROMISC_VLAN ||
2575			    fi->lkup_type == ICE_SW_LKUP_DFLT ||
2576			    fi->lkup_type == ICE_SW_LKUP_VLAN ||
2577			    (fi->lkup_type == ICE_SW_LKUP_MAC &&
2578			     !is_unicast_ether_addr(fi->l_data.mac.mac_addr)) ||
2579			    (fi->lkup_type == ICE_SW_LKUP_MAC_VLAN &&
2580			     !is_unicast_ether_addr(fi->l_data.mac.mac_addr)))
2581				fi->lan_en = true;
2582		} else {
2583			fi->lan_en = true;
2584		}
2585	}
2586
2587	if (fi->flag & ICE_FLTR_TX_ONLY)
2588		fi->lan_en = false;
2589}
2590
2591/**
2592 * ice_fill_eth_hdr - helper to copy dummy_eth_hdr into supplied buffer
2593 * @eth_hdr: pointer to buffer to populate
2594 */
2595void ice_fill_eth_hdr(u8 *eth_hdr)
2596{
2597	memcpy(eth_hdr, dummy_eth_header, DUMMY_ETH_HDR_LEN);
2598}
2599
2600/**
2601 * ice_fill_sw_rule - Helper function to fill switch rule structure
2602 * @hw: pointer to the hardware structure
2603 * @f_info: entry containing packet forwarding information
2604 * @s_rule: switch rule structure to be filled in based on mac_entry
2605 * @opc: switch rules population command type - pass in the command opcode
2606 */
2607static void
2608ice_fill_sw_rule(struct ice_hw *hw, struct ice_fltr_info *f_info,
2609		 struct ice_sw_rule_lkup_rx_tx *s_rule,
2610		 enum ice_adminq_opc opc)
2611{
2612	u16 vlan_id = ICE_MAX_VLAN_ID + 1;
2613	u16 vlan_tpid = ETH_P_8021Q;
2614	void *daddr = NULL;
2615	u16 eth_hdr_sz;
2616	u8 *eth_hdr;
2617	u32 act = 0;
2618	__be16 *off;
2619	u8 q_rgn;
2620
2621	if (opc == ice_aqc_opc_remove_sw_rules) {
2622		s_rule->act = 0;
2623		s_rule->index = cpu_to_le16(f_info->fltr_rule_id);
2624		s_rule->hdr_len = 0;
2625		return;
2626	}
2627
2628	eth_hdr_sz = sizeof(dummy_eth_header);
2629	eth_hdr = s_rule->hdr_data;
2630
2631	/* initialize the ether header with a dummy header */
2632	memcpy(eth_hdr, dummy_eth_header, eth_hdr_sz);
2633	ice_fill_sw_info(hw, f_info);
2634
2635	switch (f_info->fltr_act) {
2636	case ICE_FWD_TO_VSI:
2637		act |= FIELD_PREP(ICE_SINGLE_ACT_VSI_ID_M,
2638				  f_info->fwd_id.hw_vsi_id);
2639		if (f_info->lkup_type != ICE_SW_LKUP_VLAN)
2640			act |= ICE_SINGLE_ACT_VSI_FORWARDING |
2641				ICE_SINGLE_ACT_VALID_BIT;
2642		break;
2643	case ICE_FWD_TO_VSI_LIST:
2644		act |= ICE_SINGLE_ACT_VSI_LIST;
2645		act |= FIELD_PREP(ICE_SINGLE_ACT_VSI_LIST_ID_M,
2646				  f_info->fwd_id.vsi_list_id);
2647		if (f_info->lkup_type != ICE_SW_LKUP_VLAN)
2648			act |= ICE_SINGLE_ACT_VSI_FORWARDING |
2649				ICE_SINGLE_ACT_VALID_BIT;
2650		break;
2651	case ICE_FWD_TO_Q:
2652		act |= ICE_SINGLE_ACT_TO_Q;
2653		act |= FIELD_PREP(ICE_SINGLE_ACT_Q_INDEX_M,
2654				  f_info->fwd_id.q_id);
2655		break;
2656	case ICE_DROP_PACKET:
2657		act |= ICE_SINGLE_ACT_VSI_FORWARDING | ICE_SINGLE_ACT_DROP |
2658			ICE_SINGLE_ACT_VALID_BIT;
2659		break;
2660	case ICE_FWD_TO_QGRP:
2661		q_rgn = f_info->qgrp_size > 0 ?
2662			(u8)ilog2(f_info->qgrp_size) : 0;
2663		act |= ICE_SINGLE_ACT_TO_Q;
2664		act |= FIELD_PREP(ICE_SINGLE_ACT_Q_INDEX_M,
2665				  f_info->fwd_id.q_id);
2666		act |= FIELD_PREP(ICE_SINGLE_ACT_Q_REGION_M, q_rgn);
2667		break;
2668	default:
2669		return;
2670	}
2671
2672	if (f_info->lb_en)
2673		act |= ICE_SINGLE_ACT_LB_ENABLE;
2674	if (f_info->lan_en)
2675		act |= ICE_SINGLE_ACT_LAN_ENABLE;
2676
2677	switch (f_info->lkup_type) {
2678	case ICE_SW_LKUP_MAC:
2679		daddr = f_info->l_data.mac.mac_addr;
2680		break;
2681	case ICE_SW_LKUP_VLAN:
2682		vlan_id = f_info->l_data.vlan.vlan_id;
2683		if (f_info->l_data.vlan.tpid_valid)
2684			vlan_tpid = f_info->l_data.vlan.tpid;
2685		if (f_info->fltr_act == ICE_FWD_TO_VSI ||
2686		    f_info->fltr_act == ICE_FWD_TO_VSI_LIST) {
2687			act |= ICE_SINGLE_ACT_PRUNE;
2688			act |= ICE_SINGLE_ACT_EGRESS | ICE_SINGLE_ACT_INGRESS;
2689		}
2690		break;
2691	case ICE_SW_LKUP_ETHERTYPE_MAC:
2692		daddr = f_info->l_data.ethertype_mac.mac_addr;
2693		fallthrough;
2694	case ICE_SW_LKUP_ETHERTYPE:
2695		off = (__force __be16 *)(eth_hdr + ICE_ETH_ETHTYPE_OFFSET);
2696		*off = cpu_to_be16(f_info->l_data.ethertype_mac.ethertype);
2697		break;
2698	case ICE_SW_LKUP_MAC_VLAN:
2699		daddr = f_info->l_data.mac_vlan.mac_addr;
2700		vlan_id = f_info->l_data.mac_vlan.vlan_id;
2701		break;
2702	case ICE_SW_LKUP_PROMISC_VLAN:
2703		vlan_id = f_info->l_data.mac_vlan.vlan_id;
2704		fallthrough;
2705	case ICE_SW_LKUP_PROMISC:
2706		daddr = f_info->l_data.mac_vlan.mac_addr;
2707		break;
2708	default:
2709		break;
2710	}
2711
2712	s_rule->hdr.type = (f_info->flag & ICE_FLTR_RX) ?
2713		cpu_to_le16(ICE_AQC_SW_RULES_T_LKUP_RX) :
2714		cpu_to_le16(ICE_AQC_SW_RULES_T_LKUP_TX);
2715
2716	/* Recipe set depending on lookup type */
2717	s_rule->recipe_id = cpu_to_le16(f_info->lkup_type);
2718	s_rule->src = cpu_to_le16(f_info->src);
2719	s_rule->act = cpu_to_le32(act);
2720
2721	if (daddr)
2722		ether_addr_copy(eth_hdr + ICE_ETH_DA_OFFSET, daddr);
2723
2724	if (!(vlan_id > ICE_MAX_VLAN_ID)) {
2725		off = (__force __be16 *)(eth_hdr + ICE_ETH_VLAN_TCI_OFFSET);
2726		*off = cpu_to_be16(vlan_id);
2727		off = (__force __be16 *)(eth_hdr + ICE_ETH_ETHTYPE_OFFSET);
2728		*off = cpu_to_be16(vlan_tpid);
2729	}
2730
2731	/* Create the switch rule with the final dummy Ethernet header */
2732	if (opc != ice_aqc_opc_update_sw_rules)
2733		s_rule->hdr_len = cpu_to_le16(eth_hdr_sz);
2734}
2735
2736/**
2737 * ice_add_marker_act
2738 * @hw: pointer to the hardware structure
2739 * @m_ent: the management entry for which sw marker needs to be added
2740 * @sw_marker: sw marker to tag the Rx descriptor with
2741 * @l_id: large action resource ID
2742 *
2743 * Create a large action to hold software marker and update the switch rule
2744 * entry pointed by m_ent with newly created large action
2745 */
2746static int
2747ice_add_marker_act(struct ice_hw *hw, struct ice_fltr_mgmt_list_entry *m_ent,
2748		   u16 sw_marker, u16 l_id)
2749{
2750	struct ice_sw_rule_lkup_rx_tx *rx_tx;
2751	struct ice_sw_rule_lg_act *lg_act;
2752	/* For software marker we need 3 large actions
2753	 * 1. FWD action: FWD TO VSI or VSI LIST
2754	 * 2. GENERIC VALUE action to hold the profile ID
2755	 * 3. GENERIC VALUE action to hold the software marker ID
2756	 */
2757	const u16 num_lg_acts = 3;
2758	u16 lg_act_size;
2759	u16 rules_size;
2760	int status;
2761	u32 act;
2762	u16 id;
2763
2764	if (m_ent->fltr_info.lkup_type != ICE_SW_LKUP_MAC)
2765		return -EINVAL;
2766
2767	/* Create two back-to-back switch rules and submit them to the HW using
2768	 * one memory buffer:
2769	 *    1. Large Action
2770	 *    2. Look up Tx Rx
2771	 */
2772	lg_act_size = (u16)ICE_SW_RULE_LG_ACT_SIZE(lg_act, num_lg_acts);
2773	rules_size = lg_act_size + ICE_SW_RULE_RX_TX_ETH_HDR_SIZE(rx_tx);
2774	lg_act = devm_kzalloc(ice_hw_to_dev(hw), rules_size, GFP_KERNEL);
2775	if (!lg_act)
2776		return -ENOMEM;
2777
2778	rx_tx = (typeof(rx_tx))((u8 *)lg_act + lg_act_size);
2779
2780	/* Fill in the first switch rule i.e. large action */
2781	lg_act->hdr.type = cpu_to_le16(ICE_AQC_SW_RULES_T_LG_ACT);
2782	lg_act->index = cpu_to_le16(l_id);
2783	lg_act->size = cpu_to_le16(num_lg_acts);
2784
2785	/* First action VSI forwarding or VSI list forwarding depending on how
2786	 * many VSIs
2787	 */
2788	id = (m_ent->vsi_count > 1) ? m_ent->fltr_info.fwd_id.vsi_list_id :
2789		m_ent->fltr_info.fwd_id.hw_vsi_id;
2790
2791	act = ICE_LG_ACT_VSI_FORWARDING | ICE_LG_ACT_VALID_BIT;
2792	act |= FIELD_PREP(ICE_LG_ACT_VSI_LIST_ID_M, id);
2793	if (m_ent->vsi_count > 1)
2794		act |= ICE_LG_ACT_VSI_LIST;
2795	lg_act->act[0] = cpu_to_le32(act);
2796
2797	/* Second action descriptor type */
2798	act = ICE_LG_ACT_GENERIC;
2799
2800	act |= FIELD_PREP(ICE_LG_ACT_GENERIC_VALUE_M, 1);
2801	lg_act->act[1] = cpu_to_le32(act);
2802
2803	act = FIELD_PREP(ICE_LG_ACT_GENERIC_OFFSET_M,
2804			 ICE_LG_ACT_GENERIC_OFF_RX_DESC_PROF_IDX);
2805
2806	/* Third action Marker value */
2807	act |= ICE_LG_ACT_GENERIC;
2808	act |= FIELD_PREP(ICE_LG_ACT_GENERIC_VALUE_M, sw_marker);
2809
2810	lg_act->act[2] = cpu_to_le32(act);
2811
2812	/* call the fill switch rule to fill the lookup Tx Rx structure */
2813	ice_fill_sw_rule(hw, &m_ent->fltr_info, rx_tx,
2814			 ice_aqc_opc_update_sw_rules);
2815
2816	/* Update the action to point to the large action ID */
2817	act = ICE_SINGLE_ACT_PTR;
2818	act |= FIELD_PREP(ICE_SINGLE_ACT_PTR_VAL_M, l_id);
2819	rx_tx->act = cpu_to_le32(act);
2820
2821	/* Use the filter rule ID of the previously created rule with single
2822	 * act. Once the update happens, hardware will treat this as large
2823	 * action
2824	 */
2825	rx_tx->index = cpu_to_le16(m_ent->fltr_info.fltr_rule_id);
2826
2827	status = ice_aq_sw_rules(hw, lg_act, rules_size, 2,
2828				 ice_aqc_opc_update_sw_rules, NULL);
2829	if (!status) {
2830		m_ent->lg_act_idx = l_id;
2831		m_ent->sw_marker_id = sw_marker;
2832	}
2833
2834	devm_kfree(ice_hw_to_dev(hw), lg_act);
2835	return status;
2836}
2837
2838/**
2839 * ice_create_vsi_list_map
2840 * @hw: pointer to the hardware structure
2841 * @vsi_handle_arr: array of VSI handles to set in the VSI mapping
2842 * @num_vsi: number of VSI handles in the array
2843 * @vsi_list_id: VSI list ID generated as part of allocate resource
2844 *
2845 * Helper function to create a new entry of VSI list ID to VSI mapping
2846 * using the given VSI list ID
2847 */
2848static struct ice_vsi_list_map_info *
2849ice_create_vsi_list_map(struct ice_hw *hw, u16 *vsi_handle_arr, u16 num_vsi,
2850			u16 vsi_list_id)
2851{
2852	struct ice_switch_info *sw = hw->switch_info;
2853	struct ice_vsi_list_map_info *v_map;
2854	int i;
2855
2856	v_map = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*v_map), GFP_KERNEL);
2857	if (!v_map)
2858		return NULL;
2859
2860	v_map->vsi_list_id = vsi_list_id;
2861	v_map->ref_cnt = 1;
2862	for (i = 0; i < num_vsi; i++)
2863		set_bit(vsi_handle_arr[i], v_map->vsi_map);
2864
2865	list_add(&v_map->list_entry, &sw->vsi_list_map_head);
2866	return v_map;
2867}
2868
2869/**
2870 * ice_update_vsi_list_rule
2871 * @hw: pointer to the hardware structure
2872 * @vsi_handle_arr: array of VSI handles to form a VSI list
2873 * @num_vsi: number of VSI handles in the array
2874 * @vsi_list_id: VSI list ID generated as part of allocate resource
2875 * @remove: Boolean value to indicate if this is a remove action
2876 * @opc: switch rules population command type - pass in the command opcode
2877 * @lkup_type: lookup type of the filter
2878 *
2879 * Call AQ command to add a new switch rule or update existing switch rule
2880 * using the given VSI list ID
2881 */
2882static int
2883ice_update_vsi_list_rule(struct ice_hw *hw, u16 *vsi_handle_arr, u16 num_vsi,
2884			 u16 vsi_list_id, bool remove, enum ice_adminq_opc opc,
2885			 enum ice_sw_lkup_type lkup_type)
2886{
2887	struct ice_sw_rule_vsi_list *s_rule;
2888	u16 s_rule_size;
2889	u16 rule_type;
2890	int status;
2891	int i;
2892
2893	if (!num_vsi)
2894		return -EINVAL;
2895
2896	if (lkup_type == ICE_SW_LKUP_MAC ||
2897	    lkup_type == ICE_SW_LKUP_MAC_VLAN ||
2898	    lkup_type == ICE_SW_LKUP_ETHERTYPE ||
2899	    lkup_type == ICE_SW_LKUP_ETHERTYPE_MAC ||
2900	    lkup_type == ICE_SW_LKUP_PROMISC ||
2901	    lkup_type == ICE_SW_LKUP_PROMISC_VLAN ||
2902	    lkup_type == ICE_SW_LKUP_DFLT ||
2903	    lkup_type == ICE_SW_LKUP_LAST)
2904		rule_type = remove ? ICE_AQC_SW_RULES_T_VSI_LIST_CLEAR :
2905			ICE_AQC_SW_RULES_T_VSI_LIST_SET;
2906	else if (lkup_type == ICE_SW_LKUP_VLAN)
2907		rule_type = remove ? ICE_AQC_SW_RULES_T_PRUNE_LIST_CLEAR :
2908			ICE_AQC_SW_RULES_T_PRUNE_LIST_SET;
2909	else
2910		return -EINVAL;
2911
2912	s_rule_size = (u16)ICE_SW_RULE_VSI_LIST_SIZE(s_rule, num_vsi);
2913	s_rule = devm_kzalloc(ice_hw_to_dev(hw), s_rule_size, GFP_KERNEL);
2914	if (!s_rule)
2915		return -ENOMEM;
2916	for (i = 0; i < num_vsi; i++) {
2917		if (!ice_is_vsi_valid(hw, vsi_handle_arr[i])) {
2918			status = -EINVAL;
2919			goto exit;
2920		}
2921		/* AQ call requires hw_vsi_id(s) */
2922		s_rule->vsi[i] =
2923			cpu_to_le16(ice_get_hw_vsi_num(hw, vsi_handle_arr[i]));
2924	}
2925
2926	s_rule->hdr.type = cpu_to_le16(rule_type);
2927	s_rule->number_vsi = cpu_to_le16(num_vsi);
2928	s_rule->index = cpu_to_le16(vsi_list_id);
2929
2930	status = ice_aq_sw_rules(hw, s_rule, s_rule_size, 1, opc, NULL);
2931
2932exit:
2933	devm_kfree(ice_hw_to_dev(hw), s_rule);
2934	return status;
2935}
2936
2937/**
2938 * ice_create_vsi_list_rule - Creates and populates a VSI list rule
2939 * @hw: pointer to the HW struct
2940 * @vsi_handle_arr: array of VSI handles to form a VSI list
2941 * @num_vsi: number of VSI handles in the array
2942 * @vsi_list_id: stores the ID of the VSI list to be created
2943 * @lkup_type: switch rule filter's lookup type
2944 */
2945static int
2946ice_create_vsi_list_rule(struct ice_hw *hw, u16 *vsi_handle_arr, u16 num_vsi,
2947			 u16 *vsi_list_id, enum ice_sw_lkup_type lkup_type)
2948{
2949	int status;
2950
2951	status = ice_aq_alloc_free_vsi_list(hw, vsi_list_id, lkup_type,
2952					    ice_aqc_opc_alloc_res);
2953	if (status)
2954		return status;
2955
2956	/* Update the newly created VSI list to include the specified VSIs */
2957	return ice_update_vsi_list_rule(hw, vsi_handle_arr, num_vsi,
2958					*vsi_list_id, false,
2959					ice_aqc_opc_add_sw_rules, lkup_type);
2960}
2961
2962/**
2963 * ice_create_pkt_fwd_rule
2964 * @hw: pointer to the hardware structure
2965 * @f_entry: entry containing packet forwarding information
2966 *
2967 * Create switch rule with given filter information and add an entry
2968 * to the corresponding filter management list to track this switch rule
2969 * and VSI mapping
2970 */
2971static int
2972ice_create_pkt_fwd_rule(struct ice_hw *hw,
2973			struct ice_fltr_list_entry *f_entry)
2974{
2975	struct ice_fltr_mgmt_list_entry *fm_entry;
2976	struct ice_sw_rule_lkup_rx_tx *s_rule;
2977	enum ice_sw_lkup_type l_type;
2978	struct ice_sw_recipe *recp;
2979	int status;
2980
2981	s_rule = devm_kzalloc(ice_hw_to_dev(hw),
2982			      ICE_SW_RULE_RX_TX_ETH_HDR_SIZE(s_rule),
2983			      GFP_KERNEL);
2984	if (!s_rule)
2985		return -ENOMEM;
2986	fm_entry = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*fm_entry),
2987				GFP_KERNEL);
2988	if (!fm_entry) {
2989		status = -ENOMEM;
2990		goto ice_create_pkt_fwd_rule_exit;
2991	}
2992
2993	fm_entry->fltr_info = f_entry->fltr_info;
2994
2995	/* Initialize all the fields for the management entry */
2996	fm_entry->vsi_count = 1;
2997	fm_entry->lg_act_idx = ICE_INVAL_LG_ACT_INDEX;
2998	fm_entry->sw_marker_id = ICE_INVAL_SW_MARKER_ID;
2999	fm_entry->counter_index = ICE_INVAL_COUNTER_ID;
3000
3001	ice_fill_sw_rule(hw, &fm_entry->fltr_info, s_rule,
3002			 ice_aqc_opc_add_sw_rules);
3003
3004	status = ice_aq_sw_rules(hw, s_rule,
3005				 ICE_SW_RULE_RX_TX_ETH_HDR_SIZE(s_rule), 1,
3006				 ice_aqc_opc_add_sw_rules, NULL);
3007	if (status) {
3008		devm_kfree(ice_hw_to_dev(hw), fm_entry);
3009		goto ice_create_pkt_fwd_rule_exit;
3010	}
3011
3012	f_entry->fltr_info.fltr_rule_id = le16_to_cpu(s_rule->index);
3013	fm_entry->fltr_info.fltr_rule_id = le16_to_cpu(s_rule->index);
3014
3015	/* The book keeping entries will get removed when base driver
3016	 * calls remove filter AQ command
3017	 */
3018	l_type = fm_entry->fltr_info.lkup_type;
3019	recp = &hw->switch_info->recp_list[l_type];
3020	list_add(&fm_entry->list_entry, &recp->filt_rules);
3021
3022ice_create_pkt_fwd_rule_exit:
3023	devm_kfree(ice_hw_to_dev(hw), s_rule);
3024	return status;
3025}
3026
3027/**
3028 * ice_update_pkt_fwd_rule
3029 * @hw: pointer to the hardware structure
3030 * @f_info: filter information for switch rule
3031 *
3032 * Call AQ command to update a previously created switch rule with a
3033 * VSI list ID
3034 */
3035static int
3036ice_update_pkt_fwd_rule(struct ice_hw *hw, struct ice_fltr_info *f_info)
3037{
3038	struct ice_sw_rule_lkup_rx_tx *s_rule;
3039	int status;
3040
3041	s_rule = devm_kzalloc(ice_hw_to_dev(hw),
3042			      ICE_SW_RULE_RX_TX_ETH_HDR_SIZE(s_rule),
3043			      GFP_KERNEL);
3044	if (!s_rule)
3045		return -ENOMEM;
3046
3047	ice_fill_sw_rule(hw, f_info, s_rule, ice_aqc_opc_update_sw_rules);
3048
3049	s_rule->index = cpu_to_le16(f_info->fltr_rule_id);
3050
3051	/* Update switch rule with new rule set to forward VSI list */
3052	status = ice_aq_sw_rules(hw, s_rule,
3053				 ICE_SW_RULE_RX_TX_ETH_HDR_SIZE(s_rule), 1,
3054				 ice_aqc_opc_update_sw_rules, NULL);
3055
3056	devm_kfree(ice_hw_to_dev(hw), s_rule);
3057	return status;
3058}
3059
3060/**
3061 * ice_update_sw_rule_bridge_mode
3062 * @hw: pointer to the HW struct
3063 *
3064 * Updates unicast switch filter rules based on VEB/VEPA mode
3065 */
3066int ice_update_sw_rule_bridge_mode(struct ice_hw *hw)
3067{
3068	struct ice_switch_info *sw = hw->switch_info;
3069	struct ice_fltr_mgmt_list_entry *fm_entry;
3070	struct list_head *rule_head;
3071	struct mutex *rule_lock; /* Lock to protect filter rule list */
3072	int status = 0;
3073
3074	rule_lock = &sw->recp_list[ICE_SW_LKUP_MAC].filt_rule_lock;
3075	rule_head = &sw->recp_list[ICE_SW_LKUP_MAC].filt_rules;
3076
3077	mutex_lock(rule_lock);
3078	list_for_each_entry(fm_entry, rule_head, list_entry) {
3079		struct ice_fltr_info *fi = &fm_entry->fltr_info;
3080		u8 *addr = fi->l_data.mac.mac_addr;
3081
3082		/* Update unicast Tx rules to reflect the selected
3083		 * VEB/VEPA mode
3084		 */
3085		if ((fi->flag & ICE_FLTR_TX) && is_unicast_ether_addr(addr) &&
3086		    (fi->fltr_act == ICE_FWD_TO_VSI ||
3087		     fi->fltr_act == ICE_FWD_TO_VSI_LIST ||
3088		     fi->fltr_act == ICE_FWD_TO_Q ||
3089		     fi->fltr_act == ICE_FWD_TO_QGRP)) {
3090			status = ice_update_pkt_fwd_rule(hw, fi);
3091			if (status)
3092				break;
3093		}
3094	}
3095
3096	mutex_unlock(rule_lock);
3097
3098	return status;
3099}
3100
3101/**
3102 * ice_add_update_vsi_list
3103 * @hw: pointer to the hardware structure
3104 * @m_entry: pointer to current filter management list entry
3105 * @cur_fltr: filter information from the book keeping entry
3106 * @new_fltr: filter information with the new VSI to be added
3107 *
3108 * Call AQ command to add or update previously created VSI list with new VSI.
3109 *
3110 * Helper function to do book keeping associated with adding filter information
3111 * The algorithm to do the book keeping is described below :
3112 * When a VSI needs to subscribe to a given filter (MAC/VLAN/Ethtype etc.)
3113 *	if only one VSI has been added till now
3114 *		Allocate a new VSI list and add two VSIs
3115 *		to this list using switch rule command
3116 *		Update the previously created switch rule with the
3117 *		newly created VSI list ID
3118 *	if a VSI list was previously created
3119 *		Add the new VSI to the previously created VSI list set
3120 *		using the update switch rule command
3121 */
3122static int
3123ice_add_update_vsi_list(struct ice_hw *hw,
3124			struct ice_fltr_mgmt_list_entry *m_entry,
3125			struct ice_fltr_info *cur_fltr,
3126			struct ice_fltr_info *new_fltr)
3127{
3128	u16 vsi_list_id = 0;
3129	int status = 0;
3130
3131	if ((cur_fltr->fltr_act == ICE_FWD_TO_Q ||
3132	     cur_fltr->fltr_act == ICE_FWD_TO_QGRP))
3133		return -EOPNOTSUPP;
3134
3135	if ((new_fltr->fltr_act == ICE_FWD_TO_Q ||
3136	     new_fltr->fltr_act == ICE_FWD_TO_QGRP) &&
3137	    (cur_fltr->fltr_act == ICE_FWD_TO_VSI ||
3138	     cur_fltr->fltr_act == ICE_FWD_TO_VSI_LIST))
3139		return -EOPNOTSUPP;
3140
3141	if (m_entry->vsi_count < 2 && !m_entry->vsi_list_info) {
3142		/* Only one entry existed in the mapping and it was not already
3143		 * a part of a VSI list. So, create a VSI list with the old and
3144		 * new VSIs.
3145		 */
3146		struct ice_fltr_info tmp_fltr;
3147		u16 vsi_handle_arr[2];
3148
3149		/* A rule already exists with the new VSI being added */
3150		if (cur_fltr->vsi_handle == new_fltr->vsi_handle)
3151			return -EEXIST;
3152
3153		vsi_handle_arr[0] = cur_fltr->vsi_handle;
3154		vsi_handle_arr[1] = new_fltr->vsi_handle;
3155		status = ice_create_vsi_list_rule(hw, &vsi_handle_arr[0], 2,
3156						  &vsi_list_id,
3157						  new_fltr->lkup_type);
3158		if (status)
3159			return status;
3160
3161		tmp_fltr = *new_fltr;
3162		tmp_fltr.fltr_rule_id = cur_fltr->fltr_rule_id;
3163		tmp_fltr.fltr_act = ICE_FWD_TO_VSI_LIST;
3164		tmp_fltr.fwd_id.vsi_list_id = vsi_list_id;
3165		/* Update the previous switch rule of "MAC forward to VSI" to
3166		 * "MAC fwd to VSI list"
3167		 */
3168		status = ice_update_pkt_fwd_rule(hw, &tmp_fltr);
3169		if (status)
3170			return status;
3171
3172		cur_fltr->fwd_id.vsi_list_id = vsi_list_id;
3173		cur_fltr->fltr_act = ICE_FWD_TO_VSI_LIST;
3174		m_entry->vsi_list_info =
3175			ice_create_vsi_list_map(hw, &vsi_handle_arr[0], 2,
3176						vsi_list_id);
3177
3178		if (!m_entry->vsi_list_info)
3179			return -ENOMEM;
3180
3181		/* If this entry was large action then the large action needs
3182		 * to be updated to point to FWD to VSI list
3183		 */
3184		if (m_entry->sw_marker_id != ICE_INVAL_SW_MARKER_ID)
3185			status =
3186			    ice_add_marker_act(hw, m_entry,
3187					       m_entry->sw_marker_id,
3188					       m_entry->lg_act_idx);
3189	} else {
3190		u16 vsi_handle = new_fltr->vsi_handle;
3191		enum ice_adminq_opc opcode;
3192
3193		if (!m_entry->vsi_list_info)
3194			return -EIO;
3195
3196		/* A rule already exists with the new VSI being added */
3197		if (test_bit(vsi_handle, m_entry->vsi_list_info->vsi_map))
3198			return -EEXIST;
3199
3200		/* Update the previously created VSI list set with
3201		 * the new VSI ID passed in
3202		 */
3203		vsi_list_id = cur_fltr->fwd_id.vsi_list_id;
3204		opcode = ice_aqc_opc_update_sw_rules;
3205
3206		status = ice_update_vsi_list_rule(hw, &vsi_handle, 1,
3207						  vsi_list_id, false, opcode,
3208						  new_fltr->lkup_type);
3209		/* update VSI list mapping info with new VSI ID */
3210		if (!status)
3211			set_bit(vsi_handle, m_entry->vsi_list_info->vsi_map);
3212	}
3213	if (!status)
3214		m_entry->vsi_count++;
3215	return status;
3216}
3217
3218/**
3219 * ice_find_rule_entry - Search a rule entry
3220 * @hw: pointer to the hardware structure
3221 * @recp_id: lookup type for which the specified rule needs to be searched
3222 * @f_info: rule information
3223 *
3224 * Helper function to search for a given rule entry
3225 * Returns pointer to entry storing the rule if found
3226 */
3227static struct ice_fltr_mgmt_list_entry *
3228ice_find_rule_entry(struct ice_hw *hw, u8 recp_id, struct ice_fltr_info *f_info)
3229{
3230	struct ice_fltr_mgmt_list_entry *list_itr, *ret = NULL;
3231	struct ice_switch_info *sw = hw->switch_info;
3232	struct list_head *list_head;
3233
3234	list_head = &sw->recp_list[recp_id].filt_rules;
3235	list_for_each_entry(list_itr, list_head, list_entry) {
3236		if (!memcmp(&f_info->l_data, &list_itr->fltr_info.l_data,
3237			    sizeof(f_info->l_data)) &&
3238		    f_info->flag == list_itr->fltr_info.flag) {
3239			ret = list_itr;
3240			break;
3241		}
3242	}
3243	return ret;
3244}
3245
3246/**
3247 * ice_find_vsi_list_entry - Search VSI list map with VSI count 1
3248 * @hw: pointer to the hardware structure
3249 * @recp_id: lookup type for which VSI lists needs to be searched
3250 * @vsi_handle: VSI handle to be found in VSI list
3251 * @vsi_list_id: VSI list ID found containing vsi_handle
3252 *
3253 * Helper function to search a VSI list with single entry containing given VSI
3254 * handle element. This can be extended further to search VSI list with more
3255 * than 1 vsi_count. Returns pointer to VSI list entry if found.
3256 */
3257struct ice_vsi_list_map_info *
3258ice_find_vsi_list_entry(struct ice_hw *hw, u8 recp_id, u16 vsi_handle,
3259			u16 *vsi_list_id)
3260{
3261	struct ice_vsi_list_map_info *map_info = NULL;
3262	struct ice_switch_info *sw = hw->switch_info;
3263	struct ice_fltr_mgmt_list_entry *list_itr;
3264	struct list_head *list_head;
3265
3266	list_head = &sw->recp_list[recp_id].filt_rules;
3267	list_for_each_entry(list_itr, list_head, list_entry) {
3268		if (list_itr->vsi_count == 1 && list_itr->vsi_list_info) {
3269			map_info = list_itr->vsi_list_info;
3270			if (test_bit(vsi_handle, map_info->vsi_map)) {
3271				*vsi_list_id = map_info->vsi_list_id;
3272				return map_info;
3273			}
3274		}
3275	}
3276	return NULL;
3277}
3278
3279/**
3280 * ice_add_rule_internal - add rule for a given lookup type
3281 * @hw: pointer to the hardware structure
3282 * @recp_id: lookup type (recipe ID) for which rule has to be added
3283 * @f_entry: structure containing MAC forwarding information
3284 *
3285 * Adds or updates the rule lists for a given recipe
3286 */
3287static int
3288ice_add_rule_internal(struct ice_hw *hw, u8 recp_id,
3289		      struct ice_fltr_list_entry *f_entry)
3290{
3291	struct ice_switch_info *sw = hw->switch_info;
3292	struct ice_fltr_info *new_fltr, *cur_fltr;
3293	struct ice_fltr_mgmt_list_entry *m_entry;
3294	struct mutex *rule_lock; /* Lock to protect filter rule list */
3295	int status = 0;
3296
3297	if (!ice_is_vsi_valid(hw, f_entry->fltr_info.vsi_handle))
3298		return -EINVAL;
3299	f_entry->fltr_info.fwd_id.hw_vsi_id =
3300		ice_get_hw_vsi_num(hw, f_entry->fltr_info.vsi_handle);
3301
3302	rule_lock = &sw->recp_list[recp_id].filt_rule_lock;
3303
3304	mutex_lock(rule_lock);
3305	new_fltr = &f_entry->fltr_info;
3306	if (new_fltr->flag & ICE_FLTR_RX)
3307		new_fltr->src = hw->port_info->lport;
3308	else if (new_fltr->flag & ICE_FLTR_TX)
3309		new_fltr->src = f_entry->fltr_info.fwd_id.hw_vsi_id;
3310
3311	m_entry = ice_find_rule_entry(hw, recp_id, new_fltr);
3312	if (!m_entry) {
3313		mutex_unlock(rule_lock);
3314		return ice_create_pkt_fwd_rule(hw, f_entry);
3315	}
3316
3317	cur_fltr = &m_entry->fltr_info;
3318	status = ice_add_update_vsi_list(hw, m_entry, cur_fltr, new_fltr);
3319	mutex_unlock(rule_lock);
3320
3321	return status;
3322}
3323
3324/**
3325 * ice_remove_vsi_list_rule
3326 * @hw: pointer to the hardware structure
3327 * @vsi_list_id: VSI list ID generated as part of allocate resource
3328 * @lkup_type: switch rule filter lookup type
3329 *
3330 * The VSI list should be emptied before this function is called to remove the
3331 * VSI list.
3332 */
3333static int
3334ice_remove_vsi_list_rule(struct ice_hw *hw, u16 vsi_list_id,
3335			 enum ice_sw_lkup_type lkup_type)
3336{
3337	struct ice_sw_rule_vsi_list *s_rule;
3338	u16 s_rule_size;
3339	int status;
3340
3341	s_rule_size = (u16)ICE_SW_RULE_VSI_LIST_SIZE(s_rule, 0);
3342	s_rule = devm_kzalloc(ice_hw_to_dev(hw), s_rule_size, GFP_KERNEL);
3343	if (!s_rule)
3344		return -ENOMEM;
3345
3346	s_rule->hdr.type = cpu_to_le16(ICE_AQC_SW_RULES_T_VSI_LIST_CLEAR);
3347	s_rule->index = cpu_to_le16(vsi_list_id);
3348
3349	/* Free the vsi_list resource that we allocated. It is assumed that the
3350	 * list is empty at this point.
3351	 */
3352	status = ice_aq_alloc_free_vsi_list(hw, &vsi_list_id, lkup_type,
3353					    ice_aqc_opc_free_res);
3354
3355	devm_kfree(ice_hw_to_dev(hw), s_rule);
3356	return status;
3357}
3358
3359/**
3360 * ice_rem_update_vsi_list
3361 * @hw: pointer to the hardware structure
3362 * @vsi_handle: VSI handle of the VSI to remove
3363 * @fm_list: filter management entry for which the VSI list management needs to
3364 *           be done
3365 */
3366static int
3367ice_rem_update_vsi_list(struct ice_hw *hw, u16 vsi_handle,
3368			struct ice_fltr_mgmt_list_entry *fm_list)
3369{
3370	enum ice_sw_lkup_type lkup_type;
3371	u16 vsi_list_id;
3372	int status = 0;
3373
3374	if (fm_list->fltr_info.fltr_act != ICE_FWD_TO_VSI_LIST ||
3375	    fm_list->vsi_count == 0)
3376		return -EINVAL;
3377
3378	/* A rule with the VSI being removed does not exist */
3379	if (!test_bit(vsi_handle, fm_list->vsi_list_info->vsi_map))
3380		return -ENOENT;
3381
3382	lkup_type = fm_list->fltr_info.lkup_type;
3383	vsi_list_id = fm_list->fltr_info.fwd_id.vsi_list_id;
3384	status = ice_update_vsi_list_rule(hw, &vsi_handle, 1, vsi_list_id, true,
3385					  ice_aqc_opc_update_sw_rules,
3386					  lkup_type);
3387	if (status)
3388		return status;
3389
3390	fm_list->vsi_count--;
3391	clear_bit(vsi_handle, fm_list->vsi_list_info->vsi_map);
3392
3393	if (fm_list->vsi_count == 1 && lkup_type != ICE_SW_LKUP_VLAN) {
3394		struct ice_fltr_info tmp_fltr_info = fm_list->fltr_info;
3395		struct ice_vsi_list_map_info *vsi_list_info =
3396			fm_list->vsi_list_info;
3397		u16 rem_vsi_handle;
3398
3399		rem_vsi_handle = find_first_bit(vsi_list_info->vsi_map,
3400						ICE_MAX_VSI);
3401		if (!ice_is_vsi_valid(hw, rem_vsi_handle))
3402			return -EIO;
3403
3404		/* Make sure VSI list is empty before removing it below */
3405		status = ice_update_vsi_list_rule(hw, &rem_vsi_handle, 1,
3406						  vsi_list_id, true,
3407						  ice_aqc_opc_update_sw_rules,
3408						  lkup_type);
3409		if (status)
3410			return status;
3411
3412		tmp_fltr_info.fltr_act = ICE_FWD_TO_VSI;
3413		tmp_fltr_info.fwd_id.hw_vsi_id =
3414			ice_get_hw_vsi_num(hw, rem_vsi_handle);
3415		tmp_fltr_info.vsi_handle = rem_vsi_handle;
3416		status = ice_update_pkt_fwd_rule(hw, &tmp_fltr_info);
3417		if (status) {
3418			ice_debug(hw, ICE_DBG_SW, "Failed to update pkt fwd rule to FWD_TO_VSI on HW VSI %d, error %d\n",
3419				  tmp_fltr_info.fwd_id.hw_vsi_id, status);
3420			return status;
3421		}
3422
3423		fm_list->fltr_info = tmp_fltr_info;
3424	}
3425
3426	if ((fm_list->vsi_count == 1 && lkup_type != ICE_SW_LKUP_VLAN) ||
3427	    (fm_list->vsi_count == 0 && lkup_type == ICE_SW_LKUP_VLAN)) {
3428		struct ice_vsi_list_map_info *vsi_list_info =
3429			fm_list->vsi_list_info;
3430
3431		/* Remove the VSI list since it is no longer used */
3432		status = ice_remove_vsi_list_rule(hw, vsi_list_id, lkup_type);
3433		if (status) {
3434			ice_debug(hw, ICE_DBG_SW, "Failed to remove VSI list %d, error %d\n",
3435				  vsi_list_id, status);
3436			return status;
3437		}
3438
3439		list_del(&vsi_list_info->list_entry);
3440		devm_kfree(ice_hw_to_dev(hw), vsi_list_info);
3441		fm_list->vsi_list_info = NULL;
3442	}
3443
3444	return status;
3445}
3446
3447/**
3448 * ice_remove_rule_internal - Remove a filter rule of a given type
3449 * @hw: pointer to the hardware structure
3450 * @recp_id: recipe ID for which the rule needs to removed
3451 * @f_entry: rule entry containing filter information
3452 */
3453static int
3454ice_remove_rule_internal(struct ice_hw *hw, u8 recp_id,
3455			 struct ice_fltr_list_entry *f_entry)
3456{
3457	struct ice_switch_info *sw = hw->switch_info;
3458	struct ice_fltr_mgmt_list_entry *list_elem;
3459	struct mutex *rule_lock; /* Lock to protect filter rule list */
3460	bool remove_rule = false;
3461	u16 vsi_handle;
3462	int status = 0;
3463
3464	if (!ice_is_vsi_valid(hw, f_entry->fltr_info.vsi_handle))
3465		return -EINVAL;
3466	f_entry->fltr_info.fwd_id.hw_vsi_id =
3467		ice_get_hw_vsi_num(hw, f_entry->fltr_info.vsi_handle);
3468
3469	rule_lock = &sw->recp_list[recp_id].filt_rule_lock;
3470	mutex_lock(rule_lock);
3471	list_elem = ice_find_rule_entry(hw, recp_id, &f_entry->fltr_info);
3472	if (!list_elem) {
3473		status = -ENOENT;
3474		goto exit;
3475	}
3476
3477	if (list_elem->fltr_info.fltr_act != ICE_FWD_TO_VSI_LIST) {
3478		remove_rule = true;
3479	} else if (!list_elem->vsi_list_info) {
3480		status = -ENOENT;
3481		goto exit;
3482	} else if (list_elem->vsi_list_info->ref_cnt > 1) {
3483		/* a ref_cnt > 1 indicates that the vsi_list is being
3484		 * shared by multiple rules. Decrement the ref_cnt and
3485		 * remove this rule, but do not modify the list, as it
3486		 * is in-use by other rules.
3487		 */
3488		list_elem->vsi_list_info->ref_cnt--;
3489		remove_rule = true;
3490	} else {
3491		/* a ref_cnt of 1 indicates the vsi_list is only used
3492		 * by one rule. However, the original removal request is only
3493		 * for a single VSI. Update the vsi_list first, and only
3494		 * remove the rule if there are no further VSIs in this list.
3495		 */
3496		vsi_handle = f_entry->fltr_info.vsi_handle;
3497		status = ice_rem_update_vsi_list(hw, vsi_handle, list_elem);
3498		if (status)
3499			goto exit;
3500		/* if VSI count goes to zero after updating the VSI list */
3501		if (list_elem->vsi_count == 0)
3502			remove_rule = true;
3503	}
3504
3505	if (remove_rule) {
3506		/* Remove the lookup rule */
3507		struct ice_sw_rule_lkup_rx_tx *s_rule;
3508
3509		s_rule = devm_kzalloc(ice_hw_to_dev(hw),
3510				      ICE_SW_RULE_RX_TX_NO_HDR_SIZE(s_rule),
3511				      GFP_KERNEL);
3512		if (!s_rule) {
3513			status = -ENOMEM;
3514			goto exit;
3515		}
3516
3517		ice_fill_sw_rule(hw, &list_elem->fltr_info, s_rule,
3518				 ice_aqc_opc_remove_sw_rules);
3519
3520		status = ice_aq_sw_rules(hw, s_rule,
3521					 ICE_SW_RULE_RX_TX_NO_HDR_SIZE(s_rule),
3522					 1, ice_aqc_opc_remove_sw_rules, NULL);
3523
3524		/* Remove a book keeping from the list */
3525		devm_kfree(ice_hw_to_dev(hw), s_rule);
3526
3527		if (status)
3528			goto exit;
3529
3530		list_del(&list_elem->list_entry);
3531		devm_kfree(ice_hw_to_dev(hw), list_elem);
3532	}
3533exit:
3534	mutex_unlock(rule_lock);
3535	return status;
3536}
3537
3538/**
3539 * ice_vlan_fltr_exist - does this VLAN filter exist for given VSI
3540 * @hw: pointer to the hardware structure
3541 * @vlan_id: VLAN ID
3542 * @vsi_handle: check MAC filter for this VSI
3543 */
3544bool ice_vlan_fltr_exist(struct ice_hw *hw, u16 vlan_id, u16 vsi_handle)
3545{
3546	struct ice_fltr_mgmt_list_entry *entry;
3547	struct list_head *rule_head;
3548	struct ice_switch_info *sw;
3549	struct mutex *rule_lock; /* Lock to protect filter rule list */
3550	u16 hw_vsi_id;
3551
3552	if (vlan_id > ICE_MAX_VLAN_ID)
3553		return false;
3554
3555	if (!ice_is_vsi_valid(hw, vsi_handle))
3556		return false;
3557
3558	hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle);
3559	sw = hw->switch_info;
3560	rule_head = &sw->recp_list[ICE_SW_LKUP_VLAN].filt_rules;
3561	if (!rule_head)
3562		return false;
3563
3564	rule_lock = &sw->recp_list[ICE_SW_LKUP_VLAN].filt_rule_lock;
3565	mutex_lock(rule_lock);
3566	list_for_each_entry(entry, rule_head, list_entry) {
3567		struct ice_fltr_info *f_info = &entry->fltr_info;
3568		u16 entry_vlan_id = f_info->l_data.vlan.vlan_id;
3569		struct ice_vsi_list_map_info *map_info;
3570
3571		if (entry_vlan_id > ICE_MAX_VLAN_ID)
3572			continue;
3573
3574		if (f_info->flag != ICE_FLTR_TX ||
3575		    f_info->src_id != ICE_SRC_ID_VSI ||
3576		    f_info->lkup_type != ICE_SW_LKUP_VLAN)
3577			continue;
3578
3579		/* Only allowed filter action are FWD_TO_VSI/_VSI_LIST */
3580		if (f_info->fltr_act != ICE_FWD_TO_VSI &&
3581		    f_info->fltr_act != ICE_FWD_TO_VSI_LIST)
3582			continue;
3583
3584		if (f_info->fltr_act == ICE_FWD_TO_VSI) {
3585			if (hw_vsi_id != f_info->fwd_id.hw_vsi_id)
3586				continue;
3587		} else if (f_info->fltr_act == ICE_FWD_TO_VSI_LIST) {
3588			/* If filter_action is FWD_TO_VSI_LIST, make sure
3589			 * that VSI being checked is part of VSI list
3590			 */
3591			if (entry->vsi_count == 1 &&
3592			    entry->vsi_list_info) {
3593				map_info = entry->vsi_list_info;
3594				if (!test_bit(vsi_handle, map_info->vsi_map))
3595					continue;
3596			}
3597		}
3598
3599		if (vlan_id == entry_vlan_id) {
3600			mutex_unlock(rule_lock);
3601			return true;
3602		}
3603	}
3604	mutex_unlock(rule_lock);
3605
3606	return false;
3607}
3608
3609/**
3610 * ice_add_mac - Add a MAC address based filter rule
3611 * @hw: pointer to the hardware structure
3612 * @m_list: list of MAC addresses and forwarding information
3613 */
3614int ice_add_mac(struct ice_hw *hw, struct list_head *m_list)
3615{
3616	struct ice_fltr_list_entry *m_list_itr;
3617	int status = 0;
3618
3619	if (!m_list || !hw)
3620		return -EINVAL;
3621
3622	list_for_each_entry(m_list_itr, m_list, list_entry) {
3623		u8 *add = &m_list_itr->fltr_info.l_data.mac.mac_addr[0];
3624		u16 vsi_handle;
3625		u16 hw_vsi_id;
3626
3627		m_list_itr->fltr_info.flag = ICE_FLTR_TX;
3628		vsi_handle = m_list_itr->fltr_info.vsi_handle;
3629		if (!ice_is_vsi_valid(hw, vsi_handle))
3630			return -EINVAL;
3631		hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle);
3632		m_list_itr->fltr_info.fwd_id.hw_vsi_id = hw_vsi_id;
3633		/* update the src in case it is VSI num */
3634		if (m_list_itr->fltr_info.src_id != ICE_SRC_ID_VSI)
3635			return -EINVAL;
3636		m_list_itr->fltr_info.src = hw_vsi_id;
3637		if (m_list_itr->fltr_info.lkup_type != ICE_SW_LKUP_MAC ||
3638		    is_zero_ether_addr(add))
3639			return -EINVAL;
3640
3641		m_list_itr->status = ice_add_rule_internal(hw, ICE_SW_LKUP_MAC,
3642							   m_list_itr);
3643		if (m_list_itr->status)
3644			return m_list_itr->status;
3645	}
3646
3647	return status;
3648}
3649
3650/**
3651 * ice_add_vlan_internal - Add one VLAN based filter rule
3652 * @hw: pointer to the hardware structure
3653 * @f_entry: filter entry containing one VLAN information
3654 */
3655static int
3656ice_add_vlan_internal(struct ice_hw *hw, struct ice_fltr_list_entry *f_entry)
3657{
3658	struct ice_switch_info *sw = hw->switch_info;
3659	struct ice_fltr_mgmt_list_entry *v_list_itr;
3660	struct ice_fltr_info *new_fltr, *cur_fltr;
3661	enum ice_sw_lkup_type lkup_type;
3662	u16 vsi_list_id = 0, vsi_handle;
3663	struct mutex *rule_lock; /* Lock to protect filter rule list */
3664	int status = 0;
3665
3666	if (!ice_is_vsi_valid(hw, f_entry->fltr_info.vsi_handle))
3667		return -EINVAL;
3668
3669	f_entry->fltr_info.fwd_id.hw_vsi_id =
3670		ice_get_hw_vsi_num(hw, f_entry->fltr_info.vsi_handle);
3671	new_fltr = &f_entry->fltr_info;
3672
3673	/* VLAN ID should only be 12 bits */
3674	if (new_fltr->l_data.vlan.vlan_id > ICE_MAX_VLAN_ID)
3675		return -EINVAL;
3676
3677	if (new_fltr->src_id != ICE_SRC_ID_VSI)
3678		return -EINVAL;
3679
3680	new_fltr->src = new_fltr->fwd_id.hw_vsi_id;
3681	lkup_type = new_fltr->lkup_type;
3682	vsi_handle = new_fltr->vsi_handle;
3683	rule_lock = &sw->recp_list[ICE_SW_LKUP_VLAN].filt_rule_lock;
3684	mutex_lock(rule_lock);
3685	v_list_itr = ice_find_rule_entry(hw, ICE_SW_LKUP_VLAN, new_fltr);
3686	if (!v_list_itr) {
3687		struct ice_vsi_list_map_info *map_info = NULL;
3688
3689		if (new_fltr->fltr_act == ICE_FWD_TO_VSI) {
3690			/* All VLAN pruning rules use a VSI list. Check if
3691			 * there is already a VSI list containing VSI that we
3692			 * want to add. If found, use the same vsi_list_id for
3693			 * this new VLAN rule or else create a new list.
3694			 */
3695			map_info = ice_find_vsi_list_entry(hw, ICE_SW_LKUP_VLAN,
3696							   vsi_handle,
3697							   &vsi_list_id);
3698			if (!map_info) {
3699				status = ice_create_vsi_list_rule(hw,
3700								  &vsi_handle,
3701								  1,
3702								  &vsi_list_id,
3703								  lkup_type);
3704				if (status)
3705					goto exit;
3706			}
3707			/* Convert the action to forwarding to a VSI list. */
3708			new_fltr->fltr_act = ICE_FWD_TO_VSI_LIST;
3709			new_fltr->fwd_id.vsi_list_id = vsi_list_id;
3710		}
3711
3712		status = ice_create_pkt_fwd_rule(hw, f_entry);
3713		if (!status) {
3714			v_list_itr = ice_find_rule_entry(hw, ICE_SW_LKUP_VLAN,
3715							 new_fltr);
3716			if (!v_list_itr) {
3717				status = -ENOENT;
3718				goto exit;
3719			}
3720			/* reuse VSI list for new rule and increment ref_cnt */
3721			if (map_info) {
3722				v_list_itr->vsi_list_info = map_info;
3723				map_info->ref_cnt++;
3724			} else {
3725				v_list_itr->vsi_list_info =
3726					ice_create_vsi_list_map(hw, &vsi_handle,
3727								1, vsi_list_id);
3728			}
3729		}
3730	} else if (v_list_itr->vsi_list_info->ref_cnt == 1) {
3731		/* Update existing VSI list to add new VSI ID only if it used
3732		 * by one VLAN rule.
3733		 */
3734		cur_fltr = &v_list_itr->fltr_info;
3735		status = ice_add_update_vsi_list(hw, v_list_itr, cur_fltr,
3736						 new_fltr);
3737	} else {
3738		/* If VLAN rule exists and VSI list being used by this rule is
3739		 * referenced by more than 1 VLAN rule. Then create a new VSI
3740		 * list appending previous VSI with new VSI and update existing
3741		 * VLAN rule to point to new VSI list ID
3742		 */
3743		struct ice_fltr_info tmp_fltr;
3744		u16 vsi_handle_arr[2];
3745		u16 cur_handle;
3746
3747		/* Current implementation only supports reusing VSI list with
3748		 * one VSI count. We should never hit below condition
3749		 */
3750		if (v_list_itr->vsi_count > 1 &&
3751		    v_list_itr->vsi_list_info->ref_cnt > 1) {
3752			ice_debug(hw, ICE_DBG_SW, "Invalid configuration: Optimization to reuse VSI list with more than one VSI is not being done yet\n");
3753			status = -EIO;
3754			goto exit;
3755		}
3756
3757		cur_handle =
3758			find_first_bit(v_list_itr->vsi_list_info->vsi_map,
3759				       ICE_MAX_VSI);
3760
3761		/* A rule already exists with the new VSI being added */
3762		if (cur_handle == vsi_handle) {
3763			status = -EEXIST;
3764			goto exit;
3765		}
3766
3767		vsi_handle_arr[0] = cur_handle;
3768		vsi_handle_arr[1] = vsi_handle;
3769		status = ice_create_vsi_list_rule(hw, &vsi_handle_arr[0], 2,
3770						  &vsi_list_id, lkup_type);
3771		if (status)
3772			goto exit;
3773
3774		tmp_fltr = v_list_itr->fltr_info;
3775		tmp_fltr.fltr_rule_id = v_list_itr->fltr_info.fltr_rule_id;
3776		tmp_fltr.fwd_id.vsi_list_id = vsi_list_id;
3777		tmp_fltr.fltr_act = ICE_FWD_TO_VSI_LIST;
3778		/* Update the previous switch rule to a new VSI list which
3779		 * includes current VSI that is requested
3780		 */
3781		status = ice_update_pkt_fwd_rule(hw, &tmp_fltr);
3782		if (status)
3783			goto exit;
3784
3785		/* before overriding VSI list map info. decrement ref_cnt of
3786		 * previous VSI list
3787		 */
3788		v_list_itr->vsi_list_info->ref_cnt--;
3789
3790		/* now update to newly created list */
3791		v_list_itr->fltr_info.fwd_id.vsi_list_id = vsi_list_id;
3792		v_list_itr->vsi_list_info =
3793			ice_create_vsi_list_map(hw, &vsi_handle_arr[0], 2,
3794						vsi_list_id);
3795		v_list_itr->vsi_count++;
3796	}
3797
3798exit:
3799	mutex_unlock(rule_lock);
3800	return status;
3801}
3802
3803/**
3804 * ice_add_vlan - Add VLAN based filter rule
3805 * @hw: pointer to the hardware structure
3806 * @v_list: list of VLAN entries and forwarding information
3807 */
3808int ice_add_vlan(struct ice_hw *hw, struct list_head *v_list)
3809{
3810	struct ice_fltr_list_entry *v_list_itr;
3811
3812	if (!v_list || !hw)
3813		return -EINVAL;
3814
3815	list_for_each_entry(v_list_itr, v_list, list_entry) {
3816		if (v_list_itr->fltr_info.lkup_type != ICE_SW_LKUP_VLAN)
3817			return -EINVAL;
3818		v_list_itr->fltr_info.flag = ICE_FLTR_TX;
3819		v_list_itr->status = ice_add_vlan_internal(hw, v_list_itr);
3820		if (v_list_itr->status)
3821			return v_list_itr->status;
3822	}
3823	return 0;
3824}
3825
3826/**
3827 * ice_add_eth_mac - Add ethertype and MAC based filter rule
3828 * @hw: pointer to the hardware structure
3829 * @em_list: list of ether type MAC filter, MAC is optional
3830 *
3831 * This function requires the caller to populate the entries in
3832 * the filter list with the necessary fields (including flags to
3833 * indicate Tx or Rx rules).
3834 */
3835int ice_add_eth_mac(struct ice_hw *hw, struct list_head *em_list)
3836{
3837	struct ice_fltr_list_entry *em_list_itr;
3838
3839	if (!em_list || !hw)
3840		return -EINVAL;
3841
3842	list_for_each_entry(em_list_itr, em_list, list_entry) {
3843		enum ice_sw_lkup_type l_type =
3844			em_list_itr->fltr_info.lkup_type;
3845
3846		if (l_type != ICE_SW_LKUP_ETHERTYPE_MAC &&
3847		    l_type != ICE_SW_LKUP_ETHERTYPE)
3848			return -EINVAL;
3849
3850		em_list_itr->status = ice_add_rule_internal(hw, l_type,
3851							    em_list_itr);
3852		if (em_list_itr->status)
3853			return em_list_itr->status;
3854	}
3855	return 0;
3856}
3857
3858/**
3859 * ice_remove_eth_mac - Remove an ethertype (or MAC) based filter rule
3860 * @hw: pointer to the hardware structure
3861 * @em_list: list of ethertype or ethertype MAC entries
3862 */
3863int ice_remove_eth_mac(struct ice_hw *hw, struct list_head *em_list)
3864{
3865	struct ice_fltr_list_entry *em_list_itr, *tmp;
3866
3867	if (!em_list || !hw)
3868		return -EINVAL;
3869
3870	list_for_each_entry_safe(em_list_itr, tmp, em_list, list_entry) {
3871		enum ice_sw_lkup_type l_type =
3872			em_list_itr->fltr_info.lkup_type;
3873
3874		if (l_type != ICE_SW_LKUP_ETHERTYPE_MAC &&
3875		    l_type != ICE_SW_LKUP_ETHERTYPE)
3876			return -EINVAL;
3877
3878		em_list_itr->status = ice_remove_rule_internal(hw, l_type,
3879							       em_list_itr);
3880		if (em_list_itr->status)
3881			return em_list_itr->status;
3882	}
3883	return 0;
3884}
3885
3886/**
3887 * ice_rem_sw_rule_info
3888 * @hw: pointer to the hardware structure
3889 * @rule_head: pointer to the switch list structure that we want to delete
3890 */
3891static void
3892ice_rem_sw_rule_info(struct ice_hw *hw, struct list_head *rule_head)
3893{
3894	if (!list_empty(rule_head)) {
3895		struct ice_fltr_mgmt_list_entry *entry;
3896		struct ice_fltr_mgmt_list_entry *tmp;
3897
3898		list_for_each_entry_safe(entry, tmp, rule_head, list_entry) {
3899			list_del(&entry->list_entry);
3900			devm_kfree(ice_hw_to_dev(hw), entry);
3901		}
3902	}
3903}
3904
3905/**
3906 * ice_rem_adv_rule_info
3907 * @hw: pointer to the hardware structure
3908 * @rule_head: pointer to the switch list structure that we want to delete
3909 */
3910static void
3911ice_rem_adv_rule_info(struct ice_hw *hw, struct list_head *rule_head)
3912{
3913	struct ice_adv_fltr_mgmt_list_entry *tmp_entry;
3914	struct ice_adv_fltr_mgmt_list_entry *lst_itr;
3915
3916	if (list_empty(rule_head))
3917		return;
3918
3919	list_for_each_entry_safe(lst_itr, tmp_entry, rule_head, list_entry) {
3920		list_del(&lst_itr->list_entry);
3921		devm_kfree(ice_hw_to_dev(hw), lst_itr->lkups);
3922		devm_kfree(ice_hw_to_dev(hw), lst_itr);
3923	}
3924}
3925
3926/**
3927 * ice_cfg_dflt_vsi - change state of VSI to set/clear default
3928 * @pi: pointer to the port_info structure
3929 * @vsi_handle: VSI handle to set as default
3930 * @set: true to add the above mentioned switch rule, false to remove it
3931 * @direction: ICE_FLTR_RX or ICE_FLTR_TX
3932 *
3933 * add filter rule to set/unset given VSI as default VSI for the switch
3934 * (represented by swid)
3935 */
3936int
3937ice_cfg_dflt_vsi(struct ice_port_info *pi, u16 vsi_handle, bool set,
3938		 u8 direction)
3939{
3940	struct ice_fltr_list_entry f_list_entry;
3941	struct ice_fltr_info f_info;
3942	struct ice_hw *hw = pi->hw;
3943	u16 hw_vsi_id;
3944	int status;
3945
3946	if (!ice_is_vsi_valid(hw, vsi_handle))
3947		return -EINVAL;
3948
3949	hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle);
3950
3951	memset(&f_info, 0, sizeof(f_info));
3952
3953	f_info.lkup_type = ICE_SW_LKUP_DFLT;
3954	f_info.flag = direction;
3955	f_info.fltr_act = ICE_FWD_TO_VSI;
3956	f_info.fwd_id.hw_vsi_id = hw_vsi_id;
3957	f_info.vsi_handle = vsi_handle;
3958
3959	if (f_info.flag & ICE_FLTR_RX) {
3960		f_info.src = hw->port_info->lport;
3961		f_info.src_id = ICE_SRC_ID_LPORT;
3962	} else if (f_info.flag & ICE_FLTR_TX) {
3963		f_info.src_id = ICE_SRC_ID_VSI;
3964		f_info.src = hw_vsi_id;
3965		f_info.flag |= ICE_FLTR_TX_ONLY;
3966	}
3967	f_list_entry.fltr_info = f_info;
3968
3969	if (set)
3970		status = ice_add_rule_internal(hw, ICE_SW_LKUP_DFLT,
3971					       &f_list_entry);
3972	else
3973		status = ice_remove_rule_internal(hw, ICE_SW_LKUP_DFLT,
3974						  &f_list_entry);
3975
3976	return status;
3977}
3978
3979/**
3980 * ice_vsi_uses_fltr - Determine if given VSI uses specified filter
3981 * @fm_entry: filter entry to inspect
3982 * @vsi_handle: VSI handle to compare with filter info
3983 */
3984static bool
3985ice_vsi_uses_fltr(struct ice_fltr_mgmt_list_entry *fm_entry, u16 vsi_handle)
3986{
3987	return ((fm_entry->fltr_info.fltr_act == ICE_FWD_TO_VSI &&
3988		 fm_entry->fltr_info.vsi_handle == vsi_handle) ||
3989		(fm_entry->fltr_info.fltr_act == ICE_FWD_TO_VSI_LIST &&
3990		 fm_entry->vsi_list_info &&
3991		 (test_bit(vsi_handle, fm_entry->vsi_list_info->vsi_map))));
3992}
3993
3994/**
3995 * ice_check_if_dflt_vsi - check if VSI is default VSI
3996 * @pi: pointer to the port_info structure
3997 * @vsi_handle: vsi handle to check for in filter list
3998 * @rule_exists: indicates if there are any VSI's in the rule list
3999 *
4000 * checks if the VSI is in a default VSI list, and also indicates
4001 * if the default VSI list is empty
4002 */
4003bool
4004ice_check_if_dflt_vsi(struct ice_port_info *pi, u16 vsi_handle,
4005		      bool *rule_exists)
4006{
4007	struct ice_fltr_mgmt_list_entry *fm_entry;
4008	struct ice_sw_recipe *recp_list;
4009	struct list_head *rule_head;
4010	struct mutex *rule_lock; /* Lock to protect filter rule list */
4011	bool ret = false;
4012
4013	recp_list = &pi->hw->switch_info->recp_list[ICE_SW_LKUP_DFLT];
4014	rule_lock = &recp_list->filt_rule_lock;
4015	rule_head = &recp_list->filt_rules;
4016
4017	mutex_lock(rule_lock);
4018
4019	if (rule_exists && !list_empty(rule_head))
4020		*rule_exists = true;
4021
4022	list_for_each_entry(fm_entry, rule_head, list_entry) {
4023		if (ice_vsi_uses_fltr(fm_entry, vsi_handle)) {
4024			ret = true;
4025			break;
4026		}
4027	}
4028
4029	mutex_unlock(rule_lock);
4030
4031	return ret;
4032}
4033
4034/**
4035 * ice_remove_mac - remove a MAC address based filter rule
4036 * @hw: pointer to the hardware structure
4037 * @m_list: list of MAC addresses and forwarding information
4038 *
4039 * This function removes either a MAC filter rule or a specific VSI from a
4040 * VSI list for a multicast MAC address.
4041 *
4042 * Returns -ENOENT if a given entry was not added by ice_add_mac. Caller should
4043 * be aware that this call will only work if all the entries passed into m_list
4044 * were added previously. It will not attempt to do a partial remove of entries
4045 * that were found.
4046 */
4047int ice_remove_mac(struct ice_hw *hw, struct list_head *m_list)
4048{
4049	struct ice_fltr_list_entry *list_itr, *tmp;
4050
4051	if (!m_list)
4052		return -EINVAL;
4053
4054	list_for_each_entry_safe(list_itr, tmp, m_list, list_entry) {
4055		enum ice_sw_lkup_type l_type = list_itr->fltr_info.lkup_type;
4056		u16 vsi_handle;
4057
4058		if (l_type != ICE_SW_LKUP_MAC)
4059			return -EINVAL;
4060
4061		vsi_handle = list_itr->fltr_info.vsi_handle;
4062		if (!ice_is_vsi_valid(hw, vsi_handle))
4063			return -EINVAL;
4064
4065		list_itr->fltr_info.fwd_id.hw_vsi_id =
4066					ice_get_hw_vsi_num(hw, vsi_handle);
4067
4068		list_itr->status = ice_remove_rule_internal(hw,
4069							    ICE_SW_LKUP_MAC,
4070							    list_itr);
4071		if (list_itr->status)
4072			return list_itr->status;
4073	}
4074	return 0;
4075}
4076
4077/**
4078 * ice_remove_vlan - Remove VLAN based filter rule
4079 * @hw: pointer to the hardware structure
4080 * @v_list: list of VLAN entries and forwarding information
4081 */
4082int ice_remove_vlan(struct ice_hw *hw, struct list_head *v_list)
4083{
4084	struct ice_fltr_list_entry *v_list_itr, *tmp;
4085
4086	if (!v_list || !hw)
4087		return -EINVAL;
4088
4089	list_for_each_entry_safe(v_list_itr, tmp, v_list, list_entry) {
4090		enum ice_sw_lkup_type l_type = v_list_itr->fltr_info.lkup_type;
4091
4092		if (l_type != ICE_SW_LKUP_VLAN)
4093			return -EINVAL;
4094		v_list_itr->status = ice_remove_rule_internal(hw,
4095							      ICE_SW_LKUP_VLAN,
4096							      v_list_itr);
4097		if (v_list_itr->status)
4098			return v_list_itr->status;
4099	}
4100	return 0;
4101}
4102
4103/**
4104 * ice_add_entry_to_vsi_fltr_list - Add copy of fltr_list_entry to remove list
4105 * @hw: pointer to the hardware structure
4106 * @vsi_handle: VSI handle to remove filters from
4107 * @vsi_list_head: pointer to the list to add entry to
4108 * @fi: pointer to fltr_info of filter entry to copy & add
4109 *
4110 * Helper function, used when creating a list of filters to remove from
4111 * a specific VSI. The entry added to vsi_list_head is a COPY of the
4112 * original filter entry, with the exception of fltr_info.fltr_act and
4113 * fltr_info.fwd_id fields. These are set such that later logic can
4114 * extract which VSI to remove the fltr from, and pass on that information.
4115 */
4116static int
4117ice_add_entry_to_vsi_fltr_list(struct ice_hw *hw, u16 vsi_handle,
4118			       struct list_head *vsi_list_head,
4119			       struct ice_fltr_info *fi)
4120{
4121	struct ice_fltr_list_entry *tmp;
4122
4123	/* this memory is freed up in the caller function
4124	 * once filters for this VSI are removed
4125	 */
4126	tmp = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*tmp), GFP_KERNEL);
4127	if (!tmp)
4128		return -ENOMEM;
4129
4130	tmp->fltr_info = *fi;
4131
4132	/* Overwrite these fields to indicate which VSI to remove filter from,
4133	 * so find and remove logic can extract the information from the
4134	 * list entries. Note that original entries will still have proper
4135	 * values.
4136	 */
4137	tmp->fltr_info.fltr_act = ICE_FWD_TO_VSI;
4138	tmp->fltr_info.vsi_handle = vsi_handle;
4139	tmp->fltr_info.fwd_id.hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle);
4140
4141	list_add(&tmp->list_entry, vsi_list_head);
4142
4143	return 0;
4144}
4145
4146/**
4147 * ice_add_to_vsi_fltr_list - Add VSI filters to the list
4148 * @hw: pointer to the hardware structure
4149 * @vsi_handle: VSI handle to remove filters from
4150 * @lkup_list_head: pointer to the list that has certain lookup type filters
4151 * @vsi_list_head: pointer to the list pertaining to VSI with vsi_handle
4152 *
4153 * Locates all filters in lkup_list_head that are used by the given VSI,
4154 * and adds COPIES of those entries to vsi_list_head (intended to be used
4155 * to remove the listed filters).
4156 * Note that this means all entries in vsi_list_head must be explicitly
4157 * deallocated by the caller when done with list.
4158 */
4159static int
4160ice_add_to_vsi_fltr_list(struct ice_hw *hw, u16 vsi_handle,
4161			 struct list_head *lkup_list_head,
4162			 struct list_head *vsi_list_head)
4163{
4164	struct ice_fltr_mgmt_list_entry *fm_entry;
4165	int status = 0;
4166
4167	/* check to make sure VSI ID is valid and within boundary */
4168	if (!ice_is_vsi_valid(hw, vsi_handle))
4169		return -EINVAL;
4170
4171	list_for_each_entry(fm_entry, lkup_list_head, list_entry) {
4172		if (!ice_vsi_uses_fltr(fm_entry, vsi_handle))
4173			continue;
4174
4175		status = ice_add_entry_to_vsi_fltr_list(hw, vsi_handle,
4176							vsi_list_head,
4177							&fm_entry->fltr_info);
4178		if (status)
4179			return status;
4180	}
4181	return status;
4182}
4183
4184/**
4185 * ice_determine_promisc_mask
4186 * @fi: filter info to parse
4187 *
4188 * Helper function to determine which ICE_PROMISC_ mask corresponds
4189 * to given filter into.
4190 */
4191static u8 ice_determine_promisc_mask(struct ice_fltr_info *fi)
4192{
4193	u16 vid = fi->l_data.mac_vlan.vlan_id;
4194	u8 *macaddr = fi->l_data.mac.mac_addr;
4195	bool is_tx_fltr = false;
4196	u8 promisc_mask = 0;
4197
4198	if (fi->flag == ICE_FLTR_TX)
4199		is_tx_fltr = true;
4200
4201	if (is_broadcast_ether_addr(macaddr))
4202		promisc_mask |= is_tx_fltr ?
4203			ICE_PROMISC_BCAST_TX : ICE_PROMISC_BCAST_RX;
4204	else if (is_multicast_ether_addr(macaddr))
4205		promisc_mask |= is_tx_fltr ?
4206			ICE_PROMISC_MCAST_TX : ICE_PROMISC_MCAST_RX;
4207	else if (is_unicast_ether_addr(macaddr))
4208		promisc_mask |= is_tx_fltr ?
4209			ICE_PROMISC_UCAST_TX : ICE_PROMISC_UCAST_RX;
4210	if (vid)
4211		promisc_mask |= is_tx_fltr ?
4212			ICE_PROMISC_VLAN_TX : ICE_PROMISC_VLAN_RX;
4213
4214	return promisc_mask;
4215}
4216
4217/**
4218 * ice_remove_promisc - Remove promisc based filter rules
4219 * @hw: pointer to the hardware structure
4220 * @recp_id: recipe ID for which the rule needs to removed
4221 * @v_list: list of promisc entries
4222 */
4223static int
4224ice_remove_promisc(struct ice_hw *hw, u8 recp_id, struct list_head *v_list)
4225{
4226	struct ice_fltr_list_entry *v_list_itr, *tmp;
4227
4228	list_for_each_entry_safe(v_list_itr, tmp, v_list, list_entry) {
4229		v_list_itr->status =
4230			ice_remove_rule_internal(hw, recp_id, v_list_itr);
4231		if (v_list_itr->status)
4232			return v_list_itr->status;
4233	}
4234	return 0;
4235}
4236
4237/**
4238 * ice_clear_vsi_promisc - clear specified promiscuous mode(s) for given VSI
4239 * @hw: pointer to the hardware structure
4240 * @vsi_handle: VSI handle to clear mode
4241 * @promisc_mask: mask of promiscuous config bits to clear
4242 * @vid: VLAN ID to clear VLAN promiscuous
4243 */
4244int
4245ice_clear_vsi_promisc(struct ice_hw *hw, u16 vsi_handle, u8 promisc_mask,
4246		      u16 vid)
4247{
4248	struct ice_switch_info *sw = hw->switch_info;
4249	struct ice_fltr_list_entry *fm_entry, *tmp;
4250	struct list_head remove_list_head;
4251	struct ice_fltr_mgmt_list_entry *itr;
4252	struct list_head *rule_head;
4253	struct mutex *rule_lock;	/* Lock to protect filter rule list */
4254	int status = 0;
4255	u8 recipe_id;
4256
4257	if (!ice_is_vsi_valid(hw, vsi_handle))
4258		return -EINVAL;
4259
4260	if (promisc_mask & (ICE_PROMISC_VLAN_RX | ICE_PROMISC_VLAN_TX))
4261		recipe_id = ICE_SW_LKUP_PROMISC_VLAN;
4262	else
4263		recipe_id = ICE_SW_LKUP_PROMISC;
4264
4265	rule_head = &sw->recp_list[recipe_id].filt_rules;
4266	rule_lock = &sw->recp_list[recipe_id].filt_rule_lock;
4267
4268	INIT_LIST_HEAD(&remove_list_head);
4269
4270	mutex_lock(rule_lock);
4271	list_for_each_entry(itr, rule_head, list_entry) {
4272		struct ice_fltr_info *fltr_info;
4273		u8 fltr_promisc_mask = 0;
4274
4275		if (!ice_vsi_uses_fltr(itr, vsi_handle))
4276			continue;
4277		fltr_info = &itr->fltr_info;
4278
4279		if (recipe_id == ICE_SW_LKUP_PROMISC_VLAN &&
4280		    vid != fltr_info->l_data.mac_vlan.vlan_id)
4281			continue;
4282
4283		fltr_promisc_mask |= ice_determine_promisc_mask(fltr_info);
4284
4285		/* Skip if filter is not completely specified by given mask */
4286		if (fltr_promisc_mask & ~promisc_mask)
4287			continue;
4288
4289		status = ice_add_entry_to_vsi_fltr_list(hw, vsi_handle,
4290							&remove_list_head,
4291							fltr_info);
4292		if (status) {
4293			mutex_unlock(rule_lock);
4294			goto free_fltr_list;
4295		}
4296	}
4297	mutex_unlock(rule_lock);
4298
4299	status = ice_remove_promisc(hw, recipe_id, &remove_list_head);
4300
4301free_fltr_list:
4302	list_for_each_entry_safe(fm_entry, tmp, &remove_list_head, list_entry) {
4303		list_del(&fm_entry->list_entry);
4304		devm_kfree(ice_hw_to_dev(hw), fm_entry);
4305	}
4306
4307	return status;
4308}
4309
4310/**
4311 * ice_set_vsi_promisc - set given VSI to given promiscuous mode(s)
4312 * @hw: pointer to the hardware structure
4313 * @vsi_handle: VSI handle to configure
4314 * @promisc_mask: mask of promiscuous config bits
4315 * @vid: VLAN ID to set VLAN promiscuous
4316 */
4317int
4318ice_set_vsi_promisc(struct ice_hw *hw, u16 vsi_handle, u8 promisc_mask, u16 vid)
4319{
4320	enum { UCAST_FLTR = 1, MCAST_FLTR, BCAST_FLTR };
4321	struct ice_fltr_list_entry f_list_entry;
4322	struct ice_fltr_info new_fltr;
4323	bool is_tx_fltr;
4324	int status = 0;
4325	u16 hw_vsi_id;
4326	int pkt_type;
4327	u8 recipe_id;
4328
4329	if (!ice_is_vsi_valid(hw, vsi_handle))
4330		return -EINVAL;
4331	hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle);
4332
4333	memset(&new_fltr, 0, sizeof(new_fltr));
4334
4335	if (promisc_mask & (ICE_PROMISC_VLAN_RX | ICE_PROMISC_VLAN_TX)) {
4336		new_fltr.lkup_type = ICE_SW_LKUP_PROMISC_VLAN;
4337		new_fltr.l_data.mac_vlan.vlan_id = vid;
4338		recipe_id = ICE_SW_LKUP_PROMISC_VLAN;
4339	} else {
4340		new_fltr.lkup_type = ICE_SW_LKUP_PROMISC;
4341		recipe_id = ICE_SW_LKUP_PROMISC;
4342	}
4343
4344	/* Separate filters must be set for each direction/packet type
4345	 * combination, so we will loop over the mask value, store the
4346	 * individual type, and clear it out in the input mask as it
4347	 * is found.
4348	 */
4349	while (promisc_mask) {
4350		u8 *mac_addr;
4351
4352		pkt_type = 0;
4353		is_tx_fltr = false;
4354
4355		if (promisc_mask & ICE_PROMISC_UCAST_RX) {
4356			promisc_mask &= ~ICE_PROMISC_UCAST_RX;
4357			pkt_type = UCAST_FLTR;
4358		} else if (promisc_mask & ICE_PROMISC_UCAST_TX) {
4359			promisc_mask &= ~ICE_PROMISC_UCAST_TX;
4360			pkt_type = UCAST_FLTR;
4361			is_tx_fltr = true;
4362		} else if (promisc_mask & ICE_PROMISC_MCAST_RX) {
4363			promisc_mask &= ~ICE_PROMISC_MCAST_RX;
4364			pkt_type = MCAST_FLTR;
4365		} else if (promisc_mask & ICE_PROMISC_MCAST_TX) {
4366			promisc_mask &= ~ICE_PROMISC_MCAST_TX;
4367			pkt_type = MCAST_FLTR;
4368			is_tx_fltr = true;
4369		} else if (promisc_mask & ICE_PROMISC_BCAST_RX) {
4370			promisc_mask &= ~ICE_PROMISC_BCAST_RX;
4371			pkt_type = BCAST_FLTR;
4372		} else if (promisc_mask & ICE_PROMISC_BCAST_TX) {
4373			promisc_mask &= ~ICE_PROMISC_BCAST_TX;
4374			pkt_type = BCAST_FLTR;
4375			is_tx_fltr = true;
4376		}
4377
4378		/* Check for VLAN promiscuous flag */
4379		if (promisc_mask & ICE_PROMISC_VLAN_RX) {
4380			promisc_mask &= ~ICE_PROMISC_VLAN_RX;
4381		} else if (promisc_mask & ICE_PROMISC_VLAN_TX) {
4382			promisc_mask &= ~ICE_PROMISC_VLAN_TX;
4383			is_tx_fltr = true;
4384		}
4385
4386		/* Set filter DA based on packet type */
4387		mac_addr = new_fltr.l_data.mac.mac_addr;
4388		if (pkt_type == BCAST_FLTR) {
4389			eth_broadcast_addr(mac_addr);
4390		} else if (pkt_type == MCAST_FLTR ||
4391			   pkt_type == UCAST_FLTR) {
4392			/* Use the dummy ether header DA */
4393			ether_addr_copy(mac_addr, dummy_eth_header);
4394			if (pkt_type == MCAST_FLTR)
4395				mac_addr[0] |= 0x1;	/* Set multicast bit */
4396		}
4397
4398		/* Need to reset this to zero for all iterations */
4399		new_fltr.flag = 0;
4400		if (is_tx_fltr) {
4401			new_fltr.flag |= ICE_FLTR_TX;
4402			new_fltr.src = hw_vsi_id;
4403		} else {
4404			new_fltr.flag |= ICE_FLTR_RX;
4405			new_fltr.src = hw->port_info->lport;
4406		}
4407
4408		new_fltr.fltr_act = ICE_FWD_TO_VSI;
4409		new_fltr.vsi_handle = vsi_handle;
4410		new_fltr.fwd_id.hw_vsi_id = hw_vsi_id;
4411		f_list_entry.fltr_info = new_fltr;
4412
4413		status = ice_add_rule_internal(hw, recipe_id, &f_list_entry);
4414		if (status)
4415			goto set_promisc_exit;
4416	}
4417
4418set_promisc_exit:
4419	return status;
4420}
4421
4422/**
4423 * ice_set_vlan_vsi_promisc
4424 * @hw: pointer to the hardware structure
4425 * @vsi_handle: VSI handle to configure
4426 * @promisc_mask: mask of promiscuous config bits
4427 * @rm_vlan_promisc: Clear VLANs VSI promisc mode
4428 *
4429 * Configure VSI with all associated VLANs to given promiscuous mode(s)
4430 */
4431int
4432ice_set_vlan_vsi_promisc(struct ice_hw *hw, u16 vsi_handle, u8 promisc_mask,
4433			 bool rm_vlan_promisc)
4434{
4435	struct ice_switch_info *sw = hw->switch_info;
4436	struct ice_fltr_list_entry *list_itr, *tmp;
4437	struct list_head vsi_list_head;
4438	struct list_head *vlan_head;
4439	struct mutex *vlan_lock; /* Lock to protect filter rule list */
4440	u16 vlan_id;
4441	int status;
4442
4443	INIT_LIST_HEAD(&vsi_list_head);
4444	vlan_lock = &sw->recp_list[ICE_SW_LKUP_VLAN].filt_rule_lock;
4445	vlan_head = &sw->recp_list[ICE_SW_LKUP_VLAN].filt_rules;
4446	mutex_lock(vlan_lock);
4447	status = ice_add_to_vsi_fltr_list(hw, vsi_handle, vlan_head,
4448					  &vsi_list_head);
4449	mutex_unlock(vlan_lock);
4450	if (status)
4451		goto free_fltr_list;
4452
4453	list_for_each_entry(list_itr, &vsi_list_head, list_entry) {
4454		/* Avoid enabling or disabling VLAN zero twice when in double
4455		 * VLAN mode
4456		 */
4457		if (ice_is_dvm_ena(hw) &&
4458		    list_itr->fltr_info.l_data.vlan.tpid == 0)
4459			continue;
4460
4461		vlan_id = list_itr->fltr_info.l_data.vlan.vlan_id;
4462		if (rm_vlan_promisc)
4463			status = ice_clear_vsi_promisc(hw, vsi_handle,
4464						       promisc_mask, vlan_id);
4465		else
4466			status = ice_set_vsi_promisc(hw, vsi_handle,
4467						     promisc_mask, vlan_id);
4468		if (status && status != -EEXIST)
4469			break;
4470	}
4471
4472free_fltr_list:
4473	list_for_each_entry_safe(list_itr, tmp, &vsi_list_head, list_entry) {
4474		list_del(&list_itr->list_entry);
4475		devm_kfree(ice_hw_to_dev(hw), list_itr);
4476	}
4477	return status;
4478}
4479
4480/**
4481 * ice_remove_vsi_lkup_fltr - Remove lookup type filters for a VSI
4482 * @hw: pointer to the hardware structure
4483 * @vsi_handle: VSI handle to remove filters from
4484 * @lkup: switch rule filter lookup type
4485 */
4486static void
4487ice_remove_vsi_lkup_fltr(struct ice_hw *hw, u16 vsi_handle,
4488			 enum ice_sw_lkup_type lkup)
4489{
4490	struct ice_switch_info *sw = hw->switch_info;
4491	struct ice_fltr_list_entry *fm_entry;
4492	struct list_head remove_list_head;
4493	struct list_head *rule_head;
4494	struct ice_fltr_list_entry *tmp;
4495	struct mutex *rule_lock;	/* Lock to protect filter rule list */
4496	int status;
4497
4498	INIT_LIST_HEAD(&remove_list_head);
4499	rule_lock = &sw->recp_list[lkup].filt_rule_lock;
4500	rule_head = &sw->recp_list[lkup].filt_rules;
4501	mutex_lock(rule_lock);
4502	status = ice_add_to_vsi_fltr_list(hw, vsi_handle, rule_head,
4503					  &remove_list_head);
4504	mutex_unlock(rule_lock);
4505	if (status)
4506		goto free_fltr_list;
4507
4508	switch (lkup) {
4509	case ICE_SW_LKUP_MAC:
4510		ice_remove_mac(hw, &remove_list_head);
4511		break;
4512	case ICE_SW_LKUP_VLAN:
4513		ice_remove_vlan(hw, &remove_list_head);
4514		break;
4515	case ICE_SW_LKUP_PROMISC:
4516	case ICE_SW_LKUP_PROMISC_VLAN:
4517		ice_remove_promisc(hw, lkup, &remove_list_head);
4518		break;
4519	case ICE_SW_LKUP_MAC_VLAN:
4520	case ICE_SW_LKUP_ETHERTYPE:
4521	case ICE_SW_LKUP_ETHERTYPE_MAC:
4522	case ICE_SW_LKUP_DFLT:
4523	case ICE_SW_LKUP_LAST:
4524	default:
4525		ice_debug(hw, ICE_DBG_SW, "Unsupported lookup type %d\n", lkup);
4526		break;
4527	}
4528
4529free_fltr_list:
4530	list_for_each_entry_safe(fm_entry, tmp, &remove_list_head, list_entry) {
4531		list_del(&fm_entry->list_entry);
4532		devm_kfree(ice_hw_to_dev(hw), fm_entry);
4533	}
4534}
4535
4536/**
4537 * ice_remove_vsi_fltr - Remove all filters for a VSI
4538 * @hw: pointer to the hardware structure
4539 * @vsi_handle: VSI handle to remove filters from
4540 */
4541void ice_remove_vsi_fltr(struct ice_hw *hw, u16 vsi_handle)
4542{
4543	ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_MAC);
4544	ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_MAC_VLAN);
4545	ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_PROMISC);
4546	ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_VLAN);
4547	ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_DFLT);
4548	ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_ETHERTYPE);
4549	ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_ETHERTYPE_MAC);
4550	ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_PROMISC_VLAN);
4551}
4552
4553/**
4554 * ice_alloc_res_cntr - allocating resource counter
4555 * @hw: pointer to the hardware structure
4556 * @type: type of resource
4557 * @alloc_shared: if set it is shared else dedicated
4558 * @num_items: number of entries requested for FD resource type
4559 * @counter_id: counter index returned by AQ call
4560 */
4561int
4562ice_alloc_res_cntr(struct ice_hw *hw, u8 type, u8 alloc_shared, u16 num_items,
4563		   u16 *counter_id)
4564{
4565	DEFINE_RAW_FLEX(struct ice_aqc_alloc_free_res_elem, buf, elem, 1);
4566	u16 buf_len = __struct_size(buf);
4567	int status;
4568
4569	buf->num_elems = cpu_to_le16(num_items);
4570	buf->res_type = cpu_to_le16(FIELD_PREP(ICE_AQC_RES_TYPE_M, type) |
4571				    alloc_shared);
4572
4573	status = ice_aq_alloc_free_res(hw, buf, buf_len, ice_aqc_opc_alloc_res);
4574	if (status)
4575		return status;
4576
4577	*counter_id = le16_to_cpu(buf->elem[0].e.sw_resp);
4578	return status;
4579}
4580
4581/**
4582 * ice_free_res_cntr - free resource counter
4583 * @hw: pointer to the hardware structure
4584 * @type: type of resource
4585 * @alloc_shared: if set it is shared else dedicated
4586 * @num_items: number of entries to be freed for FD resource type
4587 * @counter_id: counter ID resource which needs to be freed
4588 */
4589int
4590ice_free_res_cntr(struct ice_hw *hw, u8 type, u8 alloc_shared, u16 num_items,
4591		  u16 counter_id)
4592{
4593	DEFINE_RAW_FLEX(struct ice_aqc_alloc_free_res_elem, buf, elem, 1);
4594	u16 buf_len = __struct_size(buf);
4595	int status;
4596
4597	buf->num_elems = cpu_to_le16(num_items);
4598	buf->res_type = cpu_to_le16(FIELD_PREP(ICE_AQC_RES_TYPE_M, type) |
4599				    alloc_shared);
4600	buf->elem[0].e.sw_resp = cpu_to_le16(counter_id);
4601
4602	status = ice_aq_alloc_free_res(hw, buf, buf_len, ice_aqc_opc_free_res);
4603	if (status)
4604		ice_debug(hw, ICE_DBG_SW, "counter resource could not be freed\n");
4605
4606	return status;
4607}
4608
4609#define ICE_PROTOCOL_ENTRY(id, ...) {		\
4610	.prot_type	= id,			\
4611	.offs		= {__VA_ARGS__},	\
4612}
4613
4614/**
4615 * ice_share_res - set a resource as shared or dedicated
4616 * @hw: hw struct of original owner of resource
4617 * @type: resource type
4618 * @shared: is the resource being set to shared
4619 * @res_id: resource id (descriptor)
4620 */
4621int ice_share_res(struct ice_hw *hw, u16 type, u8 shared, u16 res_id)
4622{
4623	DEFINE_RAW_FLEX(struct ice_aqc_alloc_free_res_elem, buf, elem, 1);
4624	u16 buf_len = __struct_size(buf);
4625	u16 res_type;
4626	int status;
4627
4628	buf->num_elems = cpu_to_le16(1);
4629	res_type = FIELD_PREP(ICE_AQC_RES_TYPE_M, type);
4630	if (shared)
4631		res_type |= ICE_AQC_RES_TYPE_FLAG_SHARED;
4632
4633	buf->res_type = cpu_to_le16(res_type);
4634	buf->elem[0].e.sw_resp = cpu_to_le16(res_id);
4635	status = ice_aq_alloc_free_res(hw, buf, buf_len,
4636				       ice_aqc_opc_share_res);
4637	if (status)
4638		ice_debug(hw, ICE_DBG_SW, "Could not set resource type %u id %u to %s\n",
4639			  type, res_id, shared ? "SHARED" : "DEDICATED");
4640
4641	return status;
4642}
4643
4644/* This is mapping table entry that maps every word within a given protocol
4645 * structure to the real byte offset as per the specification of that
4646 * protocol header.
4647 * for example dst address is 3 words in ethertype header and corresponding
4648 * bytes are 0, 2, 3 in the actual packet header and src address is at 4, 6, 8
4649 * IMPORTANT: Every structure part of "ice_prot_hdr" union should have a
4650 * matching entry describing its field. This needs to be updated if new
4651 * structure is added to that union.
4652 */
4653static const struct ice_prot_ext_tbl_entry ice_prot_ext[ICE_PROTOCOL_LAST] = {
4654	ICE_PROTOCOL_ENTRY(ICE_MAC_OFOS, 0, 2, 4, 6, 8, 10, 12),
4655	ICE_PROTOCOL_ENTRY(ICE_MAC_IL, 0, 2, 4, 6, 8, 10, 12),
4656	ICE_PROTOCOL_ENTRY(ICE_ETYPE_OL, 0),
4657	ICE_PROTOCOL_ENTRY(ICE_ETYPE_IL, 0),
4658	ICE_PROTOCOL_ENTRY(ICE_VLAN_OFOS, 2, 0),
4659	ICE_PROTOCOL_ENTRY(ICE_IPV4_OFOS, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18),
4660	ICE_PROTOCOL_ENTRY(ICE_IPV4_IL,	0, 2, 4, 6, 8, 10, 12, 14, 16, 18),
4661	ICE_PROTOCOL_ENTRY(ICE_IPV6_OFOS, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18,
4662			   20, 22, 24, 26, 28, 30, 32, 34, 36, 38),
4663	ICE_PROTOCOL_ENTRY(ICE_IPV6_IL, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20,
4664			   22, 24, 26, 28, 30, 32, 34, 36, 38),
4665	ICE_PROTOCOL_ENTRY(ICE_TCP_IL, 0, 2),
4666	ICE_PROTOCOL_ENTRY(ICE_UDP_OF, 0, 2),
4667	ICE_PROTOCOL_ENTRY(ICE_UDP_ILOS, 0, 2),
4668	ICE_PROTOCOL_ENTRY(ICE_VXLAN, 8, 10, 12, 14),
4669	ICE_PROTOCOL_ENTRY(ICE_GENEVE, 8, 10, 12, 14),
4670	ICE_PROTOCOL_ENTRY(ICE_NVGRE, 0, 2, 4, 6),
4671	ICE_PROTOCOL_ENTRY(ICE_GTP, 8, 10, 12, 14, 16, 18, 20, 22),
4672	ICE_PROTOCOL_ENTRY(ICE_GTP_NO_PAY, 8, 10, 12, 14),
4673	ICE_PROTOCOL_ENTRY(ICE_PFCP, 8, 10, 12, 14, 16, 18, 20, 22),
4674	ICE_PROTOCOL_ENTRY(ICE_PPPOE, 0, 2, 4, 6),
4675	ICE_PROTOCOL_ENTRY(ICE_L2TPV3, 0, 2, 4, 6, 8, 10),
4676	ICE_PROTOCOL_ENTRY(ICE_VLAN_EX, 2, 0),
4677	ICE_PROTOCOL_ENTRY(ICE_VLAN_IN, 2, 0),
4678	ICE_PROTOCOL_ENTRY(ICE_HW_METADATA,
4679			   ICE_SOURCE_PORT_MDID_OFFSET,
4680			   ICE_PTYPE_MDID_OFFSET,
4681			   ICE_PACKET_LENGTH_MDID_OFFSET,
4682			   ICE_SOURCE_VSI_MDID_OFFSET,
4683			   ICE_PKT_VLAN_MDID_OFFSET,
4684			   ICE_PKT_TUNNEL_MDID_OFFSET,
4685			   ICE_PKT_TCP_MDID_OFFSET,
4686			   ICE_PKT_ERROR_MDID_OFFSET),
4687};
4688
4689static struct ice_protocol_entry ice_prot_id_tbl[ICE_PROTOCOL_LAST] = {
4690	{ ICE_MAC_OFOS,		ICE_MAC_OFOS_HW },
4691	{ ICE_MAC_IL,		ICE_MAC_IL_HW },
4692	{ ICE_ETYPE_OL,		ICE_ETYPE_OL_HW },
4693	{ ICE_ETYPE_IL,		ICE_ETYPE_IL_HW },
4694	{ ICE_VLAN_OFOS,	ICE_VLAN_OL_HW },
4695	{ ICE_IPV4_OFOS,	ICE_IPV4_OFOS_HW },
4696	{ ICE_IPV4_IL,		ICE_IPV4_IL_HW },
4697	{ ICE_IPV6_OFOS,	ICE_IPV6_OFOS_HW },
4698	{ ICE_IPV6_IL,		ICE_IPV6_IL_HW },
4699	{ ICE_TCP_IL,		ICE_TCP_IL_HW },
4700	{ ICE_UDP_OF,		ICE_UDP_OF_HW },
4701	{ ICE_UDP_ILOS,		ICE_UDP_ILOS_HW },
4702	{ ICE_VXLAN,		ICE_UDP_OF_HW },
4703	{ ICE_GENEVE,		ICE_UDP_OF_HW },
4704	{ ICE_NVGRE,		ICE_GRE_OF_HW },
4705	{ ICE_GTP,		ICE_UDP_OF_HW },
4706	{ ICE_GTP_NO_PAY,	ICE_UDP_ILOS_HW },
4707	{ ICE_PFCP,		ICE_UDP_ILOS_HW },
4708	{ ICE_PPPOE,		ICE_PPPOE_HW },
4709	{ ICE_L2TPV3,		ICE_L2TPV3_HW },
4710	{ ICE_VLAN_EX,          ICE_VLAN_OF_HW },
4711	{ ICE_VLAN_IN,          ICE_VLAN_OL_HW },
4712	{ ICE_HW_METADATA,      ICE_META_DATA_ID_HW },
4713};
4714
4715/**
4716 * ice_find_recp - find a recipe
4717 * @hw: pointer to the hardware structure
4718 * @lkup_exts: extension sequence to match
4719 * @rinfo: information regarding the rule e.g. priority and action info
4720 * @is_add: flag of adding recipe
4721 *
4722 * Returns index of matching recipe, or ICE_MAX_NUM_RECIPES if not found.
4723 */
4724static u16
4725ice_find_recp(struct ice_hw *hw, struct ice_prot_lkup_ext *lkup_exts,
4726	      const struct ice_adv_rule_info *rinfo, bool is_add)
4727{
4728	bool refresh_required = true;
4729	struct ice_sw_recipe *recp;
4730	u8 i;
4731
4732	/* Walk through existing recipes to find a match */
4733	recp = hw->switch_info->recp_list;
4734	for (i = 0; i < ICE_MAX_NUM_RECIPES; i++) {
4735		/* If recipe was not created for this ID, in SW bookkeeping,
4736		 * check if FW has an entry for this recipe. If the FW has an
4737		 * entry update it in our SW bookkeeping and continue with the
4738		 * matching.
4739		 */
4740		if (hw->recp_reuse) {
4741			if (ice_get_recp_frm_fw(hw,
4742						hw->switch_info->recp_list, i,
4743						&refresh_required, is_add))
4744				continue;
4745		}
4746
4747		/* if number of words we are looking for match */
4748		if (lkup_exts->n_val_words == recp[i].lkup_exts.n_val_words) {
4749			struct ice_fv_word *ar = recp[i].lkup_exts.fv_words;
4750			struct ice_fv_word *be = lkup_exts->fv_words;
4751			u16 *cr = recp[i].lkup_exts.field_mask;
4752			u16 *de = lkup_exts->field_mask;
4753			bool found = true;
4754			u8 pe, qr;
4755
4756			/* ar, cr, and qr are related to the recipe words, while
4757			 * be, de, and pe are related to the lookup words
4758			 */
4759			for (pe = 0; pe < lkup_exts->n_val_words; pe++) {
4760				for (qr = 0; qr < recp[i].lkup_exts.n_val_words;
4761				     qr++) {
4762					if (ar[qr].off == be[pe].off &&
4763					    ar[qr].prot_id == be[pe].prot_id &&
4764					    cr[qr] == de[pe])
4765						/* Found the "pe"th word in the
4766						 * given recipe
4767						 */
4768						break;
4769				}
4770				/* After walking through all the words in the
4771				 * "i"th recipe if "p"th word was not found then
4772				 * this recipe is not what we are looking for.
4773				 * So break out from this loop and try the next
4774				 * recipe
4775				 */
4776				if (qr >= recp[i].lkup_exts.n_val_words) {
4777					found = false;
4778					break;
4779				}
4780			}
4781			/* If for "i"th recipe the found was never set to false
4782			 * then it means we found our match
4783			 * Also tun type and *_pass_l2 of recipe needs to be
4784			 * checked
4785			 */
4786			if (found && recp[i].tun_type == rinfo->tun_type &&
4787			    recp[i].need_pass_l2 == rinfo->need_pass_l2 &&
4788			    recp[i].allow_pass_l2 == rinfo->allow_pass_l2 &&
4789			    recp[i].priority == rinfo->priority)
4790				return i; /* Return the recipe ID */
4791		}
4792	}
4793	return ICE_MAX_NUM_RECIPES;
4794}
4795
4796/**
4797 * ice_change_proto_id_to_dvm - change proto id in prot_id_tbl
4798 *
4799 * As protocol id for outer vlan is different in dvm and svm, if dvm is
4800 * supported protocol array record for outer vlan has to be modified to
4801 * reflect the value proper for DVM.
4802 */
4803void ice_change_proto_id_to_dvm(void)
4804{
4805	u8 i;
4806
4807	for (i = 0; i < ARRAY_SIZE(ice_prot_id_tbl); i++)
4808		if (ice_prot_id_tbl[i].type == ICE_VLAN_OFOS &&
4809		    ice_prot_id_tbl[i].protocol_id != ICE_VLAN_OF_HW)
4810			ice_prot_id_tbl[i].protocol_id = ICE_VLAN_OF_HW;
4811}
4812
4813/**
4814 * ice_prot_type_to_id - get protocol ID from protocol type
4815 * @type: protocol type
4816 * @id: pointer to variable that will receive the ID
4817 *
4818 * Returns true if found, false otherwise
4819 */
4820static bool ice_prot_type_to_id(enum ice_protocol_type type, u8 *id)
4821{
4822	u8 i;
4823
4824	for (i = 0; i < ARRAY_SIZE(ice_prot_id_tbl); i++)
4825		if (ice_prot_id_tbl[i].type == type) {
4826			*id = ice_prot_id_tbl[i].protocol_id;
4827			return true;
4828		}
4829	return false;
4830}
4831
4832/**
4833 * ice_fill_valid_words - count valid words
4834 * @rule: advanced rule with lookup information
4835 * @lkup_exts: byte offset extractions of the words that are valid
4836 *
4837 * calculate valid words in a lookup rule using mask value
4838 */
4839static u8
4840ice_fill_valid_words(struct ice_adv_lkup_elem *rule,
4841		     struct ice_prot_lkup_ext *lkup_exts)
4842{
4843	u8 j, word, prot_id, ret_val;
4844
4845	if (!ice_prot_type_to_id(rule->type, &prot_id))
4846		return 0;
4847
4848	word = lkup_exts->n_val_words;
4849
4850	for (j = 0; j < sizeof(rule->m_u) / sizeof(u16); j++)
4851		if (((u16 *)&rule->m_u)[j] &&
4852		    rule->type < ARRAY_SIZE(ice_prot_ext)) {
4853			/* No more space to accommodate */
4854			if (word >= ICE_MAX_CHAIN_WORDS)
4855				return 0;
4856			lkup_exts->fv_words[word].off =
4857				ice_prot_ext[rule->type].offs[j];
4858			lkup_exts->fv_words[word].prot_id =
4859				ice_prot_id_tbl[rule->type].protocol_id;
4860			lkup_exts->field_mask[word] =
4861				be16_to_cpu(((__force __be16 *)&rule->m_u)[j]);
4862			word++;
4863		}
4864
4865	ret_val = word - lkup_exts->n_val_words;
4866	lkup_exts->n_val_words = word;
4867
4868	return ret_val;
4869}
4870
4871/**
4872 * ice_fill_fv_word_index - fill in the field vector indices for a recipe group
4873 * @hw: pointer to the hardware structure
4874 * @rm: recipe management list entry
4875 *
4876 * Helper function to fill in the field vector indices for protocol-offset
4877 * pairs. These indexes are then ultimately programmed into a recipe.
4878 */
4879static int
4880ice_fill_fv_word_index(struct ice_hw *hw, struct ice_sw_recipe *rm)
4881{
4882	struct ice_sw_fv_list_entry *fv;
4883	struct ice_fv_word *fv_ext;
4884	u8 i;
4885
4886	if (list_empty(&rm->fv_list))
4887		return -EINVAL;
4888
4889	fv = list_first_entry(&rm->fv_list, struct ice_sw_fv_list_entry,
4890			      list_entry);
4891	fv_ext = fv->fv_ptr->ew;
4892
4893	/* Add switch id as the first word. */
4894	rm->fv_idx[0] = ICE_AQ_SW_ID_LKUP_IDX;
4895	rm->fv_mask[0] = ICE_AQ_SW_ID_LKUP_MASK;
4896	rm->n_ext_words++;
4897
4898	for (i = 1; i < rm->n_ext_words; i++) {
4899		struct ice_fv_word *fv_word = &rm->ext_words[i - 1];
4900		u16 fv_mask = rm->word_masks[i - 1];
4901		bool found = false;
4902		u8 j;
4903
4904		for (j = 0; j < hw->blk[ICE_BLK_SW].es.fvw; j++) {
4905			if (fv_ext[j].prot_id == fv_word->prot_id &&
4906			    fv_ext[j].off == fv_word->off) {
4907				found = true;
4908
4909				/* Store index of field vector */
4910				rm->fv_idx[i] = j;
4911				rm->fv_mask[i] = fv_mask;
4912				break;
4913			}
4914		}
4915
4916		/* Protocol/offset could not be found, caller gave an invalid
4917		 * pair.
4918		 */
4919		if (!found)
4920			return -EINVAL;
4921	}
4922
4923	return 0;
4924}
4925
4926/**
4927 * ice_find_free_recp_res_idx - find free result indexes for recipe
4928 * @hw: pointer to hardware structure
4929 * @profiles: bitmap of profiles that will be associated with the new recipe
4930 * @free_idx: pointer to variable to receive the free index bitmap
4931 *
4932 * The algorithm used here is:
4933 *	1. When creating a new recipe, create a set P which contains all
4934 *	   Profiles that will be associated with our new recipe
4935 *
4936 *	2. For each Profile p in set P:
4937 *	    a. Add all recipes associated with Profile p into set R
4938 *	    b. Optional : PossibleIndexes &= profile[p].possibleIndexes
4939 *		[initially PossibleIndexes should be 0xFFFFFFFFFFFFFFFF]
4940 *		i. Or just assume they all have the same possible indexes:
4941 *			44, 45, 46, 47
4942 *			i.e., PossibleIndexes = 0x0000F00000000000
4943 *
4944 *	3. For each Recipe r in set R:
4945 *	    a. UsedIndexes |= (bitwise or ) recipe[r].res_indexes
4946 *	    b. FreeIndexes = UsedIndexes ^ PossibleIndexes
4947 *
4948 *	FreeIndexes will contain the bits indicating the indexes free for use,
4949 *      then the code needs to update the recipe[r].used_result_idx_bits to
4950 *      indicate which indexes were selected for use by this recipe.
4951 */
4952static u16
4953ice_find_free_recp_res_idx(struct ice_hw *hw, const unsigned long *profiles,
4954			   unsigned long *free_idx)
4955{
4956	DECLARE_BITMAP(possible_idx, ICE_MAX_FV_WORDS);
4957	DECLARE_BITMAP(recipes, ICE_MAX_NUM_RECIPES);
4958	DECLARE_BITMAP(used_idx, ICE_MAX_FV_WORDS);
4959	u16 bit;
4960
4961	bitmap_zero(recipes, ICE_MAX_NUM_RECIPES);
4962	bitmap_zero(used_idx, ICE_MAX_FV_WORDS);
4963
4964	bitmap_fill(possible_idx, ICE_MAX_FV_WORDS);
4965
4966	/* For each profile we are going to associate the recipe with, add the
4967	 * recipes that are associated with that profile. This will give us
4968	 * the set of recipes that our recipe may collide with. Also, determine
4969	 * what possible result indexes are usable given this set of profiles.
4970	 */
4971	for_each_set_bit(bit, profiles, ICE_MAX_NUM_PROFILES) {
4972		bitmap_or(recipes, recipes, profile_to_recipe[bit],
4973			  ICE_MAX_NUM_RECIPES);
4974		bitmap_and(possible_idx, possible_idx,
4975			   hw->switch_info->prof_res_bm[bit],
4976			   ICE_MAX_FV_WORDS);
4977	}
4978
4979	/* For each recipe that our new recipe may collide with, determine
4980	 * which indexes have been used.
4981	 */
4982	for_each_set_bit(bit, recipes, ICE_MAX_NUM_RECIPES)
4983		bitmap_or(used_idx, used_idx,
4984			  hw->switch_info->recp_list[bit].res_idxs,
4985			  ICE_MAX_FV_WORDS);
4986
4987	bitmap_xor(free_idx, used_idx, possible_idx, ICE_MAX_FV_WORDS);
4988
4989	/* return number of free indexes */
4990	return (u16)bitmap_weight(free_idx, ICE_MAX_FV_WORDS);
4991}
4992
4993/**
4994 * ice_calc_recp_cnt - calculate number of recipes based on word count
4995 * @word_cnt: number of lookup words
4996 *
4997 * Word count should include switch ID word and regular lookup words.
4998 * Returns: number of recipes required to fit @word_cnt, including extra recipes
4999 * needed for recipe chaining (if needed).
5000 */
5001static int ice_calc_recp_cnt(u8 word_cnt)
5002{
5003	/* All words fit in a single recipe, no need for chaining. */
5004	if (word_cnt <= ICE_NUM_WORDS_RECIPE)
5005		return 1;
5006
5007	/* Recipe chaining required. Result indexes are fitted right after
5008	 * regular lookup words. In some cases a new recipe must be added in
5009	 * order to fit result indexes.
5010	 *
5011	 * While the word count increases, every 5 words an extra recipe needs
5012	 * to be added. However, by adding a recipe, one word for its result
5013	 * index must also be added, therefore every 4 words recipe count
5014	 * increases by 1. This calculation does not apply to word count == 1,
5015	 * which is handled above.
5016	 */
5017	return (word_cnt + 2) / (ICE_NUM_WORDS_RECIPE - 1);
5018}
5019
5020static void fill_recipe_template(struct ice_aqc_recipe_data_elem *recp, u16 rid,
5021				 const struct ice_sw_recipe *rm)
5022{
5023	int i;
5024
5025	recp->recipe_indx = rid;
5026	recp->content.act_ctrl |= ICE_AQ_RECIPE_ACT_PRUNE_INDX_M;
5027
5028	for (i = 0; i < ICE_NUM_WORDS_RECIPE; i++) {
5029		recp->content.lkup_indx[i] = ICE_AQ_RECIPE_LKUP_IGNORE;
5030		recp->content.mask[i] = cpu_to_le16(0);
5031	}
5032
5033	set_bit(rid, (unsigned long *)recp->recipe_bitmap);
5034	recp->content.act_ctrl_fwd_priority = rm->priority;
5035
5036	if (rm->need_pass_l2)
5037		recp->content.act_ctrl |= ICE_AQ_RECIPE_ACT_NEED_PASS_L2;
5038
5039	if (rm->allow_pass_l2)
5040		recp->content.act_ctrl |= ICE_AQ_RECIPE_ACT_ALLOW_PASS_L2;
5041}
5042
5043static void bookkeep_recipe(struct ice_sw_recipe *recipe,
5044			    struct ice_aqc_recipe_data_elem *r,
5045			    const struct ice_sw_recipe *rm)
5046{
5047	memcpy(recipe->r_bitmap, r->recipe_bitmap, sizeof(recipe->r_bitmap));
5048
5049	recipe->priority = r->content.act_ctrl_fwd_priority;
5050	recipe->tun_type = rm->tun_type;
5051	recipe->need_pass_l2 = rm->need_pass_l2;
5052	recipe->allow_pass_l2 = rm->allow_pass_l2;
5053	recipe->recp_created = true;
5054}
5055
5056/* For memcpy in ice_add_sw_recipe. */
5057static_assert(sizeof_field(struct ice_aqc_recipe_data_elem, recipe_bitmap) ==
5058	      sizeof_field(struct ice_sw_recipe, r_bitmap));
5059
5060/**
5061 * ice_add_sw_recipe - function to call AQ calls to create switch recipe
5062 * @hw: pointer to hardware structure
5063 * @rm: recipe management list entry
5064 * @profiles: bitmap of profiles that will be associated.
5065 */
5066static int
5067ice_add_sw_recipe(struct ice_hw *hw, struct ice_sw_recipe *rm,
5068		  unsigned long *profiles)
5069{
5070	struct ice_aqc_recipe_data_elem *buf __free(kfree) = NULL;
5071	DECLARE_BITMAP(result_idx_bm, ICE_MAX_FV_WORDS);
5072	struct ice_aqc_recipe_data_elem *root;
5073	struct ice_sw_recipe *recipe;
5074	u16 free_res_idx, rid;
5075	int lookup = 0;
5076	int recp_cnt;
5077	int status;
5078	int word;
5079	int i;
5080
5081	recp_cnt = ice_calc_recp_cnt(rm->n_ext_words);
5082
5083	bitmap_zero(result_idx_bm, ICE_MAX_FV_WORDS);
5084	bitmap_zero(rm->r_bitmap, ICE_MAX_NUM_RECIPES);
5085
5086	/* Check number of free result indices */
5087	free_res_idx = ice_find_free_recp_res_idx(hw, profiles, result_idx_bm);
5088
5089	ice_debug(hw, ICE_DBG_SW, "Result idx slots: %d, need %d\n",
5090		  free_res_idx, recp_cnt);
5091
5092	/* Last recipe doesn't need result index */
5093	if (recp_cnt - 1 > free_res_idx)
5094		return -ENOSPC;
5095
5096	if (recp_cnt > ICE_MAX_CHAIN_RECIPE_RES)
5097		return -E2BIG;
5098
5099	buf = kcalloc(recp_cnt, sizeof(*buf), GFP_KERNEL);
5100	if (!buf)
5101		return -ENOMEM;
5102
5103	/* Setup the non-root subrecipes. These do not contain lookups for other
5104	 * subrecipes results. Set associated recipe only to own recipe index.
5105	 * Each non-root subrecipe needs a free result index from FV.
5106	 *
5107	 * Note: only done if there is more than one recipe.
5108	 */
5109	for (i = 0; i < recp_cnt - 1; i++) {
5110		struct ice_aqc_recipe_content *content;
5111		u8 result_idx;
5112
5113		status = ice_alloc_recipe(hw, &rid);
5114		if (status)
5115			return status;
5116
5117		fill_recipe_template(&buf[i], rid, rm);
5118
5119		result_idx = find_first_bit(result_idx_bm, ICE_MAX_FV_WORDS);
5120		/* Check if there really is a valid result index that can be
5121		 * used.
5122		 */
5123		if (result_idx >= ICE_MAX_FV_WORDS) {
5124			ice_debug(hw, ICE_DBG_SW, "No chain index available\n");
5125			return -ENOSPC;
5126		}
5127		clear_bit(result_idx, result_idx_bm);
5128
5129		content = &buf[i].content;
5130		content->result_indx = ICE_AQ_RECIPE_RESULT_EN |
5131				       FIELD_PREP(ICE_AQ_RECIPE_RESULT_DATA_M,
5132						  result_idx);
5133
5134		/* Set recipe association to be used for root recipe */
5135		set_bit(rid, rm->r_bitmap);
5136
5137		word = 0;
5138		while (lookup < rm->n_ext_words &&
5139		       word < ICE_NUM_WORDS_RECIPE) {
5140			content->lkup_indx[word] = rm->fv_idx[lookup];
5141			content->mask[word] = cpu_to_le16(rm->fv_mask[lookup]);
5142
5143			lookup++;
5144			word++;
5145		}
5146
5147		recipe = &hw->switch_info->recp_list[rid];
5148		set_bit(result_idx, recipe->res_idxs);
5149		bookkeep_recipe(recipe, &buf[i], rm);
5150	}
5151
5152	/* Setup the root recipe */
5153	status = ice_alloc_recipe(hw, &rid);
5154	if (status)
5155		return status;
5156
5157	recipe = &hw->switch_info->recp_list[rid];
5158	root = &buf[recp_cnt - 1];
5159	fill_recipe_template(root, rid, rm);
5160
5161	/* Set recipe association, use previously set bitmap and own rid */
5162	set_bit(rid, rm->r_bitmap);
5163	memcpy(root->recipe_bitmap, rm->r_bitmap, sizeof(root->recipe_bitmap));
5164
5165	/* For non-root recipes rid should be 0, for root it should be correct
5166	 * rid value ored with 0x80 (is root bit).
5167	 */
5168	root->content.rid = rid | ICE_AQ_RECIPE_ID_IS_ROOT;
5169
5170	/* Fill remaining lookups in root recipe */
5171	word = 0;
5172	while (lookup < rm->n_ext_words &&
5173	       word < ICE_NUM_WORDS_RECIPE /* should always be true */) {
5174		root->content.lkup_indx[word] = rm->fv_idx[lookup];
5175		root->content.mask[word] = cpu_to_le16(rm->fv_mask[lookup]);
5176
5177		lookup++;
5178		word++;
5179	}
5180
5181	/* Fill result indexes as lookups */
5182	i = 0;
5183	while (i < recp_cnt - 1 &&
5184	       word < ICE_NUM_WORDS_RECIPE /* should always be true */) {
5185		root->content.lkup_indx[word] = buf[i].content.result_indx &
5186						~ICE_AQ_RECIPE_RESULT_EN;
5187		root->content.mask[word] = cpu_to_le16(0xffff);
5188		/* For bookkeeping, it is needed to mark FV index as used for
5189		 * intermediate result.
5190		 */
5191		set_bit(root->content.lkup_indx[word], recipe->res_idxs);
5192
5193		i++;
5194		word++;
5195	}
5196
5197	rm->root_rid = rid;
5198	bookkeep_recipe(&hw->switch_info->recp_list[rid], root, rm);
5199
5200	/* Program the recipe */
5201	status = ice_acquire_change_lock(hw, ICE_RES_WRITE);
5202	if (status)
5203		return status;
5204
5205	status = ice_aq_add_recipe(hw, buf, recp_cnt, NULL);
5206	ice_release_change_lock(hw);
5207	if (status)
5208		return status;
5209
5210	return 0;
5211}
5212
5213/* ice_get_compat_fv_bitmap - Get compatible field vector bitmap for rule
5214 * @hw: pointer to hardware structure
5215 * @rinfo: other information regarding the rule e.g. priority and action info
5216 * @bm: pointer to memory for returning the bitmap of field vectors
5217 */
5218static void
5219ice_get_compat_fv_bitmap(struct ice_hw *hw, struct ice_adv_rule_info *rinfo,
5220			 unsigned long *bm)
5221{
5222	enum ice_prof_type prof_type;
5223
5224	bitmap_zero(bm, ICE_MAX_NUM_PROFILES);
5225
5226	switch (rinfo->tun_type) {
5227	case ICE_NON_TUN:
5228		prof_type = ICE_PROF_NON_TUN;
5229		break;
5230	case ICE_ALL_TUNNELS:
5231		prof_type = ICE_PROF_TUN_ALL;
5232		break;
5233	case ICE_SW_TUN_GENEVE:
5234	case ICE_SW_TUN_VXLAN:
5235		prof_type = ICE_PROF_TUN_UDP;
5236		break;
5237	case ICE_SW_TUN_NVGRE:
5238		prof_type = ICE_PROF_TUN_GRE;
5239		break;
5240	case ICE_SW_TUN_GTPU:
5241		prof_type = ICE_PROF_TUN_GTPU;
5242		break;
5243	case ICE_SW_TUN_GTPC:
5244		prof_type = ICE_PROF_TUN_GTPC;
5245		break;
5246	case ICE_SW_TUN_PFCP:
5247		prof_type = ICE_PROF_TUN_PFCP;
5248		break;
5249	case ICE_SW_TUN_AND_NON_TUN:
5250	default:
5251		prof_type = ICE_PROF_ALL;
5252		break;
5253	}
5254
5255	ice_get_sw_fv_bitmap(hw, prof_type, bm);
5256}
5257
5258/**
5259 * ice_subscribe_recipe - subscribe to an existing recipe
5260 * @hw: pointer to the hardware structure
5261 * @rid: recipe ID to subscribe to
5262 *
5263 * Return: 0 on success, and others on error
5264 */
5265static int ice_subscribe_recipe(struct ice_hw *hw, u16 rid)
5266{
5267	DEFINE_RAW_FLEX(struct ice_aqc_alloc_free_res_elem, sw_buf, elem, 1);
5268	u16 buf_len = __struct_size(sw_buf);
5269	u16 res_type;
5270	int status;
5271
5272	/* Prepare buffer to allocate resource */
5273	sw_buf->num_elems = cpu_to_le16(1);
5274	res_type = FIELD_PREP(ICE_AQC_RES_TYPE_M, ICE_AQC_RES_TYPE_RECIPE) |
5275		   ICE_AQC_RES_TYPE_FLAG_SUBSCRIBE_SHARED |
5276		   ICE_AQC_RES_TYPE_FLAG_SUBSCRIBE_CTL;
5277	sw_buf->res_type = cpu_to_le16(res_type);
5278
5279	sw_buf->elem[0].e.sw_resp = cpu_to_le16(rid);
5280
5281	status = ice_aq_alloc_free_res(hw, sw_buf, buf_len,
5282				       ice_aqc_opc_alloc_res);
5283
5284	return status;
5285}
5286
5287/**
5288 * ice_subscribable_recp_shared - share an existing subscribable recipe
5289 * @hw: pointer to the hardware structure
5290 * @rid: recipe ID to subscribe to
5291 */
5292static void ice_subscribable_recp_shared(struct ice_hw *hw, u16 rid)
5293{
5294	struct ice_sw_recipe *recps = hw->switch_info->recp_list;
5295	u16 sub_rid;
5296
5297	for_each_set_bit(sub_rid, recps[rid].r_bitmap, ICE_MAX_NUM_RECIPES)
5298		ice_subscribe_recipe(hw, sub_rid);
5299}
5300
5301/**
5302 * ice_add_adv_recipe - Add an advanced recipe that is not part of the default
5303 * @hw: pointer to hardware structure
5304 * @lkups: lookup elements or match criteria for the advanced recipe, one
5305 *  structure per protocol header
5306 * @lkups_cnt: number of protocols
5307 * @rinfo: other information regarding the rule e.g. priority and action info
5308 * @rid: return the recipe ID of the recipe created
5309 */
5310static int
5311ice_add_adv_recipe(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups,
5312		   u16 lkups_cnt, struct ice_adv_rule_info *rinfo, u16 *rid)
5313{
5314	DECLARE_BITMAP(fv_bitmap, ICE_MAX_NUM_PROFILES);
5315	DECLARE_BITMAP(profiles, ICE_MAX_NUM_PROFILES);
5316	struct ice_prot_lkup_ext *lkup_exts;
5317	struct ice_sw_fv_list_entry *fvit;
5318	struct ice_sw_fv_list_entry *tmp;
5319	struct ice_sw_recipe *rm;
5320	int status = 0;
5321	u16 rid_tmp;
5322	u8 i;
5323
5324	if (!lkups_cnt)
5325		return -EINVAL;
5326
5327	lkup_exts = kzalloc(sizeof(*lkup_exts), GFP_KERNEL);
5328	if (!lkup_exts)
5329		return -ENOMEM;
5330
5331	/* Determine the number of words to be matched and if it exceeds a
5332	 * recipe's restrictions
5333	 */
5334	for (i = 0; i < lkups_cnt; i++) {
5335		u16 count;
5336
5337		if (lkups[i].type >= ICE_PROTOCOL_LAST) {
5338			status = -EIO;
5339			goto err_free_lkup_exts;
5340		}
5341
5342		count = ice_fill_valid_words(&lkups[i], lkup_exts);
5343		if (!count) {
5344			status = -EIO;
5345			goto err_free_lkup_exts;
5346		}
5347	}
5348
5349	rm = kzalloc(sizeof(*rm), GFP_KERNEL);
5350	if (!rm) {
5351		status = -ENOMEM;
5352		goto err_free_lkup_exts;
5353	}
5354
5355	/* Get field vectors that contain fields extracted from all the protocol
5356	 * headers being programmed.
5357	 */
5358	INIT_LIST_HEAD(&rm->fv_list);
5359
5360	/* Get bitmap of field vectors (profiles) that are compatible with the
5361	 * rule request; only these will be searched in the subsequent call to
5362	 * ice_get_sw_fv_list.
5363	 */
5364	ice_get_compat_fv_bitmap(hw, rinfo, fv_bitmap);
5365
5366	status = ice_get_sw_fv_list(hw, lkup_exts, fv_bitmap, &rm->fv_list);
5367	if (status)
5368		goto err_unroll;
5369
5370	/* Copy FV words and masks from lkup_exts to recipe struct. */
5371	rm->n_ext_words = lkup_exts->n_val_words;
5372	memcpy(rm->ext_words, lkup_exts->fv_words, sizeof(rm->ext_words));
5373	memcpy(rm->word_masks, lkup_exts->field_mask, sizeof(rm->word_masks));
5374
5375	/* set the recipe priority if specified */
5376	rm->priority = (u8)rinfo->priority;
5377
5378	rm->need_pass_l2 = rinfo->need_pass_l2;
5379	rm->allow_pass_l2 = rinfo->allow_pass_l2;
5380
5381	/* Find offsets from the field vector. Pick the first one for all the
5382	 * recipes.
5383	 */
5384	status = ice_fill_fv_word_index(hw, rm);
5385	if (status)
5386		goto err_unroll;
5387
5388	/* get bitmap of all profiles the recipe will be associated with */
5389	bitmap_zero(profiles, ICE_MAX_NUM_PROFILES);
5390	list_for_each_entry(fvit, &rm->fv_list, list_entry) {
5391		ice_debug(hw, ICE_DBG_SW, "profile: %d\n", fvit->profile_id);
5392		set_bit((u16)fvit->profile_id, profiles);
5393	}
5394
5395	/* Look for a recipe which matches our requested fv / mask list */
5396	*rid = ice_find_recp(hw, lkup_exts, rinfo, true);
5397	if (*rid < ICE_MAX_NUM_RECIPES) {
5398		/* Success if found a recipe that match the existing criteria */
5399		if (hw->recp_reuse)
5400			ice_subscribable_recp_shared(hw, *rid);
5401
5402		goto err_unroll;
5403	}
5404
5405	rm->tun_type = rinfo->tun_type;
5406	/* Recipe we need does not exist, add a recipe */
5407	status = ice_add_sw_recipe(hw, rm, profiles);
5408	if (status)
5409		goto err_unroll;
5410
5411	/* Associate all the recipes created with all the profiles in the
5412	 * common field vector.
5413	 */
5414	list_for_each_entry(fvit, &rm->fv_list, list_entry) {
5415		DECLARE_BITMAP(r_bitmap, ICE_MAX_NUM_RECIPES);
5416		u64 recp_assoc;
5417		u16 j;
5418
5419		status = ice_aq_get_recipe_to_profile(hw, fvit->profile_id,
5420						      &recp_assoc, NULL);
5421		if (status)
5422			goto err_free_recipe;
5423
5424		bitmap_from_arr64(r_bitmap, &recp_assoc, ICE_MAX_NUM_RECIPES);
5425		bitmap_or(r_bitmap, r_bitmap, rm->r_bitmap,
5426			  ICE_MAX_NUM_RECIPES);
5427		status = ice_acquire_change_lock(hw, ICE_RES_WRITE);
5428		if (status)
5429			goto err_free_recipe;
5430
5431		bitmap_to_arr64(&recp_assoc, r_bitmap, ICE_MAX_NUM_RECIPES);
5432		status = ice_aq_map_recipe_to_profile(hw, fvit->profile_id,
5433						      recp_assoc, NULL);
5434		ice_release_change_lock(hw);
5435
5436		if (status)
5437			goto err_free_recipe;
5438
5439		/* Update profile to recipe bitmap array */
5440		bitmap_copy(profile_to_recipe[fvit->profile_id], r_bitmap,
5441			    ICE_MAX_NUM_RECIPES);
5442
5443		/* Update recipe to profile bitmap array */
5444		for_each_set_bit(j, rm->r_bitmap, ICE_MAX_NUM_RECIPES)
5445			set_bit((u16)fvit->profile_id, recipe_to_profile[j]);
5446	}
5447
5448	*rid = rm->root_rid;
5449	memcpy(&hw->switch_info->recp_list[*rid].lkup_exts, lkup_exts,
5450	       sizeof(*lkup_exts));
5451	goto err_unroll;
5452
5453err_free_recipe:
5454	if (hw->recp_reuse) {
5455		for_each_set_bit(rid_tmp, rm->r_bitmap, ICE_MAX_NUM_RECIPES) {
5456			if (!ice_free_recipe_res(hw, rid_tmp))
5457				clear_bit(rid_tmp, rm->r_bitmap);
5458		}
5459	}
5460
5461err_unroll:
5462	list_for_each_entry_safe(fvit, tmp, &rm->fv_list, list_entry) {
5463		list_del(&fvit->list_entry);
5464		devm_kfree(ice_hw_to_dev(hw), fvit);
5465	}
5466
5467	kfree(rm);
5468
5469err_free_lkup_exts:
5470	kfree(lkup_exts);
5471
5472	return status;
5473}
5474
5475/**
5476 * ice_dummy_packet_add_vlan - insert VLAN header to dummy pkt
5477 *
5478 * @dummy_pkt: dummy packet profile pattern to which VLAN tag(s) will be added
5479 * @num_vlan: number of VLAN tags
5480 */
5481static struct ice_dummy_pkt_profile *
5482ice_dummy_packet_add_vlan(const struct ice_dummy_pkt_profile *dummy_pkt,
5483			  u32 num_vlan)
5484{
5485	struct ice_dummy_pkt_profile *profile;
5486	struct ice_dummy_pkt_offsets *offsets;
5487	u32 buf_len, off, etype_off, i;
5488	u8 *pkt;
5489
5490	if (num_vlan < 1 || num_vlan > 2)
5491		return ERR_PTR(-EINVAL);
5492
5493	off = num_vlan * VLAN_HLEN;
5494
5495	buf_len = array_size(num_vlan, sizeof(ice_dummy_vlan_packet_offsets)) +
5496		  dummy_pkt->offsets_len;
5497	offsets = kzalloc(buf_len, GFP_KERNEL);
5498	if (!offsets)
5499		return ERR_PTR(-ENOMEM);
5500
5501	offsets[0] = dummy_pkt->offsets[0];
5502	if (num_vlan == 2) {
5503		offsets[1] = ice_dummy_qinq_packet_offsets[0];
5504		offsets[2] = ice_dummy_qinq_packet_offsets[1];
5505	} else if (num_vlan == 1) {
5506		offsets[1] = ice_dummy_vlan_packet_offsets[0];
5507	}
5508
5509	for (i = 1; dummy_pkt->offsets[i].type != ICE_PROTOCOL_LAST; i++) {
5510		offsets[i + num_vlan].type = dummy_pkt->offsets[i].type;
5511		offsets[i + num_vlan].offset =
5512			dummy_pkt->offsets[i].offset + off;
5513	}
5514	offsets[i + num_vlan] = dummy_pkt->offsets[i];
5515
5516	etype_off = dummy_pkt->offsets[1].offset;
5517
5518	buf_len = array_size(num_vlan, sizeof(ice_dummy_vlan_packet)) +
5519		  dummy_pkt->pkt_len;
5520	pkt = kzalloc(buf_len, GFP_KERNEL);
5521	if (!pkt) {
5522		kfree(offsets);
5523		return ERR_PTR(-ENOMEM);
5524	}
5525
5526	memcpy(pkt, dummy_pkt->pkt, etype_off);
5527	memcpy(pkt + etype_off,
5528	       num_vlan == 2 ? ice_dummy_qinq_packet : ice_dummy_vlan_packet,
5529	       off);
5530	memcpy(pkt + etype_off + off, dummy_pkt->pkt + etype_off,
5531	       dummy_pkt->pkt_len - etype_off);
5532
5533	profile = kzalloc(sizeof(*profile), GFP_KERNEL);
5534	if (!profile) {
5535		kfree(offsets);
5536		kfree(pkt);
5537		return ERR_PTR(-ENOMEM);
5538	}
5539
5540	profile->offsets = offsets;
5541	profile->pkt = pkt;
5542	profile->pkt_len = buf_len;
5543	profile->match |= ICE_PKT_KMALLOC;
5544
5545	return profile;
5546}
5547
5548/**
5549 * ice_find_dummy_packet - find dummy packet
5550 *
5551 * @lkups: lookup elements or match criteria for the advanced recipe, one
5552 *	   structure per protocol header
5553 * @lkups_cnt: number of protocols
5554 * @tun_type: tunnel type
5555 *
5556 * Returns the &ice_dummy_pkt_profile corresponding to these lookup params.
5557 */
5558static const struct ice_dummy_pkt_profile *
5559ice_find_dummy_packet(struct ice_adv_lkup_elem *lkups, u16 lkups_cnt,
5560		      enum ice_sw_tunnel_type tun_type)
5561{
5562	const struct ice_dummy_pkt_profile *ret = ice_dummy_pkt_profiles;
5563	u32 match = 0, vlan_count = 0;
5564	u16 i;
5565
5566	switch (tun_type) {
5567	case ICE_SW_TUN_GTPC:
5568		match |= ICE_PKT_TUN_GTPC;
5569		break;
5570	case ICE_SW_TUN_GTPU:
5571		match |= ICE_PKT_TUN_GTPU;
5572		break;
5573	case ICE_SW_TUN_NVGRE:
5574		match |= ICE_PKT_TUN_NVGRE;
5575		break;
5576	case ICE_SW_TUN_GENEVE:
5577	case ICE_SW_TUN_VXLAN:
5578		match |= ICE_PKT_TUN_UDP;
5579		break;
5580	case ICE_SW_TUN_PFCP:
5581		match |= ICE_PKT_PFCP;
5582		break;
5583	default:
5584		break;
5585	}
5586
5587	for (i = 0; i < lkups_cnt; i++) {
5588		if (lkups[i].type == ICE_UDP_ILOS)
5589			match |= ICE_PKT_INNER_UDP;
5590		else if (lkups[i].type == ICE_TCP_IL)
5591			match |= ICE_PKT_INNER_TCP;
5592		else if (lkups[i].type == ICE_IPV6_OFOS)
5593			match |= ICE_PKT_OUTER_IPV6;
5594		else if (lkups[i].type == ICE_VLAN_OFOS ||
5595			 lkups[i].type == ICE_VLAN_EX)
5596			vlan_count++;
5597		else if (lkups[i].type == ICE_VLAN_IN)
5598			vlan_count++;
5599		else if (lkups[i].type == ICE_ETYPE_OL &&
5600			 lkups[i].h_u.ethertype.ethtype_id ==
5601				cpu_to_be16(ICE_IPV6_ETHER_ID) &&
5602			 lkups[i].m_u.ethertype.ethtype_id ==
5603				cpu_to_be16(0xFFFF))
5604			match |= ICE_PKT_OUTER_IPV6;
5605		else if (lkups[i].type == ICE_ETYPE_IL &&
5606			 lkups[i].h_u.ethertype.ethtype_id ==
5607				cpu_to_be16(ICE_IPV6_ETHER_ID) &&
5608			 lkups[i].m_u.ethertype.ethtype_id ==
5609				cpu_to_be16(0xFFFF))
5610			match |= ICE_PKT_INNER_IPV6;
5611		else if (lkups[i].type == ICE_IPV6_IL)
5612			match |= ICE_PKT_INNER_IPV6;
5613		else if (lkups[i].type == ICE_GTP_NO_PAY)
5614			match |= ICE_PKT_GTP_NOPAY;
5615		else if (lkups[i].type == ICE_PPPOE) {
5616			match |= ICE_PKT_PPPOE;
5617			if (lkups[i].h_u.pppoe_hdr.ppp_prot_id ==
5618			    htons(PPP_IPV6))
5619				match |= ICE_PKT_OUTER_IPV6;
5620		} else if (lkups[i].type == ICE_L2TPV3)
5621			match |= ICE_PKT_L2TPV3;
5622	}
5623
5624	while (ret->match && (match & ret->match) != ret->match)
5625		ret++;
5626
5627	if (vlan_count != 0)
5628		ret = ice_dummy_packet_add_vlan(ret, vlan_count);
5629
5630	return ret;
5631}
5632
5633/**
5634 * ice_fill_adv_dummy_packet - fill a dummy packet with given match criteria
5635 *
5636 * @lkups: lookup elements or match criteria for the advanced recipe, one
5637 *	   structure per protocol header
5638 * @lkups_cnt: number of protocols
5639 * @s_rule: stores rule information from the match criteria
5640 * @profile: dummy packet profile (the template, its size and header offsets)
5641 */
5642static int
5643ice_fill_adv_dummy_packet(struct ice_adv_lkup_elem *lkups, u16 lkups_cnt,
5644			  struct ice_sw_rule_lkup_rx_tx *s_rule,
5645			  const struct ice_dummy_pkt_profile *profile)
5646{
5647	u8 *pkt;
5648	u16 i;
5649
5650	/* Start with a packet with a pre-defined/dummy content. Then, fill
5651	 * in the header values to be looked up or matched.
5652	 */
5653	pkt = s_rule->hdr_data;
5654
5655	memcpy(pkt, profile->pkt, profile->pkt_len);
5656
5657	for (i = 0; i < lkups_cnt; i++) {
5658		const struct ice_dummy_pkt_offsets *offsets = profile->offsets;
5659		enum ice_protocol_type type;
5660		u16 offset = 0, len = 0, j;
5661		bool found = false;
5662
5663		/* find the start of this layer; it should be found since this
5664		 * was already checked when search for the dummy packet
5665		 */
5666		type = lkups[i].type;
5667		/* metadata isn't present in the packet */
5668		if (type == ICE_HW_METADATA)
5669			continue;
5670
5671		for (j = 0; offsets[j].type != ICE_PROTOCOL_LAST; j++) {
5672			if (type == offsets[j].type) {
5673				offset = offsets[j].offset;
5674				found = true;
5675				break;
5676			}
5677		}
5678		/* this should never happen in a correct calling sequence */
5679		if (!found)
5680			return -EINVAL;
5681
5682		switch (lkups[i].type) {
5683		case ICE_MAC_OFOS:
5684		case ICE_MAC_IL:
5685			len = sizeof(struct ice_ether_hdr);
5686			break;
5687		case ICE_ETYPE_OL:
5688		case ICE_ETYPE_IL:
5689			len = sizeof(struct ice_ethtype_hdr);
5690			break;
5691		case ICE_VLAN_OFOS:
5692		case ICE_VLAN_EX:
5693		case ICE_VLAN_IN:
5694			len = sizeof(struct ice_vlan_hdr);
5695			break;
5696		case ICE_IPV4_OFOS:
5697		case ICE_IPV4_IL:
5698			len = sizeof(struct ice_ipv4_hdr);
5699			break;
5700		case ICE_IPV6_OFOS:
5701		case ICE_IPV6_IL:
5702			len = sizeof(struct ice_ipv6_hdr);
5703			break;
5704		case ICE_TCP_IL:
5705		case ICE_UDP_OF:
5706		case ICE_UDP_ILOS:
5707			len = sizeof(struct ice_l4_hdr);
5708			break;
5709		case ICE_SCTP_IL:
5710			len = sizeof(struct ice_sctp_hdr);
5711			break;
5712		case ICE_NVGRE:
5713			len = sizeof(struct ice_nvgre_hdr);
5714			break;
5715		case ICE_VXLAN:
5716		case ICE_GENEVE:
5717			len = sizeof(struct ice_udp_tnl_hdr);
5718			break;
5719		case ICE_GTP_NO_PAY:
5720		case ICE_GTP:
5721			len = sizeof(struct ice_udp_gtp_hdr);
5722			break;
5723		case ICE_PFCP:
5724			len = sizeof(struct ice_pfcp_hdr);
5725			break;
5726		case ICE_PPPOE:
5727			len = sizeof(struct ice_pppoe_hdr);
5728			break;
5729		case ICE_L2TPV3:
5730			len = sizeof(struct ice_l2tpv3_sess_hdr);
5731			break;
5732		default:
5733			return -EINVAL;
5734		}
5735
5736		/* the length should be a word multiple */
5737		if (len % ICE_BYTES_PER_WORD)
5738			return -EIO;
5739
5740		/* We have the offset to the header start, the length, the
5741		 * caller's header values and mask. Use this information to
5742		 * copy the data into the dummy packet appropriately based on
5743		 * the mask. Note that we need to only write the bits as
5744		 * indicated by the mask to make sure we don't improperly write
5745		 * over any significant packet data.
5746		 */
5747		for (j = 0; j < len / sizeof(u16); j++) {
5748			u16 *ptr = (u16 *)(pkt + offset);
5749			u16 mask = lkups[i].m_raw[j];
5750
5751			if (!mask)
5752				continue;
5753
5754			ptr[j] = (ptr[j] & ~mask) | (lkups[i].h_raw[j] & mask);
5755		}
5756	}
5757
5758	s_rule->hdr_len = cpu_to_le16(profile->pkt_len);
5759
5760	return 0;
5761}
5762
5763/**
5764 * ice_fill_adv_packet_tun - fill dummy packet with udp tunnel port
5765 * @hw: pointer to the hardware structure
5766 * @tun_type: tunnel type
5767 * @pkt: dummy packet to fill in
5768 * @offsets: offset info for the dummy packet
5769 */
5770static int
5771ice_fill_adv_packet_tun(struct ice_hw *hw, enum ice_sw_tunnel_type tun_type,
5772			u8 *pkt, const struct ice_dummy_pkt_offsets *offsets)
5773{
5774	u16 open_port, i;
5775
5776	switch (tun_type) {
5777	case ICE_SW_TUN_VXLAN:
5778		if (!ice_get_open_tunnel_port(hw, &open_port, TNL_VXLAN))
5779			return -EIO;
5780		break;
5781	case ICE_SW_TUN_GENEVE:
5782		if (!ice_get_open_tunnel_port(hw, &open_port, TNL_GENEVE))
5783			return -EIO;
5784		break;
5785	default:
5786		/* Nothing needs to be done for this tunnel type */
5787		return 0;
5788	}
5789
5790	/* Find the outer UDP protocol header and insert the port number */
5791	for (i = 0; offsets[i].type != ICE_PROTOCOL_LAST; i++) {
5792		if (offsets[i].type == ICE_UDP_OF) {
5793			struct ice_l4_hdr *hdr;
5794			u16 offset;
5795
5796			offset = offsets[i].offset;
5797			hdr = (struct ice_l4_hdr *)&pkt[offset];
5798			hdr->dst_port = cpu_to_be16(open_port);
5799
5800			return 0;
5801		}
5802	}
5803
5804	return -EIO;
5805}
5806
5807/**
5808 * ice_fill_adv_packet_vlan - fill dummy packet with VLAN tag type
5809 * @hw: pointer to hw structure
5810 * @vlan_type: VLAN tag type
5811 * @pkt: dummy packet to fill in
5812 * @offsets: offset info for the dummy packet
5813 */
5814static int
5815ice_fill_adv_packet_vlan(struct ice_hw *hw, u16 vlan_type, u8 *pkt,
5816			 const struct ice_dummy_pkt_offsets *offsets)
5817{
5818	u16 i;
5819
5820	/* Check if there is something to do */
5821	if (!vlan_type || !ice_is_dvm_ena(hw))
5822		return 0;
5823
5824	/* Find VLAN header and insert VLAN TPID */
5825	for (i = 0; offsets[i].type != ICE_PROTOCOL_LAST; i++) {
5826		if (offsets[i].type == ICE_VLAN_OFOS ||
5827		    offsets[i].type == ICE_VLAN_EX) {
5828			struct ice_vlan_hdr *hdr;
5829			u16 offset;
5830
5831			offset = offsets[i].offset;
5832			hdr = (struct ice_vlan_hdr *)&pkt[offset];
5833			hdr->type = cpu_to_be16(vlan_type);
5834
5835			return 0;
5836		}
5837	}
5838
5839	return -EIO;
5840}
5841
5842static bool ice_rules_equal(const struct ice_adv_rule_info *first,
5843			    const struct ice_adv_rule_info *second)
5844{
5845	return first->sw_act.flag == second->sw_act.flag &&
5846	       first->tun_type == second->tun_type &&
5847	       first->vlan_type == second->vlan_type &&
5848	       first->src_vsi == second->src_vsi &&
5849	       first->need_pass_l2 == second->need_pass_l2 &&
5850	       first->allow_pass_l2 == second->allow_pass_l2;
5851}
5852
5853/**
5854 * ice_find_adv_rule_entry - Search a rule entry
5855 * @hw: pointer to the hardware structure
5856 * @lkups: lookup elements or match criteria for the advanced recipe, one
5857 *	   structure per protocol header
5858 * @lkups_cnt: number of protocols
5859 * @recp_id: recipe ID for which we are finding the rule
5860 * @rinfo: other information regarding the rule e.g. priority and action info
5861 *
5862 * Helper function to search for a given advance rule entry
5863 * Returns pointer to entry storing the rule if found
5864 */
5865static struct ice_adv_fltr_mgmt_list_entry *
5866ice_find_adv_rule_entry(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups,
5867			u16 lkups_cnt, u16 recp_id,
5868			struct ice_adv_rule_info *rinfo)
5869{
5870	struct ice_adv_fltr_mgmt_list_entry *list_itr;
5871	struct ice_switch_info *sw = hw->switch_info;
5872	int i;
5873
5874	list_for_each_entry(list_itr, &sw->recp_list[recp_id].filt_rules,
5875			    list_entry) {
5876		bool lkups_matched = true;
5877
5878		if (lkups_cnt != list_itr->lkups_cnt)
5879			continue;
5880		for (i = 0; i < list_itr->lkups_cnt; i++)
5881			if (memcmp(&list_itr->lkups[i], &lkups[i],
5882				   sizeof(*lkups))) {
5883				lkups_matched = false;
5884				break;
5885			}
5886		if (ice_rules_equal(rinfo, &list_itr->rule_info) &&
5887		    lkups_matched)
5888			return list_itr;
5889	}
5890	return NULL;
5891}
5892
5893/**
5894 * ice_adv_add_update_vsi_list
5895 * @hw: pointer to the hardware structure
5896 * @m_entry: pointer to current adv filter management list entry
5897 * @cur_fltr: filter information from the book keeping entry
5898 * @new_fltr: filter information with the new VSI to be added
5899 *
5900 * Call AQ command to add or update previously created VSI list with new VSI.
5901 *
5902 * Helper function to do book keeping associated with adding filter information
5903 * The algorithm to do the booking keeping is described below :
5904 * When a VSI needs to subscribe to a given advanced filter
5905 *	if only one VSI has been added till now
5906 *		Allocate a new VSI list and add two VSIs
5907 *		to this list using switch rule command
5908 *		Update the previously created switch rule with the
5909 *		newly created VSI list ID
5910 *	if a VSI list was previously created
5911 *		Add the new VSI to the previously created VSI list set
5912 *		using the update switch rule command
5913 */
5914static int
5915ice_adv_add_update_vsi_list(struct ice_hw *hw,
5916			    struct ice_adv_fltr_mgmt_list_entry *m_entry,
5917			    struct ice_adv_rule_info *cur_fltr,
5918			    struct ice_adv_rule_info *new_fltr)
5919{
5920	u16 vsi_list_id = 0;
5921	int status;
5922
5923	if (cur_fltr->sw_act.fltr_act == ICE_FWD_TO_Q ||
5924	    cur_fltr->sw_act.fltr_act == ICE_FWD_TO_QGRP ||
5925	    cur_fltr->sw_act.fltr_act == ICE_DROP_PACKET)
5926		return -EOPNOTSUPP;
5927
5928	if ((new_fltr->sw_act.fltr_act == ICE_FWD_TO_Q ||
5929	     new_fltr->sw_act.fltr_act == ICE_FWD_TO_QGRP) &&
5930	    (cur_fltr->sw_act.fltr_act == ICE_FWD_TO_VSI ||
5931	     cur_fltr->sw_act.fltr_act == ICE_FWD_TO_VSI_LIST))
5932		return -EOPNOTSUPP;
5933
5934	if (m_entry->vsi_count < 2 && !m_entry->vsi_list_info) {
5935		 /* Only one entry existed in the mapping and it was not already
5936		  * a part of a VSI list. So, create a VSI list with the old and
5937		  * new VSIs.
5938		  */
5939		struct ice_fltr_info tmp_fltr;
5940		u16 vsi_handle_arr[2];
5941
5942		/* A rule already exists with the new VSI being added */
5943		if (cur_fltr->sw_act.fwd_id.hw_vsi_id ==
5944		    new_fltr->sw_act.fwd_id.hw_vsi_id)
5945			return -EEXIST;
5946
5947		vsi_handle_arr[0] = cur_fltr->sw_act.vsi_handle;
5948		vsi_handle_arr[1] = new_fltr->sw_act.vsi_handle;
5949		status = ice_create_vsi_list_rule(hw, &vsi_handle_arr[0], 2,
5950						  &vsi_list_id,
5951						  ICE_SW_LKUP_LAST);
5952		if (status)
5953			return status;
5954
5955		memset(&tmp_fltr, 0, sizeof(tmp_fltr));
5956		tmp_fltr.flag = m_entry->rule_info.sw_act.flag;
5957		tmp_fltr.fltr_rule_id = cur_fltr->fltr_rule_id;
5958		tmp_fltr.fltr_act = ICE_FWD_TO_VSI_LIST;
5959		tmp_fltr.fwd_id.vsi_list_id = vsi_list_id;
5960		tmp_fltr.lkup_type = ICE_SW_LKUP_LAST;
5961
5962		/* Update the previous switch rule of "forward to VSI" to
5963		 * "fwd to VSI list"
5964		 */
5965		status = ice_update_pkt_fwd_rule(hw, &tmp_fltr);
5966		if (status)
5967			return status;
5968
5969		cur_fltr->sw_act.fwd_id.vsi_list_id = vsi_list_id;
5970		cur_fltr->sw_act.fltr_act = ICE_FWD_TO_VSI_LIST;
5971		m_entry->vsi_list_info =
5972			ice_create_vsi_list_map(hw, &vsi_handle_arr[0], 2,
5973						vsi_list_id);
5974	} else {
5975		u16 vsi_handle = new_fltr->sw_act.vsi_handle;
5976
5977		if (!m_entry->vsi_list_info)
5978			return -EIO;
5979
5980		/* A rule already exists with the new VSI being added */
5981		if (test_bit(vsi_handle, m_entry->vsi_list_info->vsi_map))
5982			return -EEXIST;
5983
5984		/* Update the previously created VSI list set with
5985		 * the new VSI ID passed in
5986		 */
5987		vsi_list_id = cur_fltr->sw_act.fwd_id.vsi_list_id;
5988
5989		status = ice_update_vsi_list_rule(hw, &vsi_handle, 1,
5990						  vsi_list_id, false,
5991						  ice_aqc_opc_update_sw_rules,
5992						  ICE_SW_LKUP_LAST);
5993		/* update VSI list mapping info with new VSI ID */
5994		if (!status)
5995			set_bit(vsi_handle, m_entry->vsi_list_info->vsi_map);
5996	}
5997	if (!status)
5998		m_entry->vsi_count++;
5999	return status;
6000}
6001
6002void ice_rule_add_tunnel_metadata(struct ice_adv_lkup_elem *lkup)
6003{
6004	lkup->type = ICE_HW_METADATA;
6005	lkup->m_u.metadata.flags[ICE_PKT_FLAGS_MDID21] |=
6006		cpu_to_be16(ICE_PKT_TUNNEL_MASK);
6007}
6008
6009void ice_rule_add_direction_metadata(struct ice_adv_lkup_elem *lkup)
6010{
6011	lkup->type = ICE_HW_METADATA;
6012	lkup->m_u.metadata.flags[ICE_PKT_FLAGS_MDID20] |=
6013		cpu_to_be16(ICE_PKT_FROM_NETWORK);
6014}
6015
6016void ice_rule_add_vlan_metadata(struct ice_adv_lkup_elem *lkup)
6017{
6018	lkup->type = ICE_HW_METADATA;
6019	lkup->m_u.metadata.flags[ICE_PKT_FLAGS_MDID20] |=
6020		cpu_to_be16(ICE_PKT_VLAN_MASK);
6021}
6022
6023void ice_rule_add_src_vsi_metadata(struct ice_adv_lkup_elem *lkup)
6024{
6025	lkup->type = ICE_HW_METADATA;
6026	lkup->m_u.metadata.source_vsi = cpu_to_be16(ICE_MDID_SOURCE_VSI_MASK);
6027}
6028
6029/**
6030 * ice_add_adv_rule - helper function to create an advanced switch rule
6031 * @hw: pointer to the hardware structure
6032 * @lkups: information on the words that needs to be looked up. All words
6033 * together makes one recipe
6034 * @lkups_cnt: num of entries in the lkups array
6035 * @rinfo: other information related to the rule that needs to be programmed
6036 * @added_entry: this will return recipe_id, rule_id and vsi_handle. should be
6037 *               ignored is case of error.
6038 *
6039 * This function can program only 1 rule at a time. The lkups is used to
6040 * describe the all the words that forms the "lookup" portion of the recipe.
6041 * These words can span multiple protocols. Callers to this function need to
6042 * pass in a list of protocol headers with lookup information along and mask
6043 * that determines which words are valid from the given protocol header.
6044 * rinfo describes other information related to this rule such as forwarding
6045 * IDs, priority of this rule, etc.
6046 */
6047int
6048ice_add_adv_rule(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups,
6049		 u16 lkups_cnt, struct ice_adv_rule_info *rinfo,
6050		 struct ice_rule_query_data *added_entry)
6051{
6052	struct ice_adv_fltr_mgmt_list_entry *m_entry, *adv_fltr = NULL;
6053	struct ice_sw_rule_lkup_rx_tx *s_rule = NULL;
6054	const struct ice_dummy_pkt_profile *profile;
6055	u16 rid = 0, i, rule_buf_sz, vsi_handle;
6056	struct list_head *rule_head;
6057	struct ice_switch_info *sw;
6058	u16 word_cnt;
6059	u32 act = 0;
6060	int status;
6061	u8 q_rgn;
6062
6063	/* Initialize profile to result index bitmap */
6064	if (!hw->switch_info->prof_res_bm_init) {
6065		hw->switch_info->prof_res_bm_init = 1;
6066		ice_init_prof_result_bm(hw);
6067	}
6068
6069	if (!lkups_cnt)
6070		return -EINVAL;
6071
6072	/* get # of words we need to match */
6073	word_cnt = 0;
6074	for (i = 0; i < lkups_cnt; i++) {
6075		u16 j;
6076
6077		for (j = 0; j < ARRAY_SIZE(lkups->m_raw); j++)
6078			if (lkups[i].m_raw[j])
6079				word_cnt++;
6080	}
6081
6082	if (!word_cnt)
6083		return -EINVAL;
6084
6085	if (word_cnt > ICE_MAX_CHAIN_WORDS)
6086		return -ENOSPC;
6087
6088	/* locate a dummy packet */
6089	profile = ice_find_dummy_packet(lkups, lkups_cnt, rinfo->tun_type);
6090	if (IS_ERR(profile))
6091		return PTR_ERR(profile);
6092
6093	if (!(rinfo->sw_act.fltr_act == ICE_FWD_TO_VSI ||
6094	      rinfo->sw_act.fltr_act == ICE_FWD_TO_Q ||
6095	      rinfo->sw_act.fltr_act == ICE_FWD_TO_QGRP ||
6096	      rinfo->sw_act.fltr_act == ICE_DROP_PACKET ||
6097	      rinfo->sw_act.fltr_act == ICE_MIRROR_PACKET ||
6098	      rinfo->sw_act.fltr_act == ICE_NOP)) {
6099		status = -EIO;
6100		goto free_pkt_profile;
6101	}
6102
6103	vsi_handle = rinfo->sw_act.vsi_handle;
6104	if (!ice_is_vsi_valid(hw, vsi_handle)) {
6105		status =  -EINVAL;
6106		goto free_pkt_profile;
6107	}
6108
6109	if (rinfo->sw_act.fltr_act == ICE_FWD_TO_VSI ||
6110	    rinfo->sw_act.fltr_act == ICE_MIRROR_PACKET ||
6111	    rinfo->sw_act.fltr_act == ICE_NOP) {
6112		rinfo->sw_act.fwd_id.hw_vsi_id =
6113			ice_get_hw_vsi_num(hw, vsi_handle);
6114	}
6115
6116	if (rinfo->src_vsi)
6117		rinfo->sw_act.src = ice_get_hw_vsi_num(hw, rinfo->src_vsi);
6118	else
6119		rinfo->sw_act.src = ice_get_hw_vsi_num(hw, vsi_handle);
6120
6121	status = ice_add_adv_recipe(hw, lkups, lkups_cnt, rinfo, &rid);
6122	if (status)
6123		goto free_pkt_profile;
6124	m_entry = ice_find_adv_rule_entry(hw, lkups, lkups_cnt, rid, rinfo);
6125	if (m_entry) {
6126		/* we have to add VSI to VSI_LIST and increment vsi_count.
6127		 * Also Update VSI list so that we can change forwarding rule
6128		 * if the rule already exists, we will check if it exists with
6129		 * same vsi_id, if not then add it to the VSI list if it already
6130		 * exists if not then create a VSI list and add the existing VSI
6131		 * ID and the new VSI ID to the list
6132		 * We will add that VSI to the list
6133		 */
6134		status = ice_adv_add_update_vsi_list(hw, m_entry,
6135						     &m_entry->rule_info,
6136						     rinfo);
6137		if (added_entry) {
6138			added_entry->rid = rid;
6139			added_entry->rule_id = m_entry->rule_info.fltr_rule_id;
6140			added_entry->vsi_handle = rinfo->sw_act.vsi_handle;
6141		}
6142		goto free_pkt_profile;
6143	}
6144	rule_buf_sz = ICE_SW_RULE_RX_TX_HDR_SIZE(s_rule, profile->pkt_len);
6145	s_rule = kzalloc(rule_buf_sz, GFP_KERNEL);
6146	if (!s_rule) {
6147		status = -ENOMEM;
6148		goto free_pkt_profile;
6149	}
6150
6151	if (rinfo->sw_act.fltr_act != ICE_MIRROR_PACKET) {
6152		if (!rinfo->flags_info.act_valid) {
6153			act |= ICE_SINGLE_ACT_LAN_ENABLE;
6154			act |= ICE_SINGLE_ACT_LB_ENABLE;
6155		} else {
6156			act |= rinfo->flags_info.act & (ICE_SINGLE_ACT_LAN_ENABLE |
6157							ICE_SINGLE_ACT_LB_ENABLE);
6158		}
6159	}
6160
6161	switch (rinfo->sw_act.fltr_act) {
6162	case ICE_FWD_TO_VSI:
6163		act |= FIELD_PREP(ICE_SINGLE_ACT_VSI_ID_M,
6164				  rinfo->sw_act.fwd_id.hw_vsi_id);
6165		act |= ICE_SINGLE_ACT_VSI_FORWARDING | ICE_SINGLE_ACT_VALID_BIT;
6166		break;
6167	case ICE_FWD_TO_Q:
6168		act |= ICE_SINGLE_ACT_TO_Q;
6169		act |= FIELD_PREP(ICE_SINGLE_ACT_Q_INDEX_M,
6170				  rinfo->sw_act.fwd_id.q_id);
6171		break;
6172	case ICE_FWD_TO_QGRP:
6173		q_rgn = rinfo->sw_act.qgrp_size > 0 ?
6174			(u8)ilog2(rinfo->sw_act.qgrp_size) : 0;
6175		act |= ICE_SINGLE_ACT_TO_Q;
6176		act |= FIELD_PREP(ICE_SINGLE_ACT_Q_INDEX_M,
6177				  rinfo->sw_act.fwd_id.q_id);
6178		act |= FIELD_PREP(ICE_SINGLE_ACT_Q_REGION_M, q_rgn);
6179		break;
6180	case ICE_DROP_PACKET:
6181		act |= ICE_SINGLE_ACT_VSI_FORWARDING | ICE_SINGLE_ACT_DROP |
6182		       ICE_SINGLE_ACT_VALID_BIT;
6183		break;
6184	case ICE_MIRROR_PACKET:
6185		act |= ICE_SINGLE_ACT_OTHER_ACTS;
6186		act |= FIELD_PREP(ICE_SINGLE_ACT_VSI_ID_M,
6187				  rinfo->sw_act.fwd_id.hw_vsi_id);
6188		break;
6189	case ICE_NOP:
6190		act |= FIELD_PREP(ICE_SINGLE_ACT_VSI_ID_M,
6191				  rinfo->sw_act.fwd_id.hw_vsi_id);
6192		act &= ~ICE_SINGLE_ACT_VALID_BIT;
6193		break;
6194	default:
6195		status = -EIO;
6196		goto err_ice_add_adv_rule;
6197	}
6198
6199	/* If there is no matching criteria for direction there
6200	 * is only one difference between Rx and Tx:
6201	 * - get switch id base on VSI number from source field (Tx)
6202	 * - get switch id base on port number (Rx)
6203	 *
6204	 * If matching on direction metadata is chose rule direction is
6205	 * extracted from type value set here.
6206	 */
6207	if (rinfo->sw_act.flag & ICE_FLTR_TX) {
6208		s_rule->hdr.type = cpu_to_le16(ICE_AQC_SW_RULES_T_LKUP_TX);
6209		s_rule->src = cpu_to_le16(rinfo->sw_act.src);
6210	} else {
6211		s_rule->hdr.type = cpu_to_le16(ICE_AQC_SW_RULES_T_LKUP_RX);
6212		s_rule->src = cpu_to_le16(hw->port_info->lport);
6213	}
6214
6215	s_rule->recipe_id = cpu_to_le16(rid);
6216	s_rule->act = cpu_to_le32(act);
6217
6218	status = ice_fill_adv_dummy_packet(lkups, lkups_cnt, s_rule, profile);
6219	if (status)
6220		goto err_ice_add_adv_rule;
6221
6222	status = ice_fill_adv_packet_tun(hw, rinfo->tun_type, s_rule->hdr_data,
6223					 profile->offsets);
6224	if (status)
6225		goto err_ice_add_adv_rule;
6226
6227	status = ice_fill_adv_packet_vlan(hw, rinfo->vlan_type,
6228					  s_rule->hdr_data,
6229					  profile->offsets);
6230	if (status)
6231		goto err_ice_add_adv_rule;
6232
6233	status = ice_aq_sw_rules(hw, (struct ice_aqc_sw_rules *)s_rule,
6234				 rule_buf_sz, 1, ice_aqc_opc_add_sw_rules,
6235				 NULL);
6236	if (status)
6237		goto err_ice_add_adv_rule;
6238	adv_fltr = devm_kzalloc(ice_hw_to_dev(hw),
6239				sizeof(struct ice_adv_fltr_mgmt_list_entry),
6240				GFP_KERNEL);
6241	if (!adv_fltr) {
6242		status = -ENOMEM;
6243		goto err_ice_add_adv_rule;
6244	}
6245
6246	adv_fltr->lkups = devm_kmemdup(ice_hw_to_dev(hw), lkups,
6247				       lkups_cnt * sizeof(*lkups), GFP_KERNEL);
6248	if (!adv_fltr->lkups) {
6249		status = -ENOMEM;
6250		goto err_ice_add_adv_rule;
6251	}
6252
6253	adv_fltr->lkups_cnt = lkups_cnt;
6254	adv_fltr->rule_info = *rinfo;
6255	adv_fltr->rule_info.fltr_rule_id = le16_to_cpu(s_rule->index);
6256	sw = hw->switch_info;
6257	sw->recp_list[rid].adv_rule = true;
6258	rule_head = &sw->recp_list[rid].filt_rules;
6259
6260	if (rinfo->sw_act.fltr_act == ICE_FWD_TO_VSI)
6261		adv_fltr->vsi_count = 1;
6262
6263	/* Add rule entry to book keeping list */
6264	list_add(&adv_fltr->list_entry, rule_head);
6265	if (added_entry) {
6266		added_entry->rid = rid;
6267		added_entry->rule_id = adv_fltr->rule_info.fltr_rule_id;
6268		added_entry->vsi_handle = rinfo->sw_act.vsi_handle;
6269	}
6270err_ice_add_adv_rule:
6271	if (status && adv_fltr) {
6272		devm_kfree(ice_hw_to_dev(hw), adv_fltr->lkups);
6273		devm_kfree(ice_hw_to_dev(hw), adv_fltr);
6274	}
6275
6276	kfree(s_rule);
6277
6278free_pkt_profile:
6279	if (profile->match & ICE_PKT_KMALLOC) {
6280		kfree(profile->offsets);
6281		kfree(profile->pkt);
6282		kfree(profile);
6283	}
6284
6285	return status;
6286}
6287
6288/**
6289 * ice_replay_vsi_fltr - Replay filters for requested VSI
6290 * @hw: pointer to the hardware structure
6291 * @vsi_handle: driver VSI handle
6292 * @recp_id: Recipe ID for which rules need to be replayed
6293 * @list_head: list for which filters need to be replayed
6294 *
6295 * Replays the filter of recipe recp_id for a VSI represented via vsi_handle.
6296 * It is required to pass valid VSI handle.
6297 */
6298static int
6299ice_replay_vsi_fltr(struct ice_hw *hw, u16 vsi_handle, u8 recp_id,
6300		    struct list_head *list_head)
6301{
6302	struct ice_fltr_mgmt_list_entry *itr;
6303	int status = 0;
6304	u16 hw_vsi_id;
6305
6306	if (list_empty(list_head))
6307		return status;
6308	hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle);
6309
6310	list_for_each_entry(itr, list_head, list_entry) {
6311		struct ice_fltr_list_entry f_entry;
6312
6313		f_entry.fltr_info = itr->fltr_info;
6314		if (itr->vsi_count < 2 && recp_id != ICE_SW_LKUP_VLAN &&
6315		    itr->fltr_info.vsi_handle == vsi_handle) {
6316			/* update the src in case it is VSI num */
6317			if (f_entry.fltr_info.src_id == ICE_SRC_ID_VSI)
6318				f_entry.fltr_info.src = hw_vsi_id;
6319			status = ice_add_rule_internal(hw, recp_id, &f_entry);
6320			if (status)
6321				goto end;
6322			continue;
6323		}
6324		if (!itr->vsi_list_info ||
6325		    !test_bit(vsi_handle, itr->vsi_list_info->vsi_map))
6326			continue;
6327		f_entry.fltr_info.vsi_handle = vsi_handle;
6328		f_entry.fltr_info.fltr_act = ICE_FWD_TO_VSI;
6329		/* update the src in case it is VSI num */
6330		if (f_entry.fltr_info.src_id == ICE_SRC_ID_VSI)
6331			f_entry.fltr_info.src = hw_vsi_id;
6332		if (recp_id == ICE_SW_LKUP_VLAN)
6333			status = ice_add_vlan_internal(hw, &f_entry);
6334		else
6335			status = ice_add_rule_internal(hw, recp_id, &f_entry);
6336		if (status)
6337			goto end;
6338	}
6339end:
6340	return status;
6341}
6342
6343/**
6344 * ice_adv_rem_update_vsi_list
6345 * @hw: pointer to the hardware structure
6346 * @vsi_handle: VSI handle of the VSI to remove
6347 * @fm_list: filter management entry for which the VSI list management needs to
6348 *	     be done
6349 */
6350static int
6351ice_adv_rem_update_vsi_list(struct ice_hw *hw, u16 vsi_handle,
6352			    struct ice_adv_fltr_mgmt_list_entry *fm_list)
6353{
6354	struct ice_vsi_list_map_info *vsi_list_info;
6355	enum ice_sw_lkup_type lkup_type;
6356	u16 vsi_list_id;
6357	int status;
6358
6359	if (fm_list->rule_info.sw_act.fltr_act != ICE_FWD_TO_VSI_LIST ||
6360	    fm_list->vsi_count == 0)
6361		return -EINVAL;
6362
6363	/* A rule with the VSI being removed does not exist */
6364	if (!test_bit(vsi_handle, fm_list->vsi_list_info->vsi_map))
6365		return -ENOENT;
6366
6367	lkup_type = ICE_SW_LKUP_LAST;
6368	vsi_list_id = fm_list->rule_info.sw_act.fwd_id.vsi_list_id;
6369	status = ice_update_vsi_list_rule(hw, &vsi_handle, 1, vsi_list_id, true,
6370					  ice_aqc_opc_update_sw_rules,
6371					  lkup_type);
6372	if (status)
6373		return status;
6374
6375	fm_list->vsi_count--;
6376	clear_bit(vsi_handle, fm_list->vsi_list_info->vsi_map);
6377	vsi_list_info = fm_list->vsi_list_info;
6378	if (fm_list->vsi_count == 1) {
6379		struct ice_fltr_info tmp_fltr;
6380		u16 rem_vsi_handle;
6381
6382		rem_vsi_handle = find_first_bit(vsi_list_info->vsi_map,
6383						ICE_MAX_VSI);
6384		if (!ice_is_vsi_valid(hw, rem_vsi_handle))
6385			return -EIO;
6386
6387		/* Make sure VSI list is empty before removing it below */
6388		status = ice_update_vsi_list_rule(hw, &rem_vsi_handle, 1,
6389						  vsi_list_id, true,
6390						  ice_aqc_opc_update_sw_rules,
6391						  lkup_type);
6392		if (status)
6393			return status;
6394
6395		memset(&tmp_fltr, 0, sizeof(tmp_fltr));
6396		tmp_fltr.flag = fm_list->rule_info.sw_act.flag;
6397		tmp_fltr.fltr_rule_id = fm_list->rule_info.fltr_rule_id;
6398		fm_list->rule_info.sw_act.fltr_act = ICE_FWD_TO_VSI;
6399		tmp_fltr.fltr_act = ICE_FWD_TO_VSI;
6400		tmp_fltr.fwd_id.hw_vsi_id =
6401			ice_get_hw_vsi_num(hw, rem_vsi_handle);
6402		fm_list->rule_info.sw_act.fwd_id.hw_vsi_id =
6403			ice_get_hw_vsi_num(hw, rem_vsi_handle);
6404		fm_list->rule_info.sw_act.vsi_handle = rem_vsi_handle;
6405
6406		/* Update the previous switch rule of "MAC forward to VSI" to
6407		 * "MAC fwd to VSI list"
6408		 */
6409		status = ice_update_pkt_fwd_rule(hw, &tmp_fltr);
6410		if (status) {
6411			ice_debug(hw, ICE_DBG_SW, "Failed to update pkt fwd rule to FWD_TO_VSI on HW VSI %d, error %d\n",
6412				  tmp_fltr.fwd_id.hw_vsi_id, status);
6413			return status;
6414		}
6415		fm_list->vsi_list_info->ref_cnt--;
6416
6417		/* Remove the VSI list since it is no longer used */
6418		status = ice_remove_vsi_list_rule(hw, vsi_list_id, lkup_type);
6419		if (status) {
6420			ice_debug(hw, ICE_DBG_SW, "Failed to remove VSI list %d, error %d\n",
6421				  vsi_list_id, status);
6422			return status;
6423		}
6424
6425		list_del(&vsi_list_info->list_entry);
6426		devm_kfree(ice_hw_to_dev(hw), vsi_list_info);
6427		fm_list->vsi_list_info = NULL;
6428	}
6429
6430	return status;
6431}
6432
6433/**
6434 * ice_rem_adv_rule - removes existing advanced switch rule
6435 * @hw: pointer to the hardware structure
6436 * @lkups: information on the words that needs to be looked up. All words
6437 *         together makes one recipe
6438 * @lkups_cnt: num of entries in the lkups array
6439 * @rinfo: Its the pointer to the rule information for the rule
6440 *
6441 * This function can be used to remove 1 rule at a time. The lkups is
6442 * used to describe all the words that forms the "lookup" portion of the
6443 * rule. These words can span multiple protocols. Callers to this function
6444 * need to pass in a list of protocol headers with lookup information along
6445 * and mask that determines which words are valid from the given protocol
6446 * header. rinfo describes other information related to this rule such as
6447 * forwarding IDs, priority of this rule, etc.
6448 */
6449static int
6450ice_rem_adv_rule(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups,
6451		 u16 lkups_cnt, struct ice_adv_rule_info *rinfo)
6452{
6453	struct ice_adv_fltr_mgmt_list_entry *list_elem;
6454	struct ice_prot_lkup_ext lkup_exts;
6455	bool remove_rule = false;
6456	struct mutex *rule_lock; /* Lock to protect filter rule list */
6457	u16 i, rid, vsi_handle;
6458	int status = 0;
6459
6460	memset(&lkup_exts, 0, sizeof(lkup_exts));
6461	for (i = 0; i < lkups_cnt; i++) {
6462		u16 count;
6463
6464		if (lkups[i].type >= ICE_PROTOCOL_LAST)
6465			return -EIO;
6466
6467		count = ice_fill_valid_words(&lkups[i], &lkup_exts);
6468		if (!count)
6469			return -EIO;
6470	}
6471
6472	rid = ice_find_recp(hw, &lkup_exts, rinfo, false);
6473	/* If did not find a recipe that match the existing criteria */
6474	if (rid == ICE_MAX_NUM_RECIPES)
6475		return -EINVAL;
6476
6477	rule_lock = &hw->switch_info->recp_list[rid].filt_rule_lock;
6478	list_elem = ice_find_adv_rule_entry(hw, lkups, lkups_cnt, rid, rinfo);
6479	/* the rule is already removed */
6480	if (!list_elem)
6481		return 0;
6482	mutex_lock(rule_lock);
6483	if (list_elem->rule_info.sw_act.fltr_act != ICE_FWD_TO_VSI_LIST) {
6484		remove_rule = true;
6485	} else if (list_elem->vsi_count > 1) {
6486		remove_rule = false;
6487		vsi_handle = rinfo->sw_act.vsi_handle;
6488		status = ice_adv_rem_update_vsi_list(hw, vsi_handle, list_elem);
6489	} else {
6490		vsi_handle = rinfo->sw_act.vsi_handle;
6491		status = ice_adv_rem_update_vsi_list(hw, vsi_handle, list_elem);
6492		if (status) {
6493			mutex_unlock(rule_lock);
6494			return status;
6495		}
6496		if (list_elem->vsi_count == 0)
6497			remove_rule = true;
6498	}
6499	mutex_unlock(rule_lock);
6500	if (remove_rule) {
6501		struct ice_sw_rule_lkup_rx_tx *s_rule;
6502		u16 rule_buf_sz;
6503
6504		rule_buf_sz = ICE_SW_RULE_RX_TX_NO_HDR_SIZE(s_rule);
6505		s_rule = kzalloc(rule_buf_sz, GFP_KERNEL);
6506		if (!s_rule)
6507			return -ENOMEM;
6508		s_rule->act = 0;
6509		s_rule->index = cpu_to_le16(list_elem->rule_info.fltr_rule_id);
6510		s_rule->hdr_len = 0;
6511		status = ice_aq_sw_rules(hw, (struct ice_aqc_sw_rules *)s_rule,
6512					 rule_buf_sz, 1,
6513					 ice_aqc_opc_remove_sw_rules, NULL);
6514		if (!status || status == -ENOENT) {
6515			struct ice_switch_info *sw = hw->switch_info;
6516			struct ice_sw_recipe *r_list = sw->recp_list;
6517
6518			mutex_lock(rule_lock);
6519			list_del(&list_elem->list_entry);
6520			devm_kfree(ice_hw_to_dev(hw), list_elem->lkups);
6521			devm_kfree(ice_hw_to_dev(hw), list_elem);
6522			mutex_unlock(rule_lock);
6523			if (list_empty(&r_list[rid].filt_rules)) {
6524				r_list[rid].adv_rule = false;
6525
6526				/* All rules for this recipe are now removed */
6527				if (hw->recp_reuse)
6528					ice_release_recipe_res(hw,
6529							       &r_list[rid]);
6530			}
6531		}
6532		kfree(s_rule);
6533	}
6534	return status;
6535}
6536
6537/**
6538 * ice_rem_adv_rule_by_id - removes existing advanced switch rule by ID
6539 * @hw: pointer to the hardware structure
6540 * @remove_entry: data struct which holds rule_id, VSI handle and recipe ID
6541 *
6542 * This function is used to remove 1 rule at a time. The removal is based on
6543 * the remove_entry parameter. This function will remove rule for a given
6544 * vsi_handle with a given rule_id which is passed as parameter in remove_entry
6545 */
6546int
6547ice_rem_adv_rule_by_id(struct ice_hw *hw,
6548		       struct ice_rule_query_data *remove_entry)
6549{
6550	struct ice_adv_fltr_mgmt_list_entry *list_itr;
6551	struct list_head *list_head;
6552	struct ice_adv_rule_info rinfo;
6553	struct ice_switch_info *sw;
6554
6555	sw = hw->switch_info;
6556	if (!sw->recp_list[remove_entry->rid].recp_created)
6557		return -EINVAL;
6558	list_head = &sw->recp_list[remove_entry->rid].filt_rules;
6559	list_for_each_entry(list_itr, list_head, list_entry) {
6560		if (list_itr->rule_info.fltr_rule_id ==
6561		    remove_entry->rule_id) {
6562			rinfo = list_itr->rule_info;
6563			rinfo.sw_act.vsi_handle = remove_entry->vsi_handle;
6564			return ice_rem_adv_rule(hw, list_itr->lkups,
6565						list_itr->lkups_cnt, &rinfo);
6566		}
6567	}
6568	/* either list is empty or unable to find rule */
6569	return -ENOENT;
6570}
6571
6572/**
6573 * ice_replay_vsi_adv_rule - Replay advanced rule for requested VSI
6574 * @hw: pointer to the hardware structure
6575 * @vsi_handle: driver VSI handle
6576 * @list_head: list for which filters need to be replayed
6577 *
6578 * Replay the advanced rule for the given VSI.
6579 */
6580static int
6581ice_replay_vsi_adv_rule(struct ice_hw *hw, u16 vsi_handle,
6582			struct list_head *list_head)
6583{
6584	struct ice_rule_query_data added_entry = { 0 };
6585	struct ice_adv_fltr_mgmt_list_entry *adv_fltr;
6586	int status = 0;
6587
6588	if (list_empty(list_head))
6589		return status;
6590	list_for_each_entry(adv_fltr, list_head, list_entry) {
6591		struct ice_adv_rule_info *rinfo = &adv_fltr->rule_info;
6592		u16 lk_cnt = adv_fltr->lkups_cnt;
6593
6594		if (vsi_handle != rinfo->sw_act.vsi_handle)
6595			continue;
6596		status = ice_add_adv_rule(hw, adv_fltr->lkups, lk_cnt, rinfo,
6597					  &added_entry);
6598		if (status)
6599			break;
6600	}
6601	return status;
6602}
6603
6604/**
6605 * ice_replay_vsi_all_fltr - replay all filters stored in bookkeeping lists
6606 * @hw: pointer to the hardware structure
6607 * @vsi_handle: driver VSI handle
6608 *
6609 * Replays filters for requested VSI via vsi_handle.
6610 */
6611int ice_replay_vsi_all_fltr(struct ice_hw *hw, u16 vsi_handle)
6612{
6613	struct ice_switch_info *sw = hw->switch_info;
6614	int status;
6615	u8 i;
6616
6617	for (i = 0; i < ICE_MAX_NUM_RECIPES; i++) {
6618		struct list_head *head;
6619
6620		head = &sw->recp_list[i].filt_replay_rules;
6621		if (!sw->recp_list[i].adv_rule)
6622			status = ice_replay_vsi_fltr(hw, vsi_handle, i, head);
6623		else
6624			status = ice_replay_vsi_adv_rule(hw, vsi_handle, head);
6625		if (status)
6626			return status;
6627	}
6628	return status;
6629}
6630
6631/**
6632 * ice_rm_all_sw_replay_rule_info - deletes filter replay rules
6633 * @hw: pointer to the HW struct
6634 *
6635 * Deletes the filter replay rules.
6636 */
6637void ice_rm_all_sw_replay_rule_info(struct ice_hw *hw)
6638{
6639	struct ice_switch_info *sw = hw->switch_info;
6640	u8 i;
6641
6642	if (!sw)
6643		return;
6644
6645	for (i = 0; i < ICE_MAX_NUM_RECIPES; i++) {
6646		if (!list_empty(&sw->recp_list[i].filt_replay_rules)) {
6647			struct list_head *l_head;
6648
6649			l_head = &sw->recp_list[i].filt_replay_rules;
6650			if (!sw->recp_list[i].adv_rule)
6651				ice_rem_sw_rule_info(hw, l_head);
6652			else
6653				ice_rem_adv_rule_info(hw, l_head);
6654		}
6655	}
6656}
~/ Read-only file preview.