net/ice/base: add ethertype offset for QinQ dummy packet
[dpdk.git] / drivers / net / ice / base / ice_switch.c
index cd78685..4568242 100644 (file)
@@ -1,5 +1,5 @@
 /* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2001-2020 Intel Corporation
+ * Copyright(c) 2001-2021 Intel Corporation
  */
 
 #include "ice_switch.h"
@@ -14,6 +14,7 @@
 #define ICE_PPP_IPV6_PROTO_ID          0x0057
 #define ICE_IPV6_ETHER_ID              0x86DD
 #define ICE_TCP_PROTO_ID               0x06
+#define ICE_ETH_P_8021Q                        0x8100
 
 /* Dummy ethernet header needed in the ice_aqc_sw_rules_elem
  * struct to configure any switch filter rules.
@@ -504,6 +505,413 @@ static const u8 dummy_vlan_udp_ipv6_packet[] = {
        0x00, 0x00, /* 2 bytes for 4 byte alignment */
 };
 
+/* Outer IPv4 + Outer UDP + GTP + Inner IPv4 + Inner TCP */
+static const struct ice_dummy_pkt_offsets dummy_ipv4_gtpu_ipv4_tcp_packet_offsets[] = {
+       { ICE_MAC_OFOS,         0 },
+       { ICE_IPV4_OFOS,        14 },
+       { ICE_UDP_OF,           34 },
+       { ICE_GTP,              42 },
+       { ICE_IPV4_IL,          62 },
+       { ICE_TCP_IL,           82 },
+       { ICE_PROTOCOL_LAST,    0 },
+};
+
+static const u8 dummy_ipv4_gtpu_ipv4_tcp_packet[] = {
+       0x00, 0x00, 0x00, 0x00, /* Ethernet 0 */
+       0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,
+       0x08, 0x00,
+
+       0x45, 0x00, 0x00, 0x58, /* IP 14 */
+       0x00, 0x00, 0x00, 0x00,
+       0x00, 0x11, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,
+
+       0x00, 0x00, 0x08, 0x68, /* UDP 34 */
+       0x00, 0x44, 0x00, 0x00,
+
+       0x34, 0xff, 0x00, 0x34, /* GTP-U Header 42 */
+       0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x85,
+
+       0x02, 0x00, 0x00, 0x00, /* GTP_PDUSession_ExtensionHeader 54 */
+       0x00, 0x00, 0x00, 0x00,
+
+       0x45, 0x00, 0x00, 0x28, /* IP 62 */
+       0x00, 0x00, 0x00, 0x00,
+       0x00, 0x06, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,
+
+       0x00, 0x00, 0x00, 0x00, /* TCP 82 */
+       0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,
+       0x50, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,
+
+       0x00, 0x00, /* 2 bytes for 4 byte alignment */
+};
+
+/* Outer IPv4 + Outer UDP + GTP + Inner IPv4 + Inner UDP */
+static const struct ice_dummy_pkt_offsets dummy_ipv4_gtpu_ipv4_udp_packet_offsets[] = {
+       { ICE_MAC_OFOS,         0 },
+       { ICE_IPV4_OFOS,        14 },
+       { ICE_UDP_OF,           34 },
+       { ICE_GTP,              42 },
+       { ICE_IPV4_IL,          62 },
+       { ICE_UDP_ILOS,         82 },
+       { ICE_PROTOCOL_LAST,    0 },
+};
+
+static const u8 dummy_ipv4_gtpu_ipv4_udp_packet[] = {
+       0x00, 0x00, 0x00, 0x00, /* Ethernet 0 */
+       0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,
+       0x08, 0x00,
+
+       0x45, 0x00, 0x00, 0x4c, /* IP 14 */
+       0x00, 0x00, 0x00, 0x00,
+       0x00, 0x11, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,
+
+       0x00, 0x00, 0x08, 0x68, /* UDP 34 */
+       0x00, 0x38, 0x00, 0x00,
+
+       0x34, 0xff, 0x00, 0x28, /* GTP-U Header 42 */
+       0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x85,
+
+       0x02, 0x00, 0x00, 0x00, /* GTP_PDUSession_ExtensionHeader 54 */
+       0x00, 0x00, 0x00, 0x00,
+
+       0x45, 0x00, 0x00, 0x1c, /* IP 62 */
+       0x00, 0x00, 0x00, 0x00,
+       0x00, 0x11, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,
+
+       0x00, 0x00, 0x00, 0x00, /* UDP 82 */
+       0x00, 0x08, 0x00, 0x00,
+
+       0x00, 0x00, /* 2 bytes for 4 byte alignment */
+};
+
+/* Outer IPv6 + Outer UDP + GTP + Inner IPv4 + Inner TCP */
+static const struct ice_dummy_pkt_offsets dummy_ipv4_gtpu_ipv6_tcp_packet_offsets[] = {
+       { ICE_MAC_OFOS,         0 },
+       { ICE_IPV4_OFOS,        14 },
+       { ICE_UDP_OF,           34 },
+       { ICE_GTP,              42 },
+       { ICE_IPV6_IL,          62 },
+       { ICE_TCP_IL,           102 },
+       { ICE_PROTOCOL_LAST,    0 },
+};
+
+static const u8 dummy_ipv4_gtpu_ipv6_tcp_packet[] = {
+       0x00, 0x00, 0x00, 0x00, /* Ethernet 0 */
+       0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,
+       0x08, 0x00,
+
+       0x45, 0x00, 0x00, 0x6c, /* IP 14 */
+       0x00, 0x00, 0x00, 0x00,
+       0x00, 0x11, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,
+
+       0x00, 0x00, 0x08, 0x68, /* UDP 34 */
+       0x00, 0x58, 0x00, 0x00,
+
+       0x34, 0xff, 0x00, 0x48, /* GTP-U Header 42 */
+       0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x85,
+
+       0x02, 0x00, 0x00, 0x00, /* GTP_PDUSession_ExtensionHeader 54 */
+       0x00, 0x00, 0x00, 0x00,
+
+       0x60, 0x00, 0x00, 0x00, /* IPv6 62 */
+       0x00, 0x14, 0x06, 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, 0x00, /* TCP 102 */
+       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_ipv4_gtpu_ipv6_udp_packet_offsets[] = {
+       { ICE_MAC_OFOS,         0 },
+       { ICE_IPV4_OFOS,        14 },
+       { ICE_UDP_OF,           34 },
+       { ICE_GTP,              42 },
+       { ICE_IPV6_IL,          62 },
+       { ICE_UDP_ILOS,         102 },
+       { ICE_PROTOCOL_LAST,    0 },
+};
+
+static const u8 dummy_ipv4_gtpu_ipv6_udp_packet[] = {
+       0x00, 0x00, 0x00, 0x00, /* Ethernet 0 */
+       0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,
+       0x08, 0x00,
+
+       0x45, 0x00, 0x00, 0x60, /* IP 14 */
+       0x00, 0x00, 0x00, 0x00,
+       0x00, 0x11, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,
+
+       0x00, 0x00, 0x08, 0x68, /* UDP 34 */
+       0x00, 0x4c, 0x00, 0x00,
+
+       0x34, 0xff, 0x00, 0x3c, /* GTP-U Header 42 */
+       0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x85,
+
+       0x02, 0x00, 0x00, 0x00, /* GTP_PDUSession_ExtensionHeader 54 */
+       0x00, 0x00, 0x00, 0x00,
+
+       0x60, 0x00, 0x00, 0x00, /* IPv6 62 */
+       0x00, 0x08, 0x11, 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, 0x00, /* UDP 102 */
+       0x00, 0x08, 0x00, 0x00,
+
+       0x00, 0x00, /* 2 bytes for 4 byte alignment */
+};
+
+static const struct ice_dummy_pkt_offsets dummy_ipv6_gtpu_ipv4_tcp_packet_offsets[] = {
+       { ICE_MAC_OFOS,         0 },
+       { ICE_IPV6_OFOS,        14 },
+       { ICE_UDP_OF,           54 },
+       { ICE_GTP,              62 },
+       { ICE_IPV4_IL,          82 },
+       { ICE_TCP_IL,           102 },
+       { ICE_PROTOCOL_LAST,    0 },
+};
+
+static const u8 dummy_ipv6_gtpu_ipv4_tcp_packet[] = {
+       0x00, 0x00, 0x00, 0x00, /* Ethernet 0 */
+       0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,
+       0x86, 0xdd,
+
+       0x60, 0x00, 0x00, 0x00, /* IPv6 14 */
+       0x00, 0x44, 0x11, 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, 0x08, 0x68, /* UDP 54 */
+       0x00, 0x44, 0x00, 0x00,
+
+       0x34, 0xff, 0x00, 0x34, /* GTP-U Header 62 */
+       0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x85,
+
+       0x02, 0x00, 0x00, 0x00, /* GTP_PDUSession_ExtensionHeader 74 */
+       0x00, 0x00, 0x00, 0x00,
+
+       0x45, 0x00, 0x00, 0x28, /* IP 82 */
+       0x00, 0x00, 0x00, 0x00,
+       0x00, 0x06, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,
+
+       0x00, 0x00, 0x00, 0x00, /* TCP 102 */
+       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_ipv6_gtpu_ipv4_udp_packet_offsets[] = {
+       { ICE_MAC_OFOS,         0 },
+       { ICE_IPV6_OFOS,        14 },
+       { ICE_UDP_OF,           54 },
+       { ICE_GTP,              62 },
+       { ICE_IPV4_IL,          82 },
+       { ICE_UDP_ILOS,         102 },
+       { ICE_PROTOCOL_LAST,    0 },
+};
+
+static const u8 dummy_ipv6_gtpu_ipv4_udp_packet[] = {
+       0x00, 0x00, 0x00, 0x00, /* Ethernet 0 */
+       0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,
+       0x86, 0xdd,
+
+       0x60, 0x00, 0x00, 0x00, /* IPv6 14 */
+       0x00, 0x38, 0x11, 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, 0x08, 0x68, /* UDP 54 */
+       0x00, 0x38, 0x00, 0x00,
+
+       0x34, 0xff, 0x00, 0x28, /* GTP-U Header 62 */
+       0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x85,
+
+       0x02, 0x00, 0x00, 0x00, /* GTP_PDUSession_ExtensionHeader 74 */
+       0x00, 0x00, 0x00, 0x00,
+
+       0x45, 0x00, 0x00, 0x1c, /* IP 82 */
+       0x00, 0x00, 0x00, 0x00,
+       0x00, 0x11, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,
+
+       0x00, 0x00, 0x00, 0x00, /* UDP 102 */
+       0x00, 0x08, 0x00, 0x00,
+
+       0x00, 0x00, /* 2 bytes for 4 byte alignment */
+};
+
+static const struct ice_dummy_pkt_offsets dummy_ipv6_gtpu_ipv6_tcp_packet_offsets[] = {
+       { ICE_MAC_OFOS,         0 },
+       { ICE_IPV6_OFOS,        14 },
+       { ICE_UDP_OF,           54 },
+       { ICE_GTP,              62 },
+       { ICE_IPV6_IL,          82 },
+       { ICE_TCP_IL,           102 },
+       { ICE_PROTOCOL_LAST,    0 },
+};
+
+static const u8 dummy_ipv6_gtpu_ipv6_tcp_packet[] = {
+       0x00, 0x00, 0x00, 0x00, /* Ethernet 0 */
+       0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,
+       0x86, 0xdd,
+
+       0x60, 0x00, 0x00, 0x00, /* IPv6 14 */
+       0x00, 0x58, 0x11, 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, 0x08, 0x68, /* UDP 54 */
+       0x00, 0x58, 0x00, 0x00,
+
+       0x34, 0xff, 0x00, 0x48, /* GTP-U Header 62 */
+       0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x85,
+
+       0x02, 0x00, 0x00, 0x00, /* GTP_PDUSession_ExtensionHeader 74 */
+       0x00, 0x00, 0x00, 0x00,
+
+       0x60, 0x00, 0x00, 0x00, /* IPv6 82 */
+       0x00, 0x14, 0x06, 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, 0x00, /* TCP 122 */
+       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_ipv6_gtpu_ipv6_udp_packet_offsets[] = {
+       { ICE_MAC_OFOS,         0 },
+       { ICE_IPV6_OFOS,        14 },
+       { ICE_UDP_OF,           54 },
+       { ICE_GTP,              62 },
+       { ICE_IPV6_IL,          82 },
+       { ICE_UDP_ILOS,         102 },
+       { ICE_PROTOCOL_LAST,    0 },
+};
+
+static const u8 dummy_ipv6_gtpu_ipv6_udp_packet[] = {
+       0x00, 0x00, 0x00, 0x00, /* Ethernet 0 */
+       0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,
+       0x86, 0xdd,
+
+       0x60, 0x00, 0x00, 0x00, /* IPv6 14 */
+       0x00, 0x4c, 0x11, 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, 0x08, 0x68, /* UDP 54 */
+       0x00, 0x4c, 0x00, 0x00,
+
+       0x34, 0xff, 0x00, 0x3c, /* GTP-U Header 62 */
+       0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x85,
+
+       0x02, 0x00, 0x00, 0x00, /* GTP_PDUSession_ExtensionHeader 74 */
+       0x00, 0x00, 0x00, 0x00,
+
+       0x60, 0x00, 0x00, 0x00, /* IPv6 82 */
+       0x00, 0x08, 0x11, 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, 0x00, /* UDP 122 */
+       0x00, 0x08, 0x00, 0x00,
+
+       0x00, 0x00, /* 2 bytes for 4 byte alignment */
+};
+
 static const struct ice_dummy_pkt_offsets dummy_udp_gtp_packet_offsets[] = {
        { ICE_MAC_OFOS,         0 },
        { ICE_IPV4_OFOS,        14 },
@@ -1204,6 +1612,7 @@ static const u8 dummy_ipv6_l2tpv3_pkt[] = {
 
 static const struct ice_dummy_pkt_offsets dummy_qinq_ipv4_packet_offsets[] = {
        { ICE_MAC_OFOS,         0 },
+       { ICE_ETYPE_OL,         12 },
        { ICE_VLAN_EX,          14 },
        { ICE_VLAN_OFOS,        18 },
        { ICE_IPV4_OFOS,        22 },
@@ -1214,7 +1623,8 @@ static const u8 dummy_qinq_ipv4_pkt[] = {
        0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
        0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00,
-       0x91, 0x00,
+
+       0x91, 0x00,             /* ICE_ETYPE_OL 12 */
 
        0x00, 0x00, 0x81, 0x00, /* ICE_VLAN_EX 14 */
        0x00, 0x00, 0x08, 0x00, /* ICE_VLAN_OFOS 18 */
@@ -1233,6 +1643,7 @@ static const u8 dummy_qinq_ipv4_pkt[] = {
 
 static const struct ice_dummy_pkt_offsets dummy_qinq_ipv6_packet_offsets[] = {
        { ICE_MAC_OFOS,         0 },
+       { ICE_ETYPE_OL,         12 },
        { ICE_VLAN_EX,          14 },
        { ICE_VLAN_OFOS,        18 },
        { ICE_IPV6_OFOS,        22 },
@@ -1243,7 +1654,8 @@ static const u8 dummy_qinq_ipv6_pkt[] = {
        0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
        0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00,
-       0x91, 0x00,
+
+       0x91, 0x00,             /* ICE_ETYPE_OL 12 */
 
        0x00, 0x00, 0x81, 0x00, /* ICE_VLAN_EX 14 */
        0x00, 0x00, 0x86, 0xDD, /* ICE_VLAN_OFOS 18 */
@@ -1270,6 +1682,7 @@ static const u8 dummy_qinq_ipv6_pkt[] = {
 
 static const struct ice_dummy_pkt_offsets dummy_qinq_pppoe_packet_offsets[] = {
        { ICE_MAC_OFOS,         0 },
+       { ICE_ETYPE_OL,         12 },
        { ICE_VLAN_EX,          14 },
        { ICE_VLAN_OFOS,        18 },
        { ICE_PPPOE,            22 },
@@ -1279,6 +1692,7 @@ static const struct ice_dummy_pkt_offsets dummy_qinq_pppoe_packet_offsets[] = {
 static const
 struct ice_dummy_pkt_offsets dummy_qinq_pppoe_ipv4_packet_offsets[] = {
        { ICE_MAC_OFOS,         0 },
+       { ICE_ETYPE_OL,         12 },
        { ICE_VLAN_EX,          14 },
        { ICE_VLAN_OFOS,        18 },
        { ICE_PPPOE,            22 },
@@ -1290,7 +1704,8 @@ static const u8 dummy_qinq_pppoe_ipv4_pkt[] = {
        0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
        0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00,
-       0x91, 0x00,
+
+       0x91, 0x00,             /* ICE_ETYPE_OL 12 */
 
        0x00, 0x00, 0x81, 0x00, /* ICE_VLAN_EX 14 */
        0x00, 0x00, 0x88, 0x64, /* ICE_VLAN_OFOS 18 */
@@ -2767,6 +3182,64 @@ ice_aq_get_recipe(struct ice_hw *hw,
        return status;
 }
 
+/**
+ * ice_update_recipe_lkup_idx - update a default recipe based on the lkup_idx
+ * @hw: pointer to the HW struct
+ * @params: parameters used to update the default recipe
+ *
+ * This function only supports updating default recipes and it only supports
+ * updating a single recipe based on the lkup_idx at a time.
+ *
+ * This is done as a read-modify-write operation. First, get the current recipe
+ * contents based on the recipe's ID. Then modify the field vector index and
+ * mask if it's valid at the lkup_idx. Finally, use the add recipe AQ to update
+ * the pre-existing recipe with the modifications.
+ */
+enum ice_status
+ice_update_recipe_lkup_idx(struct ice_hw *hw,
+                          struct ice_update_recipe_lkup_idx_params *params)
+{
+       struct ice_aqc_recipe_data_elem *rcp_list;
+       u16 num_recps = ICE_MAX_NUM_RECIPES;
+       enum ice_status status;
+
+       rcp_list = (struct ice_aqc_recipe_data_elem *)ice_malloc(hw, num_recps * sizeof(*rcp_list));
+       if (!rcp_list)
+               return ICE_ERR_NO_MEMORY;
+
+       /* read current recipe list from firmware */
+       rcp_list->recipe_indx = params->rid;
+       status = ice_aq_get_recipe(hw, rcp_list, &num_recps, params->rid, NULL);
+       if (status) {
+               ice_debug(hw, ICE_DBG_SW, "Failed to get recipe %d, status %d\n",
+                         params->rid, status);
+               goto error_out;
+       }
+
+       /* only modify existing recipe's lkup_idx and mask if valid, while
+        * leaving all other fields the same, then update the recipe firmware
+        */
+       rcp_list->content.lkup_indx[params->lkup_idx] = params->fv_idx;
+       if (params->mask_valid)
+               rcp_list->content.mask[params->lkup_idx] =
+                       CPU_TO_LE16(params->mask);
+
+       if (params->ignore_valid)
+               rcp_list->content.lkup_indx[params->lkup_idx] |=
+                       ICE_AQ_RECIPE_LKUP_IGNORE;
+
+       status = ice_aq_add_recipe(hw, &rcp_list[0], 1, NULL);
+       if (status)
+               ice_debug(hw, ICE_DBG_SW, "Failed to update recipe %d lkup_idx %d fv_idx %d mask %d mask_valid %s, status %d\n",
+                         params->rid, params->lkup_idx, params->fv_idx,
+                         params->mask, params->mask_valid ? "true" : "false",
+                         status);
+
+error_out:
+       ice_free(hw, rcp_list);
+       return status;
+}
+
 /**
  * ice_aq_map_recipe_to_profile - Map recipe to packet profile
  * @hw: pointer to the HW struct
@@ -3034,6 +3507,7 @@ 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;
+       u16 vlan_tpid = ICE_ETH_P_8021Q;
        void *daddr = NULL;
        u16 eth_hdr_sz;
        u8 *eth_hdr;
@@ -3106,6 +3580,8 @@ ice_fill_sw_rule(struct ice_hw *hw, struct ice_fltr_info *f_info,
                break;
        case ICE_SW_LKUP_VLAN:
                vlan_id = f_info->l_data.vlan.vlan_id;
+               if (f_info->l_data.vlan.tpid_valid)
+                       vlan_tpid = f_info->l_data.vlan.tpid;
                if (f_info->fltr_act == ICE_FWD_TO_VSI ||
                    f_info->fltr_act == ICE_FWD_TO_VSI_LIST) {
                        act |= ICE_SINGLE_ACT_PRUNE;
@@ -3149,6 +3625,8 @@ ice_fill_sw_rule(struct ice_hw *hw, struct ice_fltr_info *f_info,
        if (!(vlan_id > ICE_MAX_VLAN_ID)) {
                off = (_FORCE_ __be16 *)(eth_hdr + ICE_ETH_VLAN_TCI_OFFSET);
                *off = CPU_TO_BE16(vlan_id);
+               off = (_FORCE_ __be16 *)(eth_hdr + ICE_ETH_ETHTYPE_OFFSET);
+               *off = CPU_TO_BE16(vlan_tpid);
        }
 
        /* Create the switch rule with the final dummy Ethernet header */
@@ -3366,8 +3844,7 @@ ice_create_vsi_list_map(struct ice_hw *hw, u16 *vsi_handle_arr, u16 num_vsi,
        struct ice_vsi_list_map_info *v_map;
        int i;
 
-       v_map = (struct ice_vsi_list_map_info *)ice_calloc(hw, 1,
-               sizeof(*v_map));
+       v_map = (struct ice_vsi_list_map_info *)ice_malloc(hw, sizeof(*v_map));
        if (!v_map)
                return NULL;
 
@@ -3684,6 +4161,9 @@ ice_add_update_vsi_list(struct ice_hw *hw,
                        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
                 */
@@ -5017,6 +5497,7 @@ 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 &&
                 (ice_is_bit_set(fm_entry->vsi_list_info->vsi_map,
                                 vsi_handle))));
 }
@@ -5091,14 +5572,12 @@ ice_add_to_vsi_fltr_list(struct ice_hw *hw, u16 vsi_handle,
 
        LIST_FOR_EACH_ENTRY(fm_entry, lkup_list_head,
                            ice_fltr_mgmt_list_entry, list_entry) {
-               struct ice_fltr_info *fi;
-
-               fi = &fm_entry->fltr_info;
-               if (!fi || !ice_vsi_uses_fltr(fm_entry, vsi_handle))
+               if (!ice_vsi_uses_fltr(fm_entry, vsi_handle))
                        continue;
 
                status = ice_add_entry_to_vsi_fltr_list(hw, vsi_handle,
-                                                       vsi_list_head, fi);
+                                                       vsi_list_head,
+                                                       &fm_entry->fltr_info);
                if (status)
                        return status;
        }