// SPDX-License-Identifier: GPL-2.0
/* Copyright (c) 2018, Intel Corporation. */

#include "ice_lib.h"
#include "ice_switch.h"

#define ICE_ETH_DA_OFFSET		0
#define ICE_ETH_ETHTYPE_OFFSET		12
#define ICE_ETH_VLAN_TCI_OFFSET		14
#define ICE_MAX_VLAN_ID			0xFFF
#define ICE_IPV6_ETHER_ID		0x86DD

/* Dummy ethernet header needed in the ice_aqc_sw_rules_elem
 * struct to configure any switch filter rules.
 * {DA (6 bytes), SA(6 bytes),
 * Ether type (2 bytes for header without VLAN tag) OR
 * VLAN tag (4 bytes for header with VLAN tag) }
 *
 * Word on Hardcoded values
 * byte 0 = 0x2: to identify it as locally administered DA MAC
 * byte 6 = 0x2: to identify it as locally administered SA MAC
 * byte 12 = 0x81 & byte 13 = 0x00:
 *	In case of VLAN filter first two bytes defines ether type (0x8100)
 *	and remaining two bytes are placeholder for programming a given VLAN ID
 *	In case of Ether type filter it is treated as header without VLAN tag
 *	and byte 12 and 13 is used to program a given Ether type instead
 */
#define DUMMY_ETH_HDR_LEN		16
static const u8 dummy_eth_header[DUMMY_ETH_HDR_LEN] = { 0x2, 0, 0, 0, 0, 0,
							0x2, 0, 0, 0, 0, 0,
							0x81, 0, 0, 0};

struct ice_dummy_pkt_offsets {
	enum ice_protocol_type type;
	u16 offset; /* ICE_PROTOCOL_LAST indicates end of list */
};

static const struct ice_dummy_pkt_offsets dummy_gre_tcp_packet_offsets[] = {
	{ ICE_MAC_OFOS,		0 },
	{ ICE_ETYPE_OL,		12 },
	{ ICE_IPV4_OFOS,	14 },
	{ ICE_NVGRE,		34 },
	{ ICE_MAC_IL,		42 },
	{ ICE_IPV4_IL,		56 },
	{ ICE_TCP_IL,		76 },
	{ ICE_PROTOCOL_LAST,	0 },
};

static const u8 dummy_gre_tcp_packet[] = {
	0x00, 0x00, 0x00, 0x00,	/* ICE_MAC_OFOS 0 */
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,

	0x08, 0x00,		/* ICE_ETYPE_OL 12 */

	0x45, 0x00, 0x00, 0x3E,	/* ICE_IPV4_OFOS 14 */
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x2F, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,

	0x80, 0x00, 0x65, 0x58,	/* ICE_NVGRE 34 */
	0x00, 0x00, 0x00, 0x00,

	0x00, 0x00, 0x00, 0x00,	/* ICE_MAC_IL 42 */
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x08, 0x00,

	0x45, 0x00, 0x00, 0x14,	/* ICE_IPV4_IL 56 */
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x06, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,

	0x00, 0x00, 0x00, 0x00,	/* ICE_TCP_IL 76 */
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x50, 0x02, 0x20, 0x00,
	0x00, 0x00, 0x00, 0x00
};

static const struct ice_dummy_pkt_offsets dummy_gre_udp_packet_offsets[] = {
	{ ICE_MAC_OFOS,		0 },
	{ ICE_ETYPE_OL,		12 },
	{ ICE_IPV4_OFOS,	14 },
	{ ICE_NVGRE,		34 },
	{ ICE_MAC_IL,		42 },
	{ ICE_IPV4_IL,		56 },
	{ ICE_UDP_ILOS,		76 },
	{ ICE_PROTOCOL_LAST,	0 },
};

static const u8 dummy_gre_udp_packet[] = {
	0x00, 0x00, 0x00, 0x00,	/* ICE_MAC_OFOS 0 */
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,

	0x08, 0x00,		/* ICE_ETYPE_OL 12 */

	0x45, 0x00, 0x00, 0x3E,	/* ICE_IPV4_OFOS 14 */
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x2F, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,

	0x80, 0x00, 0x65, 0x58,	/* ICE_NVGRE 34 */
	0x00, 0x00, 0x00, 0x00,

	0x00, 0x00, 0x00, 0x00,	/* ICE_MAC_IL 42 */
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x08, 0x00,

	0x45, 0x00, 0x00, 0x14,	/* ICE_IPV4_IL 56 */
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x11, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,

	0x00, 0x00, 0x00, 0x00,	/* ICE_UDP_ILOS 76 */
	0x00, 0x08, 0x00, 0x00,
};

static const struct ice_dummy_pkt_offsets dummy_udp_tun_tcp_packet_offsets[] = {
	{ ICE_MAC_OFOS,		0 },
	{ ICE_ETYPE_OL,		12 },
	{ ICE_IPV4_OFOS,	14 },
	{ ICE_UDP_OF,		34 },
	{ ICE_VXLAN,		42 },
	{ ICE_GENEVE,		42 },
	{ ICE_VXLAN_GPE,	42 },
	{ ICE_MAC_IL,		50 },
	{ ICE_IPV4_IL,		64 },
	{ ICE_TCP_IL,		84 },
	{ ICE_PROTOCOL_LAST,	0 },
};

static const u8 dummy_udp_tun_tcp_packet[] = {
	0x00, 0x00, 0x00, 0x00,  /* ICE_MAC_OFOS 0 */
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,

	0x08, 0x00,		/* ICE_ETYPE_OL 12 */

	0x45, 0x00, 0x00, 0x5a, /* ICE_IPV4_OFOS 14 */
	0x00, 0x01, 0x00, 0x00,
	0x40, 0x11, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,

	0x00, 0x00, 0x12, 0xb5, /* ICE_UDP_OF 34 */
	0x00, 0x46, 0x00, 0x00,

	0x00, 0x00, 0x65, 0x58, /* ICE_VXLAN 42 */
	0x00, 0x00, 0x00, 0x00,

	0x00, 0x00, 0x00, 0x00, /* ICE_MAC_IL 50 */
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x08, 0x00,

	0x45, 0x00, 0x00, 0x28, /* ICE_IPV4_IL 64 */
	0x00, 0x01, 0x00, 0x00,
	0x40, 0x06, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,

	0x00, 0x00, 0x00, 0x00, /* ICE_TCP_IL 84 */
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x50, 0x02, 0x20, 0x00,
	0x00, 0x00, 0x00, 0x00
};

static const struct ice_dummy_pkt_offsets dummy_udp_tun_udp_packet_offsets[] = {
	{ ICE_MAC_OFOS,		0 },
	{ ICE_ETYPE_OL,		12 },
	{ ICE_IPV4_OFOS,	14 },
	{ ICE_UDP_OF,		34 },
	{ ICE_VXLAN,		42 },
	{ ICE_GENEVE,		42 },
	{ ICE_VXLAN_GPE,	42 },
	{ ICE_MAC_IL,		50 },
	{ ICE_IPV4_IL,		64 },
	{ ICE_UDP_ILOS,		84 },
	{ ICE_PROTOCOL_LAST,	0 },
};

static const u8 dummy_udp_tun_udp_packet[] = {
	0x00, 0x00, 0x00, 0x00,  /* ICE_MAC_OFOS 0 */
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,

	0x08, 0x00,		/* ICE_ETYPE_OL 12 */

	0x45, 0x00, 0x00, 0x4e, /* ICE_IPV4_OFOS 14 */
	0x00, 0x01, 0x00, 0x00,
	0x00, 0x11, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,

	0x00, 0x00, 0x12, 0xb5, /* ICE_UDP_OF 34 */
	0x00, 0x3a, 0x00, 0x00,

	0x00, 0x00, 0x65, 0x58, /* ICE_VXLAN 42 */
	0x00, 0x00, 0x00, 0x00,

	0x00, 0x00, 0x00, 0x00, /* ICE_MAC_IL 50 */
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x08, 0x00,

	0x45, 0x00, 0x00, 0x1c, /* ICE_IPV4_IL 64 */
	0x00, 0x01, 0x00, 0x00,
	0x00, 0x11, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,

	0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 84 */
	0x00, 0x08, 0x00, 0x00,
};

/* offset info for MAC + IPv4 + UDP dummy packet */
static const struct ice_dummy_pkt_offsets dummy_udp_packet_offsets[] = {
	{ ICE_MAC_OFOS,		0 },
	{ ICE_ETYPE_OL,		12 },
	{ ICE_IPV4_OFOS,	14 },
	{ ICE_UDP_ILOS,		34 },
	{ ICE_PROTOCOL_LAST,	0 },
};

/* Dummy packet for MAC + IPv4 + UDP */
static const u8 dummy_udp_packet[] = {
	0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,

	0x08, 0x00,		/* ICE_ETYPE_OL 12 */

	0x45, 0x00, 0x00, 0x1c, /* ICE_IPV4_OFOS 14 */
	0x00, 0x01, 0x00, 0x00,
	0x00, 0x11, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,

	0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 34 */
	0x00, 0x08, 0x00, 0x00,

	0x00, 0x00,	/* 2 bytes for 4 byte alignment */
};

/* offset info for MAC + VLAN + IPv4 + UDP dummy packet */
static const struct ice_dummy_pkt_offsets dummy_vlan_udp_packet_offsets[] = {
	{ ICE_MAC_OFOS,		0 },
	{ ICE_VLAN_OFOS,	12 },
	{ ICE_ETYPE_OL,		16 },
	{ ICE_IPV4_OFOS,	18 },
	{ ICE_UDP_ILOS,		38 },
	{ ICE_PROTOCOL_LAST,	0 },
};

/* C-tag (801.1Q), IPv4:UDP dummy packet */
static const u8 dummy_vlan_udp_packet[] = {
	0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,

	0x81, 0x00, 0x00, 0x00, /* ICE_VLAN_OFOS 12 */

	0x08, 0x00,		/* ICE_ETYPE_OL 16 */

	0x45, 0x00, 0x00, 0x1c, /* ICE_IPV4_OFOS 18 */
	0x00, 0x01, 0x00, 0x00,
	0x00, 0x11, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,

	0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 38 */
	0x00, 0x08, 0x00, 0x00,

	0x00, 0x00,	/* 2 bytes for 4 byte alignment */
};

/* offset info for MAC + IPv4 + TCP dummy packet */
static const struct ice_dummy_pkt_offsets dummy_tcp_packet_offsets[] = {
	{ ICE_MAC_OFOS,		0 },
	{ ICE_ETYPE_OL,		12 },
	{ ICE_IPV4_OFOS,	14 },
	{ ICE_TCP_IL,		34 },
	{ ICE_PROTOCOL_LAST,	0 },
};

/* Dummy packet for MAC + IPv4 + TCP */
static const u8 dummy_tcp_packet[] = {
	0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,

	0x08, 0x00,		/* ICE_ETYPE_OL 12 */

	0x45, 0x00, 0x00, 0x28, /* ICE_IPV4_OFOS 14 */
	0x00, 0x01, 0x00, 0x00,
	0x00, 0x06, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,

	0x00, 0x00, 0x00, 0x00, /* ICE_TCP_IL 34 */
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x50, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,

	0x00, 0x00,	/* 2 bytes for 4 byte alignment */
};

/* offset info for MAC + VLAN (C-tag, 802.1Q) + IPv4 + TCP dummy packet */
static const struct ice_dummy_pkt_offsets dummy_vlan_tcp_packet_offsets[] = {
	{ ICE_MAC_OFOS,		0 },
	{ ICE_VLAN_OFOS,	12 },
	{ ICE_ETYPE_OL,		16 },
	{ ICE_IPV4_OFOS,	18 },
	{ ICE_TCP_IL,		38 },
	{ ICE_PROTOCOL_LAST,	0 },
};

/* C-tag (801.1Q), IPv4:TCP dummy packet */
static const u8 dummy_vlan_tcp_packet[] = {
	0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,

	0x81, 0x00, 0x00, 0x00,	/* ICE_VLAN_OFOS 12 */

	0x08, 0x00,		/* ICE_ETYPE_OL 16 */

	0x45, 0x00, 0x00, 0x28, /* ICE_IPV4_OFOS 18 */
	0x00, 0x01, 0x00, 0x00,
	0x00, 0x06, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,

	0x00, 0x00, 0x00, 0x00, /* ICE_TCP_IL 38 */
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x50, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,

	0x00, 0x00,	/* 2 bytes for 4 byte alignment */
};

static const struct ice_dummy_pkt_offsets dummy_tcp_ipv6_packet_offsets[] = {
	{ ICE_MAC_OFOS,		0 },
	{ ICE_ETYPE_OL,		12 },
	{ ICE_IPV6_OFOS,	14 },
	{ ICE_TCP_IL,		54 },
	{ ICE_PROTOCOL_LAST,	0 },
};

static const u8 dummy_tcp_ipv6_packet[] = {
	0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,

	0x86, 0xDD,		/* ICE_ETYPE_OL 12 */

	0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 40 */
	0x00, 0x14, 0x06, 0x00, /* Next header is TCP */
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,

	0x00, 0x00, 0x00, 0x00, /* ICE_TCP_IL 54 */
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x50, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,

	0x00, 0x00, /* 2 bytes for 4 byte alignment */
};

/* C-tag (802.1Q): IPv6 + TCP */
static const struct ice_dummy_pkt_offsets
dummy_vlan_tcp_ipv6_packet_offsets[] = {
	{ ICE_MAC_OFOS,		0 },
	{ ICE_VLAN_OFOS,	12 },
	{ ICE_ETYPE_OL,		16 },
	{ ICE_IPV6_OFOS,	18 },
	{ ICE_TCP_IL,		58 },
	{ ICE_PROTOCOL_LAST,	0 },
};

/* C-tag (802.1Q), IPv6 + TCP dummy packet */
static const u8 dummy_vlan_tcp_ipv6_packet[] = {
	0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,

	0x81, 0x00, 0x00, 0x00,	/* ICE_VLAN_OFOS 12 */

	0x86, 0xDD,		/* ICE_ETYPE_OL 16 */

	0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 18 */
	0x00, 0x14, 0x06, 0x00, /* Next header is TCP */
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,

	0x00, 0x00, 0x00, 0x00, /* ICE_TCP_IL 58 */
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x50, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,

	0x00, 0x00, /* 2 bytes for 4 byte alignment */
};

/* IPv6 + UDP */
static const struct ice_dummy_pkt_offsets dummy_udp_ipv6_packet_offsets[] = {
	{ ICE_MAC_OFOS,		0 },
	{ ICE_ETYPE_OL,		12 },
	{ ICE_IPV6_OFOS,	14 },
	{ ICE_UDP_ILOS,		54 },
	{ ICE_PROTOCOL_LAST,	0 },
};

/* IPv6 + UDP dummy packet */
static const u8 dummy_udp_ipv6_packet[] = {
	0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,

	0x86, 0xDD,		/* ICE_ETYPE_OL 12 */

	0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 40 */
	0x00, 0x10, 0x11, 0x00, /* Next header UDP */
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,

	0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 54 */
	0x00, 0x10, 0x00, 0x00,

	0x00, 0x00, 0x00, 0x00, /* needed for ESP packets */
	0x00, 0x00, 0x00, 0x00,

	0x00, 0x00, /* 2 bytes for 4 byte alignment */
};

/* C-tag (802.1Q): IPv6 + UDP */
static const struct ice_dummy_pkt_offsets
dummy_vlan_udp_ipv6_packet_offsets[] = {
	{ ICE_MAC_OFOS,		0 },
	{ ICE_VLAN_OFOS,	12 },
	{ ICE_ETYPE_OL,		16 },
	{ ICE_IPV6_OFOS,	18 },
	{ ICE_UDP_ILOS,		58 },
	{ ICE_PROTOCOL_LAST,	0 },
};

/* C-tag (802.1Q), IPv6 + UDP dummy packet */
static const u8 dummy_vlan_udp_ipv6_packet[] = {
	0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,

	0x81, 0x00, 0x00, 0x00,/* ICE_VLAN_OFOS 12 */

	0x86, 0xDD,		/* ICE_ETYPE_OL 16 */

	0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 18 */
	0x00, 0x08, 0x11, 0x00, /* Next header UDP */
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,

	0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 58 */
	0x00, 0x08, 0x00, 0x00,

	0x00, 0x00, /* 2 bytes for 4 byte alignment */
};

#define ICE_SW_RULE_RX_TX_ETH_HDR_SIZE \
	(offsetof(struct ice_aqc_sw_rules_elem, pdata.lkup_tx_rx.hdr) + \
	 (DUMMY_ETH_HDR_LEN * \
	  sizeof(((struct ice_sw_rule_lkup_rx_tx *)0)->hdr[0])))
#define ICE_SW_RULE_RX_TX_NO_HDR_SIZE \
	(offsetof(struct ice_aqc_sw_rules_elem, pdata.lkup_tx_rx.hdr))
#define ICE_SW_RULE_LG_ACT_SIZE(n) \
	(offsetof(struct ice_aqc_sw_rules_elem, pdata.lg_act.act) + \
	 ((n) * sizeof(((struct ice_sw_rule_lg_act *)0)->act[0])))
#define ICE_SW_RULE_VSI_LIST_SIZE(n) \
	(offsetof(struct ice_aqc_sw_rules_elem, pdata.vsi_list.vsi) + \
	 ((n) * sizeof(((struct ice_sw_rule_vsi_list *)0)->vsi[0])))

/* this is a recipe to profile association bitmap */
static DECLARE_BITMAP(recipe_to_profile[ICE_MAX_NUM_RECIPES],
			  ICE_MAX_NUM_PROFILES);

/* this is a profile to recipe association bitmap */
static DECLARE_BITMAP(profile_to_recipe[ICE_MAX_NUM_PROFILES],
			  ICE_MAX_NUM_RECIPES);

/**
 * ice_init_def_sw_recp - initialize the recipe book keeping tables
 * @hw: pointer to the HW struct
 *
 * Allocate memory for the entire recipe table and initialize the structures/
 * entries corresponding to basic recipes.
 */
enum ice_status ice_init_def_sw_recp(struct ice_hw *hw)
{
	struct ice_sw_recipe *recps;
	u8 i;

	recps = devm_kcalloc(ice_hw_to_dev(hw), ICE_MAX_NUM_RECIPES,
			     sizeof(*recps), GFP_KERNEL);
	if (!recps)
		return ICE_ERR_NO_MEMORY;

	for (i = 0; i < ICE_MAX_NUM_RECIPES; i++) {
		recps[i].root_rid = i;
		INIT_LIST_HEAD(&recps[i].filt_rules);
		INIT_LIST_HEAD(&recps[i].filt_replay_rules);
		INIT_LIST_HEAD(&recps[i].rg_list);
		mutex_init(&recps[i].filt_rule_lock);
	}

	hw->switch_info->recp_list = recps;

	return 0;
}

/**
 * ice_aq_get_sw_cfg - get switch configuration
 * @hw: pointer to the hardware structure
 * @buf: pointer to the result buffer
 * @buf_size: length of the buffer available for response
 * @req_desc: pointer to requested descriptor
 * @num_elems: pointer to number of elements
 * @cd: pointer to command details structure or NULL
 *
 * Get switch configuration (0x0200) to be placed in buf.
 * This admin command returns information such as initial VSI/port number
 * and switch ID it belongs to.
 *
 * NOTE: *req_desc is both an input/output parameter.
 * The caller of this function first calls this function with *request_desc set
 * to 0. If the response from f/w has *req_desc set to 0, all the switch
 * configuration information has been returned; if non-zero (meaning not all
 * the information was returned), the caller should call this function again
 * with *req_desc set to the previous value returned by f/w to get the
 * next block of switch configuration information.
 *
 * *num_elems is output only parameter. This reflects the number of elements
 * in response buffer. The caller of this function to use *num_elems while
 * parsing the response buffer.
 */
static enum ice_status
ice_aq_get_sw_cfg(struct ice_hw *hw, struct ice_aqc_get_sw_cfg_resp_elem *buf,
		  u16 buf_size, u16 *req_desc, u16 *num_elems,
		  struct ice_sq_cd *cd)
{
	struct ice_aqc_get_sw_cfg *cmd;
	struct ice_aq_desc desc;
	enum ice_status status;

	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_sw_cfg);
	cmd = &desc.params.get_sw_conf;
	cmd->element = cpu_to_le16(*req_desc);

	status = ice_aq_send_cmd(hw, &desc, buf, buf_size, cd);
	if (!status) {
		*req_desc = le16_to_cpu(cmd->element);
		*num_elems = le16_to_cpu(cmd->num_elems);
	}

	return status;
}

/**
 * ice_aq_add_vsi
 * @hw: pointer to the HW struct
 * @vsi_ctx: pointer to a VSI context struct
 * @cd: pointer to command details structure or NULL
 *
 * Add a VSI context to the hardware (0x0210)
 */
static enum ice_status
ice_aq_add_vsi(struct ice_hw *hw, struct ice_vsi_ctx *vsi_ctx,
	       struct ice_sq_cd *cd)
{
	struct ice_aqc_add_update_free_vsi_resp *res;
	struct ice_aqc_add_get_update_free_vsi *cmd;
	struct ice_aq_desc desc;
	enum ice_status status;

	cmd = &desc.params.vsi_cmd;
	res = &desc.params.add_update_free_vsi_res;

	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_add_vsi);

	if (!vsi_ctx->alloc_from_pool)
		cmd->vsi_num = cpu_to_le16(vsi_ctx->vsi_num |
					   ICE_AQ_VSI_IS_VALID);
	cmd->vf_id = vsi_ctx->vf_num;

	cmd->vsi_flags = cpu_to_le16(vsi_ctx->flags);

	desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD);

	status = ice_aq_send_cmd(hw, &desc, &vsi_ctx->info,
				 sizeof(vsi_ctx->info), cd);

	if (!status) {
		vsi_ctx->vsi_num = le16_to_cpu(res->vsi_num) & ICE_AQ_VSI_NUM_M;
		vsi_ctx->vsis_allocd = le16_to_cpu(res->vsi_used);
		vsi_ctx->vsis_unallocated = le16_to_cpu(res->vsi_free);
	}

	return status;
}

/**
 * ice_aq_free_vsi
 * @hw: pointer to the HW struct
 * @vsi_ctx: pointer to a VSI context struct
 * @keep_vsi_alloc: keep VSI allocation as part of this PF's resources
 * @cd: pointer to command details structure or NULL
 *
 * Free VSI context info from hardware (0x0213)
 */
static enum ice_status
ice_aq_free_vsi(struct ice_hw *hw, struct ice_vsi_ctx *vsi_ctx,
		bool keep_vsi_alloc, struct ice_sq_cd *cd)
{
	struct ice_aqc_add_update_free_vsi_resp *resp;
	struct ice_aqc_add_get_update_free_vsi *cmd;
	struct ice_aq_desc desc;
	enum ice_status status;

	cmd = &desc.params.vsi_cmd;
	resp = &desc.params.add_update_free_vsi_res;

	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_free_vsi);

	cmd->vsi_num = cpu_to_le16(vsi_ctx->vsi_num | ICE_AQ_VSI_IS_VALID);
	if (keep_vsi_alloc)
		cmd->cmd_flags = cpu_to_le16(ICE_AQ_VSI_KEEP_ALLOC);

	status = ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
	if (!status) {
		vsi_ctx->vsis_allocd = le16_to_cpu(resp->vsi_used);
		vsi_ctx->vsis_unallocated = le16_to_cpu(resp->vsi_free);
	}

	return status;
}

/**
 * ice_aq_update_vsi
 * @hw: pointer to the HW struct
 * @vsi_ctx: pointer to a VSI context struct
 * @cd: pointer to command details structure or NULL
 *
 * Update VSI context in the hardware (0x0211)
 */
static enum ice_status
ice_aq_update_vsi(struct ice_hw *hw, struct ice_vsi_ctx *vsi_ctx,
		  struct ice_sq_cd *cd)
{
	struct ice_aqc_add_update_free_vsi_resp *resp;
	struct ice_aqc_add_get_update_free_vsi *cmd;
	struct ice_aq_desc desc;
	enum ice_status status;

	cmd = &desc.params.vsi_cmd;
	resp = &desc.params.add_update_free_vsi_res;

	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_update_vsi);

	cmd->vsi_num = cpu_to_le16(vsi_ctx->vsi_num | ICE_AQ_VSI_IS_VALID);

	desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD);

	status = ice_aq_send_cmd(hw, &desc, &vsi_ctx->info,
				 sizeof(vsi_ctx->info), cd);

	if (!status) {
		vsi_ctx->vsis_allocd = le16_to_cpu(resp->vsi_used);
		vsi_ctx->vsis_unallocated = le16_to_cpu(resp->vsi_free);
	}

	return status;
}

/**
 * ice_is_vsi_valid - check whether the VSI is valid or not
 * @hw: pointer to the HW struct
 * @vsi_handle: VSI handle
 *
 * check whether the VSI is valid or not
 */
bool ice_is_vsi_valid(struct ice_hw *hw, u16 vsi_handle)
{
	return vsi_handle < ICE_MAX_VSI && hw->vsi_ctx[vsi_handle];
}

/**
 * ice_get_hw_vsi_num - return the HW VSI number
 * @hw: pointer to the HW struct
 * @vsi_handle: VSI handle
 *
 * return the HW VSI number
 * Caution: call this function only if VSI is valid (ice_is_vsi_valid)
 */
u16 ice_get_hw_vsi_num(struct ice_hw *hw, u16 vsi_handle)
{
	return hw->vsi_ctx[vsi_handle]->vsi_num;
}

/**
 * ice_get_vsi_ctx - return the VSI context entry for a given VSI handle
 * @hw: pointer to the HW struct
 * @vsi_handle: VSI handle
 *
 * return the VSI context entry for a given VSI handle
 */
struct ice_vsi_ctx *ice_get_vsi_ctx(struct ice_hw *hw, u16 vsi_handle)
{
	return (vsi_handle >= ICE_MAX_VSI) ? NULL : hw->vsi_ctx[vsi_handle];
}

/**
 * ice_save_vsi_ctx - save the VSI context for a given VSI handle
 * @hw: pointer to the HW struct
 * @vsi_handle: VSI handle
 * @vsi: VSI context pointer
 *
 * save the VSI context entry for a given VSI handle
 */
static void
ice_save_vsi_ctx(struct ice_hw *hw, u16 vsi_handle, struct ice_vsi_ctx *vsi)
{
	hw->vsi_ctx[vsi_handle] = vsi;
}

/**
 * ice_clear_vsi_q_ctx - clear VSI queue contexts for all TCs
 * @hw: pointer to the HW struct
 * @vsi_handle: VSI handle
 */
static void ice_clear_vsi_q_ctx(struct ice_hw *hw, u16 vsi_handle)
{
	struct ice_vsi_ctx *vsi;
	u8 i;

	vsi = ice_get_vsi_ctx(hw, vsi_handle);
	if (!vsi)
		return;
	ice_for_each_traffic_class(i) {
		if (vsi->lan_q_ctx[i]) {
			devm_kfree(ice_hw_to_dev(hw), vsi->lan_q_ctx[i]);
			vsi->lan_q_ctx[i] = NULL;
		}
		if (vsi->rdma_q_ctx[i]) {
			devm_kfree(ice_hw_to_dev(hw), vsi->rdma_q_ctx[i]);
			vsi->rdma_q_ctx[i] = NULL;
		}
	}
}

/**
 * ice_clear_vsi_ctx - clear the VSI context entry
 * @hw: pointer to the HW struct
 * @vsi_handle: VSI handle
 *
 * clear the VSI context entry
 */
static void ice_clear_vsi_ctx(struct ice_hw *hw, u16 vsi_handle)
{
	struct ice_vsi_ctx *vsi;

	vsi = ice_get_vsi_ctx(hw, vsi_handle);
	if (vsi) {
		ice_clear_vsi_q_ctx(hw, vsi_handle);
		devm_kfree(ice_hw_to_dev(hw), vsi);
		hw->vsi_ctx[vsi_handle] = NULL;
	}
}

/**
 * ice_clear_all_vsi_ctx - clear all the VSI context entries
 * @hw: pointer to the HW struct
 */
void ice_clear_all_vsi_ctx(struct ice_hw *hw)
{
	u16 i;

	for (i = 0; i < ICE_MAX_VSI; i++)
		ice_clear_vsi_ctx(hw, i);
}

/**
 * ice_add_vsi - add VSI context to the hardware and VSI handle list
 * @hw: pointer to the HW struct
 * @vsi_handle: unique VSI handle provided by drivers
 * @vsi_ctx: pointer to a VSI context struct
 * @cd: pointer to command details structure or NULL
 *
 * Add a VSI context to the hardware also add it into the VSI handle list.
 * If this function gets called after reset for existing VSIs then update
 * with the new HW VSI number in the corresponding VSI handle list entry.
 */
enum ice_status
ice_add_vsi(struct ice_hw *hw, u16 vsi_handle, struct ice_vsi_ctx *vsi_ctx,
	    struct ice_sq_cd *cd)
{
	struct ice_vsi_ctx *tmp_vsi_ctx;
	enum ice_status status;

	if (vsi_handle >= ICE_MAX_VSI)
		return ICE_ERR_PARAM;
	status = ice_aq_add_vsi(hw, vsi_ctx, cd);
	if (status)
		return status;
	tmp_vsi_ctx = ice_get_vsi_ctx(hw, vsi_handle);
	if (!tmp_vsi_ctx) {
		/* Create a new VSI context */
		tmp_vsi_ctx = devm_kzalloc(ice_hw_to_dev(hw),
					   sizeof(*tmp_vsi_ctx), GFP_KERNEL);
		if (!tmp_vsi_ctx) {
			ice_aq_free_vsi(hw, vsi_ctx, false, cd);
			return ICE_ERR_NO_MEMORY;
		}
		*tmp_vsi_ctx = *vsi_ctx;
		ice_save_vsi_ctx(hw, vsi_handle, tmp_vsi_ctx);
	} else {
		/* update with new HW VSI num */
		tmp_vsi_ctx->vsi_num = vsi_ctx->vsi_num;
	}

	return 0;
}

/**
 * ice_free_vsi- free VSI context from hardware and VSI handle list
 * @hw: pointer to the HW struct
 * @vsi_handle: unique VSI handle
 * @vsi_ctx: pointer to a VSI context struct
 * @keep_vsi_alloc: keep VSI allocation as part of this PF's resources
 * @cd: pointer to command details structure or NULL
 *
 * Free VSI context info from hardware as well as from VSI handle list
 */
enum ice_status
ice_free_vsi(struct ice_hw *hw, u16 vsi_handle, struct ice_vsi_ctx *vsi_ctx,
	     bool keep_vsi_alloc, struct ice_sq_cd *cd)
{
	enum ice_status status;

	if (!ice_is_vsi_valid(hw, vsi_handle))
		return ICE_ERR_PARAM;
	vsi_ctx->vsi_num = ice_get_hw_vsi_num(hw, vsi_handle);
	status = ice_aq_free_vsi(hw, vsi_ctx, keep_vsi_alloc, cd);
	if (!status)
		ice_clear_vsi_ctx(hw, vsi_handle);
	return status;
}

/**
 * ice_update_vsi
 * @hw: pointer to the HW struct
 * @vsi_handle: unique VSI handle
 * @vsi_ctx: pointer to a VSI context struct
 * @cd: pointer to command details structure or NULL
 *
 * Update VSI context in the hardware
 */
enum ice_status
ice_update_vsi(struct ice_hw *hw, u16 vsi_handle, struct ice_vsi_ctx *vsi_ctx,
	       struct ice_sq_cd *cd)
{
	if (!ice_is_vsi_valid(hw, vsi_handle))
		return ICE_ERR_PARAM;
	vsi_ctx->vsi_num = ice_get_hw_vsi_num(hw, vsi_handle);
	return ice_aq_update_vsi(hw, vsi_ctx, cd);
}

/**
 * ice_cfg_rdma_fltr - enable/disable RDMA filtering on VSI
 * @hw: pointer to HW struct
 * @vsi_handle: VSI SW index
 * @enable: boolean for enable/disable
 */
int
ice_cfg_rdma_fltr(struct ice_hw *hw, u16 vsi_handle, bool enable)
{
	struct ice_vsi_ctx *ctx;

	ctx = ice_get_vsi_ctx(hw, vsi_handle);
	if (!ctx)
		return -EIO;

	if (enable)
		ctx->info.q_opt_flags |= ICE_AQ_VSI_Q_OPT_PE_FLTR_EN;
	else
		ctx->info.q_opt_flags &= ~ICE_AQ_VSI_Q_OPT_PE_FLTR_EN;

	return ice_status_to_errno(ice_update_vsi(hw, vsi_handle, ctx, NULL));
}

/**
 * ice_aq_alloc_free_vsi_list
 * @hw: pointer to the HW struct
 * @vsi_list_id: VSI list ID returned or used for lookup
 * @lkup_type: switch rule filter lookup type
 * @opc: switch rules population command type - pass in the command opcode
 *
 * allocates or free a VSI list resource
 */
static enum ice_status
ice_aq_alloc_free_vsi_list(struct ice_hw *hw, u16 *vsi_list_id,
			   enum ice_sw_lkup_type lkup_type,
			   enum ice_adminq_opc opc)
{
	struct ice_aqc_alloc_free_res_elem *sw_buf;
	struct ice_aqc_res_elem *vsi_ele;
	enum ice_status status;
	u16 buf_len;

	buf_len = struct_size(sw_buf, elem, 1);
	sw_buf = devm_kzalloc(ice_hw_to_dev(hw), buf_len, GFP_KERNEL);
	if (!sw_buf)
		return ICE_ERR_NO_MEMORY;
	sw_buf->num_elems = cpu_to_le16(1);

	if (lkup_type == ICE_SW_LKUP_MAC ||
	    lkup_type == ICE_SW_LKUP_MAC_VLAN ||
	    lkup_type == ICE_SW_LKUP_ETHERTYPE ||
	    lkup_type == ICE_SW_LKUP_ETHERTYPE_MAC ||
	    lkup_type == ICE_SW_LKUP_PROMISC ||
	    lkup_type == ICE_SW_LKUP_PROMISC_VLAN) {
		sw_buf->res_type = cpu_to_le16(ICE_AQC_RES_TYPE_VSI_LIST_REP);
	} else if (lkup_type == ICE_SW_LKUP_VLAN) {
		sw_buf->res_type =
			cpu_to_le16(ICE_AQC_RES_TYPE_VSI_LIST_PRUNE);
	} else {
		status = ICE_ERR_PARAM;
		goto ice_aq_alloc_free_vsi_list_exit;
	}

	if (opc == ice_aqc_opc_free_res)
		sw_buf->elem[0].e.sw_resp = cpu_to_le16(*vsi_list_id);

	status = ice_aq_alloc_free_res(hw, 1, sw_buf, buf_len, opc, NULL);
	if (status)
		goto ice_aq_alloc_free_vsi_list_exit;

	if (opc == ice_aqc_opc_alloc_res) {
		vsi_ele = &sw_buf->elem[0];
		*vsi_list_id = le16_to_cpu(vsi_ele->e.sw_resp);
	}

ice_aq_alloc_free_vsi_list_exit:
	devm_kfree(ice_hw_to_dev(hw), sw_buf);
	return status;
}

/**
 * ice_aq_sw_rules - add/update/remove switch rules
 * @hw: pointer to the HW struct
 * @rule_list: pointer to switch rule population list
 * @rule_list_sz: total size of the rule list in bytes
 * @num_rules: number of switch rules in the rule_list
 * @opc: switch rules population command type - pass in the command opcode
 * @cd: pointer to command details structure or NULL
 *
 * Add(0x02a0)/Update(0x02a1)/Remove(0x02a2) switch rules commands to firmware
 */
enum ice_status
ice_aq_sw_rules(struct ice_hw *hw, void *rule_list, u16 rule_list_sz,
		u8 num_rules, enum ice_adminq_opc opc, struct ice_sq_cd *cd)
{
	struct ice_aq_desc desc;
	enum ice_status status;

	if (opc != ice_aqc_opc_add_sw_rules &&
	    opc != ice_aqc_opc_update_sw_rules &&
	    opc != ice_aqc_opc_remove_sw_rules)
		return ICE_ERR_PARAM;

	ice_fill_dflt_direct_cmd_desc(&desc, opc);

	desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD);
	desc.params.sw_rules.num_rules_fltr_entry_index =
		cpu_to_le16(num_rules);
	status = ice_aq_send_cmd(hw, &desc, rule_list, rule_list_sz, cd);
	if (opc != ice_aqc_opc_add_sw_rules &&
	    hw->adminq.sq_last_status == ICE_AQ_RC_ENOENT)
		status = ICE_ERR_DOES_NOT_EXIST;

	return status;
}

/**
 * ice_aq_add_recipe - add switch recipe
 * @hw: pointer to the HW struct
 * @s_recipe_list: pointer to switch rule population list
 * @num_recipes: number of switch recipes in the list
 * @cd: pointer to command details structure or NULL
 *
 * Add(0x0290)
 */
static enum ice_status
ice_aq_add_recipe(struct ice_hw *hw,
		  struct ice_aqc_recipe_data_elem *s_recipe_list,
		  u16 num_recipes, struct ice_sq_cd *cd)
{
	struct ice_aqc_add_get_recipe *cmd;
	struct ice_aq_desc desc;
	u16 buf_size;

	cmd = &desc.params.add_get_recipe;
	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_add_recipe);

	cmd->num_sub_recipes = cpu_to_le16(num_recipes);
	desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD);

	buf_size = num_recipes * sizeof(*s_recipe_list);

	return ice_aq_send_cmd(hw, &desc, s_recipe_list, buf_size, cd);
}

/**
 * ice_aq_get_recipe - get switch recipe
 * @hw: pointer to the HW struct
 * @s_recipe_list: pointer to switch rule population list
 * @num_recipes: pointer to the number of recipes (input and output)
 * @recipe_root: root recipe number of recipe(s) to retrieve
 * @cd: pointer to command details structure or NULL
 *
 * Get(0x0292)
 *
 * On input, *num_recipes should equal the number of entries in s_recipe_list.
 * On output, *num_recipes will equal the number of entries returned in
 * s_recipe_list.
 *
 * The caller must supply enough space in s_recipe_list to hold all possible
 * recipes and *num_recipes must equal ICE_MAX_NUM_RECIPES.
 */
static enum ice_status
ice_aq_get_recipe(struct ice_hw *hw,
		  struct ice_aqc_recipe_data_elem *s_recipe_list,
		  u16 *num_recipes, u16 recipe_root, struct ice_sq_cd *cd)
{
	struct ice_aqc_add_get_recipe *cmd;
	struct ice_aq_desc desc;
	enum ice_status status;
	u16 buf_size;

	if (*num_recipes != ICE_MAX_NUM_RECIPES)
		return ICE_ERR_PARAM;

	cmd = &desc.params.add_get_recipe;
	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_recipe);

	cmd->return_index = cpu_to_le16(recipe_root);
	cmd->num_sub_recipes = 0;

	buf_size = *num_recipes * sizeof(*s_recipe_list);

	status = ice_aq_send_cmd(hw, &desc, s_recipe_list, buf_size, cd);
	*num_recipes = le16_to_cpu(cmd->num_sub_recipes);

	return status;
}

/**
 * ice_aq_map_recipe_to_profile - Map recipe to packet profile
 * @hw: pointer to the HW struct
 * @profile_id: package profile ID to associate the recipe with
 * @r_bitmap: Recipe bitmap filled in and need to be returned as response
 * @cd: pointer to command details structure or NULL
 * Recipe to profile association (0x0291)
 */
static enum ice_status
ice_aq_map_recipe_to_profile(struct ice_hw *hw, u32 profile_id, u8 *r_bitmap,
			     struct ice_sq_cd *cd)
{
	struct ice_aqc_recipe_to_profile *cmd;
	struct ice_aq_desc desc;

	cmd = &desc.params.recipe_to_profile;
	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_recipe_to_profile);
	cmd->profile_id = cpu_to_le16(profile_id);
	/* Set the recipe ID bit in the bitmask to let the device know which
	 * profile we are associating the recipe to
	 */
	memcpy(cmd->recipe_assoc, r_bitmap, sizeof(cmd->recipe_assoc));

	return ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
}

/**
 * ice_aq_get_recipe_to_profile - Map recipe to packet profile
 * @hw: pointer to the HW struct
 * @profile_id: package profile ID to associate the recipe with
 * @r_bitmap: Recipe bitmap filled in and need to be returned as response
 * @cd: pointer to command details structure or NULL
 * Associate profile ID with given recipe (0x0293)
 */
static enum ice_status
ice_aq_get_recipe_to_profile(struct ice_hw *hw, u32 profile_id, u8 *r_bitmap,
			     struct ice_sq_cd *cd)
{
	struct ice_aqc_recipe_to_profile *cmd;
	struct ice_aq_desc desc;
	enum ice_status status;

	cmd = &desc.params.recipe_to_profile;
	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_recipe_to_profile);
	cmd->profile_id = cpu_to_le16(profile_id);

	status = ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
	if (!status)
		memcpy(r_bitmap, cmd->recipe_assoc, sizeof(cmd->recipe_assoc));

	return status;
}

/**
 * ice_alloc_recipe - add recipe resource
 * @hw: pointer to the hardware structure
 * @rid: recipe ID returned as response to AQ call
 */
static enum ice_status ice_alloc_recipe(struct ice_hw *hw, u16 *rid)
{
	struct ice_aqc_alloc_free_res_elem *sw_buf;
	enum ice_status status;
	u16 buf_len;

	buf_len = struct_size(sw_buf, elem, 1);
	sw_buf = kzalloc(buf_len, GFP_KERNEL);
	if (!sw_buf)
		return ICE_ERR_NO_MEMORY;

	sw_buf->num_elems = cpu_to_le16(1);
	sw_buf->res_type = cpu_to_le16((ICE_AQC_RES_TYPE_RECIPE <<
					ICE_AQC_RES_TYPE_S) |
					ICE_AQC_RES_TYPE_FLAG_SHARED);
	status = ice_aq_alloc_free_res(hw, 1, sw_buf, buf_len,
				       ice_aqc_opc_alloc_res, NULL);
	if (!status)
		*rid = le16_to_cpu(sw_buf->elem[0].e.sw_resp);
	kfree(sw_buf);

	return status;
}

/**
 * ice_get_recp_to_prof_map - updates recipe to profile mapping
 * @hw: pointer to hardware structure
 *
 * This function is used to populate recipe_to_profile matrix where index to
 * this array is the recipe ID and the element is the mapping of which profiles
 * is this recipe mapped to.
 */
static void ice_get_recp_to_prof_map(struct ice_hw *hw)
{
	DECLARE_BITMAP(r_bitmap, ICE_MAX_NUM_RECIPES);
	u16 i;

	for (i = 0; i < hw->switch_info->max_used_prof_index + 1; i++) {
		u16 j;

		bitmap_zero(profile_to_recipe[i], ICE_MAX_NUM_RECIPES);
		bitmap_zero(r_bitmap, ICE_MAX_NUM_RECIPES);
		if (ice_aq_get_recipe_to_profile(hw, i, (u8 *)r_bitmap, NULL))
			continue;
		bitmap_copy(profile_to_recipe[i], r_bitmap,
			    ICE_MAX_NUM_RECIPES);
		for_each_set_bit(j, r_bitmap, ICE_MAX_NUM_RECIPES)
			set_bit(i, recipe_to_profile[j]);
	}
}

/**
 * ice_collect_result_idx - copy result index values
 * @buf: buffer that contains the result index
 * @recp: the recipe struct to copy data into
 */
static void
ice_collect_result_idx(struct ice_aqc_recipe_data_elem *buf,
		       struct ice_sw_recipe *recp)
{
	if (buf->content.result_indx & ICE_AQ_RECIPE_RESULT_EN)
		set_bit(buf->content.result_indx & ~ICE_AQ_RECIPE_RESULT_EN,
			recp->res_idxs);
}

/**
 * ice_get_recp_frm_fw - update SW bookkeeping from FW recipe entries
 * @hw: pointer to hardware structure
 * @recps: struct that we need to populate
 * @rid: recipe ID that we are populating
 * @refresh_required: true if we should get recipe to profile mapping from FW
 *
 * This function is used to populate all the necessary entries into our
 * bookkeeping so that we have a current list of all the recipes that are
 * programmed in the firmware.
 */
static enum ice_status
ice_get_recp_frm_fw(struct ice_hw *hw, struct ice_sw_recipe *recps, u8 rid,
		    bool *refresh_required)
{
	DECLARE_BITMAP(result_bm, ICE_MAX_FV_WORDS);
	struct ice_aqc_recipe_data_elem *tmp;
	u16 num_recps = ICE_MAX_NUM_RECIPES;
	struct ice_prot_lkup_ext *lkup_exts;
	enum ice_status status;
	u8 fv_word_idx = 0;
	u16 sub_recps;

	bitmap_zero(result_bm, ICE_MAX_FV_WORDS);

	/* we need a buffer big enough to accommodate all the recipes */
	tmp = kcalloc(ICE_MAX_NUM_RECIPES, sizeof(*tmp), GFP_KERNEL);
	if (!tmp)
		return ICE_ERR_NO_MEMORY;

	tmp[0].recipe_indx = rid;
	status = ice_aq_get_recipe(hw, tmp, &num_recps, rid, NULL);
	/* non-zero status meaning recipe doesn't exist */
	if (status)
		goto err_unroll;

	/* Get recipe to profile map so that we can get the fv from lkups that
	 * we read for a recipe from FW. Since we want to minimize the number of
	 * times we make this FW call, just make one call and cache the copy
	 * until a new recipe is added. This operation is only required the
	 * first time to get the changes from FW. Then to search existing
	 * entries we don't need to update the cache again until another recipe
	 * gets added.
	 */
	if (*refresh_required) {
		ice_get_recp_to_prof_map(hw);
		*refresh_required = false;
	}

	/* Start populating all the entries for recps[rid] based on lkups from
	 * firmware. Note that we are only creating the root recipe in our
	 * database.
	 */
	lkup_exts = &recps[rid].lkup_exts;

	for (sub_recps = 0; sub_recps < num_recps; sub_recps++) {
		struct ice_aqc_recipe_data_elem root_bufs = tmp[sub_recps];
		struct ice_recp_grp_entry *rg_entry;
		u8 i, prof, idx, prot = 0;
		bool is_root;
		u16 off = 0;

		rg_entry = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*rg_entry),
					GFP_KERNEL);
		if (!rg_entry) {
			status = ICE_ERR_NO_MEMORY;
			goto err_unroll;
		}

		idx = root_bufs.recipe_indx;
		is_root = root_bufs.content.rid & ICE_AQ_RECIPE_ID_IS_ROOT;

		/* Mark all result indices in this chain */
		if (root_bufs.content.result_indx & ICE_AQ_RECIPE_RESULT_EN)
			set_bit(root_bufs.content.result_indx & ~ICE_AQ_RECIPE_RESULT_EN,
				result_bm);

		/* get the first profile that is associated with rid */
		prof = find_first_bit(recipe_to_profile[idx],
				      ICE_MAX_NUM_PROFILES);
		for (i = 0; i < ICE_NUM_WORDS_RECIPE; i++) {
			u8 lkup_indx = root_bufs.content.lkup_indx[i + 1];

			rg_entry->fv_idx[i] = lkup_indx;
			rg_entry->fv_mask[i] =
				le16_to_cpu(root_bufs.content.mask[i + 1]);

			/* If the recipe is a chained recipe then all its
			 * child recipe's result will have a result index.
			 * To fill fv_words we should not use those result
			 * index, we only need the protocol ids and offsets.
			 * We will skip all the fv_idx which stores result
			 * index in them. We also need to skip any fv_idx which
			 * has ICE_AQ_RECIPE_LKUP_IGNORE or 0 since it isn't a
			 * valid offset value.
			 */
			if (test_bit(rg_entry->fv_idx[i], hw->switch_info->prof_res_bm[prof]) ||
			    rg_entry->fv_idx[i] & ICE_AQ_RECIPE_LKUP_IGNORE ||
			    rg_entry->fv_idx[i] == 0)
				continue;

			ice_find_prot_off(hw, ICE_BLK_SW, prof,
					  rg_entry->fv_idx[i], &prot, &off);
			lkup_exts->fv_words[fv_word_idx].prot_id = prot;
			lkup_exts->fv_words[fv_word_idx].off = off;
			lkup_exts->field_mask[fv_word_idx] =
				rg_entry->fv_mask[i];
			fv_word_idx++;
		}
		/* populate rg_list with the data from the child entry of this
		 * recipe
		 */
		list_add(&rg_entry->l_entry, &recps[rid].rg_list);

		/* Propagate some data to the recipe database */
		recps[idx].is_root = !!is_root;
		recps[idx].priority = root_bufs.content.act_ctrl_fwd_priority;
		bitmap_zero(recps[idx].res_idxs, ICE_MAX_FV_WORDS);
		if (root_bufs.content.result_indx & ICE_AQ_RECIPE_RESULT_EN) {
			recps[idx].chain_idx = root_bufs.content.result_indx &
				~ICE_AQ_RECIPE_RESULT_EN;
			set_bit(recps[idx].chain_idx, recps[idx].res_idxs);
		} else {
			recps[idx].chain_idx = ICE_INVAL_CHAIN_IND;
		}

		if (!is_root)
			continue;

		/* Only do the following for root recipes entries */
		memcpy(recps[idx].r_bitmap, root_bufs.recipe_bitmap,
		       sizeof(recps[idx].r_bitmap));
		recps[idx].root_rid = root_bufs.content.rid &
			~ICE_AQ_RECIPE_ID_IS_ROOT;
		recps[idx].priority = root_bufs.content.act_ctrl_fwd_priority;
	}

	/* Complete initialization of the root recipe entry */
	lkup_exts->n_val_words = fv_word_idx;
	recps[rid].big_recp = (num_recps > 1);
	recps[rid].n_grp_count = (u8)num_recps;
	recps[rid].root_buf = devm_kmemdup(ice_hw_to_dev(hw), tmp,
					   recps[rid].n_grp_count * sizeof(*recps[rid].root_buf),
					   GFP_KERNEL);
	if (!recps[rid].root_buf) {
		status = ICE_ERR_NO_MEMORY;
		goto err_unroll;
	}

	/* Copy result indexes */
	bitmap_copy(recps[rid].res_idxs, result_bm, ICE_MAX_FV_WORDS);
	recps[rid].recp_created = true;

err_unroll:
	kfree(tmp);
	return status;
}

/* ice_init_port_info - Initialize port_info with switch configuration data
 * @pi: pointer to port_info
 * @vsi_port_num: VSI number or port number
 * @type: Type of switch element (port or VSI)
 * @swid: switch ID of the switch the element is attached to
 * @pf_vf_num: PF or VF number
 * @is_vf: true if the element is a VF, false otherwise
 */
static void
ice_init_port_info(struct ice_port_info *pi, u16 vsi_port_num, u8 type,
		   u16 swid, u16 pf_vf_num, bool is_vf)
{
	switch (type) {
	case ICE_AQC_GET_SW_CONF_RESP_PHYS_PORT:
		pi->lport = (u8)(vsi_port_num & ICE_LPORT_MASK);
		pi->sw_id = swid;
		pi->pf_vf_num = pf_vf_num;
		pi->is_vf = is_vf;
		pi->dflt_tx_vsi_num = ICE_DFLT_VSI_INVAL;
		pi->dflt_rx_vsi_num = ICE_DFLT_VSI_INVAL;
		break;
	default:
		ice_debug(pi->hw, ICE_DBG_SW, "incorrect VSI/port type received\n");
		break;
	}
}

/* ice_get_initial_sw_cfg - Get initial port and default VSI data
 * @hw: pointer to the hardware structure
 */
enum ice_status ice_get_initial_sw_cfg(struct ice_hw *hw)
{
	struct ice_aqc_get_sw_cfg_resp_elem *rbuf;
	enum ice_status status;
	u16 req_desc = 0;
	u16 num_elems;
	u16 i;

	rbuf = devm_kzalloc(ice_hw_to_dev(hw), ICE_SW_CFG_MAX_BUF_LEN,
			    GFP_KERNEL);

	if (!rbuf)
		return ICE_ERR_NO_MEMORY;

	/* Multiple calls to ice_aq_get_sw_cfg may be required
	 * to get all the switch configuration information. The need
	 * for additional calls is indicated by ice_aq_get_sw_cfg
	 * writing a non-zero value in req_desc
	 */
	do {
		struct ice_aqc_get_sw_cfg_resp_elem *ele;

		status = ice_aq_get_sw_cfg(hw, rbuf, ICE_SW_CFG_MAX_BUF_LEN,
					   &req_desc, &num_elems, NULL);

		if (status)
			break;

		for (i = 0, ele = rbuf; i < num_elems; i++, ele++) {
			u16 pf_vf_num, swid, vsi_port_num;
			bool is_vf = false;
			u8 res_type;

			vsi_port_num = le16_to_cpu(ele->vsi_port_num) &
				ICE_AQC_GET_SW_CONF_RESP_VSI_PORT_NUM_M;

			pf_vf_num = le16_to_cpu(ele->pf_vf_num) &
				ICE_AQC_GET_SW_CONF_RESP_FUNC_NUM_M;

			swid = le16_to_cpu(ele->swid);

			if (le16_to_cpu(ele->pf_vf_num) &
			    ICE_AQC_GET_SW_CONF_RESP_IS_VF)
				is_vf = true;

			res_type = (u8)(le16_to_cpu(ele->vsi_port_num) >>
					ICE_AQC_GET_SW_CONF_RESP_TYPE_S);

			if (res_type == ICE_AQC_GET_SW_CONF_RESP_VSI) {
				/* FW VSI is not needed. Just continue. */
				continue;
			}

			ice_init_port_info(hw->port_info, vsi_port_num,
					   res_type, swid, pf_vf_num, is_vf);
		}
	} while (req_desc && !status);

	devm_kfree(ice_hw_to_dev(hw), rbuf);
	return status;
}

/**
 * ice_fill_sw_info - Helper function to populate lb_en and lan_en
 * @hw: pointer to the hardware structure
 * @fi: filter info structure to fill/update
 *
 * This helper function populates the lb_en and lan_en elements of the provided
 * ice_fltr_info struct using the switch's type and characteristics of the
 * switch rule being configured.
 */
static void ice_fill_sw_info(struct ice_hw *hw, struct ice_fltr_info *fi)
{
	fi->lb_en = false;
	fi->lan_en = false;
	if ((fi->flag & ICE_FLTR_TX) &&
	    (fi->fltr_act == ICE_FWD_TO_VSI ||
	     fi->fltr_act == ICE_FWD_TO_VSI_LIST ||
	     fi->fltr_act == ICE_FWD_TO_Q ||
	     fi->fltr_act == ICE_FWD_TO_QGRP)) {
		/* Setting LB for prune actions will result in replicated
		 * packets to the internal switch that will be dropped.
		 */
		if (fi->lkup_type != ICE_SW_LKUP_VLAN)
			fi->lb_en = true;

		/* Set lan_en to TRUE if
		 * 1. The switch is a VEB AND
		 * 2
		 * 2.1 The lookup is a directional lookup like ethertype,
		 * promiscuous, ethertype-MAC, promiscuous-VLAN
		 * and default-port OR
		 * 2.2 The lookup is VLAN, OR
		 * 2.3 The lookup is MAC with mcast or bcast addr for MAC, OR
		 * 2.4 The lookup is MAC_VLAN with mcast or bcast addr for MAC.
		 *
		 * OR
		 *
		 * The switch is a VEPA.
		 *
		 * In all other cases, the LAN enable has to be set to false.
		 */
		if (hw->evb_veb) {
			if (fi->lkup_type == ICE_SW_LKUP_ETHERTYPE ||
			    fi->lkup_type == ICE_SW_LKUP_PROMISC ||
			    fi->lkup_type == ICE_SW_LKUP_ETHERTYPE_MAC ||
			    fi->lkup_type == ICE_SW_LKUP_PROMISC_VLAN ||
			    fi->lkup_type == ICE_SW_LKUP_DFLT ||
			    fi->lkup_type == ICE_SW_LKUP_VLAN ||
			    (fi->lkup_type == ICE_SW_LKUP_MAC &&
			     !is_unicast_ether_addr(fi->l_data.mac.mac_addr)) ||
			    (fi->lkup_type == ICE_SW_LKUP_MAC_VLAN &&
			     !is_unicast_ether_addr(fi->l_data.mac.mac_addr)))
				fi->lan_en = true;
		} else {
			fi->lan_en = true;
		}
	}
}

/**
 * ice_fill_sw_rule - Helper function to fill switch rule structure
 * @hw: pointer to the hardware structure
 * @f_info: entry containing packet forwarding information
 * @s_rule: switch rule structure to be filled in based on mac_entry
 * @opc: switch rules population command type - pass in the command opcode
 */
static void
ice_fill_sw_rule(struct ice_hw *hw, struct ice_fltr_info *f_info,
		 struct ice_aqc_sw_rules_elem *s_rule, enum ice_adminq_opc opc)
{
	u16 vlan_id = ICE_MAX_VLAN_ID + 1;
	void *daddr = NULL;
	u16 eth_hdr_sz;
	u8 *eth_hdr;
	u32 act = 0;
	__be16 *off;
	u8 q_rgn;

	if (opc == ice_aqc_opc_remove_sw_rules) {
		s_rule->pdata.lkup_tx_rx.act = 0;
		s_rule->pdata.lkup_tx_rx.index =
			cpu_to_le16(f_info->fltr_rule_id);
		s_rule->pdata.lkup_tx_rx.hdr_len = 0;
		return;
	}

	eth_hdr_sz = sizeof(dummy_eth_header);
	eth_hdr = s_rule->pdata.lkup_tx_rx.hdr;

	/* initialize the ether header with a dummy header */
	memcpy(eth_hdr, dummy_eth_header, eth_hdr_sz);
	ice_fill_sw_info(hw, f_info);

	switch (f_info->fltr_act) {
	case ICE_FWD_TO_VSI:
		act |= (f_info->fwd_id.hw_vsi_id << ICE_SINGLE_ACT_VSI_ID_S) &
			ICE_SINGLE_ACT_VSI_ID_M;
		if (f_info->lkup_type != ICE_SW_LKUP_VLAN)
			act |= ICE_SINGLE_ACT_VSI_FORWARDING |
				ICE_SINGLE_ACT_VALID_BIT;
		break;
	case ICE_FWD_TO_VSI_LIST:
		act |= ICE_SINGLE_ACT_VSI_LIST;
		act |= (f_info->fwd_id.vsi_list_id <<
			ICE_SINGLE_ACT_VSI_LIST_ID_S) &
			ICE_SINGLE_ACT_VSI_LIST_ID_M;
		if (f_info->lkup_type != ICE_SW_LKUP_VLAN)
			act |= ICE_SINGLE_ACT_VSI_FORWARDING |
				ICE_SINGLE_ACT_VALID_BIT;
		break;
	case ICE_FWD_TO_Q:
		act |= ICE_SINGLE_ACT_TO_Q;
		act |= (f_info->fwd_id.q_id << ICE_SINGLE_ACT_Q_INDEX_S) &
			ICE_SINGLE_ACT_Q_INDEX_M;
		break;
	case ICE_DROP_PACKET:
		act |= ICE_SINGLE_ACT_VSI_FORWARDING | ICE_SINGLE_ACT_DROP |
			ICE_SINGLE_ACT_VALID_BIT;
		break;
	case ICE_FWD_TO_QGRP:
		q_rgn = f_info->qgrp_size > 0 ?
			(u8)ilog2(f_info->qgrp_size) : 0;
		act |= ICE_SINGLE_ACT_TO_Q;
		act |= (f_info->fwd_id.q_id << ICE_SINGLE_ACT_Q_INDEX_S) &
			ICE_SINGLE_ACT_Q_INDEX_M;
		act |= (q_rgn << ICE_SINGLE_ACT_Q_REGION_S) &
			ICE_SINGLE_ACT_Q_REGION_M;
		break;
	default:
		return;
	}

	if (f_info->lb_en)
		act |= ICE_SINGLE_ACT_LB_ENABLE;
	if (f_info->lan_en)
		act |= ICE_SINGLE_ACT_LAN_ENABLE;

	switch (f_info->lkup_type) {
	case ICE_SW_LKUP_MAC:
		daddr = f_info->l_data.mac.mac_addr;
		break;
	case ICE_SW_LKUP_VLAN:
		vlan_id = f_info->l_data.vlan.vlan_id;
		if (f_info->fltr_act == ICE_FWD_TO_VSI ||
		    f_info->fltr_act == ICE_FWD_TO_VSI_LIST) {
			act |= ICE_SINGLE_ACT_PRUNE;
			act |= ICE_SINGLE_ACT_EGRESS | ICE_SINGLE_ACT_INGRESS;
		}
		break;
	case ICE_SW_LKUP_ETHERTYPE_MAC:
		daddr = f_info->l_data.ethertype_mac.mac_addr;
		fallthrough;
	case ICE_SW_LKUP_ETHERTYPE:
		off = (__force __be16 *)(eth_hdr + ICE_ETH_ETHTYPE_OFFSET);
		*off = cpu_to_be16(f_info->l_data.ethertype_mac.ethertype);
		break;
	case ICE_SW_LKUP_MAC_VLAN:
		daddr = f_info->l_data.mac_vlan.mac_addr;
		vlan_id = f_info->l_data.mac_vlan.vlan_id;
		break;
	case ICE_SW_LKUP_PROMISC_VLAN:
		vlan_id = f_info->l_data.mac_vlan.vlan_id;
		fallthrough;
	case ICE_SW_LKUP_PROMISC:
		daddr = f_info->l_data.mac_vlan.mac_addr;
		break;
	default:
		break;
	}

	s_rule->type = (f_info->flag & ICE_FLTR_RX) ?
		cpu_to_le16(ICE_AQC_SW_RULES_T_LKUP_RX) :
		cpu_to_le16(ICE_AQC_SW_RULES_T_LKUP_TX);

	/* Recipe set depending on lookup type */
	s_rule->pdata.lkup_tx_rx.recipe_id = cpu_to_le16(f_info->lkup_type);
	s_rule->pdata.lkup_tx_rx.src = cpu_to_le16(f_info->src);
	s_rule->pdata.lkup_tx_rx.act = cpu_to_le32(act);

	if (daddr)
		ether_addr_copy(eth_hdr + ICE_ETH_DA_OFFSET, daddr);

	if (!(vlan_id > ICE_MAX_VLAN_ID)) {
		off = (__force __be16 *)(eth_hdr + ICE_ETH_VLAN_TCI_OFFSET);
		*off = cpu_to_be16(vlan_id);
	}

	/* Create the switch rule with the final dummy Ethernet header */
	if (opc != ice_aqc_opc_update_sw_rules)
		s_rule->pdata.lkup_tx_rx.hdr_len = cpu_to_le16(eth_hdr_sz);
}

/**
 * ice_add_marker_act
 * @hw: pointer to the hardware structure
 * @m_ent: the management entry for which sw marker needs to be added
 * @sw_marker: sw marker to tag the Rx descriptor with
 * @l_id: large action resource ID
 *
 * Create a large action to hold software marker and update the switch rule
 * entry pointed by m_ent with newly created large action
 */
static enum ice_status
ice_add_marker_act(struct ice_hw *hw, struct ice_fltr_mgmt_list_entry *m_ent,
		   u16 sw_marker, u16 l_id)
{
	struct ice_aqc_sw_rules_elem *lg_act, *rx_tx;
	/* For software marker we need 3 large actions
	 * 1. FWD action: FWD TO VSI or VSI LIST
	 * 2. GENERIC VALUE action to hold the profile ID
	 * 3. GENERIC VALUE action to hold the software marker ID
	 */
	const u16 num_lg_acts = 3;
	enum ice_status status;
	u16 lg_act_size;
	u16 rules_size;
	u32 act;
	u16 id;

	if (m_ent->fltr_info.lkup_type != ICE_SW_LKUP_MAC)
		return ICE_ERR_PARAM;

	/* Create two back-to-back switch rules and submit them to the HW using
	 * one memory buffer:
	 *    1. Large Action
	 *    2. Look up Tx Rx
	 */
	lg_act_size = (u16)ICE_SW_RULE_LG_ACT_SIZE(num_lg_acts);
	rules_size = lg_act_size + ICE_SW_RULE_RX_TX_ETH_HDR_SIZE;
	lg_act = devm_kzalloc(ice_hw_to_dev(hw), rules_size, GFP_KERNEL);
	if (!lg_act)
		return ICE_ERR_NO_MEMORY;

	rx_tx = (struct ice_aqc_sw_rules_elem *)((u8 *)lg_act + lg_act_size);

	/* Fill in the first switch rule i.e. large action */
	lg_act->type = cpu_to_le16(ICE_AQC_SW_RULES_T_LG_ACT);
	lg_act->pdata.lg_act.index = cpu_to_le16(l_id);
	lg_act->pdata.lg_act.size = cpu_to_le16(num_lg_acts);

	/* First action VSI forwarding or VSI list forwarding depending on how
	 * many VSIs
	 */
	id = (m_ent->vsi_count > 1) ? m_ent->fltr_info.fwd_id.vsi_list_id :
		m_ent->fltr_info.fwd_id.hw_vsi_id;

	act = ICE_LG_ACT_VSI_FORWARDING | ICE_LG_ACT_VALID_BIT;
	act |= (id << ICE_LG_ACT_VSI_LIST_ID_S) & ICE_LG_ACT_VSI_LIST_ID_M;
	if (m_ent->vsi_count > 1)
		act |= ICE_LG_ACT_VSI_LIST;
	lg_act->pdata.lg_act.act[0] = cpu_to_le32(act);

	/* Second action descriptor type */
	act = ICE_LG_ACT_GENERIC;

	act |= (1 << ICE_LG_ACT_GENERIC_VALUE_S) & ICE_LG_ACT_GENERIC_VALUE_M;
	lg_act->pdata.lg_act.act[1] = cpu_to_le32(act);

	act = (ICE_LG_ACT_GENERIC_OFF_RX_DESC_PROF_IDX <<
	       ICE_LG_ACT_GENERIC_OFFSET_S) & ICE_LG_ACT_GENERIC_OFFSET_M;

	/* Third action Marker value */
	act |= ICE_LG_ACT_GENERIC;
	act |= (sw_marker << ICE_LG_ACT_GENERIC_VALUE_S) &
		ICE_LG_ACT_GENERIC_VALUE_M;

	lg_act->pdata.lg_act.act[2] = cpu_to_le32(act);

	/* call the fill switch rule to fill the lookup Tx Rx structure */
	ice_fill_sw_rule(hw, &m_ent->fltr_info, rx_tx,
			 ice_aqc_opc_update_sw_rules);

	/* Update the action to point to the large action ID */
	rx_tx->pdata.lkup_tx_rx.act =
		cpu_to_le32(ICE_SINGLE_ACT_PTR |
			    ((l_id << ICE_SINGLE_ACT_PTR_VAL_S) &
			     ICE_SINGLE_ACT_PTR_VAL_M));

	/* Use the filter rule ID of the previously created rule with single
	 * act. Once the update happens, hardware will treat this as large
	 * action
	 */
	rx_tx->pdata.lkup_tx_rx.index =
		cpu_to_le16(m_ent->fltr_info.fltr_rule_id);

	status = ice_aq_sw_rules(hw, lg_act, rules_size, 2,
				 ice_aqc_opc_update_sw_rules, NULL);
	if (!status) {
		m_ent->lg_act_idx = l_id;
		m_ent->sw_marker_id = sw_marker;
	}

	devm_kfree(ice_hw_to_dev(hw), lg_act);
	return status;
}

/**
 * ice_create_vsi_list_map
 * @hw: pointer to the hardware structure
 * @vsi_handle_arr: array of VSI handles to set in the VSI mapping
 * @num_vsi: number of VSI handles in the array
 * @vsi_list_id: VSI list ID generated as part of allocate resource
 *
 * Helper function to create a new entry of VSI list ID to VSI mapping
 * using the given VSI list ID
 */
static struct ice_vsi_list_map_info *
ice_create_vsi_list_map(struct ice_hw *hw, u16 *vsi_handle_arr, u16 num_vsi,
			u16 vsi_list_id)
{
	struct ice_switch_info *sw = hw->switch_info;
	struct ice_vsi_list_map_info *v_map;
	int i;

	v_map = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*v_map), GFP_KERNEL);
	if (!v_map)
		return NULL;

	v_map->vsi_list_id = vsi_list_id;
	v_map->ref_cnt = 1;
	for (i = 0; i < num_vsi; i++)
		set_bit(vsi_handle_arr[i], v_map->vsi_map);

	list_add(&v_map->list_entry, &sw->vsi_list_map_head);
	return v_map;
}

/**
 * ice_update_vsi_list_rule
 * @hw: pointer to the hardware structure
 * @vsi_handle_arr: array of VSI handles to form a VSI list
 * @num_vsi: number of VSI handles in the array
 * @vsi_list_id: VSI list ID generated as part of allocate resource
 * @remove: Boolean value to indicate if this is a remove action
 * @opc: switch rules population command type - pass in the command opcode
 * @lkup_type: lookup type of the filter
 *
 * Call AQ command to add a new switch rule or update existing switch rule
 * using the given VSI list ID
 */
static enum ice_status
ice_update_vsi_list_rule(struct ice_hw *hw, u16 *vsi_handle_arr, u16 num_vsi,
			 u16 vsi_list_id, bool remove, enum ice_adminq_opc opc,
			 enum ice_sw_lkup_type lkup_type)
{
	struct ice_aqc_sw_rules_elem *s_rule;
	enum ice_status status;
	u16 s_rule_size;
	u16 rule_type;
	int i;

	if (!num_vsi)
		return ICE_ERR_PARAM;

	if (lkup_type == ICE_SW_LKUP_MAC ||
	    lkup_type == ICE_SW_LKUP_MAC_VLAN ||
	    lkup_type == ICE_SW_LKUP_ETHERTYPE ||
	    lkup_type == ICE_SW_LKUP_ETHERTYPE_MAC ||
	    lkup_type == ICE_SW_LKUP_PROMISC ||
	    lkup_type == ICE_SW_LKUP_PROMISC_VLAN)
		rule_type = remove ? ICE_AQC_SW_RULES_T_VSI_LIST_CLEAR :
			ICE_AQC_SW_RULES_T_VSI_LIST_SET;
	else if (lkup_type == ICE_SW_LKUP_VLAN)
		rule_type = remove ? ICE_AQC_SW_RULES_T_PRUNE_LIST_CLEAR :
			ICE_AQC_SW_RULES_T_PRUNE_LIST_SET;
	else
		return ICE_ERR_PARAM;

	s_rule_size = (u16)ICE_SW_RULE_VSI_LIST_SIZE(num_vsi);
	s_rule = devm_kzalloc(ice_hw_to_dev(hw), s_rule_size, GFP_KERNEL);
	if (!s_rule)
		return ICE_ERR_NO_MEMORY;
	for (i = 0; i < num_vsi; i++) {
		if (!ice_is_vsi_valid(hw, vsi_handle_arr[i])) {
			status = ICE_ERR_PARAM;
			goto exit;
		}
		/* AQ call requires hw_vsi_id(s) */
		s_rule->pdata.vsi_list.vsi[i] =
			cpu_to_le16(ice_get_hw_vsi_num(hw, vsi_handle_arr[i]));
	}

	s_rule->type = cpu_to_le16(rule_type);
	s_rule->pdata.vsi_list.number_vsi = cpu_to_le16(num_vsi);
	s_rule->pdata.vsi_list.index = cpu_to_le16(vsi_list_id);

	status = ice_aq_sw_rules(hw, s_rule, s_rule_size, 1, opc, NULL);

exit:
	devm_kfree(ice_hw_to_dev(hw), s_rule);
	return status;
}

/**
 * ice_create_vsi_list_rule - Creates and populates a VSI list rule
 * @hw: pointer to the HW struct
 * @vsi_handle_arr: array of VSI handles to form a VSI list
 * @num_vsi: number of VSI handles in the array
 * @vsi_list_id: stores the ID of the VSI list to be created
 * @lkup_type: switch rule filter's lookup type
 */
static enum ice_status
ice_create_vsi_list_rule(struct ice_hw *hw, u16 *vsi_handle_arr, u16 num_vsi,
			 u16 *vsi_list_id, enum ice_sw_lkup_type lkup_type)
{
	enum ice_status status;

	status = ice_aq_alloc_free_vsi_list(hw, vsi_list_id, lkup_type,
					    ice_aqc_opc_alloc_res);
	if (status)
		return status;

	/* Update the newly created VSI list to include the specified VSIs */
	return ice_update_vsi_list_rule(hw, vsi_handle_arr, num_vsi,
					*vsi_list_id, false,
					ice_aqc_opc_add_sw_rules, lkup_type);
}

/**
 * ice_create_pkt_fwd_rule
 * @hw: pointer to the hardware structure
 * @f_entry: entry containing packet forwarding information
 *
 * Create switch rule with given filter information and add an entry
 * to the corresponding filter management list to track this switch rule
 * and VSI mapping
 */
static enum ice_status
ice_create_pkt_fwd_rule(struct ice_hw *hw,
			struct ice_fltr_list_entry *f_entry)
{
	struct ice_fltr_mgmt_list_entry *fm_entry;
	struct ice_aqc_sw_rules_elem *s_rule;
	enum ice_sw_lkup_type l_type;
	struct ice_sw_recipe *recp;
	enum ice_status status;

	s_rule = devm_kzalloc(ice_hw_to_dev(hw),
			      ICE_SW_RULE_RX_TX_ETH_HDR_SIZE, GFP_KERNEL);
	if (!s_rule)
		return ICE_ERR_NO_MEMORY;
	fm_entry = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*fm_entry),
				GFP_KERNEL);
	if (!fm_entry) {
		status = ICE_ERR_NO_MEMORY;
		goto ice_create_pkt_fwd_rule_exit;
	}

	fm_entry->fltr_info = f_entry->fltr_info;

	/* Initialize all the fields for the management entry */
	fm_entry->vsi_count = 1;
	fm_entry->lg_act_idx = ICE_INVAL_LG_ACT_INDEX;
	fm_entry->sw_marker_id = ICE_INVAL_SW_MARKER_ID;
	fm_entry->counter_index = ICE_INVAL_COUNTER_ID;

	ice_fill_sw_rule(hw, &fm_entry->fltr_info, s_rule,
			 ice_aqc_opc_add_sw_rules);

	status = ice_aq_sw_rules(hw, s_rule, ICE_SW_RULE_RX_TX_ETH_HDR_SIZE, 1,
				 ice_aqc_opc_add_sw_rules, NULL);
	if (status) {
		devm_kfree(ice_hw_to_dev(hw), fm_entry);
		goto ice_create_pkt_fwd_rule_exit;
	}

	f_entry->fltr_info.fltr_rule_id =
		le16_to_cpu(s_rule->pdata.lkup_tx_rx.index);
	fm_entry->fltr_info.fltr_rule_id =
		le16_to_cpu(s_rule->pdata.lkup_tx_rx.index);

	/* The book keeping entries will get removed when base driver
	 * calls remove filter AQ command
	 */
	l_type = fm_entry->fltr_info.lkup_type;
	recp = &hw->switch_info->recp_list[l_type];
	list_add(&fm_entry->list_entry, &recp->filt_rules);

ice_create_pkt_fwd_rule_exit:
	devm_kfree(ice_hw_to_dev(hw), s_rule);
	return status;
}

/**
 * ice_update_pkt_fwd_rule
 * @hw: pointer to the hardware structure
 * @f_info: filter information for switch rule
 *
 * Call AQ command to update a previously created switch rule with a
 * VSI list ID
 */
static enum ice_status
ice_update_pkt_fwd_rule(struct ice_hw *hw, struct ice_fltr_info *f_info)
{
	struct ice_aqc_sw_rules_elem *s_rule;
	enum ice_status status;

	s_rule = devm_kzalloc(ice_hw_to_dev(hw),
			      ICE_SW_RULE_RX_TX_ETH_HDR_SIZE, GFP_KERNEL);
	if (!s_rule)
		return ICE_ERR_NO_MEMORY;

	ice_fill_sw_rule(hw, f_info, s_rule, ice_aqc_opc_update_sw_rules);

	s_rule->pdata.lkup_tx_rx.index = cpu_to_le16(f_info->fltr_rule_id);

	/* Update switch rule with new rule set to forward VSI list */
	status = ice_aq_sw_rules(hw, s_rule, ICE_SW_RULE_RX_TX_ETH_HDR_SIZE, 1,
				 ice_aqc_opc_update_sw_rules, NULL);

	devm_kfree(ice_hw_to_dev(hw), s_rule);
	return status;
}

/**
 * ice_update_sw_rule_bridge_mode
 * @hw: pointer to the HW struct
 *
 * Updates unicast switch filter rules based on VEB/VEPA mode
 */
enum ice_status ice_update_sw_rule_bridge_mode(struct ice_hw *hw)
{
	struct ice_switch_info *sw = hw->switch_info;
	struct ice_fltr_mgmt_list_entry *fm_entry;
	enum ice_status status = 0;
	struct list_head *rule_head;
	struct mutex *rule_lock; /* Lock to protect filter rule list */

	rule_lock = &sw->recp_list[ICE_SW_LKUP_MAC].filt_rule_lock;
	rule_head = &sw->recp_list[ICE_SW_LKUP_MAC].filt_rules;

	mutex_lock(rule_lock);
	list_for_each_entry(fm_entry, rule_head, list_entry) {
		struct ice_fltr_info *fi = &fm_entry->fltr_info;
		u8 *addr = fi->l_data.mac.mac_addr;

		/* Update unicast Tx rules to reflect the selected
		 * VEB/VEPA mode
		 */
		if ((fi->flag & ICE_FLTR_TX) && is_unicast_ether_addr(addr) &&
		    (fi->fltr_act == ICE_FWD_TO_VSI ||
		     fi->fltr_act == ICE_FWD_TO_VSI_LIST ||
		     fi->fltr_act == ICE_FWD_TO_Q ||
		     fi->fltr_act == ICE_FWD_TO_QGRP)) {
			status = ice_update_pkt_fwd_rule(hw, fi);
			if (status)
				break;
		}
	}

	mutex_unlock(rule_lock);

	return status;
}

/**
 * ice_add_update_vsi_list
 * @hw: pointer to the hardware structure
 * @m_entry: pointer to current filter management list entry
 * @cur_fltr: filter information from the book keeping entry
 * @new_fltr: filter information with the new VSI to be added
 *
 * Call AQ command to add or update previously created VSI list with new VSI.
 *
 * Helper function to do book keeping associated with adding filter information
 * The algorithm to do the book keeping is described below :
 * When a VSI needs to subscribe to a given filter (MAC/VLAN/Ethtype etc.)
 *	if only one VSI has been added till now
 *		Allocate a new VSI list and add two VSIs
 *		to this list using switch rule command
 *		Update the previously created switch rule with the
 *		newly created VSI list ID
 *	if a VSI list was previously created
 *		Add the new VSI to the previously created VSI list set
 *		using the update switch rule command
 */
static enum ice_status
ice_add_update_vsi_list(struct ice_hw *hw,
			struct ice_fltr_mgmt_list_entry *m_entry,
			struct ice_fltr_info *cur_fltr,
			struct ice_fltr_info *new_fltr)
{
	enum ice_status status = 0;
	u16 vsi_list_id = 0;

	if ((cur_fltr->fltr_act == ICE_FWD_TO_Q ||
	     cur_fltr->fltr_act == ICE_FWD_TO_QGRP))
		return ICE_ERR_NOT_IMPL;

	if ((new_fltr->fltr_act == ICE_FWD_TO_Q ||
	     new_fltr->fltr_act == ICE_FWD_TO_QGRP) &&
	    (cur_fltr->fltr_act == ICE_FWD_TO_VSI ||
	     cur_fltr->fltr_act == ICE_FWD_TO_VSI_LIST))
		return ICE_ERR_NOT_IMPL;

	if (m_entry->vsi_count < 2 && !m_entry->vsi_list_info) {
		/* Only one entry existed in the mapping and it was not already
		 * a part of a VSI list. So, create a VSI list with the old and
		 * new VSIs.
		 */
		struct ice_fltr_info tmp_fltr;
		u16 vsi_handle_arr[2];

		/* A rule already exists with the new VSI being added */
		if (cur_fltr->fwd_id.hw_vsi_id == new_fltr->fwd_id.hw_vsi_id)
			return ICE_ERR_ALREADY_EXISTS;

		vsi_handle_arr[0] = cur_fltr->vsi_handle;
		vsi_handle_arr[1] = new_fltr->vsi_handle;
		status = ice_create_vsi_list_rule(hw, &vsi_handle_arr[0], 2,
						  &vsi_list_id,
						  new_fltr->lkup_type);
		if (status)
			return status;

		tmp_fltr = *new_fltr;
		tmp_fltr.fltr_rule_id = cur_fltr->fltr_rule_id;
		tmp_fltr.fltr_act = ICE_FWD_TO_VSI_LIST;
		tmp_fltr.fwd_id.vsi_list_id = vsi_list_id;
		/* Update the previous switch rule of "MAC forward to VSI" to
		 * "MAC fwd to VSI list"
		 */
		status = ice_update_pkt_fwd_rule(hw, &tmp_fltr);
		if (status)
			return status;

		cur_fltr->fwd_id.vsi_list_id = vsi_list_id;
		cur_fltr->fltr_act = ICE_FWD_TO_VSI_LIST;
		m_entry->vsi_list_info =
			ice_create_vsi_list_map(hw, &vsi_handle_arr[0], 2,
						vsi_list_id);

		if (!m_entry->vsi_list_info)
			return ICE_ERR_NO_MEMORY;

		/* If this entry was large action then the large action needs
		 * to be updated to point to FWD to VSI list
		 */
		if (m_entry->sw_marker_id != ICE_INVAL_SW_MARKER_ID)
			status =
			    ice_add_marker_act(hw, m_entry,
					       m_entry->sw_marker_id,
					       m_entry->lg_act_idx);
	} else {
		u16 vsi_handle = new_fltr->vsi_handle;
		enum ice_adminq_opc opcode;

		if (!m_entry->vsi_list_info)
			return ICE_ERR_CFG;

		/* A rule already exists with the new VSI being added */
		if (test_bit(vsi_handle, m_entry->vsi_list_info->vsi_map))
			return 0;

		/* Update the previously created VSI list set with
		 * the new VSI ID passed in
		 */
		vsi_list_id = cur_fltr->fwd_id.vsi_list_id;
		opcode = ice_aqc_opc_update_sw_rules;

		status = ice_update_vsi_list_rule(hw, &vsi_handle, 1,
						  vsi_list_id, false, opcode,
						  new_fltr->lkup_type);
		/* update VSI list mapping info with new VSI ID */
		if (!status)
			set_bit(vsi_handle, m_entry->vsi_list_info->vsi_map);
	}
	if (!status)
		m_entry->vsi_count++;
	return status;
}

/**
 * ice_find_rule_entry - Search a rule entry
 * @hw: pointer to the hardware structure
 * @recp_id: lookup type for which the specified rule needs to be searched
 * @f_info: rule information
 *
 * Helper function to search for a given rule entry
 * Returns pointer to entry storing the rule if found
 */
static struct ice_fltr_mgmt_list_entry *
ice_find_rule_entry(struct ice_hw *hw, u8 recp_id, struct ice_fltr_info *f_info)
{
	struct ice_fltr_mgmt_list_entry *list_itr, *ret = NULL;
	struct ice_switch_info *sw = hw->switch_info;
	struct list_head *list_head;

	list_head = &sw->recp_list[recp_id].filt_rules;
	list_for_each_entry(list_itr, list_head, list_entry) {
		if (!memcmp(&f_info->l_data, &list_itr->fltr_info.l_data,
			    sizeof(f_info->l_data)) &&
		    f_info->flag == list_itr->fltr_info.flag) {
			ret = list_itr;
			break;
		}
	}
	return ret;
}

/**
 * ice_find_vsi_list_entry - Search VSI list map with VSI count 1
 * @hw: pointer to the hardware structure
 * @recp_id: lookup type for which VSI lists needs to be searched
 * @vsi_handle: VSI handle to be found in VSI list
 * @vsi_list_id: VSI list ID found containing vsi_handle
 *
 * Helper function to search a VSI list with single entry containing given VSI
 * handle element. This can be extended further to search VSI list with more
 * than 1 vsi_count. Returns pointer to VSI list entry if found.
 */
static struct ice_vsi_list_map_info *
ice_find_vsi_list_entry(struct ice_hw *hw, u8 recp_id, u16 vsi_handle,
			u16 *vsi_list_id)
{
	struct ice_vsi_list_map_info *map_info = NULL;
	struct ice_switch_info *sw = hw->switch_info;
	struct ice_fltr_mgmt_list_entry *list_itr;
	struct list_head *list_head;

	list_head = &sw->recp_list[recp_id].filt_rules;
	list_for_each_entry(list_itr, list_head, list_entry) {
		if (list_itr->vsi_count == 1 && list_itr->vsi_list_info) {
			map_info = list_itr->vsi_list_info;
			if (test_bit(vsi_handle, map_info->vsi_map)) {
				*vsi_list_id = map_info->vsi_list_id;
				return map_info;
			}
		}
	}
	return NULL;
}

/**
 * ice_add_rule_internal - add rule for a given lookup type
 * @hw: pointer to the hardware structure
 * @recp_id: lookup type (recipe ID) for which rule has to be added
 * @f_entry: structure containing MAC forwarding information
 *
 * Adds or updates the rule lists for a given recipe
 */
static enum ice_status
ice_add_rule_internal(struct ice_hw *hw, u8 recp_id,
		      struct ice_fltr_list_entry *f_entry)
{
	struct ice_switch_info *sw = hw->switch_info;
	struct ice_fltr_info *new_fltr, *cur_fltr;
	struct ice_fltr_mgmt_list_entry *m_entry;
	struct mutex *rule_lock; /* Lock to protect filter rule list */
	enum ice_status status = 0;

	if (!ice_is_vsi_valid(hw, f_entry->fltr_info.vsi_handle))
		return ICE_ERR_PARAM;
	f_entry->fltr_info.fwd_id.hw_vsi_id =
		ice_get_hw_vsi_num(hw, f_entry->fltr_info.vsi_handle);

	rule_lock = &sw->recp_list[recp_id].filt_rule_lock;

	mutex_lock(rule_lock);
	new_fltr = &f_entry->fltr_info;
	if (new_fltr->flag & ICE_FLTR_RX)
		new_fltr->src = hw->port_info->lport;
	else if (new_fltr->flag & ICE_FLTR_TX)
		new_fltr->src = f_entry->fltr_info.fwd_id.hw_vsi_id;

	m_entry = ice_find_rule_entry(hw, recp_id, new_fltr);
	if (!m_entry) {
		mutex_unlock(rule_lock);
		return ice_create_pkt_fwd_rule(hw, f_entry);
	}

	cur_fltr = &m_entry->fltr_info;
	status = ice_add_update_vsi_list(hw, m_entry, cur_fltr, new_fltr);
	mutex_unlock(rule_lock);

	return status;
}

/**
 * ice_remove_vsi_list_rule
 * @hw: pointer to the hardware structure
 * @vsi_list_id: VSI list ID generated as part of allocate resource
 * @lkup_type: switch rule filter lookup type
 *
 * The VSI list should be emptied before this function is called to remove the
 * VSI list.
 */
static enum ice_status
ice_remove_vsi_list_rule(struct ice_hw *hw, u16 vsi_list_id,
			 enum ice_sw_lkup_type lkup_type)
{
	struct ice_aqc_sw_rules_elem *s_rule;
	enum ice_status status;
	u16 s_rule_size;

	s_rule_size = (u16)ICE_SW_RULE_VSI_LIST_SIZE(0);
	s_rule = devm_kzalloc(ice_hw_to_dev(hw), s_rule_size, GFP_KERNEL);
	if (!s_rule)
		return ICE_ERR_NO_MEMORY;

	s_rule->type = cpu_to_le16(ICE_AQC_SW_RULES_T_VSI_LIST_CLEAR);
	s_rule->pdata.vsi_list.index = cpu_to_le16(vsi_list_id);

	/* Free the vsi_list resource that we allocated. It is assumed that the
	 * list is empty at this point.
	 */
	status = ice_aq_alloc_free_vsi_list(hw, &vsi_list_id, lkup_type,
					    ice_aqc_opc_free_res);

	devm_kfree(ice_hw_to_dev(hw), s_rule);
	return status;
}

/**
 * ice_rem_update_vsi_list
 * @hw: pointer to the hardware structure
 * @vsi_handle: VSI handle of the VSI to remove
 * @fm_list: filter management entry for which the VSI list management needs to
 *           be done
 */
static enum ice_status
ice_rem_update_vsi_list(struct ice_hw *hw, u16 vsi_handle,
			struct ice_fltr_mgmt_list_entry *fm_list)
{
	enum ice_sw_lkup_type lkup_type;
	enum ice_status status = 0;
	u16 vsi_list_id;

	if (fm_list->fltr_info.fltr_act != ICE_FWD_TO_VSI_LIST ||
	    fm_list->vsi_count == 0)
		return ICE_ERR_PARAM;

	/* A rule with the VSI being removed does not exist */
	if (!test_bit(vsi_handle, fm_list->vsi_list_info->vsi_map))
		return ICE_ERR_DOES_NOT_EXIST;

	lkup_type = fm_list->fltr_info.lkup_type;
	vsi_list_id = fm_list->fltr_info.fwd_id.vsi_list_id;
	status = ice_update_vsi_list_rule(hw, &vsi_handle, 1, vsi_list_id, true,
					  ice_aqc_opc_update_sw_rules,
					  lkup_type);
	if (status)
		return status;

	fm_list->vsi_count--;
	clear_bit(vsi_handle, fm_list->vsi_list_info->vsi_map);

	if (fm_list->vsi_count == 1 && lkup_type != ICE_SW_LKUP_VLAN) {
		struct ice_fltr_info tmp_fltr_info = fm_list->fltr_info;
		struct ice_vsi_list_map_info *vsi_list_info =
			fm_list->vsi_list_info;
		u16 rem_vsi_handle;

		rem_vsi_handle = find_first_bit(vsi_list_info->vsi_map,
						ICE_MAX_VSI);
		if (!ice_is_vsi_valid(hw, rem_vsi_handle))
			return ICE_ERR_OUT_OF_RANGE;

		/* Make sure VSI list is empty before removing it below */
		status = ice_update_vsi_list_rule(hw, &rem_vsi_handle, 1,
						  vsi_list_id, true,
						  ice_aqc_opc_update_sw_rules,
						  lkup_type);
		if (status)
			return status;

		tmp_fltr_info.fltr_act = ICE_FWD_TO_VSI;
		tmp_fltr_info.fwd_id.hw_vsi_id =
			ice_get_hw_vsi_num(hw, rem_vsi_handle);
		tmp_fltr_info.vsi_handle = rem_vsi_handle;
		status = ice_update_pkt_fwd_rule(hw, &tmp_fltr_info);
		if (status) {
			ice_debug(hw, ICE_DBG_SW, "Failed to update pkt fwd rule to FWD_TO_VSI on HW VSI %d, error %d\n",
				  tmp_fltr_info.fwd_id.hw_vsi_id, status);
			return status;
		}

		fm_list->fltr_info = tmp_fltr_info;
	}

	if ((fm_list->vsi_count == 1 && lkup_type != ICE_SW_LKUP_VLAN) ||
	    (fm_list->vsi_count == 0 && lkup_type == ICE_SW_LKUP_VLAN)) {
		struct ice_vsi_list_map_info *vsi_list_info =
			fm_list->vsi_list_info;

		/* Remove the VSI list since it is no longer used */
		status = ice_remove_vsi_list_rule(hw, vsi_list_id, lkup_type);
		if (status) {
			ice_debug(hw, ICE_DBG_SW, "Failed to remove VSI list %d, error %d\n",
				  vsi_list_id, status);
			return status;
		}

		list_del(&vsi_list_info->list_entry);
		devm_kfree(ice_hw_to_dev(hw), vsi_list_info);
		fm_list->vsi_list_info = NULL;
	}

	return status;
}

/**
 * ice_remove_rule_internal - Remove a filter rule of a given type
 * @hw: pointer to the hardware structure
 * @recp_id: recipe ID for which the rule needs to removed
 * @f_entry: rule entry containing filter information
 */
static enum ice_status
ice_remove_rule_internal(struct ice_hw *hw, u8 recp_id,
			 struct ice_fltr_list_entry *f_entry)
{
	struct ice_switch_info *sw = hw->switch_info;
	struct ice_fltr_mgmt_list_entry *list_elem;
	struct mutex *rule_lock; /* Lock to protect filter rule list */
	enum ice_status status = 0;
	bool remove_rule = false;
	u16 vsi_handle;

	if (!ice_is_vsi_valid(hw, f_entry->fltr_info.vsi_handle))
		return ICE_ERR_PARAM;
	f_entry->fltr_info.fwd_id.hw_vsi_id =
		ice_get_hw_vsi_num(hw, f_entry->fltr_info.vsi_handle);

	rule_lock = &sw->recp_list[recp_id].filt_rule_lock;
	mutex_lock(rule_lock);
	list_elem = ice_find_rule_entry(hw, recp_id, &f_entry->fltr_info);
	if (!list_elem) {
		status = ICE_ERR_DOES_NOT_EXIST;
		goto exit;
	}

	if (list_elem->fltr_info.fltr_act != ICE_FWD_TO_VSI_LIST) {
		remove_rule = true;
	} else if (!list_elem->vsi_list_info) {
		status = ICE_ERR_DOES_NOT_EXIST;
		goto exit;
	} else if (list_elem->vsi_list_info->ref_cnt > 1) {
		/* a ref_cnt > 1 indicates that the vsi_list is being
		 * shared by multiple rules. Decrement the ref_cnt and
		 * remove this rule, but do not modify the list, as it
		 * is in-use by other rules.
		 */
		list_elem->vsi_list_info->ref_cnt--;
		remove_rule = true;
	} else {
		/* a ref_cnt of 1 indicates the vsi_list is only used
		 * by one rule. However, the original removal request is only
		 * for a single VSI. Update the vsi_list first, and only
		 * remove the rule if there are no further VSIs in this list.
		 */
		vsi_handle = f_entry->fltr_info.vsi_handle;
		status = ice_rem_update_vsi_list(hw, vsi_handle, list_elem);
		if (status)
			goto exit;
		/* if VSI count goes to zero after updating the VSI list */
		if (list_elem->vsi_count == 0)
			remove_rule = true;
	}

	if (remove_rule) {
		/* Remove the lookup rule */
		struct ice_aqc_sw_rules_elem *s_rule;

		s_rule = devm_kzalloc(ice_hw_to_dev(hw),
				      ICE_SW_RULE_RX_TX_NO_HDR_SIZE,
				      GFP_KERNEL);
		if (!s_rule) {
			status = ICE_ERR_NO_MEMORY;
			goto exit;
		}

		ice_fill_sw_rule(hw, &list_elem->fltr_info, s_rule,
				 ice_aqc_opc_remove_sw_rules);

		status = ice_aq_sw_rules(hw, s_rule,
					 ICE_SW_RULE_RX_TX_NO_HDR_SIZE, 1,
					 ice_aqc_opc_remove_sw_rules, NULL);

		/* Remove a book keeping from the list */
		devm_kfree(ice_hw_to_dev(hw), s_rule);

		if (status)
			goto exit;

		list_del(&list_elem->list_entry);
		devm_kfree(ice_hw_to_dev(hw), list_elem);
	}
exit:
	mutex_unlock(rule_lock);
	return status;
}

/**
 * ice_mac_fltr_exist - does this MAC filter exist for given VSI
 * @hw: pointer to the hardware structure
 * @mac: MAC address to be checked (for MAC filter)
 * @vsi_handle: check MAC filter for this VSI
 */
bool ice_mac_fltr_exist(struct ice_hw *hw, u8 *mac, u16 vsi_handle)
{
	struct ice_fltr_mgmt_list_entry *entry;
	struct list_head *rule_head;
	struct ice_switch_info *sw;
	struct mutex *rule_lock; /* Lock to protect filter rule list */
	u16 hw_vsi_id;

	if (!ice_is_vsi_valid(hw, vsi_handle))
		return false;

	hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle);
	sw = hw->switch_info;
	rule_head = &sw->recp_list[ICE_SW_LKUP_MAC].filt_rules;
	if (!rule_head)
		return false;

	rule_lock = &sw->recp_list[ICE_SW_LKUP_MAC].filt_rule_lock;
	mutex_lock(rule_lock);
	list_for_each_entry(entry, rule_head, list_entry) {
		struct ice_fltr_info *f_info = &entry->fltr_info;
		u8 *mac_addr = &f_info->l_data.mac.mac_addr[0];

		if (is_zero_ether_addr(mac_addr))
			continue;

		if (f_info->flag != ICE_FLTR_TX ||
		    f_info->src_id != ICE_SRC_ID_VSI ||
		    f_info->lkup_type != ICE_SW_LKUP_MAC ||
		    f_info->fltr_act != ICE_FWD_TO_VSI ||
		    hw_vsi_id != f_info->fwd_id.hw_vsi_id)
			continue;

		if (ether_addr_equal(mac, mac_addr)) {
			mutex_unlock(rule_lock);
			return true;
		}
	}
	mutex_unlock(rule_lock);
	return false;
}

/**
 * ice_vlan_fltr_exist - does this VLAN filter exist for given VSI
 * @hw: pointer to the hardware structure
 * @vlan_id: VLAN ID
 * @vsi_handle: check MAC filter for this VSI
 */
bool ice_vlan_fltr_exist(struct ice_hw *hw, u16 vlan_id, u16 vsi_handle)
{
	struct ice_fltr_mgmt_list_entry *entry;
	struct list_head *rule_head;
	struct ice_switch_info *sw;
	struct mutex *rule_lock; /* Lock to protect filter rule list */
	u16 hw_vsi_id;

	if (vlan_id > ICE_MAX_VLAN_ID)
		return false;

	if (!ice_is_vsi_valid(hw, vsi_handle))
		return false;

	hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle);
	sw = hw->switch_info;
	rule_head = &sw->recp_list[ICE_SW_LKUP_VLAN].filt_rules;
	if (!rule_head)
		return false;

	rule_lock = &sw->recp_list[ICE_SW_LKUP_VLAN].filt_rule_lock;
	mutex_lock(rule_lock);
	list_for_each_entry(entry, rule_head, list_entry) {
		struct ice_fltr_info *f_info = &entry->fltr_info;
		u16 entry_vlan_id = f_info->l_data.vlan.vlan_id;
		struct ice_vsi_list_map_info *map_info;

		if (entry_vlan_id > ICE_MAX_VLAN_ID)
			continue;

		if (f_info->flag != ICE_FLTR_TX ||
		    f_info->src_id != ICE_SRC_ID_VSI ||
		    f_info->lkup_type != ICE_SW_LKUP_VLAN)
			continue;

		/* Only allowed filter action are FWD_TO_VSI/_VSI_LIST */
		if (f_info->fltr_act != ICE_FWD_TO_VSI &&
		    f_info->fltr_act != ICE_FWD_TO_VSI_LIST)
			continue;

		if (f_info->fltr_act == ICE_FWD_TO_VSI) {
			if (hw_vsi_id != f_info->fwd_id.hw_vsi_id)
				continue;
		} else if (f_info->fltr_act == ICE_FWD_TO_VSI_LIST) {
			/* If filter_action is FWD_TO_VSI_LIST, make sure
			 * that VSI being checked is part of VSI list
			 */
			if (entry->vsi_count == 1 &&
			    entry->vsi_list_info) {
				map_info = entry->vsi_list_info;
				if (!test_bit(vsi_handle, map_info->vsi_map))
					continue;
			}
		}

		if (vlan_id == entry_vlan_id) {
			mutex_unlock(rule_lock);
			return true;
		}
	}
	mutex_unlock(rule_lock);

	return false;
}

/**
 * ice_add_mac - Add a MAC address based filter rule
 * @hw: pointer to the hardware structure
 * @m_list: list of MAC addresses and forwarding information
 *
 * IMPORTANT: When the ucast_shared flag is set to false and m_list has
 * multiple unicast addresses, the function assumes that all the
 * addresses are unique in a given add_mac call. It doesn't
 * check for duplicates in this case, removing duplicates from a given
 * list should be taken care of in the caller of this function.
 */
enum ice_status ice_add_mac(struct ice_hw *hw, struct list_head *m_list)
{
	struct ice_aqc_sw_rules_elem *s_rule, *r_iter;
	struct ice_fltr_list_entry *m_list_itr;
	struct list_head *rule_head;
	u16 total_elem_left, s_rule_size;
	struct ice_switch_info *sw;
	struct mutex *rule_lock; /* Lock to protect filter rule list */
	enum ice_status status = 0;
	u16 num_unicast = 0;
	u8 elem_sent;

	if (!m_list || !hw)
		return ICE_ERR_PARAM;

	s_rule = NULL;
	sw = hw->switch_info;
	rule_lock = &sw->recp_list[ICE_SW_LKUP_MAC].filt_rule_lock;
	list_for_each_entry(m_list_itr, m_list, list_entry) {
		u8 *add = &m_list_itr->fltr_info.l_data.mac.mac_addr[0];
		u16 vsi_handle;
		u16 hw_vsi_id;

		m_list_itr->fltr_info.flag = ICE_FLTR_TX;
		vsi_handle = m_list_itr->fltr_info.vsi_handle;
		if (!ice_is_vsi_valid(hw, vsi_handle))
			return ICE_ERR_PARAM;
		hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle);
		m_list_itr->fltr_info.fwd_id.hw_vsi_id = hw_vsi_id;
		/* update the src in case it is VSI num */
		if (m_list_itr->fltr_info.src_id != ICE_SRC_ID_VSI)
			return ICE_ERR_PARAM;
		m_list_itr->fltr_info.src = hw_vsi_id;
		if (m_list_itr->fltr_info.lkup_type != ICE_SW_LKUP_MAC ||
		    is_zero_ether_addr(add))
			return ICE_ERR_PARAM;
		if (is_unicast_ether_addr(add) && !hw->ucast_shared) {
			/* Don't overwrite the unicast address */
			mutex_lock(rule_lock);
			if (ice_find_rule_entry(hw, ICE_SW_LKUP_MAC,
						&m_list_itr->fltr_info)) {
				mutex_unlock(rule_lock);
				return ICE_ERR_ALREADY_EXISTS;
			}
			mutex_unlock(rule_lock);
			num_unicast++;
		} else if (is_multicast_ether_addr(add) ||
			   (is_unicast_ether_addr(add) && hw->ucast_shared)) {
			m_list_itr->status =
				ice_add_rule_internal(hw, ICE_SW_LKUP_MAC,
						      m_list_itr);
			if (m_list_itr->status)
				return m_list_itr->status;
		}
	}

	mutex_lock(rule_lock);
	/* Exit if no suitable entries were found for adding bulk switch rule */
	if (!num_unicast) {
		status = 0;
		goto ice_add_mac_exit;
	}

	rule_head = &sw->recp_list[ICE_SW_LKUP_MAC].filt_rules;

	/* Allocate switch rule buffer for the bulk update for unicast */
	s_rule_size = ICE_SW_RULE_RX_TX_ETH_HDR_SIZE;
	s_rule = devm_kcalloc(ice_hw_to_dev(hw), num_unicast, s_rule_size,
			      GFP_KERNEL);
	if (!s_rule) {
		status = ICE_ERR_NO_MEMORY;
		goto ice_add_mac_exit;
	}

	r_iter = s_rule;
	list_for_each_entry(m_list_itr, m_list, list_entry) {
		struct ice_fltr_info *f_info = &m_list_itr->fltr_info;
		u8 *mac_addr = &f_info->l_data.mac.mac_addr[0];

		if (is_unicast_ether_addr(mac_addr)) {
			ice_fill_sw_rule(hw, &m_list_itr->fltr_info, r_iter,
					 ice_aqc_opc_add_sw_rules);
			r_iter = (struct ice_aqc_sw_rules_elem *)
				((u8 *)r_iter + s_rule_size);
		}
	}

	/* Call AQ bulk switch rule update for all unicast addresses */
	r_iter = s_rule;
	/* Call AQ switch rule in AQ_MAX chunk */
	for (total_elem_left = num_unicast; total_elem_left > 0;
	     total_elem_left -= elem_sent) {
		struct ice_aqc_sw_rules_elem *entry = r_iter;

		elem_sent = min_t(u8, total_elem_left,
				  (ICE_AQ_MAX_BUF_LEN / s_rule_size));
		status = ice_aq_sw_rules(hw, entry, elem_sent * s_rule_size,
					 elem_sent, ice_aqc_opc_add_sw_rules,
					 NULL);
		if (status)
			goto ice_add_mac_exit;
		r_iter = (struct ice_aqc_sw_rules_elem *)
			((u8 *)r_iter + (elem_sent * s_rule_size));
	}

	/* Fill up rule ID based on the value returned from FW */
	r_iter = s_rule;
	list_for_each_entry(m_list_itr, m_list, list_entry) {
		struct ice_fltr_info *f_info = &m_list_itr->fltr_info;
		u8 *mac_addr = &f_info->l_data.mac.mac_addr[0];
		struct ice_fltr_mgmt_list_entry *fm_entry;

		if (is_unicast_ether_addr(mac_addr)) {
			f_info->fltr_rule_id =
				le16_to_cpu(r_iter->pdata.lkup_tx_rx.index);
			f_info->fltr_act = ICE_FWD_TO_VSI;
			/* Create an entry to track this MAC address */
			fm_entry = devm_kzalloc(ice_hw_to_dev(hw),
						sizeof(*fm_entry), GFP_KERNEL);
			if (!fm_entry) {
				status = ICE_ERR_NO_MEMORY;
				goto ice_add_mac_exit;
			}
			fm_entry->fltr_info = *f_info;
			fm_entry->vsi_count = 1;
			/* The book keeping entries will get removed when
			 * base driver calls remove filter AQ command
			 */

			list_add(&fm_entry->list_entry, rule_head);
			r_iter = (struct ice_aqc_sw_rules_elem *)
				((u8 *)r_iter + s_rule_size);
		}
	}

ice_add_mac_exit:
	mutex_unlock(rule_lock);
	if (s_rule)
		devm_kfree(ice_hw_to_dev(hw), s_rule);
	return status;
}

/**
 * ice_add_vlan_internal - Add one VLAN based filter rule
 * @hw: pointer to the hardware structure
 * @f_entry: filter entry containing one VLAN information
 */
static enum ice_status
ice_add_vlan_internal(struct ice_hw *hw, struct ice_fltr_list_entry *f_entry)
{
	struct ice_switch_info *sw = hw->switch_info;
	struct ice_fltr_mgmt_list_entry *v_list_itr;
	struct ice_fltr_info *new_fltr, *cur_fltr;
	enum ice_sw_lkup_type lkup_type;
	u16 vsi_list_id = 0, vsi_handle;
	struct mutex *rule_lock; /* Lock to protect filter rule list */
	enum ice_status status = 0;

	if (!ice_is_vsi_valid(hw, f_entry->fltr_info.vsi_handle))
		return ICE_ERR_PARAM;

	f_entry->fltr_info.fwd_id.hw_vsi_id =
		ice_get_hw_vsi_num(hw, f_entry->fltr_info.vsi_handle);
	new_fltr = &f_entry->fltr_info;

	/* VLAN ID should only be 12 bits */
	if (new_fltr->l_data.vlan.vlan_id > ICE_MAX_VLAN_ID)
		return ICE_ERR_PARAM;

	if (new_fltr->src_id != ICE_SRC_ID_VSI)
		return ICE_ERR_PARAM;

	new_fltr->src = new_fltr->fwd_id.hw_vsi_id;
	lkup_type = new_fltr->lkup_type;
	vsi_handle = new_fltr->vsi_handle;
	rule_lock = &sw->recp_list[ICE_SW_LKUP_VLAN].filt_rule_lock;
	mutex_lock(rule_lock);
	v_list_itr = ice_find_rule_entry(hw, ICE_SW_LKUP_VLAN, new_fltr);
	if (!v_list_itr) {
		struct ice_vsi_list_map_info *map_info = NULL;

		if (new_fltr->fltr_act == ICE_FWD_TO_VSI) {
			/* All VLAN pruning rules use a VSI list. Check if
			 * there is already a VSI list containing VSI that we
			 * want to add. If found, use the same vsi_list_id for
			 * this new VLAN rule or else create a new list.
			 */
			map_info = ice_find_vsi_list_entry(hw, ICE_SW_LKUP_VLAN,
							   vsi_handle,
							   &vsi_list_id);
			if (!map_info) {
				status = ice_create_vsi_list_rule(hw,
								  &vsi_handle,
								  1,
								  &vsi_list_id,
								  lkup_type);
				if (status)
					goto exit;
			}
			/* Convert the action to forwarding to a VSI list. */
			new_fltr->fltr_act = ICE_FWD_TO_VSI_LIST;
			new_fltr->fwd_id.vsi_list_id = vsi_list_id;
		}

		status = ice_create_pkt_fwd_rule(hw, f_entry);
		if (!status) {
			v_list_itr = ice_find_rule_entry(hw, ICE_SW_LKUP_VLAN,
							 new_fltr);
			if (!v_list_itr) {
				status = ICE_ERR_DOES_NOT_EXIST;
				goto exit;
			}
			/* reuse VSI list for new rule and increment ref_cnt */
			if (map_info) {
				v_list_itr->vsi_list_info = map_info;
				map_info->ref_cnt++;
			} else {
				v_list_itr->vsi_list_info =
					ice_create_vsi_list_map(hw, &vsi_handle,
								1, vsi_list_id);
			}
		}
	} else if (v_list_itr->vsi_list_info->ref_cnt == 1) {
		/* Update existing VSI list to add new VSI ID only if it used
		 * by one VLAN rule.
		 */
		cur_fltr = &v_list_itr->fltr_info;
		status = ice_add_update_vsi_list(hw, v_list_itr, cur_fltr,
						 new_fltr);
	} else {
		/* If VLAN rule exists and VSI list being used by this rule is
		 * referenced by more than 1 VLAN rule. Then create a new VSI
		 * list appending previous VSI with new VSI and update existing
		 * VLAN rule to point to new VSI list ID
		 */
		struct ice_fltr_info tmp_fltr;
		u16 vsi_handle_arr[2];
		u16 cur_handle;

		/* Current implementation only supports reusing VSI list with
		 * one VSI count. We should never hit below condition
		 */
		if (v_list_itr->vsi_count > 1 &&
		    v_list_itr->vsi_list_info->ref_cnt > 1) {
			ice_debug(hw, ICE_DBG_SW, "Invalid configuration: Optimization to reuse VSI list with more than one VSI is not being done yet\n");
			status = ICE_ERR_CFG;
			goto exit;
		}

		cur_handle =
			find_first_bit(v_list_itr->vsi_list_info->vsi_map,
				       ICE_MAX_VSI);

		/* A rule already exists with the new VSI being added */
		if (cur_handle == vsi_handle) {
			status = ICE_ERR_ALREADY_EXISTS;
			goto exit;
		}

		vsi_handle_arr[0] = cur_handle;
		vsi_handle_arr[1] = vsi_handle;
		status = ice_create_vsi_list_rule(hw, &vsi_handle_arr[0], 2,
						  &vsi_list_id, lkup_type);
		if (status)
			goto exit;

		tmp_fltr = v_list_itr->fltr_info;
		tmp_fltr.fltr_rule_id = v_list_itr->fltr_info.fltr_rule_id;
		tmp_fltr.fwd_id.vsi_list_id = vsi_list_id;
		tmp_fltr.fltr_act = ICE_FWD_TO_VSI_LIST;
		/* Update the previous switch rule to a new VSI list which
		 * includes current VSI that is requested
		 */
		status = ice_update_pkt_fwd_rule(hw, &tmp_fltr);
		if (status)
			goto exit;

		/* before overriding VSI list map info. decrement ref_cnt of
		 * previous VSI list
		 */
		v_list_itr->vsi_list_info->ref_cnt--;

		/* now update to newly created list */
		v_list_itr->fltr_info.fwd_id.vsi_list_id = vsi_list_id;
		v_list_itr->vsi_list_info =
			ice_create_vsi_list_map(hw, &vsi_handle_arr[0], 2,
						vsi_list_id);
		v_list_itr->vsi_count++;
	}

exit:
	mutex_unlock(rule_lock);
	return status;
}

/**
 * ice_add_vlan - Add VLAN based filter rule
 * @hw: pointer to the hardware structure
 * @v_list: list of VLAN entries and forwarding information
 */
enum ice_status ice_add_vlan(struct ice_hw *hw, struct list_head *v_list)
{
	struct ice_fltr_list_entry *v_list_itr;

	if (!v_list || !hw)
		return ICE_ERR_PARAM;

	list_for_each_entry(v_list_itr, v_list, list_entry) {
		if (v_list_itr->fltr_info.lkup_type != ICE_SW_LKUP_VLAN)
			return ICE_ERR_PARAM;
		v_list_itr->fltr_info.flag = ICE_FLTR_TX;
		v_list_itr->status = ice_add_vlan_internal(hw, v_list_itr);
		if (v_list_itr->status)
			return v_list_itr->status;
	}
	return 0;
}

/**
 * ice_add_eth_mac - Add ethertype and MAC based filter rule
 * @hw: pointer to the hardware structure
 * @em_list: list of ether type MAC filter, MAC is optional
 *
 * This function requires the caller to populate the entries in
 * the filter list with the necessary fields (including flags to
 * indicate Tx or Rx rules).
 */
enum ice_status
ice_add_eth_mac(struct ice_hw *hw, struct list_head *em_list)
{
	struct ice_fltr_list_entry *em_list_itr;

	if (!em_list || !hw)
		return ICE_ERR_PARAM;

	list_for_each_entry(em_list_itr, em_list, list_entry) {
		enum ice_sw_lkup_type l_type =
			em_list_itr->fltr_info.lkup_type;

		if (l_type != ICE_SW_LKUP_ETHERTYPE_MAC &&
		    l_type != ICE_SW_LKUP_ETHERTYPE)
			return ICE_ERR_PARAM;

		em_list_itr->status = ice_add_rule_internal(hw, l_type,
							    em_list_itr);
		if (em_list_itr->status)
			return em_list_itr->status;
	}
	return 0;
}

/**
 * ice_remove_eth_mac - Remove an ethertype (or MAC) based filter rule
 * @hw: pointer to the hardware structure
 * @em_list: list of ethertype or ethertype MAC entries
 */
enum ice_status
ice_remove_eth_mac(struct ice_hw *hw, struct list_head *em_list)
{
	struct ice_fltr_list_entry *em_list_itr, *tmp;

	if (!em_list || !hw)
		return ICE_ERR_PARAM;

	list_for_each_entry_safe(em_list_itr, tmp, em_list, list_entry) {
		enum ice_sw_lkup_type l_type =
			em_list_itr->fltr_info.lkup_type;

		if (l_type != ICE_SW_LKUP_ETHERTYPE_MAC &&
		    l_type != ICE_SW_LKUP_ETHERTYPE)
			return ICE_ERR_PARAM;

		em_list_itr->status = ice_remove_rule_internal(hw, l_type,
							       em_list_itr);
		if (em_list_itr->status)
			return em_list_itr->status;
	}
	return 0;
}

/**
 * ice_rem_sw_rule_info
 * @hw: pointer to the hardware structure
 * @rule_head: pointer to the switch list structure that we want to delete
 */
static void
ice_rem_sw_rule_info(struct ice_hw *hw, struct list_head *rule_head)
{
	if (!list_empty(rule_head)) {
		struct ice_fltr_mgmt_list_entry *entry;
		struct ice_fltr_mgmt_list_entry *tmp;

		list_for_each_entry_safe(entry, tmp, rule_head, list_entry) {
			list_del(&entry->list_entry);
			devm_kfree(ice_hw_to_dev(hw), entry);
		}
	}
}

/**
 * ice_rem_adv_rule_info
 * @hw: pointer to the hardware structure
 * @rule_head: pointer to the switch list structure that we want to delete
 */
static void
ice_rem_adv_rule_info(struct ice_hw *hw, struct list_head *rule_head)
{
	struct ice_adv_fltr_mgmt_list_entry *tmp_entry;
	struct ice_adv_fltr_mgmt_list_entry *lst_itr;

	if (list_empty(rule_head))
		return;

	list_for_each_entry_safe(lst_itr, tmp_entry, rule_head, list_entry) {
		list_del(&lst_itr->list_entry);
		devm_kfree(ice_hw_to_dev(hw), lst_itr->lkups);
		devm_kfree(ice_hw_to_dev(hw), lst_itr);
	}
}

/**
 * ice_cfg_dflt_vsi - change state of VSI to set/clear default
 * @hw: pointer to the hardware structure
 * @vsi_handle: VSI handle to set as default
 * @set: true to add the above mentioned switch rule, false to remove it
 * @direction: ICE_FLTR_RX or ICE_FLTR_TX
 *
 * add filter rule to set/unset given VSI as default VSI for the switch
 * (represented by swid)
 */
enum ice_status
ice_cfg_dflt_vsi(struct ice_hw *hw, u16 vsi_handle, bool set, u8 direction)
{
	struct ice_aqc_sw_rules_elem *s_rule;
	struct ice_fltr_info f_info;
	enum ice_adminq_opc opcode;
	enum ice_status status;
	u16 s_rule_size;
	u16 hw_vsi_id;

	if (!ice_is_vsi_valid(hw, vsi_handle))
		return ICE_ERR_PARAM;
	hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle);

	s_rule_size = set ? ICE_SW_RULE_RX_TX_ETH_HDR_SIZE :
		ICE_SW_RULE_RX_TX_NO_HDR_SIZE;

	s_rule = devm_kzalloc(ice_hw_to_dev(hw), s_rule_size, GFP_KERNEL);
	if (!s_rule)
		return ICE_ERR_NO_MEMORY;

	memset(&f_info, 0, sizeof(f_info));

	f_info.lkup_type = ICE_SW_LKUP_DFLT;
	f_info.flag = direction;
	f_info.fltr_act = ICE_FWD_TO_VSI;
	f_info.fwd_id.hw_vsi_id = hw_vsi_id;

	if (f_info.flag & ICE_FLTR_RX) {
		f_info.src = hw->port_info->lport;
		f_info.src_id = ICE_SRC_ID_LPORT;
		if (!set)
			f_info.fltr_rule_id =
				hw->port_info->dflt_rx_vsi_rule_id;
	} else if (f_info.flag & ICE_FLTR_TX) {
		f_info.src_id = ICE_SRC_ID_VSI;
		f_info.src = hw_vsi_id;
		if (!set)
			f_info.fltr_rule_id =
				hw->port_info->dflt_tx_vsi_rule_id;
	}

	if (set)
		opcode = ice_aqc_opc_add_sw_rules;
	else
		opcode = ice_aqc_opc_remove_sw_rules;

	ice_fill_sw_rule(hw, &f_info, s_rule, opcode);

	status = ice_aq_sw_rules(hw, s_rule, s_rule_size, 1, opcode, NULL);
	if (status || !(f_info.flag & ICE_FLTR_TX_RX))
		goto out;
	if (set) {
		u16 index = le16_to_cpu(s_rule->pdata.lkup_tx_rx.index);

		if (f_info.flag & ICE_FLTR_TX) {
			hw->port_info->dflt_tx_vsi_num = hw_vsi_id;
			hw->port_info->dflt_tx_vsi_rule_id = index;
		} else if (f_info.flag & ICE_FLTR_RX) {
			hw->port_info->dflt_rx_vsi_num = hw_vsi_id;
			hw->port_info->dflt_rx_vsi_rule_id = index;
		}
	} else {
		if (f_info.flag & ICE_FLTR_TX) {
			hw->port_info->dflt_tx_vsi_num = ICE_DFLT_VSI_INVAL;
			hw->port_info->dflt_tx_vsi_rule_id = ICE_INVAL_ACT;
		} else if (f_info.flag & ICE_FLTR_RX) {
			hw->port_info->dflt_rx_vsi_num = ICE_DFLT_VSI_INVAL;
			hw->port_info->dflt_rx_vsi_rule_id = ICE_INVAL_ACT;
		}
	}

out:
	devm_kfree(ice_hw_to_dev(hw), s_rule);
	return status;
}

/**
 * ice_find_ucast_rule_entry - Search for a unicast MAC filter rule entry
 * @hw: pointer to the hardware structure
 * @recp_id: lookup type for which the specified rule needs to be searched
 * @f_info: rule information
 *
 * Helper function to search for a unicast rule entry - this is to be used
 * to remove unicast MAC filter that is not shared with other VSIs on the
 * PF switch.
 *
 * Returns pointer to entry storing the rule if found
 */
static struct ice_fltr_mgmt_list_entry *
ice_find_ucast_rule_entry(struct ice_hw *hw, u8 recp_id,
			  struct ice_fltr_info *f_info)
{
	struct ice_switch_info *sw = hw->switch_info;
	struct ice_fltr_mgmt_list_entry *list_itr;
	struct list_head *list_head;

	list_head = &sw->recp_list[recp_id].filt_rules;
	list_for_each_entry(list_itr, list_head, list_entry) {
		if (!memcmp(&f_info->l_data, &list_itr->fltr_info.l_data,
			    sizeof(f_info->l_data)) &&
		    f_info->fwd_id.hw_vsi_id ==
		    list_itr->fltr_info.fwd_id.hw_vsi_id &&
		    f_info->flag == list_itr->fltr_info.flag)
			return list_itr;
	}
	return NULL;
}

/**
 * ice_remove_mac - remove a MAC address based filter rule
 * @hw: pointer to the hardware structure
 * @m_list: list of MAC addresses and forwarding information
 *
 * This function removes either a MAC filter rule or a specific VSI from a
 * VSI list for a multicast MAC address.
 *
 * Returns ICE_ERR_DOES_NOT_EXIST if a given entry was not added by
 * ice_add_mac. Caller should be aware that this call will only work if all
 * the entries passed into m_list were added previously. It will not attempt to
 * do a partial remove of entries that were found.
 */
enum ice_status ice_remove_mac(struct ice_hw *hw, struct list_head *m_list)
{
	struct ice_fltr_list_entry *list_itr, *tmp;
	struct mutex *rule_lock; /* Lock to protect filter rule list */

	if (!m_list)
		return ICE_ERR_PARAM;

	rule_lock = &hw->switch_info->recp_list[ICE_SW_LKUP_MAC].filt_rule_lock;
	list_for_each_entry_safe(list_itr, tmp, m_list, list_entry) {
		enum ice_sw_lkup_type l_type = list_itr->fltr_info.lkup_type;
		u8 *add = &list_itr->fltr_info.l_data.mac.mac_addr[0];
		u16 vsi_handle;

		if (l_type != ICE_SW_LKUP_MAC)
			return ICE_ERR_PARAM;

		vsi_handle = list_itr->fltr_info.vsi_handle;
		if (!ice_is_vsi_valid(hw, vsi_handle))
			return ICE_ERR_PARAM;

		list_itr->fltr_info.fwd_id.hw_vsi_id =
					ice_get_hw_vsi_num(hw, vsi_handle);
		if (is_unicast_ether_addr(add) && !hw->ucast_shared) {
			/* Don't remove the unicast address that belongs to
			 * another VSI on the switch, since it is not being
			 * shared...
			 */
			mutex_lock(rule_lock);
			if (!ice_find_ucast_rule_entry(hw, ICE_SW_LKUP_MAC,
						       &list_itr->fltr_info)) {
				mutex_unlock(rule_lock);
				return ICE_ERR_DOES_NOT_EXIST;
			}
			mutex_unlock(rule_lock);
		}
		list_itr->status = ice_remove_rule_internal(hw,
							    ICE_SW_LKUP_MAC,
							    list_itr);
		if (list_itr->status)
			return list_itr->status;
	}
	return 0;
}

/**
 * ice_remove_vlan - Remove VLAN based filter rule
 * @hw: pointer to the hardware structure
 * @v_list: list of VLAN entries and forwarding information
 */
enum ice_status
ice_remove_vlan(struct ice_hw *hw, struct list_head *v_list)
{
	struct ice_fltr_list_entry *v_list_itr, *tmp;

	if (!v_list || !hw)
		return ICE_ERR_PARAM;

	list_for_each_entry_safe(v_list_itr, tmp, v_list, list_entry) {
		enum ice_sw_lkup_type l_type = v_list_itr->fltr_info.lkup_type;

		if (l_type != ICE_SW_LKUP_VLAN)
			return ICE_ERR_PARAM;
		v_list_itr->status = ice_remove_rule_internal(hw,
							      ICE_SW_LKUP_VLAN,
							      v_list_itr);
		if (v_list_itr->status)
			return v_list_itr->status;
	}
	return 0;
}

/**
 * ice_vsi_uses_fltr - Determine if given VSI uses specified filter
 * @fm_entry: filter entry to inspect
 * @vsi_handle: VSI handle to compare with filter info
 */
static bool
ice_vsi_uses_fltr(struct ice_fltr_mgmt_list_entry *fm_entry, u16 vsi_handle)
{
	return ((fm_entry->fltr_info.fltr_act == ICE_FWD_TO_VSI &&
		 fm_entry->fltr_info.vsi_handle == vsi_handle) ||
		(fm_entry->fltr_info.fltr_act == ICE_FWD_TO_VSI_LIST &&
		 fm_entry->vsi_list_info &&
		 (test_bit(vsi_handle, fm_entry->vsi_list_info->vsi_map))));
}

/**
 * ice_add_entry_to_vsi_fltr_list - Add copy of fltr_list_entry to remove list
 * @hw: pointer to the hardware structure
 * @vsi_handle: VSI handle to remove filters from
 * @vsi_list_head: pointer to the list to add entry to
 * @fi: pointer to fltr_info of filter entry to copy & add
 *
 * Helper function, used when creating a list of filters to remove from
 * a specific VSI. The entry added to vsi_list_head is a COPY of the
 * original filter entry, with the exception of fltr_info.fltr_act and
 * fltr_info.fwd_id fields. These are set such that later logic can
 * extract which VSI to remove the fltr from, and pass on that information.
 */
static enum ice_status
ice_add_entry_to_vsi_fltr_list(struct ice_hw *hw, u16 vsi_handle,
			       struct list_head *vsi_list_head,
			       struct ice_fltr_info *fi)
{
	struct ice_fltr_list_entry *tmp;

	/* this memory is freed up in the caller function
	 * once filters for this VSI are removed
	 */
	tmp = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*tmp), GFP_KERNEL);
	if (!tmp)
		return ICE_ERR_NO_MEMORY;

	tmp->fltr_info = *fi;

	/* Overwrite these fields to indicate which VSI to remove filter from,
	 * so find and remove logic can extract the information from the
	 * list entries. Note that original entries will still have proper
	 * values.
	 */
	tmp->fltr_info.fltr_act = ICE_FWD_TO_VSI;
	tmp->fltr_info.vsi_handle = vsi_handle;
	tmp->fltr_info.fwd_id.hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle);

	list_add(&tmp->list_entry, vsi_list_head);

	return 0;
}

/**
 * ice_add_to_vsi_fltr_list - Add VSI filters to the list
 * @hw: pointer to the hardware structure
 * @vsi_handle: VSI handle to remove filters from
 * @lkup_list_head: pointer to the list that has certain lookup type filters
 * @vsi_list_head: pointer to the list pertaining to VSI with vsi_handle
 *
 * Locates all filters in lkup_list_head that are used by the given VSI,
 * and adds COPIES of those entries to vsi_list_head (intended to be used
 * to remove the listed filters).
 * Note that this means all entries in vsi_list_head must be explicitly
 * deallocated by the caller when done with list.
 */
static enum ice_status
ice_add_to_vsi_fltr_list(struct ice_hw *hw, u16 vsi_handle,
			 struct list_head *lkup_list_head,
			 struct list_head *vsi_list_head)
{
	struct ice_fltr_mgmt_list_entry *fm_entry;
	enum ice_status status = 0;

	/* check to make sure VSI ID is valid and within boundary */
	if (!ice_is_vsi_valid(hw, vsi_handle))
		return ICE_ERR_PARAM;

	list_for_each_entry(fm_entry, lkup_list_head, list_entry) {
		if (!ice_vsi_uses_fltr(fm_entry, vsi_handle))
			continue;

		status = ice_add_entry_to_vsi_fltr_list(hw, vsi_handle,
							vsi_list_head,
							&fm_entry->fltr_info);
		if (status)
			return status;
	}
	return status;
}

/**
 * ice_determine_promisc_mask
 * @fi: filter info to parse
 *
 * Helper function to determine which ICE_PROMISC_ mask corresponds
 * to given filter into.
 */
static u8 ice_determine_promisc_mask(struct ice_fltr_info *fi)
{
	u16 vid = fi->l_data.mac_vlan.vlan_id;
	u8 *macaddr = fi->l_data.mac.mac_addr;
	bool is_tx_fltr = false;
	u8 promisc_mask = 0;

	if (fi->flag == ICE_FLTR_TX)
		is_tx_fltr = true;

	if (is_broadcast_ether_addr(macaddr))
		promisc_mask |= is_tx_fltr ?
			ICE_PROMISC_BCAST_TX : ICE_PROMISC_BCAST_RX;
	else if (is_multicast_ether_addr(macaddr))
		promisc_mask |= is_tx_fltr ?
			ICE_PROMISC_MCAST_TX : ICE_PROMISC_MCAST_RX;
	else if (is_unicast_ether_addr(macaddr))
		promisc_mask |= is_tx_fltr ?
			ICE_PROMISC_UCAST_TX : ICE_PROMISC_UCAST_RX;
	if (vid)
		promisc_mask |= is_tx_fltr ?
			ICE_PROMISC_VLAN_TX : ICE_PROMISC_VLAN_RX;

	return promisc_mask;
}

/**
 * ice_remove_promisc - Remove promisc based filter rules
 * @hw: pointer to the hardware structure
 * @recp_id: recipe ID for which the rule needs to removed
 * @v_list: list of promisc entries
 */
static enum ice_status
ice_remove_promisc(struct ice_hw *hw, u8 recp_id,
		   struct list_head *v_list)
{
	struct ice_fltr_list_entry *v_list_itr, *tmp;

	list_for_each_entry_safe(v_list_itr, tmp, v_list, list_entry) {
		v_list_itr->status =
			ice_remove_rule_internal(hw, recp_id, v_list_itr);
		if (v_list_itr->status)
			return v_list_itr->status;
	}
	return 0;
}

/**
 * ice_clear_vsi_promisc - clear specified promiscuous mode(s) for given VSI
 * @hw: pointer to the hardware structure
 * @vsi_handle: VSI handle to clear mode
 * @promisc_mask: mask of promiscuous config bits to clear
 * @vid: VLAN ID to clear VLAN promiscuous
 */
enum ice_status
ice_clear_vsi_promisc(struct ice_hw *hw, u16 vsi_handle, u8 promisc_mask,
		      u16 vid)
{
	struct ice_switch_info *sw = hw->switch_info;
	struct ice_fltr_list_entry *fm_entry, *tmp;
	struct list_head remove_list_head;
	struct ice_fltr_mgmt_list_entry *itr;
	struct list_head *rule_head;
	struct mutex *rule_lock;	/* Lock to protect filter rule list */
	enum ice_status status = 0;
	u8 recipe_id;

	if (!ice_is_vsi_valid(hw, vsi_handle))
		return ICE_ERR_PARAM;

	if (promisc_mask & (ICE_PROMISC_VLAN_RX | ICE_PROMISC_VLAN_TX))
		recipe_id = ICE_SW_LKUP_PROMISC_VLAN;
	else
		recipe_id = ICE_SW_LKUP_PROMISC;

	rule_head = &sw->recp_list[recipe_id].filt_rules;
	rule_lock = &sw->recp_list[recipe_id].filt_rule_lock;

	INIT_LIST_HEAD(&remove_list_head);

	mutex_lock(rule_lock);
	list_for_each_entry(itr, rule_head, list_entry) {
		struct ice_fltr_info *fltr_info;
		u8 fltr_promisc_mask = 0;

		if (!ice_vsi_uses_fltr(itr, vsi_handle))
			continue;
		fltr_info = &itr->fltr_info;

		if (recipe_id == ICE_SW_LKUP_PROMISC_VLAN &&
		    vid != fltr_info->l_data.mac_vlan.vlan_id)
			continue;

		fltr_promisc_mask |= ice_determine_promisc_mask(fltr_info);

		/* Skip if filter is not completely specified by given mask */
		if (fltr_promisc_mask & ~promisc_mask)
			continue;

		status = ice_add_entry_to_vsi_fltr_list(hw, vsi_handle,
							&remove_list_head,
							fltr_info);
		if (status) {
			mutex_unlock(rule_lock);
			goto free_fltr_list;
		}
	}
	mutex_unlock(rule_lock);

	status = ice_remove_promisc(hw, recipe_id, &remove_list_head);

free_fltr_list:
	list_for_each_entry_safe(fm_entry, tmp, &remove_list_head, list_entry) {
		list_del(&fm_entry->list_entry);
		devm_kfree(ice_hw_to_dev(hw), fm_entry);
	}

	return status;
}

/**
 * ice_set_vsi_promisc - set given VSI to given promiscuous mode(s)
 * @hw: pointer to the hardware structure
 * @vsi_handle: VSI handle to configure
 * @promisc_mask: mask of promiscuous config bits
 * @vid: VLAN ID to set VLAN promiscuous
 */
enum ice_status
ice_set_vsi_promisc(struct ice_hw *hw, u16 vsi_handle, u8 promisc_mask, u16 vid)
{
	enum { UCAST_FLTR = 1, MCAST_FLTR, BCAST_FLTR };
	struct ice_fltr_list_entry f_list_entry;
	struct ice_fltr_info new_fltr;
	enum ice_status status = 0;
	bool is_tx_fltr;
	u16 hw_vsi_id;
	int pkt_type;
	u8 recipe_id;

	if (!ice_is_vsi_valid(hw, vsi_handle))
		return ICE_ERR_PARAM;
	hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle);

	memset(&new_fltr, 0, sizeof(new_fltr));

	if (promisc_mask & (ICE_PROMISC_VLAN_RX | ICE_PROMISC_VLAN_TX)) {
		new_fltr.lkup_type = ICE_SW_LKUP_PROMISC_VLAN;
		new_fltr.l_data.mac_vlan.vlan_id = vid;
		recipe_id = ICE_SW_LKUP_PROMISC_VLAN;
	} else {
		new_fltr.lkup_type = ICE_SW_LKUP_PROMISC;
		recipe_id = ICE_SW_LKUP_PROMISC;
	}

	/* Separate filters must be set for each direction/packet type
	 * combination, so we will loop over the mask value, store the
	 * individual type, and clear it out in the input mask as it
	 * is found.
	 */
	while (promisc_mask) {
		u8 *mac_addr;

		pkt_type = 0;
		is_tx_fltr = false;

		if (promisc_mask & ICE_PROMISC_UCAST_RX) {
			promisc_mask &= ~ICE_PROMISC_UCAST_RX;
			pkt_type = UCAST_FLTR;
		} else if (promisc_mask & ICE_PROMISC_UCAST_TX) {
			promisc_mask &= ~ICE_PROMISC_UCAST_TX;
			pkt_type = UCAST_FLTR;
			is_tx_fltr = true;
		} else if (promisc_mask & ICE_PROMISC_MCAST_RX) {
			promisc_mask &= ~ICE_PROMISC_MCAST_RX;
			pkt_type = MCAST_FLTR;
		} else if (promisc_mask & ICE_PROMISC_MCAST_TX) {
			promisc_mask &= ~ICE_PROMISC_MCAST_TX;
			pkt_type = MCAST_FLTR;
			is_tx_fltr = true;
		} else if (promisc_mask & ICE_PROMISC_BCAST_RX) {
			promisc_mask &= ~ICE_PROMISC_BCAST_RX;
			pkt_type = BCAST_FLTR;
		} else if (promisc_mask & ICE_PROMISC_BCAST_TX) {
			promisc_mask &= ~ICE_PROMISC_BCAST_TX;
			pkt_type = BCAST_FLTR;
			is_tx_fltr = true;
		}

		/* Check for VLAN promiscuous flag */
		if (promisc_mask & ICE_PROMISC_VLAN_RX) {
			promisc_mask &= ~ICE_PROMISC_VLAN_RX;
		} else if (promisc_mask & ICE_PROMISC_VLAN_TX) {
			promisc_mask &= ~ICE_PROMISC_VLAN_TX;
			is_tx_fltr = true;
		}

		/* Set filter DA based on packet type */
		mac_addr = new_fltr.l_data.mac.mac_addr;
		if (pkt_type == BCAST_FLTR) {
			eth_broadcast_addr(mac_addr);
		} else if (pkt_type == MCAST_FLTR ||
			   pkt_type == UCAST_FLTR) {
			/* Use the dummy ether header DA */
			ether_addr_copy(mac_addr, dummy_eth_header);
			if (pkt_type == MCAST_FLTR)
				mac_addr[0] |= 0x1;	/* Set multicast bit */
		}

		/* Need to reset this to zero for all iterations */
		new_fltr.flag = 0;
		if (is_tx_fltr) {
			new_fltr.flag |= ICE_FLTR_TX;
			new_fltr.src = hw_vsi_id;
		} else {
			new_fltr.flag |= ICE_FLTR_RX;
			new_fltr.src = hw->port_info->lport;
		}

		new_fltr.fltr_act = ICE_FWD_TO_VSI;
		new_fltr.vsi_handle = vsi_handle;
		new_fltr.fwd_id.hw_vsi_id = hw_vsi_id;
		f_list_entry.fltr_info = new_fltr;

		status = ice_add_rule_internal(hw, recipe_id, &f_list_entry);
		if (status)
			goto set_promisc_exit;
	}

set_promisc_exit:
	return status;
}

/**
 * ice_set_vlan_vsi_promisc
 * @hw: pointer to the hardware structure
 * @vsi_handle: VSI handle to configure
 * @promisc_mask: mask of promiscuous config bits
 * @rm_vlan_promisc: Clear VLANs VSI promisc mode
 *
 * Configure VSI with all associated VLANs to given promiscuous mode(s)
 */
enum ice_status
ice_set_vlan_vsi_promisc(struct ice_hw *hw, u16 vsi_handle, u8 promisc_mask,
			 bool rm_vlan_promisc)
{
	struct ice_switch_info *sw = hw->switch_info;
	struct ice_fltr_list_entry *list_itr, *tmp;
	struct list_head vsi_list_head;
	struct list_head *vlan_head;
	struct mutex *vlan_lock; /* Lock to protect filter rule list */
	enum ice_status status;
	u16 vlan_id;

	INIT_LIST_HEAD(&vsi_list_head);
	vlan_lock = &sw->recp_list[ICE_SW_LKUP_VLAN].filt_rule_lock;
	vlan_head = &sw->recp_list[ICE_SW_LKUP_VLAN].filt_rules;
	mutex_lock(vlan_lock);
	status = ice_add_to_vsi_fltr_list(hw, vsi_handle, vlan_head,
					  &vsi_list_head);
	mutex_unlock(vlan_lock);
	if (status)
		goto free_fltr_list;

	list_for_each_entry(list_itr, &vsi_list_head, list_entry) {
		vlan_id = list_itr->fltr_info.l_data.vlan.vlan_id;
		if (rm_vlan_promisc)
			status = ice_clear_vsi_promisc(hw, vsi_handle,
						       promisc_mask, vlan_id);
		else
			status = ice_set_vsi_promisc(hw, vsi_handle,
						     promisc_mask, vlan_id);
		if (status)
			break;
	}

free_fltr_list:
	list_for_each_entry_safe(list_itr, tmp, &vsi_list_head, list_entry) {
		list_del(&list_itr->list_entry);
		devm_kfree(ice_hw_to_dev(hw), list_itr);
	}
	return status;
}

/**
 * ice_remove_vsi_lkup_fltr - Remove lookup type filters for a VSI
 * @hw: pointer to the hardware structure
 * @vsi_handle: VSI handle to remove filters from
 * @lkup: switch rule filter lookup type
 */
static void
ice_remove_vsi_lkup_fltr(struct ice_hw *hw, u16 vsi_handle,
			 enum ice_sw_lkup_type lkup)
{
	struct ice_switch_info *sw = hw->switch_info;
	struct ice_fltr_list_entry *fm_entry;
	struct list_head remove_list_head;
	struct list_head *rule_head;
	struct ice_fltr_list_entry *tmp;
	struct mutex *rule_lock;	/* Lock to protect filter rule list */
	enum ice_status status;

	INIT_LIST_HEAD(&remove_list_head);
	rule_lock = &sw->recp_list[lkup].filt_rule_lock;
	rule_head = &sw->recp_list[lkup].filt_rules;
	mutex_lock(rule_lock);
	status = ice_add_to_vsi_fltr_list(hw, vsi_handle, rule_head,
					  &remove_list_head);
	mutex_unlock(rule_lock);
	if (status)
		goto free_fltr_list;

	switch (lkup) {
	case ICE_SW_LKUP_MAC:
		ice_remove_mac(hw, &remove_list_head);
		break;
	case ICE_SW_LKUP_VLAN:
		ice_remove_vlan(hw, &remove_list_head);
		break;
	case ICE_SW_LKUP_PROMISC:
	case ICE_SW_LKUP_PROMISC_VLAN:
		ice_remove_promisc(hw, lkup, &remove_list_head);
		break;
	case ICE_SW_LKUP_MAC_VLAN:
	case ICE_SW_LKUP_ETHERTYPE:
	case ICE_SW_LKUP_ETHERTYPE_MAC:
	case ICE_SW_LKUP_DFLT:
	case ICE_SW_LKUP_LAST:
	default:
		ice_debug(hw, ICE_DBG_SW, "Unsupported lookup type %d\n", lkup);
		break;
	}

free_fltr_list:
	list_for_each_entry_safe(fm_entry, tmp, &remove_list_head, list_entry) {
		list_del(&fm_entry->list_entry);
		devm_kfree(ice_hw_to_dev(hw), fm_entry);
	}
}

/**
 * ice_remove_vsi_fltr - Remove all filters for a VSI
 * @hw: pointer to the hardware structure
 * @vsi_handle: VSI handle to remove filters from
 */
void ice_remove_vsi_fltr(struct ice_hw *hw, u16 vsi_handle)
{
	ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_MAC);
	ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_MAC_VLAN);
	ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_PROMISC);
	ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_VLAN);
	ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_DFLT);
	ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_ETHERTYPE);
	ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_ETHERTYPE_MAC);
	ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_PROMISC_VLAN);
}

/**
 * ice_alloc_res_cntr - allocating resource counter
 * @hw: pointer to the hardware structure
 * @type: type of resource
 * @alloc_shared: if set it is shared else dedicated
 * @num_items: number of entries requested for FD resource type
 * @counter_id: counter index returned by AQ call
 */
enum ice_status
ice_alloc_res_cntr(struct ice_hw *hw, u8 type, u8 alloc_shared, u16 num_items,
		   u16 *counter_id)
{
	struct ice_aqc_alloc_free_res_elem *buf;
	enum ice_status status;
	u16 buf_len;

	/* Allocate resource */
	buf_len = struct_size(buf, elem, 1);
	buf = kzalloc(buf_len, GFP_KERNEL);
	if (!buf)
		return ICE_ERR_NO_MEMORY;

	buf->num_elems = cpu_to_le16(num_items);
	buf->res_type = cpu_to_le16(((type << ICE_AQC_RES_TYPE_S) &
				      ICE_AQC_RES_TYPE_M) | alloc_shared);

	status = ice_aq_alloc_free_res(hw, 1, buf, buf_len,
				       ice_aqc_opc_alloc_res, NULL);
	if (status)
		goto exit;

	*counter_id = le16_to_cpu(buf->elem[0].e.sw_resp);

exit:
	kfree(buf);
	return status;
}

/**
 * ice_free_res_cntr - free resource counter
 * @hw: pointer to the hardware structure
 * @type: type of resource
 * @alloc_shared: if set it is shared else dedicated
 * @num_items: number of entries to be freed for FD resource type
 * @counter_id: counter ID resource which needs to be freed
 */
enum ice_status
ice_free_res_cntr(struct ice_hw *hw, u8 type, u8 alloc_shared, u16 num_items,
		  u16 counter_id)
{
	struct ice_aqc_alloc_free_res_elem *buf;
	enum ice_status status;
	u16 buf_len;

	/* Free resource */
	buf_len = struct_size(buf, elem, 1);
	buf = kzalloc(buf_len, GFP_KERNEL);
	if (!buf)
		return ICE_ERR_NO_MEMORY;

	buf->num_elems = cpu_to_le16(num_items);
	buf->res_type = cpu_to_le16(((type << ICE_AQC_RES_TYPE_S) &
				      ICE_AQC_RES_TYPE_M) | alloc_shared);
	buf->elem[0].e.sw_resp = cpu_to_le16(counter_id);

	status = ice_aq_alloc_free_res(hw, 1, buf, buf_len,
				       ice_aqc_opc_free_res, NULL);
	if (status)
		ice_debug(hw, ICE_DBG_SW, "counter resource could not be freed\n");

	kfree(buf);
	return status;
}

/* This is mapping table entry that maps every word within a given protocol
 * structure to the real byte offset as per the specification of that
 * protocol header.
 * for example dst address is 3 words in ethertype header and corresponding
 * bytes are 0, 2, 3 in the actual packet header and src address is at 4, 6, 8
 * IMPORTANT: Every structure part of "ice_prot_hdr" union should have a
 * matching entry describing its field. This needs to be updated if new
 * structure is added to that union.
 */
static const struct ice_prot_ext_tbl_entry ice_prot_ext[ICE_PROTOCOL_LAST] = {
	{ ICE_MAC_OFOS,		{ 0, 2, 4, 6, 8, 10, 12 } },
	{ ICE_MAC_IL,		{ 0, 2, 4, 6, 8, 10, 12 } },
	{ ICE_ETYPE_OL,		{ 0 } },
	{ ICE_VLAN_OFOS,	{ 2, 0 } },
	{ ICE_IPV4_OFOS,	{ 0, 2, 4, 6, 8, 10, 12, 14, 16, 18 } },
	{ ICE_IPV4_IL,		{ 0, 2, 4, 6, 8, 10, 12, 14, 16, 18 } },
	{ ICE_IPV6_OFOS,	{ 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24,
				 26, 28, 30, 32, 34, 36, 38 } },
	{ ICE_IPV6_IL,		{ 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24,
				 26, 28, 30, 32, 34, 36, 38 } },
	{ ICE_TCP_IL,		{ 0, 2 } },
	{ ICE_UDP_OF,		{ 0, 2 } },
	{ ICE_UDP_ILOS,		{ 0, 2 } },
	{ ICE_VXLAN,		{ 8, 10, 12, 14 } },
	{ ICE_GENEVE,		{ 8, 10, 12, 14 } },
	{ ICE_NVGRE,            { 0, 2, 4, 6 } },
};

static struct ice_protocol_entry ice_prot_id_tbl[ICE_PROTOCOL_LAST] = {
	{ ICE_MAC_OFOS,		ICE_MAC_OFOS_HW },
	{ ICE_MAC_IL,		ICE_MAC_IL_HW },
	{ ICE_ETYPE_OL,		ICE_ETYPE_OL_HW },
	{ ICE_VLAN_OFOS,	ICE_VLAN_OL_HW },
	{ ICE_IPV4_OFOS,	ICE_IPV4_OFOS_HW },
	{ ICE_IPV4_IL,		ICE_IPV4_IL_HW },
	{ ICE_IPV6_OFOS,	ICE_IPV6_OFOS_HW },
	{ ICE_IPV6_IL,		ICE_IPV6_IL_HW },
	{ ICE_TCP_IL,		ICE_TCP_IL_HW },
	{ ICE_UDP_OF,		ICE_UDP_OF_HW },
	{ ICE_UDP_ILOS,		ICE_UDP_ILOS_HW },
	{ ICE_VXLAN,		ICE_UDP_OF_HW },
	{ ICE_GENEVE,		ICE_UDP_OF_HW },
	{ ICE_NVGRE,            ICE_GRE_OF_HW },
};

/**
 * ice_find_recp - find a recipe
 * @hw: pointer to the hardware structure
 * @lkup_exts: extension sequence to match
 *
 * Returns index of matching recipe, or ICE_MAX_NUM_RECIPES if not found.
 */
static u16 ice_find_recp(struct ice_hw *hw, struct ice_prot_lkup_ext *lkup_exts)
{
	bool refresh_required = true;
	struct ice_sw_recipe *recp;
	u8 i;

	/* Walk through existing recipes to find a match */
	recp = hw->switch_info->recp_list;
	for (i = 0; i < ICE_MAX_NUM_RECIPES; i++) {
		/* If recipe was not created for this ID, in SW bookkeeping,
		 * check if FW has an entry for this recipe. If the FW has an
		 * entry update it in our SW bookkeeping and continue with the
		 * matching.
		 */
		if (!recp[i].recp_created)
			if (ice_get_recp_frm_fw(hw,
						hw->switch_info->recp_list, i,
						&refresh_required))
				continue;

		/* Skip inverse action recipes */
		if (recp[i].root_buf && recp[i].root_buf->content.act_ctrl &
		    ICE_AQ_RECIPE_ACT_INV_ACT)
			continue;

		/* if number of words we are looking for match */
		if (lkup_exts->n_val_words == recp[i].lkup_exts.n_val_words) {
			struct ice_fv_word *ar = recp[i].lkup_exts.fv_words;
			struct ice_fv_word *be = lkup_exts->fv_words;
			u16 *cr = recp[i].lkup_exts.field_mask;
			u16 *de = lkup_exts->field_mask;
			bool found = true;
			u8 pe, qr;

			/* ar, cr, and qr are related to the recipe words, while
			 * be, de, and pe are related to the lookup words
			 */
			for (pe = 0; pe < lkup_exts->n_val_words; pe++) {
				for (qr = 0; qr < recp[i].lkup_exts.n_val_words;
				     qr++) {
					if (ar[qr].off == be[pe].off &&
					    ar[qr].prot_id == be[pe].prot_id &&
					    cr[qr] == de[pe])
						/* Found the "pe"th word in the
						 * given recipe
						 */
						break;
				}
				/* After walking through all the words in the
				 * "i"th recipe if "p"th word was not found then
				 * this recipe is not what we are looking for.
				 * So break out from this loop and try the next
				 * recipe
				 */
				if (qr >= recp[i].lkup_exts.n_val_words) {
					found = false;
					break;
				}
			}
			/* If for "i"th recipe the found was never set to false
			 * then it means we found our match
			 */
			if (found)
				return i; /* Return the recipe ID */
		}
	}
	return ICE_MAX_NUM_RECIPES;
}

/**
 * ice_prot_type_to_id - get protocol ID from protocol type
 * @type: protocol type
 * @id: pointer to variable that will receive the ID
 *
 * Returns true if found, false otherwise
 */
static bool ice_prot_type_to_id(enum ice_protocol_type type, u8 *id)
{
	u8 i;

	for (i = 0; i < ARRAY_SIZE(ice_prot_id_tbl); i++)
		if (ice_prot_id_tbl[i].type == type) {
			*id = ice_prot_id_tbl[i].protocol_id;
			return true;
		}
	return false;
}

/**
 * ice_fill_valid_words - count valid words
 * @rule: advanced rule with lookup information
 * @lkup_exts: byte offset extractions of the words that are valid
 *
 * calculate valid words in a lookup rule using mask value
 */
static u8
ice_fill_valid_words(struct ice_adv_lkup_elem *rule,
		     struct ice_prot_lkup_ext *lkup_exts)
{
	u8 j, word, prot_id, ret_val;

	if (!ice_prot_type_to_id(rule->type, &prot_id))
		return 0;

	word = lkup_exts->n_val_words;

	for (j = 0; j < sizeof(rule->m_u) / sizeof(u16); j++)
		if (((u16 *)&rule->m_u)[j] &&
		    rule->type < ARRAY_SIZE(ice_prot_ext)) {
			/* No more space to accommodate */
			if (word >= ICE_MAX_CHAIN_WORDS)
				return 0;
			lkup_exts->fv_words[word].off =
				ice_prot_ext[rule->type].offs[j];
			lkup_exts->fv_words[word].prot_id =
				ice_prot_id_tbl[rule->type].protocol_id;
			lkup_exts->field_mask[word] =
				be16_to_cpu(((__force __be16 *)&rule->m_u)[j]);
			word++;
		}

	ret_val = word - lkup_exts->n_val_words;
	lkup_exts->n_val_words = word;

	return ret_val;
}

/**
 * ice_create_first_fit_recp_def - Create a recipe grouping
 * @hw: pointer to the hardware structure
 * @lkup_exts: an array of protocol header extractions
 * @rg_list: pointer to a list that stores new recipe groups
 * @recp_cnt: pointer to a variable that stores returned number of recipe groups
 *
 * Using first fit algorithm, take all the words that are still not done
 * and start grouping them in 4-word groups. Each group makes up one
 * recipe.
 */
static enum ice_status
ice_create_first_fit_recp_def(struct ice_hw *hw,
			      struct ice_prot_lkup_ext *lkup_exts,
			      struct list_head *rg_list,
			      u8 *recp_cnt)
{
	struct ice_pref_recipe_group *grp = NULL;
	u8 j;

	*recp_cnt = 0;

	/* Walk through every word in the rule to check if it is not done. If so
	 * then this word needs to be part of a new recipe.
	 */
	for (j = 0; j < lkup_exts->n_val_words; j++)
		if (!test_bit(j, lkup_exts->done)) {
			if (!grp ||
			    grp->n_val_pairs == ICE_NUM_WORDS_RECIPE) {
				struct ice_recp_grp_entry *entry;

				entry = devm_kzalloc(ice_hw_to_dev(hw),
						     sizeof(*entry),
						     GFP_KERNEL);
				if (!entry)
					return ICE_ERR_NO_MEMORY;
				list_add(&entry->l_entry, rg_list);
				grp = &entry->r_group;
				(*recp_cnt)++;
			}

			grp->pairs[grp->n_val_pairs].prot_id =
				lkup_exts->fv_words[j].prot_id;
			grp->pairs[grp->n_val_pairs].off =
				lkup_exts->fv_words[j].off;
			grp->mask[grp->n_val_pairs] = lkup_exts->field_mask[j];
			grp->n_val_pairs++;
		}

	return 0;
}

/**
 * ice_fill_fv_word_index - fill in the field vector indices for a recipe group
 * @hw: pointer to the hardware structure
 * @fv_list: field vector with the extraction sequence information
 * @rg_list: recipe groupings with protocol-offset pairs
 *
 * Helper function to fill in the field vector indices for protocol-offset
 * pairs. These indexes are then ultimately programmed into a recipe.
 */
static enum ice_status
ice_fill_fv_word_index(struct ice_hw *hw, struct list_head *fv_list,
		       struct list_head *rg_list)
{
	struct ice_sw_fv_list_entry *fv;
	struct ice_recp_grp_entry *rg;
	struct ice_fv_word *fv_ext;

	if (list_empty(fv_list))
		return 0;

	fv = list_first_entry(fv_list, struct ice_sw_fv_list_entry,
			      list_entry);
	fv_ext = fv->fv_ptr->ew;

	list_for_each_entry(rg, rg_list, l_entry) {
		u8 i;

		for (i = 0; i < rg->r_group.n_val_pairs; i++) {
			struct ice_fv_word *pr;
			bool found = false;
			u16 mask;
			u8 j;

			pr = &rg->r_group.pairs[i];
			mask = rg->r_group.mask[i];

			for (j = 0; j < hw->blk[ICE_BLK_SW].es.fvw; j++)
				if (fv_ext[j].prot_id == pr->prot_id &&
				    fv_ext[j].off == pr->off) {
					found = true;

					/* Store index of field vector */
					rg->fv_idx[i] = j;
					rg->fv_mask[i] = mask;
					break;
				}

			/* Protocol/offset could not be found, caller gave an
			 * invalid pair
			 */
			if (!found)
				return ICE_ERR_PARAM;
		}
	}

	return 0;
}

/**
 * ice_find_free_recp_res_idx - find free result indexes for recipe
 * @hw: pointer to hardware structure
 * @profiles: bitmap of profiles that will be associated with the new recipe
 * @free_idx: pointer to variable to receive the free index bitmap
 *
 * The algorithm used here is:
 *	1. When creating a new recipe, create a set P which contains all
 *	   Profiles that will be associated with our new recipe
 *
 *	2. For each Profile p in set P:
 *	    a. Add all recipes associated with Profile p into set R
 *	    b. Optional : PossibleIndexes &= profile[p].possibleIndexes
 *		[initially PossibleIndexes should be 0xFFFFFFFFFFFFFFFF]
 *		i. Or just assume they all have the same possible indexes:
 *			44, 45, 46, 47
 *			i.e., PossibleIndexes = 0x0000F00000000000
 *
 *	3. For each Recipe r in set R:
 *	    a. UsedIndexes |= (bitwise or ) recipe[r].res_indexes
 *	    b. FreeIndexes = UsedIndexes ^ PossibleIndexes
 *
 *	FreeIndexes will contain the bits indicating the indexes free for use,
 *      then the code needs to update the recipe[r].used_result_idx_bits to
 *      indicate which indexes were selected for use by this recipe.
 */
static u16
ice_find_free_recp_res_idx(struct ice_hw *hw, const unsigned long *profiles,
			   unsigned long *free_idx)
{
	DECLARE_BITMAP(possible_idx, ICE_MAX_FV_WORDS);
	DECLARE_BITMAP(recipes, ICE_MAX_NUM_RECIPES);
	DECLARE_BITMAP(used_idx, ICE_MAX_FV_WORDS);
	u16 bit;

	bitmap_zero(possible_idx, ICE_MAX_FV_WORDS);
	bitmap_zero(recipes, ICE_MAX_NUM_RECIPES);
	bitmap_zero(used_idx, ICE_MAX_FV_WORDS);
	bitmap_zero(free_idx, ICE_MAX_FV_WORDS);

	bitmap_set(possible_idx, 0, ICE_MAX_FV_WORDS);

	/* For each profile we are going to associate the recipe with, add the
	 * recipes that are associated with that profile. This will give us
	 * the set of recipes that our recipe may collide with. Also, determine
	 * what possible result indexes are usable given this set of profiles.
	 */
	for_each_set_bit(bit, profiles, ICE_MAX_NUM_PROFILES) {
		bitmap_or(recipes, recipes, profile_to_recipe[bit],
			  ICE_MAX_NUM_RECIPES);
		bitmap_and(possible_idx, possible_idx,
			   hw->switch_info->prof_res_bm[bit],
			   ICE_MAX_FV_WORDS);
	}

	/* For each recipe that our new recipe may collide with, determine
	 * which indexes have been used.
	 */
	for_each_set_bit(bit, recipes, ICE_MAX_NUM_RECIPES)
		bitmap_or(used_idx, used_idx,
			  hw->switch_info->recp_list[bit].res_idxs,
			  ICE_MAX_FV_WORDS);

	bitmap_xor(free_idx, used_idx, possible_idx, ICE_MAX_FV_WORDS);

	/* return number of free indexes */
	return (u16)bitmap_weight(free_idx, ICE_MAX_FV_WORDS);
}

/**
 * ice_add_sw_recipe - function to call AQ calls to create switch recipe
 * @hw: pointer to hardware structure
 * @rm: recipe management list entry
 * @profiles: bitmap of profiles that will be associated.
 */
static enum ice_status
ice_add_sw_recipe(struct ice_hw *hw, struct ice_sw_recipe *rm,
		  unsigned long *profiles)
{
	DECLARE_BITMAP(result_idx_bm, ICE_MAX_FV_WORDS);
	struct ice_aqc_recipe_data_elem *tmp;
	struct ice_aqc_recipe_data_elem *buf;
	struct ice_recp_grp_entry *entry;
	enum ice_status status;
	u16 free_res_idx;
	u16 recipe_count;
	u8 chain_idx;
	u8 recps = 0;

	/* When more than one recipe are required, another recipe is needed to
	 * chain them together. Matching a tunnel metadata ID takes up one of
	 * the match fields in the chaining recipe reducing the number of
	 * chained recipes by one.
	 */
	 /* check number of free result indices */
	bitmap_zero(result_idx_bm, ICE_MAX_FV_WORDS);
	free_res_idx = ice_find_free_recp_res_idx(hw, profiles, result_idx_bm);

	ice_debug(hw, ICE_DBG_SW, "Result idx slots: %d, need %d\n",
		  free_res_idx, rm->n_grp_count);

	if (rm->n_grp_count > 1) {
		if (rm->n_grp_count > free_res_idx)
			return ICE_ERR_MAX_LIMIT;

		rm->n_grp_count++;
	}

	if (rm->n_grp_count > ICE_MAX_CHAIN_RECIPE)
		return ICE_ERR_MAX_LIMIT;

	tmp = kcalloc(ICE_MAX_NUM_RECIPES, sizeof(*tmp), GFP_KERNEL);
	if (!tmp)
		return ICE_ERR_NO_MEMORY;

	buf = devm_kcalloc(ice_hw_to_dev(hw), rm->n_grp_count, sizeof(*buf),
			   GFP_KERNEL);
	if (!buf) {
		status = ICE_ERR_NO_MEMORY;
		goto err_mem;
	}

	bitmap_zero(rm->r_bitmap, ICE_MAX_NUM_RECIPES);
	recipe_count = ICE_MAX_NUM_RECIPES;
	status = ice_aq_get_recipe(hw, tmp, &recipe_count, ICE_SW_LKUP_MAC,
				   NULL);
	if (status || recipe_count == 0)
		goto err_unroll;

	/* Allocate the recipe resources, and configure them according to the
	 * match fields from protocol headers and extracted field vectors.
	 */
	chain_idx = find_first_bit(result_idx_bm, ICE_MAX_FV_WORDS);
	list_for_each_entry(entry, &rm->rg_list, l_entry) {
		u8 i;

		status = ice_alloc_recipe(hw, &entry->rid);
		if (status)
			goto err_unroll;

		/* Clear the result index of the located recipe, as this will be
		 * updated, if needed, later in the recipe creation process.
		 */
		tmp[0].content.result_indx = 0;

		buf[recps] = tmp[0];
		buf[recps].recipe_indx = (u8)entry->rid;
		/* if the recipe is a non-root recipe RID should be programmed
		 * as 0 for the rules to be applied correctly.
		 */
		buf[recps].content.rid = 0;
		memset(&buf[recps].content.lkup_indx, 0,
		       sizeof(buf[recps].content.lkup_indx));

		/* All recipes use look-up index 0 to match switch ID. */
		buf[recps].content.lkup_indx[0] = ICE_AQ_SW_ID_LKUP_IDX;
		buf[recps].content.mask[0] =
			cpu_to_le16(ICE_AQ_SW_ID_LKUP_MASK);
		/* Setup lkup_indx 1..4 to INVALID/ignore and set the mask
		 * to be 0
		 */
		for (i = 1; i <= ICE_NUM_WORDS_RECIPE; i++) {
			buf[recps].content.lkup_indx[i] = 0x80;
			buf[recps].content.mask[i] = 0;
		}

		for (i = 0; i < entry->r_group.n_val_pairs; i++) {
			buf[recps].content.lkup_indx[i + 1] = entry->fv_idx[i];
			buf[recps].content.mask[i + 1] =
				cpu_to_le16(entry->fv_mask[i]);
		}

		if (rm->n_grp_count > 1) {
			/* Checks to see if there really is a valid result index
			 * that can be used.
			 */
			if (chain_idx >= ICE_MAX_FV_WORDS) {
				ice_debug(hw, ICE_DBG_SW, "No chain index available\n");
				status = ICE_ERR_MAX_LIMIT;
				goto err_unroll;
			}

			entry->chain_idx = chain_idx;
			buf[recps].content.result_indx =
				ICE_AQ_RECIPE_RESULT_EN |
				((chain_idx << ICE_AQ_RECIPE_RESULT_DATA_S) &
				 ICE_AQ_RECIPE_RESULT_DATA_M);
			clear_bit(chain_idx, result_idx_bm);
			chain_idx = find_first_bit(result_idx_bm,
						   ICE_MAX_FV_WORDS);
		}

		/* fill recipe dependencies */
		bitmap_zero((unsigned long *)buf[recps].recipe_bitmap,
			    ICE_MAX_NUM_RECIPES);
		set_bit(buf[recps].recipe_indx,
			(unsigned long *)buf[recps].recipe_bitmap);
		buf[recps].content.act_ctrl_fwd_priority = rm->priority;
		recps++;
	}

	if (rm->n_grp_count == 1) {
		rm->root_rid = buf[0].recipe_indx;
		set_bit(buf[0].recipe_indx, rm->r_bitmap);
		buf[0].content.rid = rm->root_rid | ICE_AQ_RECIPE_ID_IS_ROOT;
		if (sizeof(buf[0].recipe_bitmap) >= sizeof(rm->r_bitmap)) {
			memcpy(buf[0].recipe_bitmap, rm->r_bitmap,
			       sizeof(buf[0].recipe_bitmap));
		} else {
			status = ICE_ERR_BAD_PTR;
			goto err_unroll;
		}
		/* Applicable only for ROOT_RECIPE, set the fwd_priority for
		 * the recipe which is getting created if specified
		 * by user. Usually any advanced switch filter, which results
		 * into new extraction sequence, ended up creating a new recipe
		 * of type ROOT and usually recipes are associated with profiles
		 * Switch rule referreing newly created recipe, needs to have
		 * either/or 'fwd' or 'join' priority, otherwise switch rule
		 * evaluation will not happen correctly. In other words, if
		 * switch rule to be evaluated on priority basis, then recipe
		 * needs to have priority, otherwise it will be evaluated last.
		 */
		buf[0].content.act_ctrl_fwd_priority = rm->priority;
	} else {
		struct ice_recp_grp_entry *last_chain_entry;
		u16 rid, i;

		/* Allocate the last recipe that will chain the outcomes of the
		 * other recipes together
		 */
		status = ice_alloc_recipe(hw, &rid);
		if (status)
			goto err_unroll;

		buf[recps].recipe_indx = (u8)rid;
		buf[recps].content.rid = (u8)rid;
		buf[recps].content.rid |= ICE_AQ_RECIPE_ID_IS_ROOT;
		/* the new entry created should also be part of rg_list to
		 * make sure we have complete recipe
		 */
		last_chain_entry = devm_kzalloc(ice_hw_to_dev(hw),
						sizeof(*last_chain_entry),
						GFP_KERNEL);
		if (!last_chain_entry) {
			status = ICE_ERR_NO_MEMORY;
			goto err_unroll;
		}
		last_chain_entry->rid = rid;
		memset(&buf[recps].content.lkup_indx, 0,
		       sizeof(buf[recps].content.lkup_indx));
		/* All recipes use look-up index 0 to match switch ID. */
		buf[recps].content.lkup_indx[0] = ICE_AQ_SW_ID_LKUP_IDX;
		buf[recps].content.mask[0] =
			cpu_to_le16(ICE_AQ_SW_ID_LKUP_MASK);
		for (i = 1; i <= ICE_NUM_WORDS_RECIPE; i++) {
			buf[recps].content.lkup_indx[i] =
				ICE_AQ_RECIPE_LKUP_IGNORE;
			buf[recps].content.mask[i] = 0;
		}

		i = 1;
		/* update r_bitmap with the recp that is used for chaining */
		set_bit(rid, rm->r_bitmap);
		/* this is the recipe that chains all the other recipes so it
		 * should not have a chaining ID to indicate the same
		 */
		last_chain_entry->chain_idx = ICE_INVAL_CHAIN_IND;
		list_for_each_entry(entry, &rm->rg_list, l_entry) {
			last_chain_entry->fv_idx[i] = entry->chain_idx;
			buf[recps].content.lkup_indx[i] = entry->chain_idx;
			buf[recps].content.mask[i++] = cpu_to_le16(0xFFFF);
			set_bit(entry->rid, rm->r_bitmap);
		}
		list_add(&last_chain_entry->l_entry, &rm->rg_list);
		if (sizeof(buf[recps].recipe_bitmap) >=
		    sizeof(rm->r_bitmap)) {
			memcpy(buf[recps].recipe_bitmap, rm->r_bitmap,
			       sizeof(buf[recps].recipe_bitmap));
		} else {
			status = ICE_ERR_BAD_PTR;
			goto err_unroll;
		}
		buf[recps].content.act_ctrl_fwd_priority = rm->priority;

		recps++;
		rm->root_rid = (u8)rid;
	}
	status = ice_acquire_change_lock(hw, ICE_RES_WRITE);
	if (status)
		goto err_unroll;

	status = ice_aq_add_recipe(hw, buf, rm->n_grp_count, NULL);
	ice_release_change_lock(hw);
	if (status)
		goto err_unroll;

	/* Every recipe that just got created add it to the recipe
	 * book keeping list
	 */
	list_for_each_entry(entry, &rm->rg_list, l_entry) {
		struct ice_switch_info *sw = hw->switch_info;
		bool is_root, idx_found = false;
		struct ice_sw_recipe *recp;
		u16 idx, buf_idx = 0;

		/* find buffer index for copying some data */
		for (idx = 0; idx < rm->n_grp_count; idx++)
			if (buf[idx].recipe_indx == entry->rid) {
				buf_idx = idx;
				idx_found = true;
			}

		if (!idx_found) {
			status = ICE_ERR_OUT_OF_RANGE;
			goto err_unroll;
		}

		recp = &sw->recp_list[entry->rid];
		is_root = (rm->root_rid == entry->rid);
		recp->is_root = is_root;

		recp->root_rid = entry->rid;
		recp->big_recp = (is_root && rm->n_grp_count > 1);

		memcpy(&recp->ext_words, entry->r_group.pairs,
		       entry->r_group.n_val_pairs * sizeof(struct ice_fv_word));

		memcpy(recp->r_bitmap, buf[buf_idx].recipe_bitmap,
		       sizeof(recp->r_bitmap));

		/* Copy non-result fv index values and masks to recipe. This
		 * call will also update the result recipe bitmask.
		 */
		ice_collect_result_idx(&buf[buf_idx], recp);

		/* for non-root recipes, also copy to the root, this allows
		 * easier matching of a complete chained recipe
		 */
		if (!is_root)
			ice_collect_result_idx(&buf[buf_idx],
					       &sw->recp_list[rm->root_rid]);

		recp->n_ext_words = entry->r_group.n_val_pairs;
		recp->chain_idx = entry->chain_idx;
		recp->priority = buf[buf_idx].content.act_ctrl_fwd_priority;
		recp->n_grp_count = rm->n_grp_count;
		recp->tun_type = rm->tun_type;
		recp->recp_created = true;
	}
	rm->root_buf = buf;
	kfree(tmp);
	return status;

err_unroll:
err_mem:
	kfree(tmp);
	devm_kfree(ice_hw_to_dev(hw), buf);
	return status;
}

/**
 * ice_create_recipe_group - creates recipe group
 * @hw: pointer to hardware structure
 * @rm: recipe management list entry
 * @lkup_exts: lookup elements
 */
static enum ice_status
ice_create_recipe_group(struct ice_hw *hw, struct ice_sw_recipe *rm,
			struct ice_prot_lkup_ext *lkup_exts)
{
	enum ice_status status;
	u8 recp_count = 0;

	rm->n_grp_count = 0;

	/* Create recipes for words that are marked not done by packing them
	 * as best fit.
	 */
	status = ice_create_first_fit_recp_def(hw, lkup_exts,
					       &rm->rg_list, &recp_count);
	if (!status) {
		rm->n_grp_count += recp_count;
		rm->n_ext_words = lkup_exts->n_val_words;
		memcpy(&rm->ext_words, lkup_exts->fv_words,
		       sizeof(rm->ext_words));
		memcpy(rm->word_masks, lkup_exts->field_mask,
		       sizeof(rm->word_masks));
	}

	return status;
}

/**
 * ice_get_fv - get field vectors/extraction sequences for spec. lookup types
 * @hw: pointer to hardware structure
 * @lkups: lookup elements or match criteria for the advanced recipe, one
 *	   structure per protocol header
 * @lkups_cnt: number of protocols
 * @bm: bitmap of field vectors to consider
 * @fv_list: pointer to a list that holds the returned field vectors
 */
static enum ice_status
ice_get_fv(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups, u16 lkups_cnt,
	   unsigned long *bm, struct list_head *fv_list)
{
	enum ice_status status;
	u8 *prot_ids;
	u16 i;

	prot_ids = kcalloc(lkups_cnt, sizeof(*prot_ids), GFP_KERNEL);
	if (!prot_ids)
		return ICE_ERR_NO_MEMORY;

	for (i = 0; i < lkups_cnt; i++)
		if (!ice_prot_type_to_id(lkups[i].type, &prot_ids[i])) {
			status = ICE_ERR_CFG;
			goto free_mem;
		}

	/* Find field vectors that include all specified protocol types */
	status = ice_get_sw_fv_list(hw, prot_ids, lkups_cnt, bm, fv_list);

free_mem:
	kfree(prot_ids);
	return status;
}

/**
 * ice_tun_type_match_word - determine if tun type needs a match mask
 * @tun_type: tunnel type
 * @mask: mask to be used for the tunnel
 */
static bool ice_tun_type_match_word(enum ice_sw_tunnel_type tun_type, u16 *mask)
{
	switch (tun_type) {
	case ICE_SW_TUN_GENEVE:
	case ICE_SW_TUN_VXLAN:
	case ICE_SW_TUN_NVGRE:
		*mask = ICE_TUN_FLAG_MASK;
		return true;

	default:
		*mask = 0;
		return false;
	}
}

/**
 * ice_add_special_words - Add words that are not protocols, such as metadata
 * @rinfo: other information regarding the rule e.g. priority and action info
 * @lkup_exts: lookup word structure
 */
static enum ice_status
ice_add_special_words(struct ice_adv_rule_info *rinfo,
		      struct ice_prot_lkup_ext *lkup_exts)
{
	u16 mask;

	/* If this is a tunneled packet, then add recipe index to match the
	 * tunnel bit in the packet metadata flags.
	 */
	if (ice_tun_type_match_word(rinfo->tun_type, &mask)) {
		if (lkup_exts->n_val_words < ICE_MAX_CHAIN_WORDS) {
			u8 word = lkup_exts->n_val_words++;

			lkup_exts->fv_words[word].prot_id = ICE_META_DATA_ID_HW;
			lkup_exts->fv_words[word].off = ICE_TUN_FLAG_MDID_OFF;
			lkup_exts->field_mask[word] = mask;
		} else {
			return ICE_ERR_MAX_LIMIT;
		}
	}

	return 0;
}

/* ice_get_compat_fv_bitmap - Get compatible field vector bitmap for rule
 * @hw: pointer to hardware structure
 * @rinfo: other information regarding the rule e.g. priority and action info
 * @bm: pointer to memory for returning the bitmap of field vectors
 */
static void
ice_get_compat_fv_bitmap(struct ice_hw *hw, struct ice_adv_rule_info *rinfo,
			 unsigned long *bm)
{
	enum ice_prof_type prof_type;

	bitmap_zero(bm, ICE_MAX_NUM_PROFILES);

	switch (rinfo->tun_type) {
	case ICE_NON_TUN:
		prof_type = ICE_PROF_NON_TUN;
		break;
	case ICE_ALL_TUNNELS:
		prof_type = ICE_PROF_TUN_ALL;
		break;
	case ICE_SW_TUN_GENEVE:
	case ICE_SW_TUN_VXLAN:
		prof_type = ICE_PROF_TUN_UDP;
		break;
	case ICE_SW_TUN_NVGRE:
		prof_type = ICE_PROF_TUN_GRE;
		break;
	default:
		prof_type = ICE_PROF_ALL;
		break;
	}

	ice_get_sw_fv_bitmap(hw, prof_type, bm);
}

/**
 * ice_add_adv_recipe - Add an advanced recipe that is not part of the default
 * @hw: pointer to hardware structure
 * @lkups: lookup elements or match criteria for the advanced recipe, one
 *  structure per protocol header
 * @lkups_cnt: number of protocols
 * @rinfo: other information regarding the rule e.g. priority and action info
 * @rid: return the recipe ID of the recipe created
 */
static enum ice_status
ice_add_adv_recipe(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups,
		   u16 lkups_cnt, struct ice_adv_rule_info *rinfo, u16 *rid)
{
	DECLARE_BITMAP(fv_bitmap, ICE_MAX_NUM_PROFILES);
	DECLARE_BITMAP(profiles, ICE_MAX_NUM_PROFILES);
	struct ice_prot_lkup_ext *lkup_exts;
	struct ice_recp_grp_entry *r_entry;
	struct ice_sw_fv_list_entry *fvit;
	struct ice_recp_grp_entry *r_tmp;
	struct ice_sw_fv_list_entry *tmp;
	enum ice_status status = 0;
	struct ice_sw_recipe *rm;
	u8 i;

	if (!lkups_cnt)
		return ICE_ERR_PARAM;

	lkup_exts = kzalloc(sizeof(*lkup_exts), GFP_KERNEL);
	if (!lkup_exts)
		return ICE_ERR_NO_MEMORY;

	/* Determine the number of words to be matched and if it exceeds a
	 * recipe's restrictions
	 */
	for (i = 0; i < lkups_cnt; i++) {
		u16 count;

		if (lkups[i].type >= ICE_PROTOCOL_LAST) {
			status = ICE_ERR_CFG;
			goto err_free_lkup_exts;
		}

		count = ice_fill_valid_words(&lkups[i], lkup_exts);
		if (!count) {
			status = ICE_ERR_CFG;
			goto err_free_lkup_exts;
		}
	}

	rm = kzalloc(sizeof(*rm), GFP_KERNEL);
	if (!rm) {
		status = ICE_ERR_NO_MEMORY;
		goto err_free_lkup_exts;
	}

	/* Get field vectors that contain fields extracted from all the protocol
	 * headers being programmed.
	 */
	INIT_LIST_HEAD(&rm->fv_list);
	INIT_LIST_HEAD(&rm->rg_list);

	/* Get bitmap of field vectors (profiles) that are compatible with the
	 * rule request; only these will be searched in the subsequent call to
	 * ice_get_fv.
	 */
	ice_get_compat_fv_bitmap(hw, rinfo, fv_bitmap);

	status = ice_get_fv(hw, lkups, lkups_cnt, fv_bitmap, &rm->fv_list);
	if (status)
		goto err_unroll;

	/* Create any special protocol/offset pairs, such as looking at tunnel
	 * bits by extracting metadata
	 */
	status = ice_add_special_words(rinfo, lkup_exts);
	if (status)
		goto err_free_lkup_exts;

	/* Group match words into recipes using preferred recipe grouping
	 * criteria.
	 */
	status = ice_create_recipe_group(hw, rm, lkup_exts);
	if (status)
		goto err_unroll;

	/* set the recipe priority if specified */
	rm->priority = (u8)rinfo->priority;

	/* Find offsets from the field vector. Pick the first one for all the
	 * recipes.
	 */
	status = ice_fill_fv_word_index(hw, &rm->fv_list, &rm->rg_list);
	if (status)
		goto err_unroll;

	/* get bitmap of all profiles the recipe will be associated with */
	bitmap_zero(profiles, ICE_MAX_NUM_PROFILES);
	list_for_each_entry(fvit, &rm->fv_list, list_entry) {
		ice_debug(hw, ICE_DBG_SW, "profile: %d\n", fvit->profile_id);
		set_bit((u16)fvit->profile_id, profiles);
	}

	/* Look for a recipe which matches our requested fv / mask list */
	*rid = ice_find_recp(hw, lkup_exts);
	if (*rid < ICE_MAX_NUM_RECIPES)
		/* Success if found a recipe that match the existing criteria */
		goto err_unroll;

	/* Recipe we need does not exist, add a recipe */
	status = ice_add_sw_recipe(hw, rm, profiles);
	if (status)
		goto err_unroll;

	/* Associate all the recipes created with all the profiles in the
	 * common field vector.
	 */
	list_for_each_entry(fvit, &rm->fv_list, list_entry) {
		DECLARE_BITMAP(r_bitmap, ICE_MAX_NUM_RECIPES);
		u16 j;

		status = ice_aq_get_recipe_to_profile(hw, fvit->profile_id,
						      (u8 *)r_bitmap, NULL);
		if (status)
			goto err_unroll;

		bitmap_or(r_bitmap, r_bitmap, rm->r_bitmap,
			  ICE_MAX_NUM_RECIPES);
		status = ice_acquire_change_lock(hw, ICE_RES_WRITE);
		if (status)
			goto err_unroll;

		status = ice_aq_map_recipe_to_profile(hw, fvit->profile_id,
						      (u8 *)r_bitmap,
						      NULL);
		ice_release_change_lock(hw);

		if (status)
			goto err_unroll;

		/* Update profile to recipe bitmap array */
		bitmap_copy(profile_to_recipe[fvit->profile_id], r_bitmap,
			    ICE_MAX_NUM_RECIPES);

		/* Update recipe to profile bitmap array */
		for_each_set_bit(j, rm->r_bitmap, ICE_MAX_NUM_RECIPES)
			set_bit((u16)fvit->profile_id, recipe_to_profile[j]);
	}

	*rid = rm->root_rid;
	memcpy(&hw->switch_info->recp_list[*rid].lkup_exts, lkup_exts,
	       sizeof(*lkup_exts));
err_unroll:
	list_for_each_entry_safe(r_entry, r_tmp, &rm->rg_list, l_entry) {
		list_del(&r_entry->l_entry);
		devm_kfree(ice_hw_to_dev(hw), r_entry);
	}

	list_for_each_entry_safe(fvit, tmp, &rm->fv_list, list_entry) {
		list_del(&fvit->list_entry);
		devm_kfree(ice_hw_to_dev(hw), fvit);
	}

	if (rm->root_buf)
		devm_kfree(ice_hw_to_dev(hw), rm->root_buf);

	kfree(rm);

err_free_lkup_exts:
	kfree(lkup_exts);

	return status;
}

/**
 * ice_find_dummy_packet - find dummy packet
 *
 * @lkups: lookup elements or match criteria for the advanced recipe, one
 *	   structure per protocol header
 * @lkups_cnt: number of protocols
 * @tun_type: tunnel type
 * @pkt: dummy packet to fill according to filter match criteria
 * @pkt_len: packet length of dummy packet
 * @offsets: pointer to receive the pointer to the offsets for the packet
 */
static void
ice_find_dummy_packet(struct ice_adv_lkup_elem *lkups, u16 lkups_cnt,
		      enum ice_sw_tunnel_type tun_type,
		      const u8 **pkt, u16 *pkt_len,
		      const struct ice_dummy_pkt_offsets **offsets)
{
	bool tcp = false, udp = false, ipv6 = false, vlan = false;
	u16 i;

	for (i = 0; i < lkups_cnt; i++) {
		if (lkups[i].type == ICE_UDP_ILOS)
			udp = true;
		else if (lkups[i].type == ICE_TCP_IL)
			tcp = true;
		else if (lkups[i].type == ICE_IPV6_OFOS)
			ipv6 = true;
		else if (lkups[i].type == ICE_VLAN_OFOS)
			vlan = true;
		else if (lkups[i].type == ICE_ETYPE_OL &&
			 lkups[i].h_u.ethertype.ethtype_id ==
				cpu_to_be16(ICE_IPV6_ETHER_ID) &&
			 lkups[i].m_u.ethertype.ethtype_id ==
					cpu_to_be16(0xFFFF))
			ipv6 = true;
	}

	if (tun_type == ICE_SW_TUN_NVGRE) {
		if (tcp) {
			*pkt = dummy_gre_tcp_packet;
			*pkt_len = sizeof(dummy_gre_tcp_packet);
			*offsets = dummy_gre_tcp_packet_offsets;
			return;
		}

		*pkt = dummy_gre_udp_packet;
		*pkt_len = sizeof(dummy_gre_udp_packet);
		*offsets = dummy_gre_udp_packet_offsets;
		return;
	}

	if (tun_type == ICE_SW_TUN_VXLAN ||
	    tun_type == ICE_SW_TUN_GENEVE) {
		if (tcp) {
			*pkt = dummy_udp_tun_tcp_packet;
			*pkt_len = sizeof(dummy_udp_tun_tcp_packet);
			*offsets = dummy_udp_tun_tcp_packet_offsets;
			return;
		}

		*pkt = dummy_udp_tun_udp_packet;
		*pkt_len = sizeof(dummy_udp_tun_udp_packet);
		*offsets = dummy_udp_tun_udp_packet_offsets;
		return;
	}

	if (udp && !ipv6) {
		if (vlan) {
			*pkt = dummy_vlan_udp_packet;
			*pkt_len = sizeof(dummy_vlan_udp_packet);
			*offsets = dummy_vlan_udp_packet_offsets;
			return;
		}
		*pkt = dummy_udp_packet;
		*pkt_len = sizeof(dummy_udp_packet);
		*offsets = dummy_udp_packet_offsets;
		return;
	} else if (udp && ipv6) {
		if (vlan) {
			*pkt = dummy_vlan_udp_ipv6_packet;
			*pkt_len = sizeof(dummy_vlan_udp_ipv6_packet);
			*offsets = dummy_vlan_udp_ipv6_packet_offsets;
			return;
		}
		*pkt = dummy_udp_ipv6_packet;
		*pkt_len = sizeof(dummy_udp_ipv6_packet);
		*offsets = dummy_udp_ipv6_packet_offsets;
		return;
	} else if ((tcp && ipv6) || ipv6) {
		if (vlan) {
			*pkt = dummy_vlan_tcp_ipv6_packet;
			*pkt_len = sizeof(dummy_vlan_tcp_ipv6_packet);
			*offsets = dummy_vlan_tcp_ipv6_packet_offsets;
			return;
		}
		*pkt = dummy_tcp_ipv6_packet;
		*pkt_len = sizeof(dummy_tcp_ipv6_packet);
		*offsets = dummy_tcp_ipv6_packet_offsets;
		return;
	}

	if (vlan) {
		*pkt = dummy_vlan_tcp_packet;
		*pkt_len = sizeof(dummy_vlan_tcp_packet);
		*offsets = dummy_vlan_tcp_packet_offsets;
	} else {
		*pkt = dummy_tcp_packet;
		*pkt_len = sizeof(dummy_tcp_packet);
		*offsets = dummy_tcp_packet_offsets;
	}
}

/**
 * ice_fill_adv_dummy_packet - fill a dummy packet with given match criteria
 *
 * @lkups: lookup elements or match criteria for the advanced recipe, one
 *	   structure per protocol header
 * @lkups_cnt: number of protocols
 * @s_rule: stores rule information from the match criteria
 * @dummy_pkt: dummy packet to fill according to filter match criteria
 * @pkt_len: packet length of dummy packet
 * @offsets: offset info for the dummy packet
 */
static enum ice_status
ice_fill_adv_dummy_packet(struct ice_adv_lkup_elem *lkups, u16 lkups_cnt,
			  struct ice_aqc_sw_rules_elem *s_rule,
			  const u8 *dummy_pkt, u16 pkt_len,
			  const struct ice_dummy_pkt_offsets *offsets)
{
	u8 *pkt;
	u16 i;

	/* Start with a packet with a pre-defined/dummy content. Then, fill
	 * in the header values to be looked up or matched.
	 */
	pkt = s_rule->pdata.lkup_tx_rx.hdr;

	memcpy(pkt, dummy_pkt, pkt_len);

	for (i = 0; i < lkups_cnt; i++) {
		enum ice_protocol_type type;
		u16 offset = 0, len = 0, j;
		bool found = false;

		/* find the start of this layer; it should be found since this
		 * was already checked when search for the dummy packet
		 */
		type = lkups[i].type;
		for (j = 0; offsets[j].type != ICE_PROTOCOL_LAST; j++) {
			if (type == offsets[j].type) {
				offset = offsets[j].offset;
				found = true;
				break;
			}
		}
		/* this should never happen in a correct calling sequence */
		if (!found)
			return ICE_ERR_PARAM;

		switch (lkups[i].type) {
		case ICE_MAC_OFOS:
		case ICE_MAC_IL:
			len = sizeof(struct ice_ether_hdr);
			break;
		case ICE_ETYPE_OL:
			len = sizeof(struct ice_ethtype_hdr);
			break;
		case ICE_VLAN_OFOS:
			len = sizeof(struct ice_vlan_hdr);
			break;
		case ICE_IPV4_OFOS:
		case ICE_IPV4_IL:
			len = sizeof(struct ice_ipv4_hdr);
			break;
		case ICE_IPV6_OFOS:
		case ICE_IPV6_IL:
			len = sizeof(struct ice_ipv6_hdr);
			break;
		case ICE_TCP_IL:
		case ICE_UDP_OF:
		case ICE_UDP_ILOS:
			len = sizeof(struct ice_l4_hdr);
			break;
		case ICE_SCTP_IL:
			len = sizeof(struct ice_sctp_hdr);
			break;
		case ICE_NVGRE:
			len = sizeof(struct ice_nvgre_hdr);
			break;
		case ICE_VXLAN:
		case ICE_GENEVE:
			len = sizeof(struct ice_udp_tnl_hdr);
			break;
		default:
			return ICE_ERR_PARAM;
		}

		/* the length should be a word multiple */
		if (len % ICE_BYTES_PER_WORD)
			return ICE_ERR_CFG;

		/* We have the offset to the header start, the length, the
		 * caller's header values and mask. Use this information to
		 * copy the data into the dummy packet appropriately based on
		 * the mask. Note that we need to only write the bits as
		 * indicated by the mask to make sure we don't improperly write
		 * over any significant packet data.
		 */
		for (j = 0; j < len / sizeof(u16); j++)
			if (((u16 *)&lkups[i].m_u)[j])
				((u16 *)(pkt + offset))[j] =
					(((u16 *)(pkt + offset))[j] &
					 ~((u16 *)&lkups[i].m_u)[j]) |
					(((u16 *)&lkups[i].h_u)[j] &
					 ((u16 *)&lkups[i].m_u)[j]);
	}

	s_rule->pdata.lkup_tx_rx.hdr_len = cpu_to_le16(pkt_len);

	return 0;
}

/**
 * ice_fill_adv_packet_tun - fill dummy packet with udp tunnel port
 * @hw: pointer to the hardware structure
 * @tun_type: tunnel type
 * @pkt: dummy packet to fill in
 * @offsets: offset info for the dummy packet
 */
static enum ice_status
ice_fill_adv_packet_tun(struct ice_hw *hw, enum ice_sw_tunnel_type tun_type,
			u8 *pkt, const struct ice_dummy_pkt_offsets *offsets)
{
	u16 open_port, i;

	switch (tun_type) {
	case ICE_SW_TUN_VXLAN:
	case ICE_SW_TUN_GENEVE:
		if (!ice_get_open_tunnel_port(hw, &open_port))
			return ICE_ERR_CFG;
		break;

	default:
		/* Nothing needs to be done for this tunnel type */
		return 0;
	}

	/* Find the outer UDP protocol header and insert the port number */
	for (i = 0; offsets[i].type != ICE_PROTOCOL_LAST; i++) {
		if (offsets[i].type == ICE_UDP_OF) {
			struct ice_l4_hdr *hdr;
			u16 offset;

			offset = offsets[i].offset;
			hdr = (struct ice_l4_hdr *)&pkt[offset];
			hdr->dst_port = cpu_to_be16(open_port);

			return 0;
		}
	}

	return ICE_ERR_CFG;
}

/**
 * ice_find_adv_rule_entry - Search a rule entry
 * @hw: pointer to the hardware structure
 * @lkups: lookup elements or match criteria for the advanced recipe, one
 *	   structure per protocol header
 * @lkups_cnt: number of protocols
 * @recp_id: recipe ID for which we are finding the rule
 * @rinfo: other information regarding the rule e.g. priority and action info
 *
 * Helper function to search for a given advance rule entry
 * Returns pointer to entry storing the rule if found
 */
static struct ice_adv_fltr_mgmt_list_entry *
ice_find_adv_rule_entry(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups,
			u16 lkups_cnt, u16 recp_id,
			struct ice_adv_rule_info *rinfo)
{
	struct ice_adv_fltr_mgmt_list_entry *list_itr;
	struct ice_switch_info *sw = hw->switch_info;
	int i;

	list_for_each_entry(list_itr, &sw->recp_list[recp_id].filt_rules,
			    list_entry) {
		bool lkups_matched = true;

		if (lkups_cnt != list_itr->lkups_cnt)
			continue;
		for (i = 0; i < list_itr->lkups_cnt; i++)
			if (memcmp(&list_itr->lkups[i], &lkups[i],
				   sizeof(*lkups))) {
				lkups_matched = false;
				break;
			}
		if (rinfo->sw_act.flag == list_itr->rule_info.sw_act.flag &&
		    rinfo->tun_type == list_itr->rule_info.tun_type &&
		    lkups_matched)
			return list_itr;
	}
	return NULL;
}

/**
 * ice_adv_add_update_vsi_list
 * @hw: pointer to the hardware structure
 * @m_entry: pointer to current adv filter management list entry
 * @cur_fltr: filter information from the book keeping entry
 * @new_fltr: filter information with the new VSI to be added
 *
 * Call AQ command to add or update previously created VSI list with new VSI.
 *
 * Helper function to do book keeping associated with adding filter information
 * The algorithm to do the booking keeping is described below :
 * When a VSI needs to subscribe to a given advanced filter
 *	if only one VSI has been added till now
 *		Allocate a new VSI list and add two VSIs
 *		to this list using switch rule command
 *		Update the previously created switch rule with the
 *		newly created VSI list ID
 *	if a VSI list was previously created
 *		Add the new VSI to the previously created VSI list set
 *		using the update switch rule command
 */
static enum ice_status
ice_adv_add_update_vsi_list(struct ice_hw *hw,
			    struct ice_adv_fltr_mgmt_list_entry *m_entry,
			    struct ice_adv_rule_info *cur_fltr,
			    struct ice_adv_rule_info *new_fltr)
{
	enum ice_status status;
	u16 vsi_list_id = 0;

	if (cur_fltr->sw_act.fltr_act == ICE_FWD_TO_Q ||
	    cur_fltr->sw_act.fltr_act == ICE_FWD_TO_QGRP ||
	    cur_fltr->sw_act.fltr_act == ICE_DROP_PACKET)
		return ICE_ERR_NOT_IMPL;

	if ((new_fltr->sw_act.fltr_act == ICE_FWD_TO_Q ||
	     new_fltr->sw_act.fltr_act == ICE_FWD_TO_QGRP) &&
	    (cur_fltr->sw_act.fltr_act == ICE_FWD_TO_VSI ||
	     cur_fltr->sw_act.fltr_act == ICE_FWD_TO_VSI_LIST))
		return ICE_ERR_NOT_IMPL;

	if (m_entry->vsi_count < 2 && !m_entry->vsi_list_info) {
		 /* Only one entry existed in the mapping and it was not already
		  * a part of a VSI list. So, create a VSI list with the old and
		  * new VSIs.
		  */
		struct ice_fltr_info tmp_fltr;
		u16 vsi_handle_arr[2];

		/* A rule already exists with the new VSI being added */
		if (cur_fltr->sw_act.fwd_id.hw_vsi_id ==
		    new_fltr->sw_act.fwd_id.hw_vsi_id)
			return ICE_ERR_ALREADY_EXISTS;

		vsi_handle_arr[0] = cur_fltr->sw_act.vsi_handle;
		vsi_handle_arr[1] = new_fltr->sw_act.vsi_handle;
		status = ice_create_vsi_list_rule(hw, &vsi_handle_arr[0], 2,
						  &vsi_list_id,
						  ICE_SW_LKUP_LAST);
		if (status)
			return status;

		memset(&tmp_fltr, 0, sizeof(tmp_fltr));
		tmp_fltr.flag = m_entry->rule_info.sw_act.flag;
		tmp_fltr.fltr_rule_id = cur_fltr->fltr_rule_id;
		tmp_fltr.fltr_act = ICE_FWD_TO_VSI_LIST;
		tmp_fltr.fwd_id.vsi_list_id = vsi_list_id;
		tmp_fltr.lkup_type = ICE_SW_LKUP_LAST;

		/* Update the previous switch rule of "forward to VSI" to
		 * "fwd to VSI list"
		 */
		status = ice_update_pkt_fwd_rule(hw, &tmp_fltr);
		if (status)
			return status;

		cur_fltr->sw_act.fwd_id.vsi_list_id = vsi_list_id;
		cur_fltr->sw_act.fltr_act = ICE_FWD_TO_VSI_LIST;
		m_entry->vsi_list_info =
			ice_create_vsi_list_map(hw, &vsi_handle_arr[0], 2,
						vsi_list_id);
	} else {
		u16 vsi_handle = new_fltr->sw_act.vsi_handle;

		if (!m_entry->vsi_list_info)
			return ICE_ERR_CFG;

		/* A rule already exists with the new VSI being added */
		if (test_bit(vsi_handle, m_entry->vsi_list_info->vsi_map))
			return 0;

		/* Update the previously created VSI list set with
		 * the new VSI ID passed in
		 */
		vsi_list_id = cur_fltr->sw_act.fwd_id.vsi_list_id;

		status = ice_update_vsi_list_rule(hw, &vsi_handle, 1,
						  vsi_list_id, false,
						  ice_aqc_opc_update_sw_rules,
						  ICE_SW_LKUP_LAST);
		/* update VSI list mapping info with new VSI ID */
		if (!status)
			set_bit(vsi_handle, m_entry->vsi_list_info->vsi_map);
	}
	if (!status)
		m_entry->vsi_count++;
	return status;
}

/**
 * ice_add_adv_rule - helper function to create an advanced switch rule
 * @hw: pointer to the hardware structure
 * @lkups: information on the words that needs to be looked up. All words
 * together makes one recipe
 * @lkups_cnt: num of entries in the lkups array
 * @rinfo: other information related to the rule that needs to be programmed
 * @added_entry: this will return recipe_id, rule_id and vsi_handle. should be
 *               ignored is case of error.
 *
 * This function can program only 1 rule at a time. The lkups is used to
 * describe the all the words that forms the "lookup" portion of the recipe.
 * These words can span multiple protocols. Callers to this function need to
 * pass in a list of protocol headers with lookup information along and mask
 * that determines which words are valid from the given protocol header.
 * rinfo describes other information related to this rule such as forwarding
 * IDs, priority of this rule, etc.
 */
enum ice_status
ice_add_adv_rule(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups,
		 u16 lkups_cnt, struct ice_adv_rule_info *rinfo,
		 struct ice_rule_query_data *added_entry)
{
	struct ice_adv_fltr_mgmt_list_entry *m_entry, *adv_fltr = NULL;
	u16 rid = 0, i, pkt_len, rule_buf_sz, vsi_handle;
	const struct ice_dummy_pkt_offsets *pkt_offsets;
	struct ice_aqc_sw_rules_elem *s_rule = NULL;
	struct list_head *rule_head;
	struct ice_switch_info *sw;
	enum ice_status status;
	const u8 *pkt = NULL;
	u16 word_cnt;
	u32 act = 0;
	u8 q_rgn;

	/* Initialize profile to result index bitmap */
	if (!hw->switch_info->prof_res_bm_init) {
		hw->switch_info->prof_res_bm_init = 1;
		ice_init_prof_result_bm(hw);
	}

	if (!lkups_cnt)
		return ICE_ERR_PARAM;

	/* get # of words we need to match */
	word_cnt = 0;
	for (i = 0; i < lkups_cnt; i++) {
		u16 j, *ptr;

		ptr = (u16 *)&lkups[i].m_u;
		for (j = 0; j < sizeof(lkups->m_u) / sizeof(u16); j++)
			if (ptr[j] != 0)
				word_cnt++;
	}

	if (!word_cnt || word_cnt > ICE_MAX_CHAIN_WORDS)
		return ICE_ERR_PARAM;

	/* make sure that we can locate a dummy packet */
	ice_find_dummy_packet(lkups, lkups_cnt, rinfo->tun_type, &pkt, &pkt_len,
			      &pkt_offsets);
	if (!pkt) {
		status = ICE_ERR_PARAM;
		goto err_ice_add_adv_rule;
	}

	if (!(rinfo->sw_act.fltr_act == ICE_FWD_TO_VSI ||
	      rinfo->sw_act.fltr_act == ICE_FWD_TO_Q ||
	      rinfo->sw_act.fltr_act == ICE_FWD_TO_QGRP ||
	      rinfo->sw_act.fltr_act == ICE_DROP_PACKET))
		return ICE_ERR_CFG;

	vsi_handle = rinfo->sw_act.vsi_handle;
	if (!ice_is_vsi_valid(hw, vsi_handle))
		return ICE_ERR_PARAM;

	if (rinfo->sw_act.fltr_act == ICE_FWD_TO_VSI)
		rinfo->sw_act.fwd_id.hw_vsi_id =
			ice_get_hw_vsi_num(hw, vsi_handle);
	if (rinfo->sw_act.flag & ICE_FLTR_TX)
		rinfo->sw_act.src = ice_get_hw_vsi_num(hw, vsi_handle);

	status = ice_add_adv_recipe(hw, lkups, lkups_cnt, rinfo, &rid);
	if (status)
		return status;
	m_entry = ice_find_adv_rule_entry(hw, lkups, lkups_cnt, rid, rinfo);
	if (m_entry) {
		/* we have to add VSI to VSI_LIST and increment vsi_count.
		 * Also Update VSI list so that we can change forwarding rule
		 * if the rule already exists, we will check if it exists with
		 * same vsi_id, if not then add it to the VSI list if it already
		 * exists if not then create a VSI list and add the existing VSI
		 * ID and the new VSI ID to the list
		 * We will add that VSI to the list
		 */
		status = ice_adv_add_update_vsi_list(hw, m_entry,
						     &m_entry->rule_info,
						     rinfo);
		if (added_entry) {
			added_entry->rid = rid;
			added_entry->rule_id = m_entry->rule_info.fltr_rule_id;
			added_entry->vsi_handle = rinfo->sw_act.vsi_handle;
		}
		return status;
	}
	rule_buf_sz = ICE_SW_RULE_RX_TX_NO_HDR_SIZE + pkt_len;
	s_rule = kzalloc(rule_buf_sz, GFP_KERNEL);
	if (!s_rule)
		return ICE_ERR_NO_MEMORY;
	if (!rinfo->flags_info.act_valid) {
		act |= ICE_SINGLE_ACT_LAN_ENABLE;
		act |= ICE_SINGLE_ACT_LB_ENABLE;
	} else {
		act |= rinfo->flags_info.act & (ICE_SINGLE_ACT_LAN_ENABLE |
						ICE_SINGLE_ACT_LB_ENABLE);
	}

	switch (rinfo->sw_act.fltr_act) {
	case ICE_FWD_TO_VSI:
		act |= (rinfo->sw_act.fwd_id.hw_vsi_id <<
			ICE_SINGLE_ACT_VSI_ID_S) & ICE_SINGLE_ACT_VSI_ID_M;
		act |= ICE_SINGLE_ACT_VSI_FORWARDING | ICE_SINGLE_ACT_VALID_BIT;
		break;
	case ICE_FWD_TO_Q:
		act |= ICE_SINGLE_ACT_TO_Q;
		act |= (rinfo->sw_act.fwd_id.q_id << ICE_SINGLE_ACT_Q_INDEX_S) &
		       ICE_SINGLE_ACT_Q_INDEX_M;
		break;
	case ICE_FWD_TO_QGRP:
		q_rgn = rinfo->sw_act.qgrp_size > 0 ?
			(u8)ilog2(rinfo->sw_act.qgrp_size) : 0;
		act |= ICE_SINGLE_ACT_TO_Q;
		act |= (rinfo->sw_act.fwd_id.q_id << ICE_SINGLE_ACT_Q_INDEX_S) &
		       ICE_SINGLE_ACT_Q_INDEX_M;
		act |= (q_rgn << ICE_SINGLE_ACT_Q_REGION_S) &
		       ICE_SINGLE_ACT_Q_REGION_M;
		break;
	case ICE_DROP_PACKET:
		act |= ICE_SINGLE_ACT_VSI_FORWARDING | ICE_SINGLE_ACT_DROP |
		       ICE_SINGLE_ACT_VALID_BIT;
		break;
	default:
		status = ICE_ERR_CFG;
		goto err_ice_add_adv_rule;
	}

	/* set the rule LOOKUP type based on caller specified 'Rx'
	 * instead of hardcoding it to be either LOOKUP_TX/RX
	 *
	 * for 'Rx' set the source to be the port number
	 * for 'Tx' set the source to be the source HW VSI number (determined
	 * by caller)
	 */
	if (rinfo->rx) {
		s_rule->type = cpu_to_le16(ICE_AQC_SW_RULES_T_LKUP_RX);
		s_rule->pdata.lkup_tx_rx.src =
			cpu_to_le16(hw->port_info->lport);
	} else {
		s_rule->type = cpu_to_le16(ICE_AQC_SW_RULES_T_LKUP_TX);
		s_rule->pdata.lkup_tx_rx.src = cpu_to_le16(rinfo->sw_act.src);
	}

	s_rule->pdata.lkup_tx_rx.recipe_id = cpu_to_le16(rid);
	s_rule->pdata.lkup_tx_rx.act = cpu_to_le32(act);

	status = ice_fill_adv_dummy_packet(lkups, lkups_cnt, s_rule, pkt,
					   pkt_len, pkt_offsets);
	if (status)
		goto err_ice_add_adv_rule;

	if (rinfo->tun_type != ICE_NON_TUN) {
		status = ice_fill_adv_packet_tun(hw, rinfo->tun_type,
						 s_rule->pdata.lkup_tx_rx.hdr,
						 pkt_offsets);
		if (status)
			goto err_ice_add_adv_rule;
	}

	status = ice_aq_sw_rules(hw, (struct ice_aqc_sw_rules *)s_rule,
				 rule_buf_sz, 1, ice_aqc_opc_add_sw_rules,
				 NULL);
	if (status)
		goto err_ice_add_adv_rule;
	adv_fltr = devm_kzalloc(ice_hw_to_dev(hw),
				sizeof(struct ice_adv_fltr_mgmt_list_entry),
				GFP_KERNEL);
	if (!adv_fltr) {
		status = ICE_ERR_NO_MEMORY;
		goto err_ice_add_adv_rule;
	}

	adv_fltr->lkups = devm_kmemdup(ice_hw_to_dev(hw), lkups,
				       lkups_cnt * sizeof(*lkups), GFP_KERNEL);
	if (!adv_fltr->lkups) {
		status = ICE_ERR_NO_MEMORY;
		goto err_ice_add_adv_rule;
	}

	adv_fltr->lkups_cnt = lkups_cnt;
	adv_fltr->rule_info = *rinfo;
	adv_fltr->rule_info.fltr_rule_id =
		le16_to_cpu(s_rule->pdata.lkup_tx_rx.index);
	sw = hw->switch_info;
	sw->recp_list[rid].adv_rule = true;
	rule_head = &sw->recp_list[rid].filt_rules;

	if (rinfo->sw_act.fltr_act == ICE_FWD_TO_VSI)
		adv_fltr->vsi_count = 1;

	/* Add rule entry to book keeping list */
	list_add(&adv_fltr->list_entry, rule_head);
	if (added_entry) {
		added_entry->rid = rid;
		added_entry->rule_id = adv_fltr->rule_info.fltr_rule_id;
		added_entry->vsi_handle = rinfo->sw_act.vsi_handle;
	}
err_ice_add_adv_rule:
	if (status && adv_fltr) {
		devm_kfree(ice_hw_to_dev(hw), adv_fltr->lkups);
		devm_kfree(ice_hw_to_dev(hw), adv_fltr);
	}

	kfree(s_rule);

	return status;
}

/**
 * ice_replay_vsi_fltr - Replay filters for requested VSI
 * @hw: pointer to the hardware structure
 * @vsi_handle: driver VSI handle
 * @recp_id: Recipe ID for which rules need to be replayed
 * @list_head: list for which filters need to be replayed
 *
 * Replays the filter of recipe recp_id for a VSI represented via vsi_handle.
 * It is required to pass valid VSI handle.
 */
static enum ice_status
ice_replay_vsi_fltr(struct ice_hw *hw, u16 vsi_handle, u8 recp_id,
		    struct list_head *list_head)
{
	struct ice_fltr_mgmt_list_entry *itr;
	enum ice_status status = 0;
	u16 hw_vsi_id;

	if (list_empty(list_head))
		return status;
	hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle);

	list_for_each_entry(itr, list_head, list_entry) {
		struct ice_fltr_list_entry f_entry;

		f_entry.fltr_info = itr->fltr_info;
		if (itr->vsi_count < 2 && recp_id != ICE_SW_LKUP_VLAN &&
		    itr->fltr_info.vsi_handle == vsi_handle) {
			/* update the src in case it is VSI num */
			if (f_entry.fltr_info.src_id == ICE_SRC_ID_VSI)
				f_entry.fltr_info.src = hw_vsi_id;
			status = ice_add_rule_internal(hw, recp_id, &f_entry);
			if (status)
				goto end;
			continue;
		}
		if (!itr->vsi_list_info ||
		    !test_bit(vsi_handle, itr->vsi_list_info->vsi_map))
			continue;
		/* Clearing it so that the logic can add it back */
		clear_bit(vsi_handle, itr->vsi_list_info->vsi_map);
		f_entry.fltr_info.vsi_handle = vsi_handle;
		f_entry.fltr_info.fltr_act = ICE_FWD_TO_VSI;
		/* update the src in case it is VSI num */
		if (f_entry.fltr_info.src_id == ICE_SRC_ID_VSI)
			f_entry.fltr_info.src = hw_vsi_id;
		if (recp_id == ICE_SW_LKUP_VLAN)
			status = ice_add_vlan_internal(hw, &f_entry);
		else
			status = ice_add_rule_internal(hw, recp_id, &f_entry);
		if (status)
			goto end;
	}
end:
	return status;
}

/**
 * ice_adv_rem_update_vsi_list
 * @hw: pointer to the hardware structure
 * @vsi_handle: VSI handle of the VSI to remove
 * @fm_list: filter management entry for which the VSI list management needs to
 *	     be done
 */
static enum ice_status
ice_adv_rem_update_vsi_list(struct ice_hw *hw, u16 vsi_handle,
			    struct ice_adv_fltr_mgmt_list_entry *fm_list)
{
	struct ice_vsi_list_map_info *vsi_list_info;
	enum ice_sw_lkup_type lkup_type;
	enum ice_status status;
	u16 vsi_list_id;

	if (fm_list->rule_info.sw_act.fltr_act != ICE_FWD_TO_VSI_LIST ||
	    fm_list->vsi_count == 0)
		return ICE_ERR_PARAM;

	/* A rule with the VSI being removed does not exist */
	if (!test_bit(vsi_handle, fm_list->vsi_list_info->vsi_map))
		return ICE_ERR_DOES_NOT_EXIST;

	lkup_type = ICE_SW_LKUP_LAST;
	vsi_list_id = fm_list->rule_info.sw_act.fwd_id.vsi_list_id;
	status = ice_update_vsi_list_rule(hw, &vsi_handle, 1, vsi_list_id, true,
					  ice_aqc_opc_update_sw_rules,
					  lkup_type);
	if (status)
		return status;

	fm_list->vsi_count--;
	clear_bit(vsi_handle, fm_list->vsi_list_info->vsi_map);
	vsi_list_info = fm_list->vsi_list_info;
	if (fm_list->vsi_count == 1) {
		struct ice_fltr_info tmp_fltr;
		u16 rem_vsi_handle;

		rem_vsi_handle = find_first_bit(vsi_list_info->vsi_map,
						ICE_MAX_VSI);
		if (!ice_is_vsi_valid(hw, rem_vsi_handle))
			return ICE_ERR_OUT_OF_RANGE;

		/* Make sure VSI list is empty before removing it below */
		status = ice_update_vsi_list_rule(hw, &rem_vsi_handle, 1,
						  vsi_list_id, true,
						  ice_aqc_opc_update_sw_rules,
						  lkup_type);
		if (status)
			return status;

		memset(&tmp_fltr, 0, sizeof(tmp_fltr));
		tmp_fltr.flag = fm_list->rule_info.sw_act.flag;
		tmp_fltr.fltr_rule_id = fm_list->rule_info.fltr_rule_id;
		fm_list->rule_info.sw_act.fltr_act = ICE_FWD_TO_VSI;
		tmp_fltr.fltr_act = ICE_FWD_TO_VSI;
		tmp_fltr.fwd_id.hw_vsi_id =
			ice_get_hw_vsi_num(hw, rem_vsi_handle);
		fm_list->rule_info.sw_act.fwd_id.hw_vsi_id =
			ice_get_hw_vsi_num(hw, rem_vsi_handle);
		fm_list->rule_info.sw_act.vsi_handle = rem_vsi_handle;

		/* Update the previous switch rule of "MAC forward to VSI" to
		 * "MAC fwd to VSI list"
		 */
		status = ice_update_pkt_fwd_rule(hw, &tmp_fltr);
		if (status) {
			ice_debug(hw, ICE_DBG_SW, "Failed to update pkt fwd rule to FWD_TO_VSI on HW VSI %d, error %d\n",
				  tmp_fltr.fwd_id.hw_vsi_id, status);
			return status;
		}
		fm_list->vsi_list_info->ref_cnt--;

		/* Remove the VSI list since it is no longer used */
		status = ice_remove_vsi_list_rule(hw, vsi_list_id, lkup_type);
		if (status) {
			ice_debug(hw, ICE_DBG_SW, "Failed to remove VSI list %d, error %d\n",
				  vsi_list_id, status);
			return status;
		}

		list_del(&vsi_list_info->list_entry);
		devm_kfree(ice_hw_to_dev(hw), vsi_list_info);
		fm_list->vsi_list_info = NULL;
	}

	return status;
}

/**
 * ice_rem_adv_rule - removes existing advanced switch rule
 * @hw: pointer to the hardware structure
 * @lkups: information on the words that needs to be looked up. All words
 *         together makes one recipe
 * @lkups_cnt: num of entries in the lkups array
 * @rinfo: Its the pointer to the rule information for the rule
 *
 * This function can be used to remove 1 rule at a time. The lkups is
 * used to describe all the words that forms the "lookup" portion of the
 * rule. These words can span multiple protocols. Callers to this function
 * need to pass in a list of protocol headers with lookup information along
 * and mask that determines which words are valid from the given protocol
 * header. rinfo describes other information related to this rule such as
 * forwarding IDs, priority of this rule, etc.
 */
static enum ice_status
ice_rem_adv_rule(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups,
		 u16 lkups_cnt, struct ice_adv_rule_info *rinfo)
{
	struct ice_adv_fltr_mgmt_list_entry *list_elem;
	struct ice_prot_lkup_ext lkup_exts;
	enum ice_status status = 0;
	bool remove_rule = false;
	struct mutex *rule_lock; /* Lock to protect filter rule list */
	u16 i, rid, vsi_handle;

	memset(&lkup_exts, 0, sizeof(lkup_exts));
	for (i = 0; i < lkups_cnt; i++) {
		u16 count;

		if (lkups[i].type >= ICE_PROTOCOL_LAST)
			return ICE_ERR_CFG;

		count = ice_fill_valid_words(&lkups[i], &lkup_exts);
		if (!count)
			return ICE_ERR_CFG;
	}

	/* Create any special protocol/offset pairs, such as looking at tunnel
	 * bits by extracting metadata
	 */
	status = ice_add_special_words(rinfo, &lkup_exts);
	if (status)
		return status;

	rid = ice_find_recp(hw, &lkup_exts);
	/* If did not find a recipe that match the existing criteria */
	if (rid == ICE_MAX_NUM_RECIPES)
		return ICE_ERR_PARAM;

	rule_lock = &hw->switch_info->recp_list[rid].filt_rule_lock;
	list_elem = ice_find_adv_rule_entry(hw, lkups, lkups_cnt, rid, rinfo);
	/* the rule is already removed */
	if (!list_elem)
		return 0;
	mutex_lock(rule_lock);
	if (list_elem->rule_info.sw_act.fltr_act != ICE_FWD_TO_VSI_LIST) {
		remove_rule = true;
	} else if (list_elem->vsi_count > 1) {
		remove_rule = false;
		vsi_handle = rinfo->sw_act.vsi_handle;
		status = ice_adv_rem_update_vsi_list(hw, vsi_handle, list_elem);
	} else {
		vsi_handle = rinfo->sw_act.vsi_handle;
		status = ice_adv_rem_update_vsi_list(hw, vsi_handle, list_elem);
		if (status) {
			mutex_unlock(rule_lock);
			return status;
		}
		if (list_elem->vsi_count == 0)
			remove_rule = true;
	}
	mutex_unlock(rule_lock);
	if (remove_rule) {
		struct ice_aqc_sw_rules_elem *s_rule;
		u16 rule_buf_sz;

		rule_buf_sz = ICE_SW_RULE_RX_TX_NO_HDR_SIZE;
		s_rule = kzalloc(rule_buf_sz, GFP_KERNEL);
		if (!s_rule)
			return ICE_ERR_NO_MEMORY;
		s_rule->pdata.lkup_tx_rx.act = 0;
		s_rule->pdata.lkup_tx_rx.index =
			cpu_to_le16(list_elem->rule_info.fltr_rule_id);
		s_rule->pdata.lkup_tx_rx.hdr_len = 0;
		status = ice_aq_sw_rules(hw, (struct ice_aqc_sw_rules *)s_rule,
					 rule_buf_sz, 1,
					 ice_aqc_opc_remove_sw_rules, NULL);
		if (!status || status == ICE_ERR_DOES_NOT_EXIST) {
			struct ice_switch_info *sw = hw->switch_info;

			mutex_lock(rule_lock);
			list_del(&list_elem->list_entry);
			devm_kfree(ice_hw_to_dev(hw), list_elem->lkups);
			devm_kfree(ice_hw_to_dev(hw), list_elem);
			mutex_unlock(rule_lock);
			if (list_empty(&sw->recp_list[rid].filt_rules))
				sw->recp_list[rid].adv_rule = false;
		}
		kfree(s_rule);
	}
	return status;
}

/**
 * ice_rem_adv_rule_by_id - removes existing advanced switch rule by ID
 * @hw: pointer to the hardware structure
 * @remove_entry: data struct which holds rule_id, VSI handle and recipe ID
 *
 * This function is used to remove 1 rule at a time. The removal is based on
 * the remove_entry parameter. This function will remove rule for a given
 * vsi_handle with a given rule_id which is passed as parameter in remove_entry
 */
enum ice_status
ice_rem_adv_rule_by_id(struct ice_hw *hw,
		       struct ice_rule_query_data *remove_entry)
{
	struct ice_adv_fltr_mgmt_list_entry *list_itr;
	struct list_head *list_head;
	struct ice_adv_rule_info rinfo;
	struct ice_switch_info *sw;

	sw = hw->switch_info;
	if (!sw->recp_list[remove_entry->rid].recp_created)
		return ICE_ERR_PARAM;
	list_head = &sw->recp_list[remove_entry->rid].filt_rules;
	list_for_each_entry(list_itr, list_head, list_entry) {
		if (list_itr->rule_info.fltr_rule_id ==
		    remove_entry->rule_id) {
			rinfo = list_itr->rule_info;
			rinfo.sw_act.vsi_handle = remove_entry->vsi_handle;
			return ice_rem_adv_rule(hw, list_itr->lkups,
						list_itr->lkups_cnt, &rinfo);
		}
	}
	/* either list is empty or unable to find rule */
	return ICE_ERR_DOES_NOT_EXIST;
}

/**
 * ice_replay_vsi_all_fltr - replay all filters stored in bookkeeping lists
 * @hw: pointer to the hardware structure
 * @vsi_handle: driver VSI handle
 *
 * Replays filters for requested VSI via vsi_handle.
 */
enum ice_status ice_replay_vsi_all_fltr(struct ice_hw *hw, u16 vsi_handle)
{
	struct ice_switch_info *sw = hw->switch_info;
	enum ice_status status = 0;
	u8 i;

	for (i = 0; i < ICE_SW_LKUP_LAST; i++) {
		struct list_head *head;

		head = &sw->recp_list[i].filt_replay_rules;
		status = ice_replay_vsi_fltr(hw, vsi_handle, i, head);
		if (status)
			return status;
	}
	return status;
}

/**
 * ice_rm_all_sw_replay_rule_info - deletes filter replay rules
 * @hw: pointer to the HW struct
 *
 * Deletes the filter replay rules.
 */
void ice_rm_all_sw_replay_rule_info(struct ice_hw *hw)
{
	struct ice_switch_info *sw = hw->switch_info;
	u8 i;

	if (!sw)
		return;

	for (i = 0; i < ICE_MAX_NUM_RECIPES; i++) {
		if (!list_empty(&sw->recp_list[i].filt_replay_rules)) {
			struct list_head *l_head;

			l_head = &sw->recp_list[i].filt_replay_rules;
			if (!sw->recp_list[i].adv_rule)
				ice_rem_sw_rule_info(hw, l_head);
			else
				ice_rem_adv_rule_info(hw, l_head);
		}
	}
}
