19c20346bSAnirudh Venkataramanan // SPDX-License-Identifier: GPL-2.0 29c20346bSAnirudh Venkataramanan /* Copyright (c) 2018, Intel Corporation. */ 39c20346bSAnirudh Venkataramanan 4348048e7SDave Ertman #include "ice_lib.h" 59c20346bSAnirudh Venkataramanan #include "ice_switch.h" 69c20346bSAnirudh Venkataramanan 79daf8208SAnirudh Venkataramanan #define ICE_ETH_DA_OFFSET 0 89daf8208SAnirudh Venkataramanan #define ICE_ETH_ETHTYPE_OFFSET 12 99daf8208SAnirudh Venkataramanan #define ICE_ETH_VLAN_TCI_OFFSET 14 109daf8208SAnirudh Venkataramanan #define ICE_MAX_VLAN_ID 0xFFF 110f94570dSGrishma Kotecha #define ICE_IPV6_ETHER_ID 0x86DD 129daf8208SAnirudh Venkataramanan 139daf8208SAnirudh Venkataramanan /* Dummy ethernet header needed in the ice_aqc_sw_rules_elem 149daf8208SAnirudh Venkataramanan * struct to configure any switch filter rules. 159daf8208SAnirudh Venkataramanan * {DA (6 bytes), SA(6 bytes), 169daf8208SAnirudh Venkataramanan * Ether type (2 bytes for header without VLAN tag) OR 179daf8208SAnirudh Venkataramanan * VLAN tag (4 bytes for header with VLAN tag) } 189daf8208SAnirudh Venkataramanan * 199daf8208SAnirudh Venkataramanan * Word on Hardcoded values 209daf8208SAnirudh Venkataramanan * byte 0 = 0x2: to identify it as locally administered DA MAC 219daf8208SAnirudh Venkataramanan * byte 6 = 0x2: to identify it as locally administered SA MAC 229daf8208SAnirudh Venkataramanan * byte 12 = 0x81 & byte 13 = 0x00: 239daf8208SAnirudh Venkataramanan * In case of VLAN filter first two bytes defines ether type (0x8100) 24f9867df6SAnirudh Venkataramanan * and remaining two bytes are placeholder for programming a given VLAN ID 259daf8208SAnirudh Venkataramanan * In case of Ether type filter it is treated as header without VLAN tag 269daf8208SAnirudh Venkataramanan * and byte 12 and 13 is used to program a given Ether type instead 279daf8208SAnirudh Venkataramanan */ 289daf8208SAnirudh Venkataramanan static const u8 dummy_eth_header[DUMMY_ETH_HDR_LEN] = { 0x2, 0, 0, 0, 0, 0, 299daf8208SAnirudh Venkataramanan 0x2, 0, 0, 0, 0, 0, 309daf8208SAnirudh Venkataramanan 0x81, 0, 0, 0}; 319daf8208SAnirudh Venkataramanan 32e33163a4SAlexander Lobakin enum { 3326395726SMartyna Szapar-Mudlaw ICE_PKT_OUTER_IPV6 = BIT(0), 3426395726SMartyna Szapar-Mudlaw ICE_PKT_TUN_GTPC = BIT(1), 3526395726SMartyna Szapar-Mudlaw ICE_PKT_TUN_GTPU = BIT(2), 3626395726SMartyna Szapar-Mudlaw ICE_PKT_TUN_NVGRE = BIT(3), 3726395726SMartyna Szapar-Mudlaw ICE_PKT_TUN_UDP = BIT(4), 3826395726SMartyna Szapar-Mudlaw ICE_PKT_INNER_IPV6 = BIT(5), 3926395726SMartyna Szapar-Mudlaw ICE_PKT_INNER_TCP = BIT(6), 4026395726SMartyna Szapar-Mudlaw ICE_PKT_INNER_UDP = BIT(7), 4126395726SMartyna Szapar-Mudlaw ICE_PKT_GTP_NOPAY = BIT(8), 4226395726SMartyna Szapar-Mudlaw ICE_PKT_KMALLOC = BIT(9), 43cd8efeeeSMarcin Szycik ICE_PKT_PPPOE = BIT(10), 44cd634549SMarcin Szycik ICE_PKT_L2TPV3 = BIT(11), 45e33163a4SAlexander Lobakin }; 46e33163a4SAlexander Lobakin 470f94570dSGrishma Kotecha struct ice_dummy_pkt_offsets { 480f94570dSGrishma Kotecha enum ice_protocol_type type; 490f94570dSGrishma Kotecha u16 offset; /* ICE_PROTOCOL_LAST indicates end of list */ 500f94570dSGrishma Kotecha }; 510f94570dSGrishma Kotecha 521b699f81SAlexander Lobakin struct ice_dummy_pkt_profile { 531b699f81SAlexander Lobakin const struct ice_dummy_pkt_offsets *offsets; 541b699f81SAlexander Lobakin const u8 *pkt; 55e33163a4SAlexander Lobakin u32 match; 561b699f81SAlexander Lobakin u16 pkt_len; 5726395726SMartyna Szapar-Mudlaw u16 offsets_len; 581b699f81SAlexander Lobakin }; 591b699f81SAlexander Lobakin 6007a28842SAlexander Lobakin #define ICE_DECLARE_PKT_OFFSETS(type) \ 6107a28842SAlexander Lobakin static const struct ice_dummy_pkt_offsets \ 6207a28842SAlexander Lobakin ice_dummy_##type##_packet_offsets[] 6307a28842SAlexander Lobakin 6407a28842SAlexander Lobakin #define ICE_DECLARE_PKT_TEMPLATE(type) \ 6507a28842SAlexander Lobakin static const u8 ice_dummy_##type##_packet[] 6607a28842SAlexander Lobakin 67e33163a4SAlexander Lobakin #define ICE_PKT_PROFILE(type, m) { \ 68e33163a4SAlexander Lobakin .match = (m), \ 6907a28842SAlexander Lobakin .pkt = ice_dummy_##type##_packet, \ 7007a28842SAlexander Lobakin .pkt_len = sizeof(ice_dummy_##type##_packet), \ 7107a28842SAlexander Lobakin .offsets = ice_dummy_##type##_packet_offsets, \ 7226395726SMartyna Szapar-Mudlaw .offsets_len = sizeof(ice_dummy_##type##_packet_offsets), \ 73e33163a4SAlexander Lobakin } 741b699f81SAlexander Lobakin 7526395726SMartyna Szapar-Mudlaw ICE_DECLARE_PKT_OFFSETS(vlan) = { 7626395726SMartyna Szapar-Mudlaw { ICE_VLAN_OFOS, 12 }, 7726395726SMartyna Szapar-Mudlaw }; 7826395726SMartyna Szapar-Mudlaw 7926395726SMartyna Szapar-Mudlaw ICE_DECLARE_PKT_TEMPLATE(vlan) = { 8026395726SMartyna Szapar-Mudlaw 0x81, 0x00, 0x00, 0x00, /* ICE_VLAN_OFOS 12 */ 8126395726SMartyna Szapar-Mudlaw }; 8226395726SMartyna Szapar-Mudlaw 8326395726SMartyna Szapar-Mudlaw ICE_DECLARE_PKT_OFFSETS(qinq) = { 8426395726SMartyna Szapar-Mudlaw { ICE_VLAN_EX, 12 }, 8526395726SMartyna Szapar-Mudlaw { ICE_VLAN_IN, 16 }, 8626395726SMartyna Szapar-Mudlaw }; 8726395726SMartyna Szapar-Mudlaw 8826395726SMartyna Szapar-Mudlaw ICE_DECLARE_PKT_TEMPLATE(qinq) = { 8926395726SMartyna Szapar-Mudlaw 0x91, 0x00, 0x00, 0x00, /* ICE_VLAN_EX 12 */ 9026395726SMartyna Szapar-Mudlaw 0x81, 0x00, 0x00, 0x00, /* ICE_VLAN_IN 16 */ 9126395726SMartyna Szapar-Mudlaw }; 9226395726SMartyna Szapar-Mudlaw 9307a28842SAlexander Lobakin ICE_DECLARE_PKT_OFFSETS(gre_tcp) = { 94f0a35040SMichal Swiatkowski { ICE_MAC_OFOS, 0 }, 95f0a35040SMichal Swiatkowski { ICE_ETYPE_OL, 12 }, 96f0a35040SMichal Swiatkowski { ICE_IPV4_OFOS, 14 }, 97f0a35040SMichal Swiatkowski { ICE_NVGRE, 34 }, 98f0a35040SMichal Swiatkowski { ICE_MAC_IL, 42 }, 9934a89775SMartyna Szapar-Mudlaw { ICE_ETYPE_IL, 54 }, 100f0a35040SMichal Swiatkowski { ICE_IPV4_IL, 56 }, 101f0a35040SMichal Swiatkowski { ICE_TCP_IL, 76 }, 102f0a35040SMichal Swiatkowski { ICE_PROTOCOL_LAST, 0 }, 103f0a35040SMichal Swiatkowski }; 104f0a35040SMichal Swiatkowski 10507a28842SAlexander Lobakin ICE_DECLARE_PKT_TEMPLATE(gre_tcp) = { 106f0a35040SMichal Swiatkowski 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */ 107f0a35040SMichal Swiatkowski 0x00, 0x00, 0x00, 0x00, 108f0a35040SMichal Swiatkowski 0x00, 0x00, 0x00, 0x00, 109f0a35040SMichal Swiatkowski 110f0a35040SMichal Swiatkowski 0x08, 0x00, /* ICE_ETYPE_OL 12 */ 111f0a35040SMichal Swiatkowski 112f0a35040SMichal Swiatkowski 0x45, 0x00, 0x00, 0x3E, /* ICE_IPV4_OFOS 14 */ 113f0a35040SMichal Swiatkowski 0x00, 0x00, 0x00, 0x00, 114f0a35040SMichal Swiatkowski 0x00, 0x2F, 0x00, 0x00, 115f0a35040SMichal Swiatkowski 0x00, 0x00, 0x00, 0x00, 116f0a35040SMichal Swiatkowski 0x00, 0x00, 0x00, 0x00, 117f0a35040SMichal Swiatkowski 118f0a35040SMichal Swiatkowski 0x80, 0x00, 0x65, 0x58, /* ICE_NVGRE 34 */ 119f0a35040SMichal Swiatkowski 0x00, 0x00, 0x00, 0x00, 120f0a35040SMichal Swiatkowski 121f0a35040SMichal Swiatkowski 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_IL 42 */ 122f0a35040SMichal Swiatkowski 0x00, 0x00, 0x00, 0x00, 123f0a35040SMichal Swiatkowski 0x00, 0x00, 0x00, 0x00, 12434a89775SMartyna Szapar-Mudlaw 12534a89775SMartyna Szapar-Mudlaw 0x08, 0x00, /* ICE_ETYPE_IL 54 */ 126f0a35040SMichal Swiatkowski 127f0a35040SMichal Swiatkowski 0x45, 0x00, 0x00, 0x14, /* ICE_IPV4_IL 56 */ 128f0a35040SMichal Swiatkowski 0x00, 0x00, 0x00, 0x00, 129f0a35040SMichal Swiatkowski 0x00, 0x06, 0x00, 0x00, 130f0a35040SMichal Swiatkowski 0x00, 0x00, 0x00, 0x00, 131f0a35040SMichal Swiatkowski 0x00, 0x00, 0x00, 0x00, 132f0a35040SMichal Swiatkowski 133f0a35040SMichal Swiatkowski 0x00, 0x00, 0x00, 0x00, /* ICE_TCP_IL 76 */ 134f0a35040SMichal Swiatkowski 0x00, 0x00, 0x00, 0x00, 135f0a35040SMichal Swiatkowski 0x00, 0x00, 0x00, 0x00, 136f0a35040SMichal Swiatkowski 0x50, 0x02, 0x20, 0x00, 137f0a35040SMichal Swiatkowski 0x00, 0x00, 0x00, 0x00 138f0a35040SMichal Swiatkowski }; 139f0a35040SMichal Swiatkowski 14007a28842SAlexander Lobakin ICE_DECLARE_PKT_OFFSETS(gre_udp) = { 141f0a35040SMichal Swiatkowski { ICE_MAC_OFOS, 0 }, 142f0a35040SMichal Swiatkowski { ICE_ETYPE_OL, 12 }, 143f0a35040SMichal Swiatkowski { ICE_IPV4_OFOS, 14 }, 144f0a35040SMichal Swiatkowski { ICE_NVGRE, 34 }, 145f0a35040SMichal Swiatkowski { ICE_MAC_IL, 42 }, 14634a89775SMartyna Szapar-Mudlaw { ICE_ETYPE_IL, 54 }, 147f0a35040SMichal Swiatkowski { ICE_IPV4_IL, 56 }, 148f0a35040SMichal Swiatkowski { ICE_UDP_ILOS, 76 }, 149f0a35040SMichal Swiatkowski { ICE_PROTOCOL_LAST, 0 }, 150f0a35040SMichal Swiatkowski }; 151f0a35040SMichal Swiatkowski 15207a28842SAlexander Lobakin ICE_DECLARE_PKT_TEMPLATE(gre_udp) = { 153f0a35040SMichal Swiatkowski 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */ 154f0a35040SMichal Swiatkowski 0x00, 0x00, 0x00, 0x00, 155f0a35040SMichal Swiatkowski 0x00, 0x00, 0x00, 0x00, 156f0a35040SMichal Swiatkowski 157f0a35040SMichal Swiatkowski 0x08, 0x00, /* ICE_ETYPE_OL 12 */ 158f0a35040SMichal Swiatkowski 159f0a35040SMichal Swiatkowski 0x45, 0x00, 0x00, 0x3E, /* ICE_IPV4_OFOS 14 */ 160f0a35040SMichal Swiatkowski 0x00, 0x00, 0x00, 0x00, 161f0a35040SMichal Swiatkowski 0x00, 0x2F, 0x00, 0x00, 162f0a35040SMichal Swiatkowski 0x00, 0x00, 0x00, 0x00, 163f0a35040SMichal Swiatkowski 0x00, 0x00, 0x00, 0x00, 164f0a35040SMichal Swiatkowski 165f0a35040SMichal Swiatkowski 0x80, 0x00, 0x65, 0x58, /* ICE_NVGRE 34 */ 166f0a35040SMichal Swiatkowski 0x00, 0x00, 0x00, 0x00, 167f0a35040SMichal Swiatkowski 168f0a35040SMichal Swiatkowski 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_IL 42 */ 169f0a35040SMichal Swiatkowski 0x00, 0x00, 0x00, 0x00, 170f0a35040SMichal Swiatkowski 0x00, 0x00, 0x00, 0x00, 17134a89775SMartyna Szapar-Mudlaw 17234a89775SMartyna Szapar-Mudlaw 0x08, 0x00, /* ICE_ETYPE_IL 54 */ 173f0a35040SMichal Swiatkowski 174f0a35040SMichal Swiatkowski 0x45, 0x00, 0x00, 0x14, /* ICE_IPV4_IL 56 */ 175f0a35040SMichal Swiatkowski 0x00, 0x00, 0x00, 0x00, 176f0a35040SMichal Swiatkowski 0x00, 0x11, 0x00, 0x00, 177f0a35040SMichal Swiatkowski 0x00, 0x00, 0x00, 0x00, 178f0a35040SMichal Swiatkowski 0x00, 0x00, 0x00, 0x00, 179f0a35040SMichal Swiatkowski 180f0a35040SMichal Swiatkowski 0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 76 */ 181f0a35040SMichal Swiatkowski 0x00, 0x08, 0x00, 0x00, 182f0a35040SMichal Swiatkowski }; 183f0a35040SMichal Swiatkowski 18407a28842SAlexander Lobakin ICE_DECLARE_PKT_OFFSETS(udp_tun_tcp) = { 1858b032a55SMichal Swiatkowski { ICE_MAC_OFOS, 0 }, 1868b032a55SMichal Swiatkowski { ICE_ETYPE_OL, 12 }, 1878b032a55SMichal Swiatkowski { ICE_IPV4_OFOS, 14 }, 1888b032a55SMichal Swiatkowski { ICE_UDP_OF, 34 }, 1898b032a55SMichal Swiatkowski { ICE_VXLAN, 42 }, 1908b032a55SMichal Swiatkowski { ICE_GENEVE, 42 }, 1918b032a55SMichal Swiatkowski { ICE_VXLAN_GPE, 42 }, 1928b032a55SMichal Swiatkowski { ICE_MAC_IL, 50 }, 19334a89775SMartyna Szapar-Mudlaw { ICE_ETYPE_IL, 62 }, 1948b032a55SMichal Swiatkowski { ICE_IPV4_IL, 64 }, 1958b032a55SMichal Swiatkowski { ICE_TCP_IL, 84 }, 1968b032a55SMichal Swiatkowski { ICE_PROTOCOL_LAST, 0 }, 1978b032a55SMichal Swiatkowski }; 1988b032a55SMichal Swiatkowski 19907a28842SAlexander Lobakin ICE_DECLARE_PKT_TEMPLATE(udp_tun_tcp) = { 2008b032a55SMichal Swiatkowski 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */ 2018b032a55SMichal Swiatkowski 0x00, 0x00, 0x00, 0x00, 2028b032a55SMichal Swiatkowski 0x00, 0x00, 0x00, 0x00, 2038b032a55SMichal Swiatkowski 2048b032a55SMichal Swiatkowski 0x08, 0x00, /* ICE_ETYPE_OL 12 */ 2058b032a55SMichal Swiatkowski 2068b032a55SMichal Swiatkowski 0x45, 0x00, 0x00, 0x5a, /* ICE_IPV4_OFOS 14 */ 2078b032a55SMichal Swiatkowski 0x00, 0x01, 0x00, 0x00, 2088b032a55SMichal Swiatkowski 0x40, 0x11, 0x00, 0x00, 2098b032a55SMichal Swiatkowski 0x00, 0x00, 0x00, 0x00, 2108b032a55SMichal Swiatkowski 0x00, 0x00, 0x00, 0x00, 2118b032a55SMichal Swiatkowski 2128b032a55SMichal Swiatkowski 0x00, 0x00, 0x12, 0xb5, /* ICE_UDP_OF 34 */ 2138b032a55SMichal Swiatkowski 0x00, 0x46, 0x00, 0x00, 2148b032a55SMichal Swiatkowski 2158b032a55SMichal Swiatkowski 0x00, 0x00, 0x65, 0x58, /* ICE_VXLAN 42 */ 2168b032a55SMichal Swiatkowski 0x00, 0x00, 0x00, 0x00, 2178b032a55SMichal Swiatkowski 2188b032a55SMichal Swiatkowski 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_IL 50 */ 2198b032a55SMichal Swiatkowski 0x00, 0x00, 0x00, 0x00, 2208b032a55SMichal Swiatkowski 0x00, 0x00, 0x00, 0x00, 22134a89775SMartyna Szapar-Mudlaw 22234a89775SMartyna Szapar-Mudlaw 0x08, 0x00, /* ICE_ETYPE_IL 62 */ 2238b032a55SMichal Swiatkowski 2248b032a55SMichal Swiatkowski 0x45, 0x00, 0x00, 0x28, /* ICE_IPV4_IL 64 */ 2258b032a55SMichal Swiatkowski 0x00, 0x01, 0x00, 0x00, 2268b032a55SMichal Swiatkowski 0x40, 0x06, 0x00, 0x00, 2278b032a55SMichal Swiatkowski 0x00, 0x00, 0x00, 0x00, 2288b032a55SMichal Swiatkowski 0x00, 0x00, 0x00, 0x00, 2298b032a55SMichal Swiatkowski 2308b032a55SMichal Swiatkowski 0x00, 0x00, 0x00, 0x00, /* ICE_TCP_IL 84 */ 2318b032a55SMichal Swiatkowski 0x00, 0x00, 0x00, 0x00, 2328b032a55SMichal Swiatkowski 0x00, 0x00, 0x00, 0x00, 2338b032a55SMichal Swiatkowski 0x50, 0x02, 0x20, 0x00, 2348b032a55SMichal Swiatkowski 0x00, 0x00, 0x00, 0x00 2358b032a55SMichal Swiatkowski }; 2368b032a55SMichal Swiatkowski 23707a28842SAlexander Lobakin ICE_DECLARE_PKT_OFFSETS(udp_tun_udp) = { 2388b032a55SMichal Swiatkowski { ICE_MAC_OFOS, 0 }, 2398b032a55SMichal Swiatkowski { ICE_ETYPE_OL, 12 }, 2408b032a55SMichal Swiatkowski { ICE_IPV4_OFOS, 14 }, 2418b032a55SMichal Swiatkowski { ICE_UDP_OF, 34 }, 2428b032a55SMichal Swiatkowski { ICE_VXLAN, 42 }, 2438b032a55SMichal Swiatkowski { ICE_GENEVE, 42 }, 2448b032a55SMichal Swiatkowski { ICE_VXLAN_GPE, 42 }, 2458b032a55SMichal Swiatkowski { ICE_MAC_IL, 50 }, 24634a89775SMartyna Szapar-Mudlaw { ICE_ETYPE_IL, 62 }, 2478b032a55SMichal Swiatkowski { ICE_IPV4_IL, 64 }, 2488b032a55SMichal Swiatkowski { ICE_UDP_ILOS, 84 }, 2498b032a55SMichal Swiatkowski { ICE_PROTOCOL_LAST, 0 }, 2508b032a55SMichal Swiatkowski }; 2518b032a55SMichal Swiatkowski 25207a28842SAlexander Lobakin ICE_DECLARE_PKT_TEMPLATE(udp_tun_udp) = { 2538b032a55SMichal Swiatkowski 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */ 2548b032a55SMichal Swiatkowski 0x00, 0x00, 0x00, 0x00, 2558b032a55SMichal Swiatkowski 0x00, 0x00, 0x00, 0x00, 2568b032a55SMichal Swiatkowski 2578b032a55SMichal Swiatkowski 0x08, 0x00, /* ICE_ETYPE_OL 12 */ 2588b032a55SMichal Swiatkowski 2598b032a55SMichal Swiatkowski 0x45, 0x00, 0x00, 0x4e, /* ICE_IPV4_OFOS 14 */ 2608b032a55SMichal Swiatkowski 0x00, 0x01, 0x00, 0x00, 2618b032a55SMichal Swiatkowski 0x00, 0x11, 0x00, 0x00, 2628b032a55SMichal Swiatkowski 0x00, 0x00, 0x00, 0x00, 2638b032a55SMichal Swiatkowski 0x00, 0x00, 0x00, 0x00, 2648b032a55SMichal Swiatkowski 2658b032a55SMichal Swiatkowski 0x00, 0x00, 0x12, 0xb5, /* ICE_UDP_OF 34 */ 2668b032a55SMichal Swiatkowski 0x00, 0x3a, 0x00, 0x00, 2678b032a55SMichal Swiatkowski 2688b032a55SMichal Swiatkowski 0x00, 0x00, 0x65, 0x58, /* ICE_VXLAN 42 */ 2698b032a55SMichal Swiatkowski 0x00, 0x00, 0x00, 0x00, 2708b032a55SMichal Swiatkowski 2718b032a55SMichal Swiatkowski 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_IL 50 */ 2728b032a55SMichal Swiatkowski 0x00, 0x00, 0x00, 0x00, 2738b032a55SMichal Swiatkowski 0x00, 0x00, 0x00, 0x00, 27434a89775SMartyna Szapar-Mudlaw 27534a89775SMartyna Szapar-Mudlaw 0x08, 0x00, /* ICE_ETYPE_IL 62 */ 2768b032a55SMichal Swiatkowski 2778b032a55SMichal Swiatkowski 0x45, 0x00, 0x00, 0x1c, /* ICE_IPV4_IL 64 */ 2788b032a55SMichal Swiatkowski 0x00, 0x01, 0x00, 0x00, 2798b032a55SMichal Swiatkowski 0x00, 0x11, 0x00, 0x00, 2808b032a55SMichal Swiatkowski 0x00, 0x00, 0x00, 0x00, 2818b032a55SMichal Swiatkowski 0x00, 0x00, 0x00, 0x00, 2828b032a55SMichal Swiatkowski 2838b032a55SMichal Swiatkowski 0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 84 */ 2848b032a55SMichal Swiatkowski 0x00, 0x08, 0x00, 0x00, 2858b032a55SMichal Swiatkowski }; 2868b032a55SMichal Swiatkowski 28707a28842SAlexander Lobakin ICE_DECLARE_PKT_OFFSETS(gre_ipv6_tcp) = { 28834a89775SMartyna Szapar-Mudlaw { ICE_MAC_OFOS, 0 }, 28934a89775SMartyna Szapar-Mudlaw { ICE_ETYPE_OL, 12 }, 29034a89775SMartyna Szapar-Mudlaw { ICE_IPV4_OFOS, 14 }, 29134a89775SMartyna Szapar-Mudlaw { ICE_NVGRE, 34 }, 29234a89775SMartyna Szapar-Mudlaw { ICE_MAC_IL, 42 }, 29334a89775SMartyna Szapar-Mudlaw { ICE_ETYPE_IL, 54 }, 29434a89775SMartyna Szapar-Mudlaw { ICE_IPV6_IL, 56 }, 29534a89775SMartyna Szapar-Mudlaw { ICE_TCP_IL, 96 }, 29634a89775SMartyna Szapar-Mudlaw { ICE_PROTOCOL_LAST, 0 }, 29734a89775SMartyna Szapar-Mudlaw }; 29834a89775SMartyna Szapar-Mudlaw 29907a28842SAlexander Lobakin ICE_DECLARE_PKT_TEMPLATE(gre_ipv6_tcp) = { 30034a89775SMartyna Szapar-Mudlaw 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */ 30134a89775SMartyna Szapar-Mudlaw 0x00, 0x00, 0x00, 0x00, 30234a89775SMartyna Szapar-Mudlaw 0x00, 0x00, 0x00, 0x00, 30334a89775SMartyna Szapar-Mudlaw 30434a89775SMartyna Szapar-Mudlaw 0x08, 0x00, /* ICE_ETYPE_OL 12 */ 30534a89775SMartyna Szapar-Mudlaw 30634a89775SMartyna Szapar-Mudlaw 0x45, 0x00, 0x00, 0x66, /* ICE_IPV4_OFOS 14 */ 30734a89775SMartyna Szapar-Mudlaw 0x00, 0x00, 0x00, 0x00, 30834a89775SMartyna Szapar-Mudlaw 0x00, 0x2F, 0x00, 0x00, 30934a89775SMartyna Szapar-Mudlaw 0x00, 0x00, 0x00, 0x00, 31034a89775SMartyna Szapar-Mudlaw 0x00, 0x00, 0x00, 0x00, 31134a89775SMartyna Szapar-Mudlaw 31234a89775SMartyna Szapar-Mudlaw 0x80, 0x00, 0x65, 0x58, /* ICE_NVGRE 34 */ 31334a89775SMartyna Szapar-Mudlaw 0x00, 0x00, 0x00, 0x00, 31434a89775SMartyna Szapar-Mudlaw 31534a89775SMartyna Szapar-Mudlaw 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_IL 42 */ 31634a89775SMartyna Szapar-Mudlaw 0x00, 0x00, 0x00, 0x00, 31734a89775SMartyna Szapar-Mudlaw 0x00, 0x00, 0x00, 0x00, 31834a89775SMartyna Szapar-Mudlaw 31934a89775SMartyna Szapar-Mudlaw 0x86, 0xdd, /* ICE_ETYPE_IL 54 */ 32034a89775SMartyna Szapar-Mudlaw 32134a89775SMartyna Szapar-Mudlaw 0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_IL 56 */ 32234a89775SMartyna Szapar-Mudlaw 0x00, 0x08, 0x06, 0x40, 32334a89775SMartyna Szapar-Mudlaw 0x00, 0x00, 0x00, 0x00, 32434a89775SMartyna Szapar-Mudlaw 0x00, 0x00, 0x00, 0x00, 32534a89775SMartyna Szapar-Mudlaw 0x00, 0x00, 0x00, 0x00, 32634a89775SMartyna Szapar-Mudlaw 0x00, 0x00, 0x00, 0x00, 32734a89775SMartyna Szapar-Mudlaw 0x00, 0x00, 0x00, 0x00, 32834a89775SMartyna Szapar-Mudlaw 0x00, 0x00, 0x00, 0x00, 32934a89775SMartyna Szapar-Mudlaw 0x00, 0x00, 0x00, 0x00, 33034a89775SMartyna Szapar-Mudlaw 0x00, 0x00, 0x00, 0x00, 33134a89775SMartyna Szapar-Mudlaw 33234a89775SMartyna Szapar-Mudlaw 0x00, 0x00, 0x00, 0x00, /* ICE_TCP_IL 96 */ 33334a89775SMartyna Szapar-Mudlaw 0x00, 0x00, 0x00, 0x00, 33434a89775SMartyna Szapar-Mudlaw 0x00, 0x00, 0x00, 0x00, 33534a89775SMartyna Szapar-Mudlaw 0x50, 0x02, 0x20, 0x00, 33634a89775SMartyna Szapar-Mudlaw 0x00, 0x00, 0x00, 0x00 33734a89775SMartyna Szapar-Mudlaw }; 33834a89775SMartyna Szapar-Mudlaw 33907a28842SAlexander Lobakin ICE_DECLARE_PKT_OFFSETS(gre_ipv6_udp) = { 34034a89775SMartyna Szapar-Mudlaw { ICE_MAC_OFOS, 0 }, 34134a89775SMartyna Szapar-Mudlaw { ICE_ETYPE_OL, 12 }, 34234a89775SMartyna Szapar-Mudlaw { ICE_IPV4_OFOS, 14 }, 34334a89775SMartyna Szapar-Mudlaw { ICE_NVGRE, 34 }, 34434a89775SMartyna Szapar-Mudlaw { ICE_MAC_IL, 42 }, 34534a89775SMartyna Szapar-Mudlaw { ICE_ETYPE_IL, 54 }, 34634a89775SMartyna Szapar-Mudlaw { ICE_IPV6_IL, 56 }, 34734a89775SMartyna Szapar-Mudlaw { ICE_UDP_ILOS, 96 }, 34834a89775SMartyna Szapar-Mudlaw { ICE_PROTOCOL_LAST, 0 }, 34934a89775SMartyna Szapar-Mudlaw }; 35034a89775SMartyna Szapar-Mudlaw 35107a28842SAlexander Lobakin ICE_DECLARE_PKT_TEMPLATE(gre_ipv6_udp) = { 35234a89775SMartyna Szapar-Mudlaw 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */ 35334a89775SMartyna Szapar-Mudlaw 0x00, 0x00, 0x00, 0x00, 35434a89775SMartyna Szapar-Mudlaw 0x00, 0x00, 0x00, 0x00, 35534a89775SMartyna Szapar-Mudlaw 35634a89775SMartyna Szapar-Mudlaw 0x08, 0x00, /* ICE_ETYPE_OL 12 */ 35734a89775SMartyna Szapar-Mudlaw 35834a89775SMartyna Szapar-Mudlaw 0x45, 0x00, 0x00, 0x5a, /* ICE_IPV4_OFOS 14 */ 35934a89775SMartyna Szapar-Mudlaw 0x00, 0x00, 0x00, 0x00, 36034a89775SMartyna Szapar-Mudlaw 0x00, 0x2F, 0x00, 0x00, 36134a89775SMartyna Szapar-Mudlaw 0x00, 0x00, 0x00, 0x00, 36234a89775SMartyna Szapar-Mudlaw 0x00, 0x00, 0x00, 0x00, 36334a89775SMartyna Szapar-Mudlaw 36434a89775SMartyna Szapar-Mudlaw 0x80, 0x00, 0x65, 0x58, /* ICE_NVGRE 34 */ 36534a89775SMartyna Szapar-Mudlaw 0x00, 0x00, 0x00, 0x00, 36634a89775SMartyna Szapar-Mudlaw 36734a89775SMartyna Szapar-Mudlaw 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_IL 42 */ 36834a89775SMartyna Szapar-Mudlaw 0x00, 0x00, 0x00, 0x00, 36934a89775SMartyna Szapar-Mudlaw 0x00, 0x00, 0x00, 0x00, 37034a89775SMartyna Szapar-Mudlaw 37134a89775SMartyna Szapar-Mudlaw 0x86, 0xdd, /* ICE_ETYPE_IL 54 */ 37234a89775SMartyna Szapar-Mudlaw 37334a89775SMartyna Szapar-Mudlaw 0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_IL 56 */ 37434a89775SMartyna Szapar-Mudlaw 0x00, 0x08, 0x11, 0x40, 37534a89775SMartyna Szapar-Mudlaw 0x00, 0x00, 0x00, 0x00, 37634a89775SMartyna Szapar-Mudlaw 0x00, 0x00, 0x00, 0x00, 37734a89775SMartyna Szapar-Mudlaw 0x00, 0x00, 0x00, 0x00, 37834a89775SMartyna Szapar-Mudlaw 0x00, 0x00, 0x00, 0x00, 37934a89775SMartyna Szapar-Mudlaw 0x00, 0x00, 0x00, 0x00, 38034a89775SMartyna Szapar-Mudlaw 0x00, 0x00, 0x00, 0x00, 38134a89775SMartyna Szapar-Mudlaw 0x00, 0x00, 0x00, 0x00, 38234a89775SMartyna Szapar-Mudlaw 0x00, 0x00, 0x00, 0x00, 38334a89775SMartyna Szapar-Mudlaw 38434a89775SMartyna Szapar-Mudlaw 0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 96 */ 38534a89775SMartyna Szapar-Mudlaw 0x00, 0x08, 0x00, 0x00, 38634a89775SMartyna Szapar-Mudlaw }; 38734a89775SMartyna Szapar-Mudlaw 38807a28842SAlexander Lobakin ICE_DECLARE_PKT_OFFSETS(udp_tun_ipv6_tcp) = { 38934a89775SMartyna Szapar-Mudlaw { ICE_MAC_OFOS, 0 }, 39034a89775SMartyna Szapar-Mudlaw { ICE_ETYPE_OL, 12 }, 39134a89775SMartyna Szapar-Mudlaw { ICE_IPV4_OFOS, 14 }, 39234a89775SMartyna Szapar-Mudlaw { ICE_UDP_OF, 34 }, 39334a89775SMartyna Szapar-Mudlaw { ICE_VXLAN, 42 }, 39434a89775SMartyna Szapar-Mudlaw { ICE_GENEVE, 42 }, 39534a89775SMartyna Szapar-Mudlaw { ICE_VXLAN_GPE, 42 }, 39634a89775SMartyna Szapar-Mudlaw { ICE_MAC_IL, 50 }, 39734a89775SMartyna Szapar-Mudlaw { ICE_ETYPE_IL, 62 }, 39834a89775SMartyna Szapar-Mudlaw { ICE_IPV6_IL, 64 }, 39934a89775SMartyna Szapar-Mudlaw { ICE_TCP_IL, 104 }, 40034a89775SMartyna Szapar-Mudlaw { ICE_PROTOCOL_LAST, 0 }, 40134a89775SMartyna Szapar-Mudlaw }; 40234a89775SMartyna Szapar-Mudlaw 40307a28842SAlexander Lobakin ICE_DECLARE_PKT_TEMPLATE(udp_tun_ipv6_tcp) = { 40434a89775SMartyna Szapar-Mudlaw 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */ 40534a89775SMartyna Szapar-Mudlaw 0x00, 0x00, 0x00, 0x00, 40634a89775SMartyna Szapar-Mudlaw 0x00, 0x00, 0x00, 0x00, 40734a89775SMartyna Szapar-Mudlaw 40834a89775SMartyna Szapar-Mudlaw 0x08, 0x00, /* ICE_ETYPE_OL 12 */ 40934a89775SMartyna Szapar-Mudlaw 41034a89775SMartyna Szapar-Mudlaw 0x45, 0x00, 0x00, 0x6e, /* ICE_IPV4_OFOS 14 */ 41134a89775SMartyna Szapar-Mudlaw 0x00, 0x01, 0x00, 0x00, 41234a89775SMartyna Szapar-Mudlaw 0x40, 0x11, 0x00, 0x00, 41334a89775SMartyna Szapar-Mudlaw 0x00, 0x00, 0x00, 0x00, 41434a89775SMartyna Szapar-Mudlaw 0x00, 0x00, 0x00, 0x00, 41534a89775SMartyna Szapar-Mudlaw 41634a89775SMartyna Szapar-Mudlaw 0x00, 0x00, 0x12, 0xb5, /* ICE_UDP_OF 34 */ 41734a89775SMartyna Szapar-Mudlaw 0x00, 0x5a, 0x00, 0x00, 41834a89775SMartyna Szapar-Mudlaw 41934a89775SMartyna Szapar-Mudlaw 0x00, 0x00, 0x65, 0x58, /* ICE_VXLAN 42 */ 42034a89775SMartyna Szapar-Mudlaw 0x00, 0x00, 0x00, 0x00, 42134a89775SMartyna Szapar-Mudlaw 42234a89775SMartyna Szapar-Mudlaw 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_IL 50 */ 42334a89775SMartyna Szapar-Mudlaw 0x00, 0x00, 0x00, 0x00, 42434a89775SMartyna Szapar-Mudlaw 0x00, 0x00, 0x00, 0x00, 42534a89775SMartyna Szapar-Mudlaw 42634a89775SMartyna Szapar-Mudlaw 0x86, 0xdd, /* ICE_ETYPE_IL 62 */ 42734a89775SMartyna Szapar-Mudlaw 42834a89775SMartyna Szapar-Mudlaw 0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_IL 64 */ 42934a89775SMartyna Szapar-Mudlaw 0x00, 0x08, 0x06, 0x40, 43034a89775SMartyna Szapar-Mudlaw 0x00, 0x00, 0x00, 0x00, 43134a89775SMartyna Szapar-Mudlaw 0x00, 0x00, 0x00, 0x00, 43234a89775SMartyna Szapar-Mudlaw 0x00, 0x00, 0x00, 0x00, 43334a89775SMartyna Szapar-Mudlaw 0x00, 0x00, 0x00, 0x00, 43434a89775SMartyna Szapar-Mudlaw 0x00, 0x00, 0x00, 0x00, 43534a89775SMartyna Szapar-Mudlaw 0x00, 0x00, 0x00, 0x00, 43634a89775SMartyna Szapar-Mudlaw 0x00, 0x00, 0x00, 0x00, 43734a89775SMartyna Szapar-Mudlaw 0x00, 0x00, 0x00, 0x00, 43834a89775SMartyna Szapar-Mudlaw 43934a89775SMartyna Szapar-Mudlaw 0x00, 0x00, 0x00, 0x00, /* ICE_TCP_IL 104 */ 44034a89775SMartyna Szapar-Mudlaw 0x00, 0x00, 0x00, 0x00, 44134a89775SMartyna Szapar-Mudlaw 0x00, 0x00, 0x00, 0x00, 44234a89775SMartyna Szapar-Mudlaw 0x50, 0x02, 0x20, 0x00, 44334a89775SMartyna Szapar-Mudlaw 0x00, 0x00, 0x00, 0x00 44434a89775SMartyna Szapar-Mudlaw }; 44534a89775SMartyna Szapar-Mudlaw 44607a28842SAlexander Lobakin ICE_DECLARE_PKT_OFFSETS(udp_tun_ipv6_udp) = { 44734a89775SMartyna Szapar-Mudlaw { ICE_MAC_OFOS, 0 }, 44834a89775SMartyna Szapar-Mudlaw { ICE_ETYPE_OL, 12 }, 44934a89775SMartyna Szapar-Mudlaw { ICE_IPV4_OFOS, 14 }, 45034a89775SMartyna Szapar-Mudlaw { ICE_UDP_OF, 34 }, 45134a89775SMartyna Szapar-Mudlaw { ICE_VXLAN, 42 }, 45234a89775SMartyna Szapar-Mudlaw { ICE_GENEVE, 42 }, 45334a89775SMartyna Szapar-Mudlaw { ICE_VXLAN_GPE, 42 }, 45434a89775SMartyna Szapar-Mudlaw { ICE_MAC_IL, 50 }, 45534a89775SMartyna Szapar-Mudlaw { ICE_ETYPE_IL, 62 }, 45634a89775SMartyna Szapar-Mudlaw { ICE_IPV6_IL, 64 }, 45734a89775SMartyna Szapar-Mudlaw { ICE_UDP_ILOS, 104 }, 45834a89775SMartyna Szapar-Mudlaw { ICE_PROTOCOL_LAST, 0 }, 45934a89775SMartyna Szapar-Mudlaw }; 46034a89775SMartyna Szapar-Mudlaw 46107a28842SAlexander Lobakin ICE_DECLARE_PKT_TEMPLATE(udp_tun_ipv6_udp) = { 46234a89775SMartyna Szapar-Mudlaw 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */ 46334a89775SMartyna Szapar-Mudlaw 0x00, 0x00, 0x00, 0x00, 46434a89775SMartyna Szapar-Mudlaw 0x00, 0x00, 0x00, 0x00, 46534a89775SMartyna Szapar-Mudlaw 46634a89775SMartyna Szapar-Mudlaw 0x08, 0x00, /* ICE_ETYPE_OL 12 */ 46734a89775SMartyna Szapar-Mudlaw 46834a89775SMartyna Szapar-Mudlaw 0x45, 0x00, 0x00, 0x62, /* ICE_IPV4_OFOS 14 */ 46934a89775SMartyna Szapar-Mudlaw 0x00, 0x01, 0x00, 0x00, 47034a89775SMartyna Szapar-Mudlaw 0x00, 0x11, 0x00, 0x00, 47134a89775SMartyna Szapar-Mudlaw 0x00, 0x00, 0x00, 0x00, 47234a89775SMartyna Szapar-Mudlaw 0x00, 0x00, 0x00, 0x00, 47334a89775SMartyna Szapar-Mudlaw 47434a89775SMartyna Szapar-Mudlaw 0x00, 0x00, 0x12, 0xb5, /* ICE_UDP_OF 34 */ 47534a89775SMartyna Szapar-Mudlaw 0x00, 0x4e, 0x00, 0x00, 47634a89775SMartyna Szapar-Mudlaw 47734a89775SMartyna Szapar-Mudlaw 0x00, 0x00, 0x65, 0x58, /* ICE_VXLAN 42 */ 47834a89775SMartyna Szapar-Mudlaw 0x00, 0x00, 0x00, 0x00, 47934a89775SMartyna Szapar-Mudlaw 48034a89775SMartyna Szapar-Mudlaw 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_IL 50 */ 48134a89775SMartyna Szapar-Mudlaw 0x00, 0x00, 0x00, 0x00, 48234a89775SMartyna Szapar-Mudlaw 0x00, 0x00, 0x00, 0x00, 48334a89775SMartyna Szapar-Mudlaw 48434a89775SMartyna Szapar-Mudlaw 0x86, 0xdd, /* ICE_ETYPE_IL 62 */ 48534a89775SMartyna Szapar-Mudlaw 48634a89775SMartyna Szapar-Mudlaw 0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_IL 64 */ 48734a89775SMartyna Szapar-Mudlaw 0x00, 0x08, 0x11, 0x40, 48834a89775SMartyna Szapar-Mudlaw 0x00, 0x00, 0x00, 0x00, 48934a89775SMartyna Szapar-Mudlaw 0x00, 0x00, 0x00, 0x00, 49034a89775SMartyna Szapar-Mudlaw 0x00, 0x00, 0x00, 0x00, 49134a89775SMartyna Szapar-Mudlaw 0x00, 0x00, 0x00, 0x00, 49234a89775SMartyna Szapar-Mudlaw 0x00, 0x00, 0x00, 0x00, 49334a89775SMartyna Szapar-Mudlaw 0x00, 0x00, 0x00, 0x00, 49434a89775SMartyna Szapar-Mudlaw 0x00, 0x00, 0x00, 0x00, 49534a89775SMartyna Szapar-Mudlaw 0x00, 0x00, 0x00, 0x00, 49634a89775SMartyna Szapar-Mudlaw 49734a89775SMartyna Szapar-Mudlaw 0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 104 */ 49834a89775SMartyna Szapar-Mudlaw 0x00, 0x08, 0x00, 0x00, 49934a89775SMartyna Szapar-Mudlaw }; 50034a89775SMartyna Szapar-Mudlaw 5010f94570dSGrishma Kotecha /* offset info for MAC + IPv4 + UDP dummy packet */ 50207a28842SAlexander Lobakin ICE_DECLARE_PKT_OFFSETS(udp) = { 5030f94570dSGrishma Kotecha { ICE_MAC_OFOS, 0 }, 5040f94570dSGrishma Kotecha { ICE_ETYPE_OL, 12 }, 5050f94570dSGrishma Kotecha { ICE_IPV4_OFOS, 14 }, 5060f94570dSGrishma Kotecha { ICE_UDP_ILOS, 34 }, 5070f94570dSGrishma Kotecha { ICE_PROTOCOL_LAST, 0 }, 5080f94570dSGrishma Kotecha }; 5090f94570dSGrishma Kotecha 5100f94570dSGrishma Kotecha /* Dummy packet for MAC + IPv4 + UDP */ 51107a28842SAlexander Lobakin ICE_DECLARE_PKT_TEMPLATE(udp) = { 5120f94570dSGrishma Kotecha 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */ 5130f94570dSGrishma Kotecha 0x00, 0x00, 0x00, 0x00, 5140f94570dSGrishma Kotecha 0x00, 0x00, 0x00, 0x00, 5150f94570dSGrishma Kotecha 5160f94570dSGrishma Kotecha 0x08, 0x00, /* ICE_ETYPE_OL 12 */ 5170f94570dSGrishma Kotecha 5180f94570dSGrishma Kotecha 0x45, 0x00, 0x00, 0x1c, /* ICE_IPV4_OFOS 14 */ 5190f94570dSGrishma Kotecha 0x00, 0x01, 0x00, 0x00, 5200f94570dSGrishma Kotecha 0x00, 0x11, 0x00, 0x00, 5210f94570dSGrishma Kotecha 0x00, 0x00, 0x00, 0x00, 5220f94570dSGrishma Kotecha 0x00, 0x00, 0x00, 0x00, 5230f94570dSGrishma Kotecha 5240f94570dSGrishma Kotecha 0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 34 */ 5250f94570dSGrishma Kotecha 0x00, 0x08, 0x00, 0x00, 5260f94570dSGrishma Kotecha 5270f94570dSGrishma Kotecha 0x00, 0x00, /* 2 bytes for 4 byte alignment */ 5280f94570dSGrishma Kotecha }; 5290f94570dSGrishma Kotecha 5300f94570dSGrishma Kotecha /* offset info for MAC + IPv4 + TCP dummy packet */ 53107a28842SAlexander Lobakin ICE_DECLARE_PKT_OFFSETS(tcp) = { 5320f94570dSGrishma Kotecha { ICE_MAC_OFOS, 0 }, 5330f94570dSGrishma Kotecha { ICE_ETYPE_OL, 12 }, 5340f94570dSGrishma Kotecha { ICE_IPV4_OFOS, 14 }, 5350f94570dSGrishma Kotecha { ICE_TCP_IL, 34 }, 5360f94570dSGrishma Kotecha { ICE_PROTOCOL_LAST, 0 }, 5370f94570dSGrishma Kotecha }; 5380f94570dSGrishma Kotecha 5390f94570dSGrishma Kotecha /* Dummy packet for MAC + IPv4 + TCP */ 54007a28842SAlexander Lobakin ICE_DECLARE_PKT_TEMPLATE(tcp) = { 5410f94570dSGrishma Kotecha 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */ 5420f94570dSGrishma Kotecha 0x00, 0x00, 0x00, 0x00, 5430f94570dSGrishma Kotecha 0x00, 0x00, 0x00, 0x00, 5440f94570dSGrishma Kotecha 5450f94570dSGrishma Kotecha 0x08, 0x00, /* ICE_ETYPE_OL 12 */ 5460f94570dSGrishma Kotecha 5470f94570dSGrishma Kotecha 0x45, 0x00, 0x00, 0x28, /* ICE_IPV4_OFOS 14 */ 5480f94570dSGrishma Kotecha 0x00, 0x01, 0x00, 0x00, 5490f94570dSGrishma Kotecha 0x00, 0x06, 0x00, 0x00, 5500f94570dSGrishma Kotecha 0x00, 0x00, 0x00, 0x00, 5510f94570dSGrishma Kotecha 0x00, 0x00, 0x00, 0x00, 5520f94570dSGrishma Kotecha 5530f94570dSGrishma Kotecha 0x00, 0x00, 0x00, 0x00, /* ICE_TCP_IL 34 */ 5540f94570dSGrishma Kotecha 0x00, 0x00, 0x00, 0x00, 5550f94570dSGrishma Kotecha 0x00, 0x00, 0x00, 0x00, 5560f94570dSGrishma Kotecha 0x50, 0x00, 0x00, 0x00, 5570f94570dSGrishma Kotecha 0x00, 0x00, 0x00, 0x00, 5580f94570dSGrishma Kotecha 5590f94570dSGrishma Kotecha 0x00, 0x00, /* 2 bytes for 4 byte alignment */ 5600f94570dSGrishma Kotecha }; 5610f94570dSGrishma Kotecha 56207a28842SAlexander Lobakin ICE_DECLARE_PKT_OFFSETS(tcp_ipv6) = { 5630f94570dSGrishma Kotecha { ICE_MAC_OFOS, 0 }, 5640f94570dSGrishma Kotecha { ICE_ETYPE_OL, 12 }, 5650f94570dSGrishma Kotecha { ICE_IPV6_OFOS, 14 }, 5660f94570dSGrishma Kotecha { ICE_TCP_IL, 54 }, 5670f94570dSGrishma Kotecha { ICE_PROTOCOL_LAST, 0 }, 5680f94570dSGrishma Kotecha }; 5690f94570dSGrishma Kotecha 57007a28842SAlexander Lobakin ICE_DECLARE_PKT_TEMPLATE(tcp_ipv6) = { 5710f94570dSGrishma Kotecha 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */ 5720f94570dSGrishma Kotecha 0x00, 0x00, 0x00, 0x00, 5730f94570dSGrishma Kotecha 0x00, 0x00, 0x00, 0x00, 5740f94570dSGrishma Kotecha 5750f94570dSGrishma Kotecha 0x86, 0xDD, /* ICE_ETYPE_OL 12 */ 5760f94570dSGrishma Kotecha 5770f94570dSGrishma Kotecha 0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 40 */ 5780f94570dSGrishma Kotecha 0x00, 0x14, 0x06, 0x00, /* Next header is TCP */ 5790f94570dSGrishma Kotecha 0x00, 0x00, 0x00, 0x00, 5800f94570dSGrishma Kotecha 0x00, 0x00, 0x00, 0x00, 5810f94570dSGrishma Kotecha 0x00, 0x00, 0x00, 0x00, 5820f94570dSGrishma Kotecha 0x00, 0x00, 0x00, 0x00, 5830f94570dSGrishma Kotecha 0x00, 0x00, 0x00, 0x00, 5840f94570dSGrishma Kotecha 0x00, 0x00, 0x00, 0x00, 5850f94570dSGrishma Kotecha 0x00, 0x00, 0x00, 0x00, 5860f94570dSGrishma Kotecha 0x00, 0x00, 0x00, 0x00, 5870f94570dSGrishma Kotecha 5880f94570dSGrishma Kotecha 0x00, 0x00, 0x00, 0x00, /* ICE_TCP_IL 54 */ 5890f94570dSGrishma Kotecha 0x00, 0x00, 0x00, 0x00, 5900f94570dSGrishma Kotecha 0x00, 0x00, 0x00, 0x00, 5910f94570dSGrishma Kotecha 0x50, 0x00, 0x00, 0x00, 5920f94570dSGrishma Kotecha 0x00, 0x00, 0x00, 0x00, 5930f94570dSGrishma Kotecha 5940f94570dSGrishma Kotecha 0x00, 0x00, /* 2 bytes for 4 byte alignment */ 5950f94570dSGrishma Kotecha }; 5960f94570dSGrishma Kotecha 5970f94570dSGrishma Kotecha /* IPv6 + UDP */ 59807a28842SAlexander Lobakin ICE_DECLARE_PKT_OFFSETS(udp_ipv6) = { 5990f94570dSGrishma Kotecha { ICE_MAC_OFOS, 0 }, 6000f94570dSGrishma Kotecha { ICE_ETYPE_OL, 12 }, 6010f94570dSGrishma Kotecha { ICE_IPV6_OFOS, 14 }, 6020f94570dSGrishma Kotecha { ICE_UDP_ILOS, 54 }, 6030f94570dSGrishma Kotecha { ICE_PROTOCOL_LAST, 0 }, 6040f94570dSGrishma Kotecha }; 6050f94570dSGrishma Kotecha 6060f94570dSGrishma Kotecha /* IPv6 + UDP dummy packet */ 60707a28842SAlexander Lobakin ICE_DECLARE_PKT_TEMPLATE(udp_ipv6) = { 6080f94570dSGrishma Kotecha 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */ 6090f94570dSGrishma Kotecha 0x00, 0x00, 0x00, 0x00, 6100f94570dSGrishma Kotecha 0x00, 0x00, 0x00, 0x00, 6110f94570dSGrishma Kotecha 6120f94570dSGrishma Kotecha 0x86, 0xDD, /* ICE_ETYPE_OL 12 */ 6130f94570dSGrishma Kotecha 6140f94570dSGrishma Kotecha 0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 40 */ 6150f94570dSGrishma Kotecha 0x00, 0x10, 0x11, 0x00, /* Next header UDP */ 6160f94570dSGrishma Kotecha 0x00, 0x00, 0x00, 0x00, 6170f94570dSGrishma Kotecha 0x00, 0x00, 0x00, 0x00, 6180f94570dSGrishma Kotecha 0x00, 0x00, 0x00, 0x00, 6190f94570dSGrishma Kotecha 0x00, 0x00, 0x00, 0x00, 6200f94570dSGrishma Kotecha 0x00, 0x00, 0x00, 0x00, 6210f94570dSGrishma Kotecha 0x00, 0x00, 0x00, 0x00, 6220f94570dSGrishma Kotecha 0x00, 0x00, 0x00, 0x00, 6230f94570dSGrishma Kotecha 0x00, 0x00, 0x00, 0x00, 6240f94570dSGrishma Kotecha 6250f94570dSGrishma Kotecha 0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 54 */ 6260f94570dSGrishma Kotecha 0x00, 0x10, 0x00, 0x00, 6270f94570dSGrishma Kotecha 6280f94570dSGrishma Kotecha 0x00, 0x00, 0x00, 0x00, /* needed for ESP packets */ 6290f94570dSGrishma Kotecha 0x00, 0x00, 0x00, 0x00, 6300f94570dSGrishma Kotecha 6310f94570dSGrishma Kotecha 0x00, 0x00, /* 2 bytes for 4 byte alignment */ 6320f94570dSGrishma Kotecha }; 6330f94570dSGrishma Kotecha 6349a225f81SMarcin Szycik /* Outer IPv4 + Outer UDP + GTP + Inner IPv4 + Inner TCP */ 63507a28842SAlexander Lobakin ICE_DECLARE_PKT_OFFSETS(ipv4_gtpu_ipv4_tcp) = { 6369a225f81SMarcin Szycik { ICE_MAC_OFOS, 0 }, 6379a225f81SMarcin Szycik { ICE_IPV4_OFOS, 14 }, 6389a225f81SMarcin Szycik { ICE_UDP_OF, 34 }, 6399a225f81SMarcin Szycik { ICE_GTP, 42 }, 6409a225f81SMarcin Szycik { ICE_IPV4_IL, 62 }, 6419a225f81SMarcin Szycik { ICE_TCP_IL, 82 }, 6429a225f81SMarcin Szycik { ICE_PROTOCOL_LAST, 0 }, 6439a225f81SMarcin Szycik }; 6449a225f81SMarcin Szycik 64507a28842SAlexander Lobakin ICE_DECLARE_PKT_TEMPLATE(ipv4_gtpu_ipv4_tcp) = { 6469a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, /* Ethernet 0 */ 6479a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 6489a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 6499a225f81SMarcin Szycik 0x08, 0x00, 6509a225f81SMarcin Szycik 6519a225f81SMarcin Szycik 0x45, 0x00, 0x00, 0x58, /* IP 14 */ 6529a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 6539a225f81SMarcin Szycik 0x00, 0x11, 0x00, 0x00, 6549a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 6559a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 6569a225f81SMarcin Szycik 6579a225f81SMarcin Szycik 0x00, 0x00, 0x08, 0x68, /* UDP 34 */ 6589a225f81SMarcin Szycik 0x00, 0x44, 0x00, 0x00, 6599a225f81SMarcin Szycik 6609a225f81SMarcin Szycik 0x34, 0xff, 0x00, 0x34, /* ICE_GTP Header 42 */ 6619a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 6629a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x85, 6639a225f81SMarcin Szycik 6649a225f81SMarcin Szycik 0x02, 0x00, 0x00, 0x00, /* GTP_PDUSession_ExtensionHeader 54 */ 6659a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 6669a225f81SMarcin Szycik 6679a225f81SMarcin Szycik 0x45, 0x00, 0x00, 0x28, /* IP 62 */ 6689a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 6699a225f81SMarcin Szycik 0x00, 0x06, 0x00, 0x00, 6709a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 6719a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 6729a225f81SMarcin Szycik 6739a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, /* TCP 82 */ 6749a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 6759a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 6769a225f81SMarcin Szycik 0x50, 0x00, 0x00, 0x00, 6779a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 6789a225f81SMarcin Szycik 6799a225f81SMarcin Szycik 0x00, 0x00, /* 2 bytes for 4 byte alignment */ 6809a225f81SMarcin Szycik }; 6819a225f81SMarcin Szycik 6829a225f81SMarcin Szycik /* Outer IPv4 + Outer UDP + GTP + Inner IPv4 + Inner UDP */ 68307a28842SAlexander Lobakin ICE_DECLARE_PKT_OFFSETS(ipv4_gtpu_ipv4_udp) = { 6849a225f81SMarcin Szycik { ICE_MAC_OFOS, 0 }, 6859a225f81SMarcin Szycik { ICE_IPV4_OFOS, 14 }, 6869a225f81SMarcin Szycik { ICE_UDP_OF, 34 }, 6879a225f81SMarcin Szycik { ICE_GTP, 42 }, 6889a225f81SMarcin Szycik { ICE_IPV4_IL, 62 }, 6899a225f81SMarcin Szycik { ICE_UDP_ILOS, 82 }, 6909a225f81SMarcin Szycik { ICE_PROTOCOL_LAST, 0 }, 6919a225f81SMarcin Szycik }; 6929a225f81SMarcin Szycik 69307a28842SAlexander Lobakin ICE_DECLARE_PKT_TEMPLATE(ipv4_gtpu_ipv4_udp) = { 6949a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, /* Ethernet 0 */ 6959a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 6969a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 6979a225f81SMarcin Szycik 0x08, 0x00, 6989a225f81SMarcin Szycik 6999a225f81SMarcin Szycik 0x45, 0x00, 0x00, 0x4c, /* IP 14 */ 7009a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 7019a225f81SMarcin Szycik 0x00, 0x11, 0x00, 0x00, 7029a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 7039a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 7049a225f81SMarcin Szycik 7059a225f81SMarcin Szycik 0x00, 0x00, 0x08, 0x68, /* UDP 34 */ 7069a225f81SMarcin Szycik 0x00, 0x38, 0x00, 0x00, 7079a225f81SMarcin Szycik 7089a225f81SMarcin Szycik 0x34, 0xff, 0x00, 0x28, /* ICE_GTP Header 42 */ 7099a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 7109a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x85, 7119a225f81SMarcin Szycik 7129a225f81SMarcin Szycik 0x02, 0x00, 0x00, 0x00, /* GTP_PDUSession_ExtensionHeader 54 */ 7139a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 7149a225f81SMarcin Szycik 7159a225f81SMarcin Szycik 0x45, 0x00, 0x00, 0x1c, /* IP 62 */ 7169a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 7179a225f81SMarcin Szycik 0x00, 0x11, 0x00, 0x00, 7189a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 7199a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 7209a225f81SMarcin Szycik 7219a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, /* UDP 82 */ 7229a225f81SMarcin Szycik 0x00, 0x08, 0x00, 0x00, 7239a225f81SMarcin Szycik 7249a225f81SMarcin Szycik 0x00, 0x00, /* 2 bytes for 4 byte alignment */ 7259a225f81SMarcin Szycik }; 7269a225f81SMarcin Szycik 7279a225f81SMarcin Szycik /* Outer IPv6 + Outer UDP + GTP + Inner IPv4 + Inner TCP */ 72807a28842SAlexander Lobakin ICE_DECLARE_PKT_OFFSETS(ipv4_gtpu_ipv6_tcp) = { 7299a225f81SMarcin Szycik { ICE_MAC_OFOS, 0 }, 7309a225f81SMarcin Szycik { ICE_IPV4_OFOS, 14 }, 7319a225f81SMarcin Szycik { ICE_UDP_OF, 34 }, 7329a225f81SMarcin Szycik { ICE_GTP, 42 }, 7339a225f81SMarcin Szycik { ICE_IPV6_IL, 62 }, 7349a225f81SMarcin Szycik { ICE_TCP_IL, 102 }, 7359a225f81SMarcin Szycik { ICE_PROTOCOL_LAST, 0 }, 7369a225f81SMarcin Szycik }; 7379a225f81SMarcin Szycik 73807a28842SAlexander Lobakin ICE_DECLARE_PKT_TEMPLATE(ipv4_gtpu_ipv6_tcp) = { 7399a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, /* Ethernet 0 */ 7409a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 7419a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 7429a225f81SMarcin Szycik 0x08, 0x00, 7439a225f81SMarcin Szycik 7449a225f81SMarcin Szycik 0x45, 0x00, 0x00, 0x6c, /* IP 14 */ 7459a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 7469a225f81SMarcin Szycik 0x00, 0x11, 0x00, 0x00, 7479a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 7489a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 7499a225f81SMarcin Szycik 7509a225f81SMarcin Szycik 0x00, 0x00, 0x08, 0x68, /* UDP 34 */ 7519a225f81SMarcin Szycik 0x00, 0x58, 0x00, 0x00, 7529a225f81SMarcin Szycik 7539a225f81SMarcin Szycik 0x34, 0xff, 0x00, 0x48, /* ICE_GTP Header 42 */ 7549a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 7559a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x85, 7569a225f81SMarcin Szycik 7579a225f81SMarcin Szycik 0x02, 0x00, 0x00, 0x00, /* GTP_PDUSession_ExtensionHeader 54 */ 7589a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 7599a225f81SMarcin Szycik 7609a225f81SMarcin Szycik 0x60, 0x00, 0x00, 0x00, /* IPv6 62 */ 7619a225f81SMarcin Szycik 0x00, 0x14, 0x06, 0x00, 7629a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 7639a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 7649a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 7659a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 7669a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 7679a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 7689a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 7699a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 7709a225f81SMarcin Szycik 7719a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, /* TCP 102 */ 7729a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 7739a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 7749a225f81SMarcin Szycik 0x50, 0x00, 0x00, 0x00, 7759a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 7769a225f81SMarcin Szycik 7779a225f81SMarcin Szycik 0x00, 0x00, /* 2 bytes for 4 byte alignment */ 7789a225f81SMarcin Szycik }; 7799a225f81SMarcin Szycik 78007a28842SAlexander Lobakin ICE_DECLARE_PKT_OFFSETS(ipv4_gtpu_ipv6_udp) = { 7819a225f81SMarcin Szycik { ICE_MAC_OFOS, 0 }, 7829a225f81SMarcin Szycik { ICE_IPV4_OFOS, 14 }, 7839a225f81SMarcin Szycik { ICE_UDP_OF, 34 }, 7849a225f81SMarcin Szycik { ICE_GTP, 42 }, 7859a225f81SMarcin Szycik { ICE_IPV6_IL, 62 }, 7869a225f81SMarcin Szycik { ICE_UDP_ILOS, 102 }, 7879a225f81SMarcin Szycik { ICE_PROTOCOL_LAST, 0 }, 7889a225f81SMarcin Szycik }; 7899a225f81SMarcin Szycik 79007a28842SAlexander Lobakin ICE_DECLARE_PKT_TEMPLATE(ipv4_gtpu_ipv6_udp) = { 7919a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, /* Ethernet 0 */ 7929a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 7939a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 7949a225f81SMarcin Szycik 0x08, 0x00, 7959a225f81SMarcin Szycik 7969a225f81SMarcin Szycik 0x45, 0x00, 0x00, 0x60, /* IP 14 */ 7979a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 7989a225f81SMarcin Szycik 0x00, 0x11, 0x00, 0x00, 7999a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 8009a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 8019a225f81SMarcin Szycik 8029a225f81SMarcin Szycik 0x00, 0x00, 0x08, 0x68, /* UDP 34 */ 8039a225f81SMarcin Szycik 0x00, 0x4c, 0x00, 0x00, 8049a225f81SMarcin Szycik 8059a225f81SMarcin Szycik 0x34, 0xff, 0x00, 0x3c, /* ICE_GTP Header 42 */ 8069a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 8079a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x85, 8089a225f81SMarcin Szycik 8099a225f81SMarcin Szycik 0x02, 0x00, 0x00, 0x00, /* GTP_PDUSession_ExtensionHeader 54 */ 8109a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 8119a225f81SMarcin Szycik 8129a225f81SMarcin Szycik 0x60, 0x00, 0x00, 0x00, /* IPv6 62 */ 8139a225f81SMarcin Szycik 0x00, 0x08, 0x11, 0x00, 8149a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 8159a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 8169a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 8179a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 8189a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 8199a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 8209a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 8219a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 8229a225f81SMarcin Szycik 8239a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, /* UDP 102 */ 8249a225f81SMarcin Szycik 0x00, 0x08, 0x00, 0x00, 8259a225f81SMarcin Szycik 8269a225f81SMarcin Szycik 0x00, 0x00, /* 2 bytes for 4 byte alignment */ 8279a225f81SMarcin Szycik }; 8289a225f81SMarcin Szycik 82907a28842SAlexander Lobakin ICE_DECLARE_PKT_OFFSETS(ipv6_gtpu_ipv4_tcp) = { 8309a225f81SMarcin Szycik { ICE_MAC_OFOS, 0 }, 8319a225f81SMarcin Szycik { ICE_IPV6_OFOS, 14 }, 8329a225f81SMarcin Szycik { ICE_UDP_OF, 54 }, 8339a225f81SMarcin Szycik { ICE_GTP, 62 }, 8349a225f81SMarcin Szycik { ICE_IPV4_IL, 82 }, 8359a225f81SMarcin Szycik { ICE_TCP_IL, 102 }, 8369a225f81SMarcin Szycik { ICE_PROTOCOL_LAST, 0 }, 8379a225f81SMarcin Szycik }; 8389a225f81SMarcin Szycik 83907a28842SAlexander Lobakin ICE_DECLARE_PKT_TEMPLATE(ipv6_gtpu_ipv4_tcp) = { 8409a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, /* Ethernet 0 */ 8419a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 8429a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 8439a225f81SMarcin Szycik 0x86, 0xdd, 8449a225f81SMarcin Szycik 8459a225f81SMarcin Szycik 0x60, 0x00, 0x00, 0x00, /* IPv6 14 */ 8469a225f81SMarcin Szycik 0x00, 0x44, 0x11, 0x00, 8479a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 8489a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 8499a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 8509a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 8519a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 8529a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 8539a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 8549a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 8559a225f81SMarcin Szycik 8569a225f81SMarcin Szycik 0x00, 0x00, 0x08, 0x68, /* UDP 54 */ 8579a225f81SMarcin Szycik 0x00, 0x44, 0x00, 0x00, 8589a225f81SMarcin Szycik 8599a225f81SMarcin Szycik 0x34, 0xff, 0x00, 0x34, /* ICE_GTP Header 62 */ 8609a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 8619a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x85, 8629a225f81SMarcin Szycik 8639a225f81SMarcin Szycik 0x02, 0x00, 0x00, 0x00, /* GTP_PDUSession_ExtensionHeader 74 */ 8649a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 8659a225f81SMarcin Szycik 8669a225f81SMarcin Szycik 0x45, 0x00, 0x00, 0x28, /* IP 82 */ 8679a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 8689a225f81SMarcin Szycik 0x00, 0x06, 0x00, 0x00, 8699a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 8709a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 8719a225f81SMarcin Szycik 8729a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, /* TCP 102 */ 8739a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 8749a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 8759a225f81SMarcin Szycik 0x50, 0x00, 0x00, 0x00, 8769a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 8779a225f81SMarcin Szycik 8789a225f81SMarcin Szycik 0x00, 0x00, /* 2 bytes for 4 byte alignment */ 8799a225f81SMarcin Szycik }; 8809a225f81SMarcin Szycik 88107a28842SAlexander Lobakin ICE_DECLARE_PKT_OFFSETS(ipv6_gtpu_ipv4_udp) = { 8829a225f81SMarcin Szycik { ICE_MAC_OFOS, 0 }, 8839a225f81SMarcin Szycik { ICE_IPV6_OFOS, 14 }, 8849a225f81SMarcin Szycik { ICE_UDP_OF, 54 }, 8859a225f81SMarcin Szycik { ICE_GTP, 62 }, 8869a225f81SMarcin Szycik { ICE_IPV4_IL, 82 }, 8879a225f81SMarcin Szycik { ICE_UDP_ILOS, 102 }, 8889a225f81SMarcin Szycik { ICE_PROTOCOL_LAST, 0 }, 8899a225f81SMarcin Szycik }; 8909a225f81SMarcin Szycik 89107a28842SAlexander Lobakin ICE_DECLARE_PKT_TEMPLATE(ipv6_gtpu_ipv4_udp) = { 8929a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, /* Ethernet 0 */ 8939a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 8949a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 8959a225f81SMarcin Szycik 0x86, 0xdd, 8969a225f81SMarcin Szycik 8979a225f81SMarcin Szycik 0x60, 0x00, 0x00, 0x00, /* IPv6 14 */ 8989a225f81SMarcin Szycik 0x00, 0x38, 0x11, 0x00, 8999a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 9009a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 9019a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 9029a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 9039a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 9049a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 9059a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 9069a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 9079a225f81SMarcin Szycik 9089a225f81SMarcin Szycik 0x00, 0x00, 0x08, 0x68, /* UDP 54 */ 9099a225f81SMarcin Szycik 0x00, 0x38, 0x00, 0x00, 9109a225f81SMarcin Szycik 9119a225f81SMarcin Szycik 0x34, 0xff, 0x00, 0x28, /* ICE_GTP Header 62 */ 9129a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 9139a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x85, 9149a225f81SMarcin Szycik 9159a225f81SMarcin Szycik 0x02, 0x00, 0x00, 0x00, /* GTP_PDUSession_ExtensionHeader 74 */ 9169a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 9179a225f81SMarcin Szycik 9189a225f81SMarcin Szycik 0x45, 0x00, 0x00, 0x1c, /* IP 82 */ 9199a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 9209a225f81SMarcin Szycik 0x00, 0x11, 0x00, 0x00, 9219a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 9229a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 9239a225f81SMarcin Szycik 9249a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, /* UDP 102 */ 9259a225f81SMarcin Szycik 0x00, 0x08, 0x00, 0x00, 9269a225f81SMarcin Szycik 9279a225f81SMarcin Szycik 0x00, 0x00, /* 2 bytes for 4 byte alignment */ 9289a225f81SMarcin Szycik }; 9299a225f81SMarcin Szycik 93007a28842SAlexander Lobakin ICE_DECLARE_PKT_OFFSETS(ipv6_gtpu_ipv6_tcp) = { 9319a225f81SMarcin Szycik { ICE_MAC_OFOS, 0 }, 9329a225f81SMarcin Szycik { ICE_IPV6_OFOS, 14 }, 9339a225f81SMarcin Szycik { ICE_UDP_OF, 54 }, 9349a225f81SMarcin Szycik { ICE_GTP, 62 }, 9359a225f81SMarcin Szycik { ICE_IPV6_IL, 82 }, 9369a225f81SMarcin Szycik { ICE_TCP_IL, 122 }, 9379a225f81SMarcin Szycik { ICE_PROTOCOL_LAST, 0 }, 9389a225f81SMarcin Szycik }; 9399a225f81SMarcin Szycik 94007a28842SAlexander Lobakin ICE_DECLARE_PKT_TEMPLATE(ipv6_gtpu_ipv6_tcp) = { 9419a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, /* Ethernet 0 */ 9429a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 9439a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 9449a225f81SMarcin Szycik 0x86, 0xdd, 9459a225f81SMarcin Szycik 9469a225f81SMarcin Szycik 0x60, 0x00, 0x00, 0x00, /* IPv6 14 */ 9479a225f81SMarcin Szycik 0x00, 0x58, 0x11, 0x00, 9489a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 9499a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 9509a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 9519a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 9529a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 9539a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 9549a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 9559a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 9569a225f81SMarcin Szycik 9579a225f81SMarcin Szycik 0x00, 0x00, 0x08, 0x68, /* UDP 54 */ 9589a225f81SMarcin Szycik 0x00, 0x58, 0x00, 0x00, 9599a225f81SMarcin Szycik 9609a225f81SMarcin Szycik 0x34, 0xff, 0x00, 0x48, /* ICE_GTP Header 62 */ 9619a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 9629a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x85, 9639a225f81SMarcin Szycik 9649a225f81SMarcin Szycik 0x02, 0x00, 0x00, 0x00, /* GTP_PDUSession_ExtensionHeader 74 */ 9659a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 9669a225f81SMarcin Szycik 9679a225f81SMarcin Szycik 0x60, 0x00, 0x00, 0x00, /* IPv6 82 */ 9689a225f81SMarcin Szycik 0x00, 0x14, 0x06, 0x00, 9699a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 9709a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 9719a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 9729a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 9739a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 9749a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 9759a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 9769a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 9779a225f81SMarcin Szycik 9789a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, /* TCP 122 */ 9799a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 9809a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 9819a225f81SMarcin Szycik 0x50, 0x00, 0x00, 0x00, 9829a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 9839a225f81SMarcin Szycik 9849a225f81SMarcin Szycik 0x00, 0x00, /* 2 bytes for 4 byte alignment */ 9859a225f81SMarcin Szycik }; 9869a225f81SMarcin Szycik 98707a28842SAlexander Lobakin ICE_DECLARE_PKT_OFFSETS(ipv6_gtpu_ipv6_udp) = { 9889a225f81SMarcin Szycik { ICE_MAC_OFOS, 0 }, 9899a225f81SMarcin Szycik { ICE_IPV6_OFOS, 14 }, 9909a225f81SMarcin Szycik { ICE_UDP_OF, 54 }, 9919a225f81SMarcin Szycik { ICE_GTP, 62 }, 9929a225f81SMarcin Szycik { ICE_IPV6_IL, 82 }, 9939a225f81SMarcin Szycik { ICE_UDP_ILOS, 122 }, 9949a225f81SMarcin Szycik { ICE_PROTOCOL_LAST, 0 }, 9959a225f81SMarcin Szycik }; 9969a225f81SMarcin Szycik 99707a28842SAlexander Lobakin ICE_DECLARE_PKT_TEMPLATE(ipv6_gtpu_ipv6_udp) = { 9989a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, /* Ethernet 0 */ 9999a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 10009a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 10019a225f81SMarcin Szycik 0x86, 0xdd, 10029a225f81SMarcin Szycik 10039a225f81SMarcin Szycik 0x60, 0x00, 0x00, 0x00, /* IPv6 14 */ 10049a225f81SMarcin Szycik 0x00, 0x4c, 0x11, 0x00, 10059a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 10069a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 10079a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 10089a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 10099a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 10109a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 10119a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 10129a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 10139a225f81SMarcin Szycik 10149a225f81SMarcin Szycik 0x00, 0x00, 0x08, 0x68, /* UDP 54 */ 10159a225f81SMarcin Szycik 0x00, 0x4c, 0x00, 0x00, 10169a225f81SMarcin Szycik 10179a225f81SMarcin Szycik 0x34, 0xff, 0x00, 0x3c, /* ICE_GTP Header 62 */ 10189a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 10199a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x85, 10209a225f81SMarcin Szycik 10219a225f81SMarcin Szycik 0x02, 0x00, 0x00, 0x00, /* GTP_PDUSession_ExtensionHeader 74 */ 10229a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 10239a225f81SMarcin Szycik 10249a225f81SMarcin Szycik 0x60, 0x00, 0x00, 0x00, /* IPv6 82 */ 10259a225f81SMarcin Szycik 0x00, 0x08, 0x11, 0x00, 10269a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 10279a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 10289a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 10299a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 10309a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 10319a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 10329a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 10339a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 10349a225f81SMarcin Szycik 10359a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, /* UDP 122 */ 10369a225f81SMarcin Szycik 0x00, 0x08, 0x00, 0x00, 10379a225f81SMarcin Szycik 10389a225f81SMarcin Szycik 0x00, 0x00, /* 2 bytes for 4 byte alignment */ 10399a225f81SMarcin Szycik }; 10409a225f81SMarcin Szycik 104107a28842SAlexander Lobakin ICE_DECLARE_PKT_OFFSETS(ipv4_gtpu_ipv4) = { 10421b699f81SAlexander Lobakin { ICE_MAC_OFOS, 0 }, 10431b699f81SAlexander Lobakin { ICE_IPV4_OFOS, 14 }, 10441b699f81SAlexander Lobakin { ICE_UDP_OF, 34 }, 10451b699f81SAlexander Lobakin { ICE_GTP_NO_PAY, 42 }, 10461b699f81SAlexander Lobakin { ICE_PROTOCOL_LAST, 0 }, 10471b699f81SAlexander Lobakin }; 10481b699f81SAlexander Lobakin 104907a28842SAlexander Lobakin ICE_DECLARE_PKT_TEMPLATE(ipv4_gtpu_ipv4) = { 10509a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */ 10519a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 10529a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 10539a225f81SMarcin Szycik 0x08, 0x00, 10549a225f81SMarcin Szycik 10559a225f81SMarcin Szycik 0x45, 0x00, 0x00, 0x44, /* ICE_IPV4_OFOS 14 */ 10569a225f81SMarcin Szycik 0x00, 0x00, 0x40, 0x00, 10579a225f81SMarcin Szycik 0x40, 0x11, 0x00, 0x00, 10589a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 10599a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 10609a225f81SMarcin Szycik 10619a225f81SMarcin Szycik 0x08, 0x68, 0x08, 0x68, /* ICE_UDP_OF 34 */ 10629a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 10639a225f81SMarcin Szycik 10649a225f81SMarcin Szycik 0x34, 0xff, 0x00, 0x28, /* ICE_GTP 42 */ 10659a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 10669a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x85, 10679a225f81SMarcin Szycik 10689a225f81SMarcin Szycik 0x02, 0x00, 0x00, 0x00, /* PDU Session extension header */ 10699a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 10709a225f81SMarcin Szycik 10719a225f81SMarcin Szycik 0x45, 0x00, 0x00, 0x14, /* ICE_IPV4_IL 62 */ 10729a225f81SMarcin Szycik 0x00, 0x00, 0x40, 0x00, 10739a225f81SMarcin Szycik 0x40, 0x00, 0x00, 0x00, 10749a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 10759a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 10769a225f81SMarcin Szycik 0x00, 0x00, 10779a225f81SMarcin Szycik }; 10789a225f81SMarcin Szycik 107907a28842SAlexander Lobakin ICE_DECLARE_PKT_OFFSETS(ipv6_gtp) = { 10809a225f81SMarcin Szycik { ICE_MAC_OFOS, 0 }, 10819a225f81SMarcin Szycik { ICE_IPV6_OFOS, 14 }, 10829a225f81SMarcin Szycik { ICE_UDP_OF, 54 }, 10839a225f81SMarcin Szycik { ICE_GTP_NO_PAY, 62 }, 10849a225f81SMarcin Szycik { ICE_PROTOCOL_LAST, 0 }, 10859a225f81SMarcin Szycik }; 10869a225f81SMarcin Szycik 108707a28842SAlexander Lobakin ICE_DECLARE_PKT_TEMPLATE(ipv6_gtp) = { 10889a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */ 10899a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 10909a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 10919a225f81SMarcin Szycik 0x86, 0xdd, 10929a225f81SMarcin Szycik 10939a225f81SMarcin Szycik 0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 14 */ 10949a225f81SMarcin Szycik 0x00, 0x6c, 0x11, 0x00, /* Next header UDP*/ 10959a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 10969a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 10979a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 10989a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 10999a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 11009a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 11019a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 11029a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 11039a225f81SMarcin Szycik 11049a225f81SMarcin Szycik 0x08, 0x68, 0x08, 0x68, /* ICE_UDP_OF 54 */ 11059a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 11069a225f81SMarcin Szycik 11079a225f81SMarcin Szycik 0x30, 0x00, 0x00, 0x28, /* ICE_GTP 62 */ 11089a225f81SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 11099a225f81SMarcin Szycik 11109a225f81SMarcin Szycik 0x00, 0x00, 11119a225f81SMarcin Szycik }; 11129a225f81SMarcin Szycik 1113cd8efeeeSMarcin Szycik ICE_DECLARE_PKT_OFFSETS(pppoe_ipv4_tcp) = { 1114cd8efeeeSMarcin Szycik { ICE_MAC_OFOS, 0 }, 1115cd8efeeeSMarcin Szycik { ICE_ETYPE_OL, 12 }, 1116cd8efeeeSMarcin Szycik { ICE_PPPOE, 14 }, 1117cd8efeeeSMarcin Szycik { ICE_IPV4_OFOS, 22 }, 1118cd8efeeeSMarcin Szycik { ICE_TCP_IL, 42 }, 1119cd8efeeeSMarcin Szycik { ICE_PROTOCOL_LAST, 0 }, 1120cd8efeeeSMarcin Szycik }; 1121cd8efeeeSMarcin Szycik 1122cd8efeeeSMarcin Szycik ICE_DECLARE_PKT_TEMPLATE(pppoe_ipv4_tcp) = { 1123cd8efeeeSMarcin Szycik 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */ 1124cd8efeeeSMarcin Szycik 0x00, 0x00, 0x00, 0x00, 1125cd8efeeeSMarcin Szycik 0x00, 0x00, 0x00, 0x00, 1126cd8efeeeSMarcin Szycik 1127cd8efeeeSMarcin Szycik 0x88, 0x64, /* ICE_ETYPE_OL 12 */ 1128cd8efeeeSMarcin Szycik 1129cd8efeeeSMarcin Szycik 0x11, 0x00, 0x00, 0x00, /* ICE_PPPOE 14 */ 1130cd8efeeeSMarcin Szycik 0x00, 0x16, 1131cd8efeeeSMarcin Szycik 1132cd8efeeeSMarcin Szycik 0x00, 0x21, /* PPP Link Layer 20 */ 1133cd8efeeeSMarcin Szycik 1134cd8efeeeSMarcin Szycik 0x45, 0x00, 0x00, 0x28, /* ICE_IPV4_OFOS 22 */ 1135cd8efeeeSMarcin Szycik 0x00, 0x01, 0x00, 0x00, 1136cd8efeeeSMarcin Szycik 0x00, 0x06, 0x00, 0x00, 1137cd8efeeeSMarcin Szycik 0x00, 0x00, 0x00, 0x00, 1138cd8efeeeSMarcin Szycik 0x00, 0x00, 0x00, 0x00, 1139cd8efeeeSMarcin Szycik 1140cd8efeeeSMarcin Szycik 0x00, 0x00, 0x00, 0x00, /* ICE_TCP_IL 42 */ 1141cd8efeeeSMarcin Szycik 0x00, 0x00, 0x00, 0x00, 1142cd8efeeeSMarcin Szycik 0x00, 0x00, 0x00, 0x00, 1143cd8efeeeSMarcin Szycik 0x50, 0x00, 0x00, 0x00, 1144cd8efeeeSMarcin Szycik 0x00, 0x00, 0x00, 0x00, 1145cd8efeeeSMarcin Szycik 1146cd8efeeeSMarcin Szycik 0x00, 0x00, /* 2 bytes for 4 bytes alignment */ 1147cd8efeeeSMarcin Szycik }; 1148cd8efeeeSMarcin Szycik 1149cd8efeeeSMarcin Szycik ICE_DECLARE_PKT_OFFSETS(pppoe_ipv4_udp) = { 1150cd8efeeeSMarcin Szycik { ICE_MAC_OFOS, 0 }, 1151cd8efeeeSMarcin Szycik { ICE_ETYPE_OL, 12 }, 1152cd8efeeeSMarcin Szycik { ICE_PPPOE, 14 }, 1153cd8efeeeSMarcin Szycik { ICE_IPV4_OFOS, 22 }, 1154cd8efeeeSMarcin Szycik { ICE_UDP_ILOS, 42 }, 1155cd8efeeeSMarcin Szycik { ICE_PROTOCOL_LAST, 0 }, 1156cd8efeeeSMarcin Szycik }; 1157cd8efeeeSMarcin Szycik 1158cd8efeeeSMarcin Szycik ICE_DECLARE_PKT_TEMPLATE(pppoe_ipv4_udp) = { 1159cd8efeeeSMarcin Szycik 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */ 1160cd8efeeeSMarcin Szycik 0x00, 0x00, 0x00, 0x00, 1161cd8efeeeSMarcin Szycik 0x00, 0x00, 0x00, 0x00, 1162cd8efeeeSMarcin Szycik 1163cd8efeeeSMarcin Szycik 0x88, 0x64, /* ICE_ETYPE_OL 12 */ 1164cd8efeeeSMarcin Szycik 1165cd8efeeeSMarcin Szycik 0x11, 0x00, 0x00, 0x00, /* ICE_PPPOE 14 */ 1166cd8efeeeSMarcin Szycik 0x00, 0x16, 1167cd8efeeeSMarcin Szycik 1168cd8efeeeSMarcin Szycik 0x00, 0x21, /* PPP Link Layer 20 */ 1169cd8efeeeSMarcin Szycik 1170cd8efeeeSMarcin Szycik 0x45, 0x00, 0x00, 0x1c, /* ICE_IPV4_OFOS 22 */ 1171cd8efeeeSMarcin Szycik 0x00, 0x01, 0x00, 0x00, 1172cd8efeeeSMarcin Szycik 0x00, 0x11, 0x00, 0x00, 1173cd8efeeeSMarcin Szycik 0x00, 0x00, 0x00, 0x00, 1174cd8efeeeSMarcin Szycik 0x00, 0x00, 0x00, 0x00, 1175cd8efeeeSMarcin Szycik 1176cd8efeeeSMarcin Szycik 0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 42 */ 1177cd8efeeeSMarcin Szycik 0x00, 0x08, 0x00, 0x00, 1178cd8efeeeSMarcin Szycik 1179cd8efeeeSMarcin Szycik 0x00, 0x00, /* 2 bytes for 4 bytes alignment */ 1180cd8efeeeSMarcin Szycik }; 1181cd8efeeeSMarcin Szycik 1182cd8efeeeSMarcin Szycik ICE_DECLARE_PKT_OFFSETS(pppoe_ipv6_tcp) = { 1183cd8efeeeSMarcin Szycik { ICE_MAC_OFOS, 0 }, 1184cd8efeeeSMarcin Szycik { ICE_ETYPE_OL, 12 }, 1185cd8efeeeSMarcin Szycik { ICE_PPPOE, 14 }, 1186cd8efeeeSMarcin Szycik { ICE_IPV6_OFOS, 22 }, 1187cd8efeeeSMarcin Szycik { ICE_TCP_IL, 62 }, 1188cd8efeeeSMarcin Szycik { ICE_PROTOCOL_LAST, 0 }, 1189cd8efeeeSMarcin Szycik }; 1190cd8efeeeSMarcin Szycik 1191cd8efeeeSMarcin Szycik ICE_DECLARE_PKT_TEMPLATE(pppoe_ipv6_tcp) = { 1192cd8efeeeSMarcin Szycik 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */ 1193cd8efeeeSMarcin Szycik 0x00, 0x00, 0x00, 0x00, 1194cd8efeeeSMarcin Szycik 0x00, 0x00, 0x00, 0x00, 1195cd8efeeeSMarcin Szycik 1196cd8efeeeSMarcin Szycik 0x88, 0x64, /* ICE_ETYPE_OL 12 */ 1197cd8efeeeSMarcin Szycik 1198cd8efeeeSMarcin Szycik 0x11, 0x00, 0x00, 0x00, /* ICE_PPPOE 14 */ 1199cd8efeeeSMarcin Szycik 0x00, 0x2a, 1200cd8efeeeSMarcin Szycik 1201cd8efeeeSMarcin Szycik 0x00, 0x57, /* PPP Link Layer 20 */ 1202cd8efeeeSMarcin Szycik 1203cd8efeeeSMarcin Szycik 0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 22 */ 1204cd8efeeeSMarcin Szycik 0x00, 0x14, 0x06, 0x00, /* Next header is TCP */ 1205cd8efeeeSMarcin Szycik 0x00, 0x00, 0x00, 0x00, 1206cd8efeeeSMarcin Szycik 0x00, 0x00, 0x00, 0x00, 1207cd8efeeeSMarcin Szycik 0x00, 0x00, 0x00, 0x00, 1208cd8efeeeSMarcin Szycik 0x00, 0x00, 0x00, 0x00, 1209cd8efeeeSMarcin Szycik 0x00, 0x00, 0x00, 0x00, 1210cd8efeeeSMarcin Szycik 0x00, 0x00, 0x00, 0x00, 1211cd8efeeeSMarcin Szycik 0x00, 0x00, 0x00, 0x00, 1212cd8efeeeSMarcin Szycik 0x00, 0x00, 0x00, 0x00, 1213cd8efeeeSMarcin Szycik 1214cd8efeeeSMarcin Szycik 0x00, 0x00, 0x00, 0x00, /* ICE_TCP_IL 62 */ 1215cd8efeeeSMarcin Szycik 0x00, 0x00, 0x00, 0x00, 1216cd8efeeeSMarcin Szycik 0x00, 0x00, 0x00, 0x00, 1217cd8efeeeSMarcin Szycik 0x50, 0x00, 0x00, 0x00, 1218cd8efeeeSMarcin Szycik 0x00, 0x00, 0x00, 0x00, 1219cd8efeeeSMarcin Szycik 1220cd8efeeeSMarcin Szycik 0x00, 0x00, /* 2 bytes for 4 bytes alignment */ 1221cd8efeeeSMarcin Szycik }; 1222cd8efeeeSMarcin Szycik 1223cd8efeeeSMarcin Szycik ICE_DECLARE_PKT_OFFSETS(pppoe_ipv6_udp) = { 1224cd8efeeeSMarcin Szycik { ICE_MAC_OFOS, 0 }, 1225cd8efeeeSMarcin Szycik { ICE_ETYPE_OL, 12 }, 1226cd8efeeeSMarcin Szycik { ICE_PPPOE, 14 }, 1227cd8efeeeSMarcin Szycik { ICE_IPV6_OFOS, 22 }, 1228cd8efeeeSMarcin Szycik { ICE_UDP_ILOS, 62 }, 1229cd8efeeeSMarcin Szycik { ICE_PROTOCOL_LAST, 0 }, 1230cd8efeeeSMarcin Szycik }; 1231cd8efeeeSMarcin Szycik 1232cd8efeeeSMarcin Szycik ICE_DECLARE_PKT_TEMPLATE(pppoe_ipv6_udp) = { 1233cd8efeeeSMarcin Szycik 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */ 1234cd8efeeeSMarcin Szycik 0x00, 0x00, 0x00, 0x00, 1235cd8efeeeSMarcin Szycik 0x00, 0x00, 0x00, 0x00, 1236cd8efeeeSMarcin Szycik 1237cd8efeeeSMarcin Szycik 0x88, 0x64, /* ICE_ETYPE_OL 12 */ 1238cd8efeeeSMarcin Szycik 1239cd8efeeeSMarcin Szycik 0x11, 0x00, 0x00, 0x00, /* ICE_PPPOE 14 */ 1240cd8efeeeSMarcin Szycik 0x00, 0x2a, 1241cd8efeeeSMarcin Szycik 1242cd8efeeeSMarcin Szycik 0x00, 0x57, /* PPP Link Layer 20 */ 1243cd8efeeeSMarcin Szycik 1244cd8efeeeSMarcin Szycik 0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 22 */ 1245cd8efeeeSMarcin Szycik 0x00, 0x08, 0x11, 0x00, /* Next header UDP*/ 1246cd8efeeeSMarcin Szycik 0x00, 0x00, 0x00, 0x00, 1247cd8efeeeSMarcin Szycik 0x00, 0x00, 0x00, 0x00, 1248cd8efeeeSMarcin Szycik 0x00, 0x00, 0x00, 0x00, 1249cd8efeeeSMarcin Szycik 0x00, 0x00, 0x00, 0x00, 1250cd8efeeeSMarcin Szycik 0x00, 0x00, 0x00, 0x00, 1251cd8efeeeSMarcin Szycik 0x00, 0x00, 0x00, 0x00, 1252cd8efeeeSMarcin Szycik 0x00, 0x00, 0x00, 0x00, 1253cd8efeeeSMarcin Szycik 0x00, 0x00, 0x00, 0x00, 1254cd8efeeeSMarcin Szycik 1255cd8efeeeSMarcin Szycik 0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 62 */ 1256cd8efeeeSMarcin Szycik 0x00, 0x08, 0x00, 0x00, 1257cd8efeeeSMarcin Szycik 1258cd8efeeeSMarcin Szycik 0x00, 0x00, /* 2 bytes for 4 bytes alignment */ 1259cd8efeeeSMarcin Szycik }; 1260cd8efeeeSMarcin Szycik 1261cd634549SMarcin Szycik ICE_DECLARE_PKT_OFFSETS(ipv4_l2tpv3) = { 1262cd634549SMarcin Szycik { ICE_MAC_OFOS, 0 }, 1263cd634549SMarcin Szycik { ICE_ETYPE_OL, 12 }, 1264cd634549SMarcin Szycik { ICE_IPV4_OFOS, 14 }, 1265cd634549SMarcin Szycik { ICE_L2TPV3, 34 }, 1266cd634549SMarcin Szycik { ICE_PROTOCOL_LAST, 0 }, 1267cd634549SMarcin Szycik }; 1268cd634549SMarcin Szycik 1269cd634549SMarcin Szycik ICE_DECLARE_PKT_TEMPLATE(ipv4_l2tpv3) = { 1270cd634549SMarcin Szycik 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */ 1271cd634549SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 1272cd634549SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 1273cd634549SMarcin Szycik 1274cd634549SMarcin Szycik 0x08, 0x00, /* ICE_ETYPE_OL 12 */ 1275cd634549SMarcin Szycik 1276cd634549SMarcin Szycik 0x45, 0x00, 0x00, 0x20, /* ICE_IPV4_IL 14 */ 1277cd634549SMarcin Szycik 0x00, 0x00, 0x40, 0x00, 1278cd634549SMarcin Szycik 0x40, 0x73, 0x00, 0x00, 1279cd634549SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 1280cd634549SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 1281cd634549SMarcin Szycik 1282cd634549SMarcin Szycik 0x00, 0x00, 0x00, 0x00, /* ICE_L2TPV3 34 */ 1283cd634549SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 1284cd634549SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 1285cd634549SMarcin Szycik 0x00, 0x00, /* 2 bytes for 4 bytes alignment */ 1286cd634549SMarcin Szycik }; 1287cd634549SMarcin Szycik 1288cd634549SMarcin Szycik ICE_DECLARE_PKT_OFFSETS(ipv6_l2tpv3) = { 1289cd634549SMarcin Szycik { ICE_MAC_OFOS, 0 }, 1290cd634549SMarcin Szycik { ICE_ETYPE_OL, 12 }, 1291cd634549SMarcin Szycik { ICE_IPV6_OFOS, 14 }, 1292cd634549SMarcin Szycik { ICE_L2TPV3, 54 }, 1293cd634549SMarcin Szycik { ICE_PROTOCOL_LAST, 0 }, 1294cd634549SMarcin Szycik }; 1295cd634549SMarcin Szycik 1296cd634549SMarcin Szycik ICE_DECLARE_PKT_TEMPLATE(ipv6_l2tpv3) = { 1297cd634549SMarcin Szycik 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */ 1298cd634549SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 1299cd634549SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 1300cd634549SMarcin Szycik 1301cd634549SMarcin Szycik 0x86, 0xDD, /* ICE_ETYPE_OL 12 */ 1302cd634549SMarcin Szycik 1303cd634549SMarcin Szycik 0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_IL 14 */ 1304cd634549SMarcin Szycik 0x00, 0x0c, 0x73, 0x40, 1305cd634549SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 1306cd634549SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 1307cd634549SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 1308cd634549SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 1309cd634549SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 1310cd634549SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 1311cd634549SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 1312cd634549SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 1313cd634549SMarcin Szycik 1314cd634549SMarcin Szycik 0x00, 0x00, 0x00, 0x00, /* ICE_L2TPV3 54 */ 1315cd634549SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 1316cd634549SMarcin Szycik 0x00, 0x00, 0x00, 0x00, 1317cd634549SMarcin Szycik 0x00, 0x00, /* 2 bytes for 4 bytes alignment */ 1318cd634549SMarcin Szycik }; 1319cd634549SMarcin Szycik 1320e33163a4SAlexander Lobakin static const struct ice_dummy_pkt_profile ice_dummy_pkt_profiles[] = { 1321e33163a4SAlexander Lobakin ICE_PKT_PROFILE(ipv6_gtp, ICE_PKT_TUN_GTPU | ICE_PKT_OUTER_IPV6 | 1322e33163a4SAlexander Lobakin ICE_PKT_GTP_NOPAY), 1323e33163a4SAlexander Lobakin ICE_PKT_PROFILE(ipv6_gtpu_ipv6_udp, ICE_PKT_TUN_GTPU | 1324e33163a4SAlexander Lobakin ICE_PKT_OUTER_IPV6 | 1325e33163a4SAlexander Lobakin ICE_PKT_INNER_IPV6 | 1326e33163a4SAlexander Lobakin ICE_PKT_INNER_UDP), 1327e33163a4SAlexander Lobakin ICE_PKT_PROFILE(ipv6_gtpu_ipv6_tcp, ICE_PKT_TUN_GTPU | 1328e33163a4SAlexander Lobakin ICE_PKT_OUTER_IPV6 | 1329e33163a4SAlexander Lobakin ICE_PKT_INNER_IPV6), 1330e33163a4SAlexander Lobakin ICE_PKT_PROFILE(ipv6_gtpu_ipv4_udp, ICE_PKT_TUN_GTPU | 1331e33163a4SAlexander Lobakin ICE_PKT_OUTER_IPV6 | 1332e33163a4SAlexander Lobakin ICE_PKT_INNER_UDP), 1333e33163a4SAlexander Lobakin ICE_PKT_PROFILE(ipv6_gtpu_ipv4_tcp, ICE_PKT_TUN_GTPU | 1334e33163a4SAlexander Lobakin ICE_PKT_OUTER_IPV6), 1335e33163a4SAlexander Lobakin ICE_PKT_PROFILE(ipv4_gtpu_ipv4, ICE_PKT_TUN_GTPU | ICE_PKT_GTP_NOPAY), 1336e33163a4SAlexander Lobakin ICE_PKT_PROFILE(ipv4_gtpu_ipv6_udp, ICE_PKT_TUN_GTPU | 1337e33163a4SAlexander Lobakin ICE_PKT_INNER_IPV6 | 1338e33163a4SAlexander Lobakin ICE_PKT_INNER_UDP), 1339e33163a4SAlexander Lobakin ICE_PKT_PROFILE(ipv4_gtpu_ipv6_tcp, ICE_PKT_TUN_GTPU | 1340e33163a4SAlexander Lobakin ICE_PKT_INNER_IPV6), 1341e33163a4SAlexander Lobakin ICE_PKT_PROFILE(ipv4_gtpu_ipv4_udp, ICE_PKT_TUN_GTPU | 1342e33163a4SAlexander Lobakin ICE_PKT_INNER_UDP), 1343e33163a4SAlexander Lobakin ICE_PKT_PROFILE(ipv4_gtpu_ipv4_tcp, ICE_PKT_TUN_GTPU), 1344e33163a4SAlexander Lobakin ICE_PKT_PROFILE(ipv6_gtp, ICE_PKT_TUN_GTPC | ICE_PKT_OUTER_IPV6), 1345e33163a4SAlexander Lobakin ICE_PKT_PROFILE(ipv4_gtpu_ipv4, ICE_PKT_TUN_GTPC), 1346cd8efeeeSMarcin Szycik ICE_PKT_PROFILE(pppoe_ipv6_udp, ICE_PKT_PPPOE | ICE_PKT_OUTER_IPV6 | 1347cd8efeeeSMarcin Szycik ICE_PKT_INNER_UDP), 1348cd8efeeeSMarcin Szycik ICE_PKT_PROFILE(pppoe_ipv6_tcp, ICE_PKT_PPPOE | ICE_PKT_OUTER_IPV6), 1349cd8efeeeSMarcin Szycik ICE_PKT_PROFILE(pppoe_ipv4_udp, ICE_PKT_PPPOE | ICE_PKT_INNER_UDP), 1350cd8efeeeSMarcin Szycik ICE_PKT_PROFILE(pppoe_ipv4_tcp, ICE_PKT_PPPOE), 1351e33163a4SAlexander Lobakin ICE_PKT_PROFILE(gre_ipv6_tcp, ICE_PKT_TUN_NVGRE | ICE_PKT_INNER_IPV6 | 1352e33163a4SAlexander Lobakin ICE_PKT_INNER_TCP), 1353e33163a4SAlexander Lobakin ICE_PKT_PROFILE(gre_tcp, ICE_PKT_TUN_NVGRE | ICE_PKT_INNER_TCP), 1354e33163a4SAlexander Lobakin ICE_PKT_PROFILE(gre_ipv6_udp, ICE_PKT_TUN_NVGRE | ICE_PKT_INNER_IPV6), 1355e33163a4SAlexander Lobakin ICE_PKT_PROFILE(gre_udp, ICE_PKT_TUN_NVGRE), 1356e33163a4SAlexander Lobakin ICE_PKT_PROFILE(udp_tun_ipv6_tcp, ICE_PKT_TUN_UDP | 1357e33163a4SAlexander Lobakin ICE_PKT_INNER_IPV6 | 1358e33163a4SAlexander Lobakin ICE_PKT_INNER_TCP), 1359cd634549SMarcin Szycik ICE_PKT_PROFILE(ipv6_l2tpv3, ICE_PKT_L2TPV3 | ICE_PKT_OUTER_IPV6), 1360cd634549SMarcin Szycik ICE_PKT_PROFILE(ipv4_l2tpv3, ICE_PKT_L2TPV3), 1361e33163a4SAlexander Lobakin ICE_PKT_PROFILE(udp_tun_tcp, ICE_PKT_TUN_UDP | ICE_PKT_INNER_TCP), 1362e33163a4SAlexander Lobakin ICE_PKT_PROFILE(udp_tun_ipv6_udp, ICE_PKT_TUN_UDP | 1363e33163a4SAlexander Lobakin ICE_PKT_INNER_IPV6), 1364e33163a4SAlexander Lobakin ICE_PKT_PROFILE(udp_tun_udp, ICE_PKT_TUN_UDP), 1365e33163a4SAlexander Lobakin ICE_PKT_PROFILE(udp_ipv6, ICE_PKT_OUTER_IPV6 | ICE_PKT_INNER_UDP), 1366e33163a4SAlexander Lobakin ICE_PKT_PROFILE(udp, ICE_PKT_INNER_UDP), 1367e33163a4SAlexander Lobakin ICE_PKT_PROFILE(tcp_ipv6, ICE_PKT_OUTER_IPV6), 1368e33163a4SAlexander Lobakin ICE_PKT_PROFILE(tcp, 0), 1369e33163a4SAlexander Lobakin }; 1370e33163a4SAlexander Lobakin 1371fd2a6b71SDan Nowlin /* this is a recipe to profile association bitmap */ 1372fd2a6b71SDan Nowlin static DECLARE_BITMAP(recipe_to_profile[ICE_MAX_NUM_RECIPES], 1373fd2a6b71SDan Nowlin ICE_MAX_NUM_PROFILES); 1374fd2a6b71SDan Nowlin 1375fd2a6b71SDan Nowlin /* this is a profile to recipe association bitmap */ 1376fd2a6b71SDan Nowlin static DECLARE_BITMAP(profile_to_recipe[ICE_MAX_NUM_PROFILES], 1377fd2a6b71SDan Nowlin ICE_MAX_NUM_RECIPES); 1378fd2a6b71SDan Nowlin 13799daf8208SAnirudh Venkataramanan /** 138080d144c9SAnirudh Venkataramanan * ice_init_def_sw_recp - initialize the recipe book keeping tables 1381f9867df6SAnirudh Venkataramanan * @hw: pointer to the HW struct 138280d144c9SAnirudh Venkataramanan * 138380d144c9SAnirudh Venkataramanan * Allocate memory for the entire recipe table and initialize the structures/ 138480d144c9SAnirudh Venkataramanan * entries corresponding to basic recipes. 138580d144c9SAnirudh Venkataramanan */ 13865e24d598STony Nguyen int ice_init_def_sw_recp(struct ice_hw *hw) 138780d144c9SAnirudh Venkataramanan { 138880d144c9SAnirudh Venkataramanan struct ice_sw_recipe *recps; 138980d144c9SAnirudh Venkataramanan u8 i; 139080d144c9SAnirudh Venkataramanan 139180d144c9SAnirudh Venkataramanan recps = devm_kcalloc(ice_hw_to_dev(hw), ICE_MAX_NUM_RECIPES, 1392c6dfd690SBruce Allan sizeof(*recps), GFP_KERNEL); 139380d144c9SAnirudh Venkataramanan if (!recps) 1394d54699e2STony Nguyen return -ENOMEM; 139580d144c9SAnirudh Venkataramanan 1396450052a4SDan Nowlin for (i = 0; i < ICE_MAX_NUM_RECIPES; i++) { 139780d144c9SAnirudh Venkataramanan recps[i].root_rid = i; 139880d144c9SAnirudh Venkataramanan INIT_LIST_HEAD(&recps[i].filt_rules); 1399334cb062SAnirudh Venkataramanan INIT_LIST_HEAD(&recps[i].filt_replay_rules); 1400450052a4SDan Nowlin INIT_LIST_HEAD(&recps[i].rg_list); 140180d144c9SAnirudh Venkataramanan mutex_init(&recps[i].filt_rule_lock); 140280d144c9SAnirudh Venkataramanan } 140380d144c9SAnirudh Venkataramanan 140480d144c9SAnirudh Venkataramanan hw->switch_info->recp_list = recps; 140580d144c9SAnirudh Venkataramanan 140680d144c9SAnirudh Venkataramanan return 0; 140780d144c9SAnirudh Venkataramanan } 140880d144c9SAnirudh Venkataramanan 140980d144c9SAnirudh Venkataramanan /** 14109c20346bSAnirudh Venkataramanan * ice_aq_get_sw_cfg - get switch configuration 14119c20346bSAnirudh Venkataramanan * @hw: pointer to the hardware structure 14129c20346bSAnirudh Venkataramanan * @buf: pointer to the result buffer 14139c20346bSAnirudh Venkataramanan * @buf_size: length of the buffer available for response 14149c20346bSAnirudh Venkataramanan * @req_desc: pointer to requested descriptor 14159c20346bSAnirudh Venkataramanan * @num_elems: pointer to number of elements 14169c20346bSAnirudh Venkataramanan * @cd: pointer to command details structure or NULL 14179c20346bSAnirudh Venkataramanan * 1418b3c38904SBruce Allan * Get switch configuration (0x0200) to be placed in buf. 14199c20346bSAnirudh Venkataramanan * This admin command returns information such as initial VSI/port number 14209c20346bSAnirudh Venkataramanan * and switch ID it belongs to. 14219c20346bSAnirudh Venkataramanan * 14229c20346bSAnirudh Venkataramanan * NOTE: *req_desc is both an input/output parameter. 14239c20346bSAnirudh Venkataramanan * The caller of this function first calls this function with *request_desc set 14249c20346bSAnirudh Venkataramanan * to 0. If the response from f/w has *req_desc set to 0, all the switch 14259c20346bSAnirudh Venkataramanan * configuration information has been returned; if non-zero (meaning not all 14269c20346bSAnirudh Venkataramanan * the information was returned), the caller should call this function again 14279c20346bSAnirudh Venkataramanan * with *req_desc set to the previous value returned by f/w to get the 14289c20346bSAnirudh Venkataramanan * next block of switch configuration information. 14299c20346bSAnirudh Venkataramanan * 14309c20346bSAnirudh Venkataramanan * *num_elems is output only parameter. This reflects the number of elements 14319c20346bSAnirudh Venkataramanan * in response buffer. The caller of this function to use *num_elems while 14329c20346bSAnirudh Venkataramanan * parsing the response buffer. 14339c20346bSAnirudh Venkataramanan */ 14345e24d598STony Nguyen static int 1435b3c38904SBruce Allan ice_aq_get_sw_cfg(struct ice_hw *hw, struct ice_aqc_get_sw_cfg_resp_elem *buf, 14369c20346bSAnirudh Venkataramanan u16 buf_size, u16 *req_desc, u16 *num_elems, 14379c20346bSAnirudh Venkataramanan struct ice_sq_cd *cd) 14389c20346bSAnirudh Venkataramanan { 14399c20346bSAnirudh Venkataramanan struct ice_aqc_get_sw_cfg *cmd; 14409c20346bSAnirudh Venkataramanan struct ice_aq_desc desc; 14415e24d598STony Nguyen int status; 14429c20346bSAnirudh Venkataramanan 14439c20346bSAnirudh Venkataramanan ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_sw_cfg); 14449c20346bSAnirudh Venkataramanan cmd = &desc.params.get_sw_conf; 14459c20346bSAnirudh Venkataramanan cmd->element = cpu_to_le16(*req_desc); 14469c20346bSAnirudh Venkataramanan 14479c20346bSAnirudh Venkataramanan status = ice_aq_send_cmd(hw, &desc, buf, buf_size, cd); 14489c20346bSAnirudh Venkataramanan if (!status) { 14499c20346bSAnirudh Venkataramanan *req_desc = le16_to_cpu(cmd->element); 14509c20346bSAnirudh Venkataramanan *num_elems = le16_to_cpu(cmd->num_elems); 14519c20346bSAnirudh Venkataramanan } 14529c20346bSAnirudh Venkataramanan 14539c20346bSAnirudh Venkataramanan return status; 14549c20346bSAnirudh Venkataramanan } 14559c20346bSAnirudh Venkataramanan 14563a858ba3SAnirudh Venkataramanan /** 14573a858ba3SAnirudh Venkataramanan * ice_aq_add_vsi 1458f9867df6SAnirudh Venkataramanan * @hw: pointer to the HW struct 14593a858ba3SAnirudh Venkataramanan * @vsi_ctx: pointer to a VSI context struct 14603a858ba3SAnirudh Venkataramanan * @cd: pointer to command details structure or NULL 14613a858ba3SAnirudh Venkataramanan * 14623a858ba3SAnirudh Venkataramanan * Add a VSI context to the hardware (0x0210) 14633a858ba3SAnirudh Venkataramanan */ 14645e24d598STony Nguyen static int 14653a858ba3SAnirudh Venkataramanan ice_aq_add_vsi(struct ice_hw *hw, struct ice_vsi_ctx *vsi_ctx, 14663a858ba3SAnirudh Venkataramanan struct ice_sq_cd *cd) 14673a858ba3SAnirudh Venkataramanan { 14683a858ba3SAnirudh Venkataramanan struct ice_aqc_add_update_free_vsi_resp *res; 14693a858ba3SAnirudh Venkataramanan struct ice_aqc_add_get_update_free_vsi *cmd; 14703a858ba3SAnirudh Venkataramanan struct ice_aq_desc desc; 14715e24d598STony Nguyen int status; 14723a858ba3SAnirudh Venkataramanan 14733a858ba3SAnirudh Venkataramanan cmd = &desc.params.vsi_cmd; 14740f9d5027SAnirudh Venkataramanan res = &desc.params.add_update_free_vsi_res; 14753a858ba3SAnirudh Venkataramanan 14763a858ba3SAnirudh Venkataramanan ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_add_vsi); 14773a858ba3SAnirudh Venkataramanan 14783a858ba3SAnirudh Venkataramanan if (!vsi_ctx->alloc_from_pool) 14793a858ba3SAnirudh Venkataramanan cmd->vsi_num = cpu_to_le16(vsi_ctx->vsi_num | 14803a858ba3SAnirudh Venkataramanan ICE_AQ_VSI_IS_VALID); 14811071a835SAnirudh Venkataramanan cmd->vf_id = vsi_ctx->vf_num; 14823a858ba3SAnirudh Venkataramanan 14833a858ba3SAnirudh Venkataramanan cmd->vsi_flags = cpu_to_le16(vsi_ctx->flags); 14843a858ba3SAnirudh Venkataramanan 14853a858ba3SAnirudh Venkataramanan desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD); 14863a858ba3SAnirudh Venkataramanan 14873a858ba3SAnirudh Venkataramanan status = ice_aq_send_cmd(hw, &desc, &vsi_ctx->info, 14883a858ba3SAnirudh Venkataramanan sizeof(vsi_ctx->info), cd); 14893a858ba3SAnirudh Venkataramanan 14903a858ba3SAnirudh Venkataramanan if (!status) { 14913a858ba3SAnirudh Venkataramanan vsi_ctx->vsi_num = le16_to_cpu(res->vsi_num) & ICE_AQ_VSI_NUM_M; 14923a858ba3SAnirudh Venkataramanan vsi_ctx->vsis_allocd = le16_to_cpu(res->vsi_used); 14933a858ba3SAnirudh Venkataramanan vsi_ctx->vsis_unallocated = le16_to_cpu(res->vsi_free); 14943a858ba3SAnirudh Venkataramanan } 14953a858ba3SAnirudh Venkataramanan 14963a858ba3SAnirudh Venkataramanan return status; 14973a858ba3SAnirudh Venkataramanan } 14983a858ba3SAnirudh Venkataramanan 14993a858ba3SAnirudh Venkataramanan /** 15000f9d5027SAnirudh Venkataramanan * ice_aq_free_vsi 1501f9867df6SAnirudh Venkataramanan * @hw: pointer to the HW struct 15020f9d5027SAnirudh Venkataramanan * @vsi_ctx: pointer to a VSI context struct 15030f9d5027SAnirudh Venkataramanan * @keep_vsi_alloc: keep VSI allocation as part of this PF's resources 15040f9d5027SAnirudh Venkataramanan * @cd: pointer to command details structure or NULL 15050f9d5027SAnirudh Venkataramanan * 15060f9d5027SAnirudh Venkataramanan * Free VSI context info from hardware (0x0213) 15070f9d5027SAnirudh Venkataramanan */ 15085e24d598STony Nguyen static int 15090f9d5027SAnirudh Venkataramanan ice_aq_free_vsi(struct ice_hw *hw, struct ice_vsi_ctx *vsi_ctx, 15100f9d5027SAnirudh Venkataramanan bool keep_vsi_alloc, struct ice_sq_cd *cd) 15110f9d5027SAnirudh Venkataramanan { 15120f9d5027SAnirudh Venkataramanan struct ice_aqc_add_update_free_vsi_resp *resp; 15130f9d5027SAnirudh Venkataramanan struct ice_aqc_add_get_update_free_vsi *cmd; 15140f9d5027SAnirudh Venkataramanan struct ice_aq_desc desc; 15155e24d598STony Nguyen int status; 15160f9d5027SAnirudh Venkataramanan 15170f9d5027SAnirudh Venkataramanan cmd = &desc.params.vsi_cmd; 15180f9d5027SAnirudh Venkataramanan resp = &desc.params.add_update_free_vsi_res; 15190f9d5027SAnirudh Venkataramanan 15200f9d5027SAnirudh Venkataramanan ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_free_vsi); 15210f9d5027SAnirudh Venkataramanan 15220f9d5027SAnirudh Venkataramanan cmd->vsi_num = cpu_to_le16(vsi_ctx->vsi_num | ICE_AQ_VSI_IS_VALID); 15230f9d5027SAnirudh Venkataramanan if (keep_vsi_alloc) 15240f9d5027SAnirudh Venkataramanan cmd->cmd_flags = cpu_to_le16(ICE_AQ_VSI_KEEP_ALLOC); 15250f9d5027SAnirudh Venkataramanan 15260f9d5027SAnirudh Venkataramanan status = ice_aq_send_cmd(hw, &desc, NULL, 0, cd); 15270f9d5027SAnirudh Venkataramanan if (!status) { 15280f9d5027SAnirudh Venkataramanan vsi_ctx->vsis_allocd = le16_to_cpu(resp->vsi_used); 15290f9d5027SAnirudh Venkataramanan vsi_ctx->vsis_unallocated = le16_to_cpu(resp->vsi_free); 15300f9d5027SAnirudh Venkataramanan } 15310f9d5027SAnirudh Venkataramanan 15320f9d5027SAnirudh Venkataramanan return status; 15330f9d5027SAnirudh Venkataramanan } 15340f9d5027SAnirudh Venkataramanan 15350f9d5027SAnirudh Venkataramanan /** 15363a858ba3SAnirudh Venkataramanan * ice_aq_update_vsi 1537f9867df6SAnirudh Venkataramanan * @hw: pointer to the HW struct 15383a858ba3SAnirudh Venkataramanan * @vsi_ctx: pointer to a VSI context struct 15393a858ba3SAnirudh Venkataramanan * @cd: pointer to command details structure or NULL 15403a858ba3SAnirudh Venkataramanan * 15413a858ba3SAnirudh Venkataramanan * Update VSI context in the hardware (0x0211) 15423a858ba3SAnirudh Venkataramanan */ 15435e24d598STony Nguyen static int 15443a858ba3SAnirudh Venkataramanan ice_aq_update_vsi(struct ice_hw *hw, struct ice_vsi_ctx *vsi_ctx, 15453a858ba3SAnirudh Venkataramanan struct ice_sq_cd *cd) 15463a858ba3SAnirudh Venkataramanan { 15473a858ba3SAnirudh Venkataramanan struct ice_aqc_add_update_free_vsi_resp *resp; 15483a858ba3SAnirudh Venkataramanan struct ice_aqc_add_get_update_free_vsi *cmd; 15493a858ba3SAnirudh Venkataramanan struct ice_aq_desc desc; 15505e24d598STony Nguyen int status; 15513a858ba3SAnirudh Venkataramanan 15523a858ba3SAnirudh Venkataramanan cmd = &desc.params.vsi_cmd; 15530f9d5027SAnirudh Venkataramanan resp = &desc.params.add_update_free_vsi_res; 15543a858ba3SAnirudh Venkataramanan 15553a858ba3SAnirudh Venkataramanan ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_update_vsi); 15563a858ba3SAnirudh Venkataramanan 15573a858ba3SAnirudh Venkataramanan cmd->vsi_num = cpu_to_le16(vsi_ctx->vsi_num | ICE_AQ_VSI_IS_VALID); 15583a858ba3SAnirudh Venkataramanan 15593a858ba3SAnirudh Venkataramanan desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD); 15603a858ba3SAnirudh Venkataramanan 15613a858ba3SAnirudh Venkataramanan status = ice_aq_send_cmd(hw, &desc, &vsi_ctx->info, 15623a858ba3SAnirudh Venkataramanan sizeof(vsi_ctx->info), cd); 15633a858ba3SAnirudh Venkataramanan 15643a858ba3SAnirudh Venkataramanan if (!status) { 15653a858ba3SAnirudh Venkataramanan vsi_ctx->vsis_allocd = le16_to_cpu(resp->vsi_used); 15663a858ba3SAnirudh Venkataramanan vsi_ctx->vsis_unallocated = le16_to_cpu(resp->vsi_free); 15673a858ba3SAnirudh Venkataramanan } 15683a858ba3SAnirudh Venkataramanan 15693a858ba3SAnirudh Venkataramanan return status; 15703a858ba3SAnirudh Venkataramanan } 15713a858ba3SAnirudh Venkataramanan 15723a858ba3SAnirudh Venkataramanan /** 15730f9d5027SAnirudh Venkataramanan * ice_is_vsi_valid - check whether the VSI is valid or not 1574f9867df6SAnirudh Venkataramanan * @hw: pointer to the HW struct 15750f9d5027SAnirudh Venkataramanan * @vsi_handle: VSI handle 15760f9d5027SAnirudh Venkataramanan * 15770f9d5027SAnirudh Venkataramanan * check whether the VSI is valid or not 15780f9d5027SAnirudh Venkataramanan */ 15794fb33f31SAnirudh Venkataramanan bool ice_is_vsi_valid(struct ice_hw *hw, u16 vsi_handle) 15800f9d5027SAnirudh Venkataramanan { 15810f9d5027SAnirudh Venkataramanan return vsi_handle < ICE_MAX_VSI && hw->vsi_ctx[vsi_handle]; 15820f9d5027SAnirudh Venkataramanan } 15830f9d5027SAnirudh Venkataramanan 15840f9d5027SAnirudh Venkataramanan /** 1585f9867df6SAnirudh Venkataramanan * ice_get_hw_vsi_num - return the HW VSI number 1586f9867df6SAnirudh Venkataramanan * @hw: pointer to the HW struct 15870f9d5027SAnirudh Venkataramanan * @vsi_handle: VSI handle 15880f9d5027SAnirudh Venkataramanan * 1589f9867df6SAnirudh Venkataramanan * return the HW VSI number 15900f9d5027SAnirudh Venkataramanan * Caution: call this function only if VSI is valid (ice_is_vsi_valid) 15910f9d5027SAnirudh Venkataramanan */ 15924fb33f31SAnirudh Venkataramanan u16 ice_get_hw_vsi_num(struct ice_hw *hw, u16 vsi_handle) 15930f9d5027SAnirudh Venkataramanan { 15940f9d5027SAnirudh Venkataramanan return hw->vsi_ctx[vsi_handle]->vsi_num; 15950f9d5027SAnirudh Venkataramanan } 15960f9d5027SAnirudh Venkataramanan 15970f9d5027SAnirudh Venkataramanan /** 15980f9d5027SAnirudh Venkataramanan * ice_get_vsi_ctx - return the VSI context entry for a given VSI handle 1599f9867df6SAnirudh Venkataramanan * @hw: pointer to the HW struct 16000f9d5027SAnirudh Venkataramanan * @vsi_handle: VSI handle 16010f9d5027SAnirudh Venkataramanan * 16020f9d5027SAnirudh Venkataramanan * return the VSI context entry for a given VSI handle 16030f9d5027SAnirudh Venkataramanan */ 16044fb33f31SAnirudh Venkataramanan struct ice_vsi_ctx *ice_get_vsi_ctx(struct ice_hw *hw, u16 vsi_handle) 16050f9d5027SAnirudh Venkataramanan { 16060f9d5027SAnirudh Venkataramanan return (vsi_handle >= ICE_MAX_VSI) ? NULL : hw->vsi_ctx[vsi_handle]; 16070f9d5027SAnirudh Venkataramanan } 16080f9d5027SAnirudh Venkataramanan 16090f9d5027SAnirudh Venkataramanan /** 16100f9d5027SAnirudh Venkataramanan * ice_save_vsi_ctx - save the VSI context for a given VSI handle 1611f9867df6SAnirudh Venkataramanan * @hw: pointer to the HW struct 16120f9d5027SAnirudh Venkataramanan * @vsi_handle: VSI handle 16130f9d5027SAnirudh Venkataramanan * @vsi: VSI context pointer 16140f9d5027SAnirudh Venkataramanan * 16150f9d5027SAnirudh Venkataramanan * save the VSI context entry for a given VSI handle 16160f9d5027SAnirudh Venkataramanan */ 1617c8b7abddSBruce Allan static void 1618c8b7abddSBruce Allan ice_save_vsi_ctx(struct ice_hw *hw, u16 vsi_handle, struct ice_vsi_ctx *vsi) 16190f9d5027SAnirudh Venkataramanan { 16200f9d5027SAnirudh Venkataramanan hw->vsi_ctx[vsi_handle] = vsi; 16210f9d5027SAnirudh Venkataramanan } 16220f9d5027SAnirudh Venkataramanan 16230f9d5027SAnirudh Venkataramanan /** 1624bb87ee0eSAnirudh Venkataramanan * ice_clear_vsi_q_ctx - clear VSI queue contexts for all TCs 1625bb87ee0eSAnirudh Venkataramanan * @hw: pointer to the HW struct 1626bb87ee0eSAnirudh Venkataramanan * @vsi_handle: VSI handle 1627bb87ee0eSAnirudh Venkataramanan */ 1628bb87ee0eSAnirudh Venkataramanan static void ice_clear_vsi_q_ctx(struct ice_hw *hw, u16 vsi_handle) 1629bb87ee0eSAnirudh Venkataramanan { 1630ad667d62SPrzemek Kitszel struct ice_vsi_ctx *vsi = ice_get_vsi_ctx(hw, vsi_handle); 1631bb87ee0eSAnirudh Venkataramanan u8 i; 1632bb87ee0eSAnirudh Venkataramanan 1633bb87ee0eSAnirudh Venkataramanan if (!vsi) 1634bb87ee0eSAnirudh Venkataramanan return; 1635bb87ee0eSAnirudh Venkataramanan ice_for_each_traffic_class(i) { 1636bb87ee0eSAnirudh Venkataramanan devm_kfree(ice_hw_to_dev(hw), vsi->lan_q_ctx[i]); 1637bb87ee0eSAnirudh Venkataramanan vsi->lan_q_ctx[i] = NULL; 1638348048e7SDave Ertman devm_kfree(ice_hw_to_dev(hw), vsi->rdma_q_ctx[i]); 1639348048e7SDave Ertman vsi->rdma_q_ctx[i] = NULL; 1640348048e7SDave Ertman } 1641bb87ee0eSAnirudh Venkataramanan } 1642bb87ee0eSAnirudh Venkataramanan 1643bb87ee0eSAnirudh Venkataramanan /** 16440f9d5027SAnirudh Venkataramanan * ice_clear_vsi_ctx - clear the VSI context entry 1645f9867df6SAnirudh Venkataramanan * @hw: pointer to the HW struct 16460f9d5027SAnirudh Venkataramanan * @vsi_handle: VSI handle 16470f9d5027SAnirudh Venkataramanan * 16480f9d5027SAnirudh Venkataramanan * clear the VSI context entry 16490f9d5027SAnirudh Venkataramanan */ 16500f9d5027SAnirudh Venkataramanan static void ice_clear_vsi_ctx(struct ice_hw *hw, u16 vsi_handle) 16510f9d5027SAnirudh Venkataramanan { 16520f9d5027SAnirudh Venkataramanan struct ice_vsi_ctx *vsi; 16530f9d5027SAnirudh Venkataramanan 16540f9d5027SAnirudh Venkataramanan vsi = ice_get_vsi_ctx(hw, vsi_handle); 16550f9d5027SAnirudh Venkataramanan if (vsi) { 1656bb87ee0eSAnirudh Venkataramanan ice_clear_vsi_q_ctx(hw, vsi_handle); 16570f9d5027SAnirudh Venkataramanan devm_kfree(ice_hw_to_dev(hw), vsi); 16580f9d5027SAnirudh Venkataramanan hw->vsi_ctx[vsi_handle] = NULL; 16590f9d5027SAnirudh Venkataramanan } 16600f9d5027SAnirudh Venkataramanan } 16610f9d5027SAnirudh Venkataramanan 16620f9d5027SAnirudh Venkataramanan /** 166333e055fcSVictor Raj * ice_clear_all_vsi_ctx - clear all the VSI context entries 1664f9867df6SAnirudh Venkataramanan * @hw: pointer to the HW struct 166533e055fcSVictor Raj */ 166633e055fcSVictor Raj void ice_clear_all_vsi_ctx(struct ice_hw *hw) 166733e055fcSVictor Raj { 166833e055fcSVictor Raj u16 i; 166933e055fcSVictor Raj 167033e055fcSVictor Raj for (i = 0; i < ICE_MAX_VSI; i++) 167133e055fcSVictor Raj ice_clear_vsi_ctx(hw, i); 167233e055fcSVictor Raj } 167333e055fcSVictor Raj 167433e055fcSVictor Raj /** 16750f9d5027SAnirudh Venkataramanan * ice_add_vsi - add VSI context to the hardware and VSI handle list 1676f9867df6SAnirudh Venkataramanan * @hw: pointer to the HW struct 16770f9d5027SAnirudh Venkataramanan * @vsi_handle: unique VSI handle provided by drivers 16780f9d5027SAnirudh Venkataramanan * @vsi_ctx: pointer to a VSI context struct 16790f9d5027SAnirudh Venkataramanan * @cd: pointer to command details structure or NULL 16800f9d5027SAnirudh Venkataramanan * 16810f9d5027SAnirudh Venkataramanan * Add a VSI context to the hardware also add it into the VSI handle list. 16820f9d5027SAnirudh Venkataramanan * If this function gets called after reset for existing VSIs then update 16830f9d5027SAnirudh Venkataramanan * with the new HW VSI number in the corresponding VSI handle list entry. 16840f9d5027SAnirudh Venkataramanan */ 16855e24d598STony Nguyen int 16860f9d5027SAnirudh Venkataramanan ice_add_vsi(struct ice_hw *hw, u16 vsi_handle, struct ice_vsi_ctx *vsi_ctx, 16870f9d5027SAnirudh Venkataramanan struct ice_sq_cd *cd) 16880f9d5027SAnirudh Venkataramanan { 16890f9d5027SAnirudh Venkataramanan struct ice_vsi_ctx *tmp_vsi_ctx; 16905e24d598STony Nguyen int status; 16910f9d5027SAnirudh Venkataramanan 16920f9d5027SAnirudh Venkataramanan if (vsi_handle >= ICE_MAX_VSI) 1693d54699e2STony Nguyen return -EINVAL; 16940f9d5027SAnirudh Venkataramanan status = ice_aq_add_vsi(hw, vsi_ctx, cd); 16950f9d5027SAnirudh Venkataramanan if (status) 16960f9d5027SAnirudh Venkataramanan return status; 16970f9d5027SAnirudh Venkataramanan tmp_vsi_ctx = ice_get_vsi_ctx(hw, vsi_handle); 16980f9d5027SAnirudh Venkataramanan if (!tmp_vsi_ctx) { 1699f9867df6SAnirudh Venkataramanan /* Create a new VSI context */ 17000f9d5027SAnirudh Venkataramanan tmp_vsi_ctx = devm_kzalloc(ice_hw_to_dev(hw), 17010f9d5027SAnirudh Venkataramanan sizeof(*tmp_vsi_ctx), GFP_KERNEL); 17020f9d5027SAnirudh Venkataramanan if (!tmp_vsi_ctx) { 17030f9d5027SAnirudh Venkataramanan ice_aq_free_vsi(hw, vsi_ctx, false, cd); 1704d54699e2STony Nguyen return -ENOMEM; 17050f9d5027SAnirudh Venkataramanan } 17060f9d5027SAnirudh Venkataramanan *tmp_vsi_ctx = *vsi_ctx; 17070f9d5027SAnirudh Venkataramanan ice_save_vsi_ctx(hw, vsi_handle, tmp_vsi_ctx); 17080f9d5027SAnirudh Venkataramanan } else { 17090f9d5027SAnirudh Venkataramanan /* update with new HW VSI num */ 17100f9d5027SAnirudh Venkataramanan tmp_vsi_ctx->vsi_num = vsi_ctx->vsi_num; 17110f9d5027SAnirudh Venkataramanan } 17120f9d5027SAnirudh Venkataramanan 17131b5c19c7SBruce Allan return 0; 17140f9d5027SAnirudh Venkataramanan } 17150f9d5027SAnirudh Venkataramanan 17160f9d5027SAnirudh Venkataramanan /** 17170f9d5027SAnirudh Venkataramanan * ice_free_vsi- free VSI context from hardware and VSI handle list 1718f9867df6SAnirudh Venkataramanan * @hw: pointer to the HW struct 17190f9d5027SAnirudh Venkataramanan * @vsi_handle: unique VSI handle 17203a858ba3SAnirudh Venkataramanan * @vsi_ctx: pointer to a VSI context struct 17213a858ba3SAnirudh Venkataramanan * @keep_vsi_alloc: keep VSI allocation as part of this PF's resources 17223a858ba3SAnirudh Venkataramanan * @cd: pointer to command details structure or NULL 17233a858ba3SAnirudh Venkataramanan * 17240f9d5027SAnirudh Venkataramanan * Free VSI context info from hardware as well as from VSI handle list 17253a858ba3SAnirudh Venkataramanan */ 17265e24d598STony Nguyen int 17270f9d5027SAnirudh Venkataramanan ice_free_vsi(struct ice_hw *hw, u16 vsi_handle, struct ice_vsi_ctx *vsi_ctx, 17283a858ba3SAnirudh Venkataramanan bool keep_vsi_alloc, struct ice_sq_cd *cd) 17293a858ba3SAnirudh Venkataramanan { 17305e24d598STony Nguyen int status; 17313a858ba3SAnirudh Venkataramanan 17320f9d5027SAnirudh Venkataramanan if (!ice_is_vsi_valid(hw, vsi_handle)) 1733d54699e2STony Nguyen return -EINVAL; 17340f9d5027SAnirudh Venkataramanan vsi_ctx->vsi_num = ice_get_hw_vsi_num(hw, vsi_handle); 17350f9d5027SAnirudh Venkataramanan status = ice_aq_free_vsi(hw, vsi_ctx, keep_vsi_alloc, cd); 17360f9d5027SAnirudh Venkataramanan if (!status) 17370f9d5027SAnirudh Venkataramanan ice_clear_vsi_ctx(hw, vsi_handle); 17383a858ba3SAnirudh Venkataramanan return status; 17393a858ba3SAnirudh Venkataramanan } 17403a858ba3SAnirudh Venkataramanan 17419daf8208SAnirudh Venkataramanan /** 17425726ca0eSAnirudh Venkataramanan * ice_update_vsi 1743f9867df6SAnirudh Venkataramanan * @hw: pointer to the HW struct 17445726ca0eSAnirudh Venkataramanan * @vsi_handle: unique VSI handle 17455726ca0eSAnirudh Venkataramanan * @vsi_ctx: pointer to a VSI context struct 17465726ca0eSAnirudh Venkataramanan * @cd: pointer to command details structure or NULL 17475726ca0eSAnirudh Venkataramanan * 17485726ca0eSAnirudh Venkataramanan * Update VSI context in the hardware 17495726ca0eSAnirudh Venkataramanan */ 17505e24d598STony Nguyen int 17515726ca0eSAnirudh Venkataramanan ice_update_vsi(struct ice_hw *hw, u16 vsi_handle, struct ice_vsi_ctx *vsi_ctx, 17525726ca0eSAnirudh Venkataramanan struct ice_sq_cd *cd) 17535726ca0eSAnirudh Venkataramanan { 17545726ca0eSAnirudh Venkataramanan if (!ice_is_vsi_valid(hw, vsi_handle)) 1755d54699e2STony Nguyen return -EINVAL; 17565726ca0eSAnirudh Venkataramanan vsi_ctx->vsi_num = ice_get_hw_vsi_num(hw, vsi_handle); 17575726ca0eSAnirudh Venkataramanan return ice_aq_update_vsi(hw, vsi_ctx, cd); 17585726ca0eSAnirudh Venkataramanan } 17595726ca0eSAnirudh Venkataramanan 17605726ca0eSAnirudh Venkataramanan /** 1761348048e7SDave Ertman * ice_cfg_rdma_fltr - enable/disable RDMA filtering on VSI 1762348048e7SDave Ertman * @hw: pointer to HW struct 1763348048e7SDave Ertman * @vsi_handle: VSI SW index 1764348048e7SDave Ertman * @enable: boolean for enable/disable 1765348048e7SDave Ertman */ 1766348048e7SDave Ertman int 1767348048e7SDave Ertman ice_cfg_rdma_fltr(struct ice_hw *hw, u16 vsi_handle, bool enable) 1768348048e7SDave Ertman { 1769d94dbdc4SBrett Creeley struct ice_vsi_ctx *ctx, *cached_ctx; 1770d94dbdc4SBrett Creeley int status; 1771348048e7SDave Ertman 1772d94dbdc4SBrett Creeley cached_ctx = ice_get_vsi_ctx(hw, vsi_handle); 1773d94dbdc4SBrett Creeley if (!cached_ctx) 1774d94dbdc4SBrett Creeley return -ENOENT; 1775d94dbdc4SBrett Creeley 1776d94dbdc4SBrett Creeley ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); 1777348048e7SDave Ertman if (!ctx) 1778d94dbdc4SBrett Creeley return -ENOMEM; 1779d94dbdc4SBrett Creeley 1780d94dbdc4SBrett Creeley ctx->info.q_opt_rss = cached_ctx->info.q_opt_rss; 1781d94dbdc4SBrett Creeley ctx->info.q_opt_tc = cached_ctx->info.q_opt_tc; 1782d94dbdc4SBrett Creeley ctx->info.q_opt_flags = cached_ctx->info.q_opt_flags; 1783d94dbdc4SBrett Creeley 1784d94dbdc4SBrett Creeley ctx->info.valid_sections = cpu_to_le16(ICE_AQ_VSI_PROP_Q_OPT_VALID); 1785348048e7SDave Ertman 1786348048e7SDave Ertman if (enable) 1787348048e7SDave Ertman ctx->info.q_opt_flags |= ICE_AQ_VSI_Q_OPT_PE_FLTR_EN; 1788348048e7SDave Ertman else 1789348048e7SDave Ertman ctx->info.q_opt_flags &= ~ICE_AQ_VSI_Q_OPT_PE_FLTR_EN; 1790348048e7SDave Ertman 1791d94dbdc4SBrett Creeley status = ice_update_vsi(hw, vsi_handle, ctx, NULL); 1792d94dbdc4SBrett Creeley if (!status) { 1793d94dbdc4SBrett Creeley cached_ctx->info.q_opt_flags = ctx->info.q_opt_flags; 1794d94dbdc4SBrett Creeley cached_ctx->info.valid_sections |= ctx->info.valid_sections; 1795d94dbdc4SBrett Creeley } 1796d94dbdc4SBrett Creeley 1797d94dbdc4SBrett Creeley kfree(ctx); 1798d94dbdc4SBrett Creeley return status; 1799348048e7SDave Ertman } 1800348048e7SDave Ertman 1801348048e7SDave Ertman /** 18029daf8208SAnirudh Venkataramanan * ice_aq_alloc_free_vsi_list 1803f9867df6SAnirudh Venkataramanan * @hw: pointer to the HW struct 1804f9867df6SAnirudh Venkataramanan * @vsi_list_id: VSI list ID returned or used for lookup 18059daf8208SAnirudh Venkataramanan * @lkup_type: switch rule filter lookup type 18069daf8208SAnirudh Venkataramanan * @opc: switch rules population command type - pass in the command opcode 18079daf8208SAnirudh Venkataramanan * 18089daf8208SAnirudh Venkataramanan * allocates or free a VSI list resource 18099daf8208SAnirudh Venkataramanan */ 18105e24d598STony Nguyen static int 18119daf8208SAnirudh Venkataramanan ice_aq_alloc_free_vsi_list(struct ice_hw *hw, u16 *vsi_list_id, 18129daf8208SAnirudh Venkataramanan enum ice_sw_lkup_type lkup_type, 18139daf8208SAnirudh Venkataramanan enum ice_adminq_opc opc) 18149daf8208SAnirudh Venkataramanan { 18159daf8208SAnirudh Venkataramanan struct ice_aqc_alloc_free_res_elem *sw_buf; 18169daf8208SAnirudh Venkataramanan struct ice_aqc_res_elem *vsi_ele; 18179daf8208SAnirudh Venkataramanan u16 buf_len; 18185518ac2aSTony Nguyen int status; 18199daf8208SAnirudh Venkataramanan 182066486d89SBruce Allan buf_len = struct_size(sw_buf, elem, 1); 18219daf8208SAnirudh Venkataramanan sw_buf = devm_kzalloc(ice_hw_to_dev(hw), buf_len, GFP_KERNEL); 18229daf8208SAnirudh Venkataramanan if (!sw_buf) 1823d54699e2STony Nguyen return -ENOMEM; 18249daf8208SAnirudh Venkataramanan sw_buf->num_elems = cpu_to_le16(1); 18259daf8208SAnirudh Venkataramanan 18269daf8208SAnirudh Venkataramanan if (lkup_type == ICE_SW_LKUP_MAC || 18279daf8208SAnirudh Venkataramanan lkup_type == ICE_SW_LKUP_MAC_VLAN || 18289daf8208SAnirudh Venkataramanan lkup_type == ICE_SW_LKUP_ETHERTYPE || 18299daf8208SAnirudh Venkataramanan lkup_type == ICE_SW_LKUP_ETHERTYPE_MAC || 18309daf8208SAnirudh Venkataramanan lkup_type == ICE_SW_LKUP_PROMISC || 1831d7393425SMichal Wilczynski lkup_type == ICE_SW_LKUP_PROMISC_VLAN || 1832d7393425SMichal Wilczynski lkup_type == ICE_SW_LKUP_DFLT) { 18339daf8208SAnirudh Venkataramanan sw_buf->res_type = cpu_to_le16(ICE_AQC_RES_TYPE_VSI_LIST_REP); 18349daf8208SAnirudh Venkataramanan } else if (lkup_type == ICE_SW_LKUP_VLAN) { 183523ccae5cSDave Ertman if (opc == ice_aqc_opc_alloc_res) 183623ccae5cSDave Ertman sw_buf->res_type = 183723ccae5cSDave Ertman cpu_to_le16(ICE_AQC_RES_TYPE_VSI_LIST_PRUNE | 183823ccae5cSDave Ertman ICE_AQC_RES_TYPE_FLAG_SHARED); 183923ccae5cSDave Ertman else 18409daf8208SAnirudh Venkataramanan sw_buf->res_type = 18419daf8208SAnirudh Venkataramanan cpu_to_le16(ICE_AQC_RES_TYPE_VSI_LIST_PRUNE); 18429daf8208SAnirudh Venkataramanan } else { 1843d54699e2STony Nguyen status = -EINVAL; 18449daf8208SAnirudh Venkataramanan goto ice_aq_alloc_free_vsi_list_exit; 18459daf8208SAnirudh Venkataramanan } 18469daf8208SAnirudh Venkataramanan 18479daf8208SAnirudh Venkataramanan if (opc == ice_aqc_opc_free_res) 18489daf8208SAnirudh Venkataramanan sw_buf->elem[0].e.sw_resp = cpu_to_le16(*vsi_list_id); 18499daf8208SAnirudh Venkataramanan 1850*52da2fb2SPrzemek Kitszel status = ice_aq_alloc_free_res(hw, sw_buf, buf_len, opc); 18519daf8208SAnirudh Venkataramanan if (status) 18529daf8208SAnirudh Venkataramanan goto ice_aq_alloc_free_vsi_list_exit; 18539daf8208SAnirudh Venkataramanan 18549daf8208SAnirudh Venkataramanan if (opc == ice_aqc_opc_alloc_res) { 18559daf8208SAnirudh Venkataramanan vsi_ele = &sw_buf->elem[0]; 18569daf8208SAnirudh Venkataramanan *vsi_list_id = le16_to_cpu(vsi_ele->e.sw_resp); 18579daf8208SAnirudh Venkataramanan } 18589daf8208SAnirudh Venkataramanan 18599daf8208SAnirudh Venkataramanan ice_aq_alloc_free_vsi_list_exit: 18609daf8208SAnirudh Venkataramanan devm_kfree(ice_hw_to_dev(hw), sw_buf); 18619daf8208SAnirudh Venkataramanan return status; 18629daf8208SAnirudh Venkataramanan } 18639daf8208SAnirudh Venkataramanan 18649daf8208SAnirudh Venkataramanan /** 18659daf8208SAnirudh Venkataramanan * ice_aq_sw_rules - add/update/remove switch rules 1866f9867df6SAnirudh Venkataramanan * @hw: pointer to the HW struct 18679daf8208SAnirudh Venkataramanan * @rule_list: pointer to switch rule population list 18689daf8208SAnirudh Venkataramanan * @rule_list_sz: total size of the rule list in bytes 18699daf8208SAnirudh Venkataramanan * @num_rules: number of switch rules in the rule_list 18709daf8208SAnirudh Venkataramanan * @opc: switch rules population command type - pass in the command opcode 18719daf8208SAnirudh Venkataramanan * @cd: pointer to command details structure or NULL 18729daf8208SAnirudh Venkataramanan * 18739daf8208SAnirudh Venkataramanan * Add(0x02a0)/Update(0x02a1)/Remove(0x02a2) switch rules commands to firmware 18749daf8208SAnirudh Venkataramanan */ 18755e24d598STony Nguyen int 18769daf8208SAnirudh Venkataramanan ice_aq_sw_rules(struct ice_hw *hw, void *rule_list, u16 rule_list_sz, 18779daf8208SAnirudh Venkataramanan u8 num_rules, enum ice_adminq_opc opc, struct ice_sq_cd *cd) 18789daf8208SAnirudh Venkataramanan { 18799daf8208SAnirudh Venkataramanan struct ice_aq_desc desc; 18805e24d598STony Nguyen int status; 18819daf8208SAnirudh Venkataramanan 18829daf8208SAnirudh Venkataramanan if (opc != ice_aqc_opc_add_sw_rules && 18839daf8208SAnirudh Venkataramanan opc != ice_aqc_opc_update_sw_rules && 18849daf8208SAnirudh Venkataramanan opc != ice_aqc_opc_remove_sw_rules) 1885d54699e2STony Nguyen return -EINVAL; 18869daf8208SAnirudh Venkataramanan 18879daf8208SAnirudh Venkataramanan ice_fill_dflt_direct_cmd_desc(&desc, opc); 18889daf8208SAnirudh Venkataramanan 18899daf8208SAnirudh Venkataramanan desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD); 18909daf8208SAnirudh Venkataramanan desc.params.sw_rules.num_rules_fltr_entry_index = 18919daf8208SAnirudh Venkataramanan cpu_to_le16(num_rules); 1892ca1fdb88SKiran Patil status = ice_aq_send_cmd(hw, &desc, rule_list, rule_list_sz, cd); 1893ca1fdb88SKiran Patil if (opc != ice_aqc_opc_add_sw_rules && 1894ca1fdb88SKiran Patil hw->adminq.sq_last_status == ICE_AQ_RC_ENOENT) 1895d54699e2STony Nguyen status = -ENOENT; 1896ca1fdb88SKiran Patil 1897ca1fdb88SKiran Patil return status; 18989daf8208SAnirudh Venkataramanan } 18999daf8208SAnirudh Venkataramanan 19007715ec32SGrishma Kotecha /** 19017715ec32SGrishma Kotecha * ice_aq_add_recipe - add switch recipe 19027715ec32SGrishma Kotecha * @hw: pointer to the HW struct 19037715ec32SGrishma Kotecha * @s_recipe_list: pointer to switch rule population list 19047715ec32SGrishma Kotecha * @num_recipes: number of switch recipes in the list 19057715ec32SGrishma Kotecha * @cd: pointer to command details structure or NULL 19067715ec32SGrishma Kotecha * 19077715ec32SGrishma Kotecha * Add(0x0290) 19087715ec32SGrishma Kotecha */ 190923ccae5cSDave Ertman int 19107715ec32SGrishma Kotecha ice_aq_add_recipe(struct ice_hw *hw, 19117715ec32SGrishma Kotecha struct ice_aqc_recipe_data_elem *s_recipe_list, 19127715ec32SGrishma Kotecha u16 num_recipes, struct ice_sq_cd *cd) 19137715ec32SGrishma Kotecha { 19147715ec32SGrishma Kotecha struct ice_aqc_add_get_recipe *cmd; 19157715ec32SGrishma Kotecha struct ice_aq_desc desc; 19167715ec32SGrishma Kotecha u16 buf_size; 19177715ec32SGrishma Kotecha 19187715ec32SGrishma Kotecha cmd = &desc.params.add_get_recipe; 19197715ec32SGrishma Kotecha ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_add_recipe); 19207715ec32SGrishma Kotecha 19217715ec32SGrishma Kotecha cmd->num_sub_recipes = cpu_to_le16(num_recipes); 19227715ec32SGrishma Kotecha desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD); 19237715ec32SGrishma Kotecha 19247715ec32SGrishma Kotecha buf_size = num_recipes * sizeof(*s_recipe_list); 19257715ec32SGrishma Kotecha 19267715ec32SGrishma Kotecha return ice_aq_send_cmd(hw, &desc, s_recipe_list, buf_size, cd); 19277715ec32SGrishma Kotecha } 19287715ec32SGrishma Kotecha 19297715ec32SGrishma Kotecha /** 19307715ec32SGrishma Kotecha * ice_aq_get_recipe - get switch recipe 19317715ec32SGrishma Kotecha * @hw: pointer to the HW struct 19327715ec32SGrishma Kotecha * @s_recipe_list: pointer to switch rule population list 19337715ec32SGrishma Kotecha * @num_recipes: pointer to the number of recipes (input and output) 19347715ec32SGrishma Kotecha * @recipe_root: root recipe number of recipe(s) to retrieve 19357715ec32SGrishma Kotecha * @cd: pointer to command details structure or NULL 19367715ec32SGrishma Kotecha * 19377715ec32SGrishma Kotecha * Get(0x0292) 19387715ec32SGrishma Kotecha * 19397715ec32SGrishma Kotecha * On input, *num_recipes should equal the number of entries in s_recipe_list. 19407715ec32SGrishma Kotecha * On output, *num_recipes will equal the number of entries returned in 19417715ec32SGrishma Kotecha * s_recipe_list. 19427715ec32SGrishma Kotecha * 19437715ec32SGrishma Kotecha * The caller must supply enough space in s_recipe_list to hold all possible 19447715ec32SGrishma Kotecha * recipes and *num_recipes must equal ICE_MAX_NUM_RECIPES. 19457715ec32SGrishma Kotecha */ 194623ccae5cSDave Ertman int 19477715ec32SGrishma Kotecha ice_aq_get_recipe(struct ice_hw *hw, 19487715ec32SGrishma Kotecha struct ice_aqc_recipe_data_elem *s_recipe_list, 19497715ec32SGrishma Kotecha u16 *num_recipes, u16 recipe_root, struct ice_sq_cd *cd) 19507715ec32SGrishma Kotecha { 19517715ec32SGrishma Kotecha struct ice_aqc_add_get_recipe *cmd; 19527715ec32SGrishma Kotecha struct ice_aq_desc desc; 19537715ec32SGrishma Kotecha u16 buf_size; 19545518ac2aSTony Nguyen int status; 19557715ec32SGrishma Kotecha 19567715ec32SGrishma Kotecha if (*num_recipes != ICE_MAX_NUM_RECIPES) 1957d54699e2STony Nguyen return -EINVAL; 19587715ec32SGrishma Kotecha 19597715ec32SGrishma Kotecha cmd = &desc.params.add_get_recipe; 19607715ec32SGrishma Kotecha ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_recipe); 19617715ec32SGrishma Kotecha 19627715ec32SGrishma Kotecha cmd->return_index = cpu_to_le16(recipe_root); 19637715ec32SGrishma Kotecha cmd->num_sub_recipes = 0; 19647715ec32SGrishma Kotecha 19657715ec32SGrishma Kotecha buf_size = *num_recipes * sizeof(*s_recipe_list); 19667715ec32SGrishma Kotecha 19677715ec32SGrishma Kotecha status = ice_aq_send_cmd(hw, &desc, s_recipe_list, buf_size, cd); 19687715ec32SGrishma Kotecha *num_recipes = le16_to_cpu(cmd->num_sub_recipes); 19697715ec32SGrishma Kotecha 19707715ec32SGrishma Kotecha return status; 19717715ec32SGrishma Kotecha } 19727715ec32SGrishma Kotecha 19737715ec32SGrishma Kotecha /** 1974a1ffafb0SBrett Creeley * ice_update_recipe_lkup_idx - update a default recipe based on the lkup_idx 1975a1ffafb0SBrett Creeley * @hw: pointer to the HW struct 1976a1ffafb0SBrett Creeley * @params: parameters used to update the default recipe 1977a1ffafb0SBrett Creeley * 1978a1ffafb0SBrett Creeley * This function only supports updating default recipes and it only supports 1979a1ffafb0SBrett Creeley * updating a single recipe based on the lkup_idx at a time. 1980a1ffafb0SBrett Creeley * 1981a1ffafb0SBrett Creeley * This is done as a read-modify-write operation. First, get the current recipe 1982a1ffafb0SBrett Creeley * contents based on the recipe's ID. Then modify the field vector index and 1983a1ffafb0SBrett Creeley * mask if it's valid at the lkup_idx. Finally, use the add recipe AQ to update 1984a1ffafb0SBrett Creeley * the pre-existing recipe with the modifications. 1985a1ffafb0SBrett Creeley */ 1986a1ffafb0SBrett Creeley int 1987a1ffafb0SBrett Creeley ice_update_recipe_lkup_idx(struct ice_hw *hw, 1988a1ffafb0SBrett Creeley struct ice_update_recipe_lkup_idx_params *params) 1989a1ffafb0SBrett Creeley { 1990a1ffafb0SBrett Creeley struct ice_aqc_recipe_data_elem *rcp_list; 1991a1ffafb0SBrett Creeley u16 num_recps = ICE_MAX_NUM_RECIPES; 1992a1ffafb0SBrett Creeley int status; 1993a1ffafb0SBrett Creeley 1994a1ffafb0SBrett Creeley rcp_list = kcalloc(num_recps, sizeof(*rcp_list), GFP_KERNEL); 1995a1ffafb0SBrett Creeley if (!rcp_list) 1996a1ffafb0SBrett Creeley return -ENOMEM; 1997a1ffafb0SBrett Creeley 1998a1ffafb0SBrett Creeley /* read current recipe list from firmware */ 1999a1ffafb0SBrett Creeley rcp_list->recipe_indx = params->rid; 2000a1ffafb0SBrett Creeley status = ice_aq_get_recipe(hw, rcp_list, &num_recps, params->rid, NULL); 2001a1ffafb0SBrett Creeley if (status) { 2002a1ffafb0SBrett Creeley ice_debug(hw, ICE_DBG_SW, "Failed to get recipe %d, status %d\n", 2003a1ffafb0SBrett Creeley params->rid, status); 2004a1ffafb0SBrett Creeley goto error_out; 2005a1ffafb0SBrett Creeley } 2006a1ffafb0SBrett Creeley 2007a1ffafb0SBrett Creeley /* only modify existing recipe's lkup_idx and mask if valid, while 2008a1ffafb0SBrett Creeley * leaving all other fields the same, then update the recipe firmware 2009a1ffafb0SBrett Creeley */ 2010a1ffafb0SBrett Creeley rcp_list->content.lkup_indx[params->lkup_idx] = params->fv_idx; 2011a1ffafb0SBrett Creeley if (params->mask_valid) 2012a1ffafb0SBrett Creeley rcp_list->content.mask[params->lkup_idx] = 2013a1ffafb0SBrett Creeley cpu_to_le16(params->mask); 2014a1ffafb0SBrett Creeley 2015a1ffafb0SBrett Creeley if (params->ignore_valid) 2016a1ffafb0SBrett Creeley rcp_list->content.lkup_indx[params->lkup_idx] |= 2017a1ffafb0SBrett Creeley ICE_AQ_RECIPE_LKUP_IGNORE; 2018a1ffafb0SBrett Creeley 2019a1ffafb0SBrett Creeley status = ice_aq_add_recipe(hw, &rcp_list[0], 1, NULL); 2020a1ffafb0SBrett Creeley if (status) 2021a1ffafb0SBrett Creeley 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", 2022a1ffafb0SBrett Creeley params->rid, params->lkup_idx, params->fv_idx, 2023a1ffafb0SBrett Creeley params->mask, params->mask_valid ? "true" : "false", 2024a1ffafb0SBrett Creeley status); 2025a1ffafb0SBrett Creeley 2026a1ffafb0SBrett Creeley error_out: 2027a1ffafb0SBrett Creeley kfree(rcp_list); 2028a1ffafb0SBrett Creeley return status; 2029a1ffafb0SBrett Creeley } 2030a1ffafb0SBrett Creeley 2031a1ffafb0SBrett Creeley /** 20327715ec32SGrishma Kotecha * ice_aq_map_recipe_to_profile - Map recipe to packet profile 20337715ec32SGrishma Kotecha * @hw: pointer to the HW struct 20347715ec32SGrishma Kotecha * @profile_id: package profile ID to associate the recipe with 20357715ec32SGrishma Kotecha * @r_bitmap: Recipe bitmap filled in and need to be returned as response 20367715ec32SGrishma Kotecha * @cd: pointer to command details structure or NULL 20377715ec32SGrishma Kotecha * Recipe to profile association (0x0291) 20387715ec32SGrishma Kotecha */ 203923ccae5cSDave Ertman int 20407715ec32SGrishma Kotecha ice_aq_map_recipe_to_profile(struct ice_hw *hw, u32 profile_id, u8 *r_bitmap, 20417715ec32SGrishma Kotecha struct ice_sq_cd *cd) 20427715ec32SGrishma Kotecha { 20437715ec32SGrishma Kotecha struct ice_aqc_recipe_to_profile *cmd; 20447715ec32SGrishma Kotecha struct ice_aq_desc desc; 20457715ec32SGrishma Kotecha 20467715ec32SGrishma Kotecha cmd = &desc.params.recipe_to_profile; 20477715ec32SGrishma Kotecha ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_recipe_to_profile); 20487715ec32SGrishma Kotecha cmd->profile_id = cpu_to_le16(profile_id); 20497715ec32SGrishma Kotecha /* Set the recipe ID bit in the bitmask to let the device know which 20507715ec32SGrishma Kotecha * profile we are associating the recipe to 20517715ec32SGrishma Kotecha */ 20527715ec32SGrishma Kotecha memcpy(cmd->recipe_assoc, r_bitmap, sizeof(cmd->recipe_assoc)); 20537715ec32SGrishma Kotecha 20547715ec32SGrishma Kotecha return ice_aq_send_cmd(hw, &desc, NULL, 0, cd); 20557715ec32SGrishma Kotecha } 20567715ec32SGrishma Kotecha 20577715ec32SGrishma Kotecha /** 20587715ec32SGrishma Kotecha * ice_aq_get_recipe_to_profile - Map recipe to packet profile 20597715ec32SGrishma Kotecha * @hw: pointer to the HW struct 20607715ec32SGrishma Kotecha * @profile_id: package profile ID to associate the recipe with 20617715ec32SGrishma Kotecha * @r_bitmap: Recipe bitmap filled in and need to be returned as response 20627715ec32SGrishma Kotecha * @cd: pointer to command details structure or NULL 20637715ec32SGrishma Kotecha * Associate profile ID with given recipe (0x0293) 20647715ec32SGrishma Kotecha */ 206523ccae5cSDave Ertman int 20667715ec32SGrishma Kotecha ice_aq_get_recipe_to_profile(struct ice_hw *hw, u32 profile_id, u8 *r_bitmap, 20677715ec32SGrishma Kotecha struct ice_sq_cd *cd) 20687715ec32SGrishma Kotecha { 20697715ec32SGrishma Kotecha struct ice_aqc_recipe_to_profile *cmd; 20707715ec32SGrishma Kotecha struct ice_aq_desc desc; 20715e24d598STony Nguyen int status; 20727715ec32SGrishma Kotecha 20737715ec32SGrishma Kotecha cmd = &desc.params.recipe_to_profile; 20747715ec32SGrishma Kotecha ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_recipe_to_profile); 20757715ec32SGrishma Kotecha cmd->profile_id = cpu_to_le16(profile_id); 20767715ec32SGrishma Kotecha 20777715ec32SGrishma Kotecha status = ice_aq_send_cmd(hw, &desc, NULL, 0, cd); 20787715ec32SGrishma Kotecha if (!status) 20797715ec32SGrishma Kotecha memcpy(r_bitmap, cmd->recipe_assoc, sizeof(cmd->recipe_assoc)); 20807715ec32SGrishma Kotecha 20817715ec32SGrishma Kotecha return status; 20827715ec32SGrishma Kotecha } 20837715ec32SGrishma Kotecha 20847715ec32SGrishma Kotecha /** 20857715ec32SGrishma Kotecha * ice_alloc_recipe - add recipe resource 20867715ec32SGrishma Kotecha * @hw: pointer to the hardware structure 20877715ec32SGrishma Kotecha * @rid: recipe ID returned as response to AQ call 20887715ec32SGrishma Kotecha */ 208923ccae5cSDave Ertman int ice_alloc_recipe(struct ice_hw *hw, u16 *rid) 20907715ec32SGrishma Kotecha { 20917715ec32SGrishma Kotecha struct ice_aqc_alloc_free_res_elem *sw_buf; 20927715ec32SGrishma Kotecha u16 buf_len; 20935518ac2aSTony Nguyen int status; 20947715ec32SGrishma Kotecha 20957715ec32SGrishma Kotecha buf_len = struct_size(sw_buf, elem, 1); 20967715ec32SGrishma Kotecha sw_buf = kzalloc(buf_len, GFP_KERNEL); 20977715ec32SGrishma Kotecha if (!sw_buf) 2098d54699e2STony Nguyen return -ENOMEM; 20997715ec32SGrishma Kotecha 21007715ec32SGrishma Kotecha sw_buf->num_elems = cpu_to_le16(1); 21017715ec32SGrishma Kotecha sw_buf->res_type = cpu_to_le16((ICE_AQC_RES_TYPE_RECIPE << 21027715ec32SGrishma Kotecha ICE_AQC_RES_TYPE_S) | 21037715ec32SGrishma Kotecha ICE_AQC_RES_TYPE_FLAG_SHARED); 2104*52da2fb2SPrzemek Kitszel status = ice_aq_alloc_free_res(hw, sw_buf, buf_len, 2105*52da2fb2SPrzemek Kitszel ice_aqc_opc_alloc_res); 21067715ec32SGrishma Kotecha if (!status) 21077715ec32SGrishma Kotecha *rid = le16_to_cpu(sw_buf->elem[0].e.sw_resp); 21087715ec32SGrishma Kotecha kfree(sw_buf); 21097715ec32SGrishma Kotecha 21107715ec32SGrishma Kotecha return status; 21117715ec32SGrishma Kotecha } 21127715ec32SGrishma Kotecha 2113fd2a6b71SDan Nowlin /** 2114fd2a6b71SDan Nowlin * ice_get_recp_to_prof_map - updates recipe to profile mapping 2115fd2a6b71SDan Nowlin * @hw: pointer to hardware structure 2116fd2a6b71SDan Nowlin * 2117fd2a6b71SDan Nowlin * This function is used to populate recipe_to_profile matrix where index to 2118fd2a6b71SDan Nowlin * this array is the recipe ID and the element is the mapping of which profiles 2119fd2a6b71SDan Nowlin * is this recipe mapped to. 2120fd2a6b71SDan Nowlin */ 2121fd2a6b71SDan Nowlin static void ice_get_recp_to_prof_map(struct ice_hw *hw) 2122fd2a6b71SDan Nowlin { 2123fd2a6b71SDan Nowlin DECLARE_BITMAP(r_bitmap, ICE_MAX_NUM_RECIPES); 2124fd2a6b71SDan Nowlin u16 i; 2125fd2a6b71SDan Nowlin 2126fd2a6b71SDan Nowlin for (i = 0; i < hw->switch_info->max_used_prof_index + 1; i++) { 2127fd2a6b71SDan Nowlin u16 j; 2128fd2a6b71SDan Nowlin 2129fd2a6b71SDan Nowlin bitmap_zero(profile_to_recipe[i], ICE_MAX_NUM_RECIPES); 2130fd2a6b71SDan Nowlin bitmap_zero(r_bitmap, ICE_MAX_NUM_RECIPES); 2131fd2a6b71SDan Nowlin if (ice_aq_get_recipe_to_profile(hw, i, (u8 *)r_bitmap, NULL)) 2132fd2a6b71SDan Nowlin continue; 2133fd2a6b71SDan Nowlin bitmap_copy(profile_to_recipe[i], r_bitmap, 2134fd2a6b71SDan Nowlin ICE_MAX_NUM_RECIPES); 2135fd2a6b71SDan Nowlin for_each_set_bit(j, r_bitmap, ICE_MAX_NUM_RECIPES) 2136fd2a6b71SDan Nowlin set_bit(i, recipe_to_profile[j]); 2137fd2a6b71SDan Nowlin } 2138fd2a6b71SDan Nowlin } 2139fd2a6b71SDan Nowlin 2140fd2a6b71SDan Nowlin /** 2141fd2a6b71SDan Nowlin * ice_collect_result_idx - copy result index values 2142fd2a6b71SDan Nowlin * @buf: buffer that contains the result index 2143fd2a6b71SDan Nowlin * @recp: the recipe struct to copy data into 2144fd2a6b71SDan Nowlin */ 2145fd2a6b71SDan Nowlin static void 2146fd2a6b71SDan Nowlin ice_collect_result_idx(struct ice_aqc_recipe_data_elem *buf, 2147fd2a6b71SDan Nowlin struct ice_sw_recipe *recp) 2148fd2a6b71SDan Nowlin { 2149fd2a6b71SDan Nowlin if (buf->content.result_indx & ICE_AQ_RECIPE_RESULT_EN) 2150fd2a6b71SDan Nowlin set_bit(buf->content.result_indx & ~ICE_AQ_RECIPE_RESULT_EN, 2151fd2a6b71SDan Nowlin recp->res_idxs); 2152fd2a6b71SDan Nowlin } 2153fd2a6b71SDan Nowlin 2154fd2a6b71SDan Nowlin /** 2155fd2a6b71SDan Nowlin * ice_get_recp_frm_fw - update SW bookkeeping from FW recipe entries 2156fd2a6b71SDan Nowlin * @hw: pointer to hardware structure 2157fd2a6b71SDan Nowlin * @recps: struct that we need to populate 2158fd2a6b71SDan Nowlin * @rid: recipe ID that we are populating 2159fd2a6b71SDan Nowlin * @refresh_required: true if we should get recipe to profile mapping from FW 2160fd2a6b71SDan Nowlin * 2161fd2a6b71SDan Nowlin * This function is used to populate all the necessary entries into our 2162fd2a6b71SDan Nowlin * bookkeeping so that we have a current list of all the recipes that are 2163fd2a6b71SDan Nowlin * programmed in the firmware. 2164fd2a6b71SDan Nowlin */ 21655e24d598STony Nguyen static int 2166fd2a6b71SDan Nowlin ice_get_recp_frm_fw(struct ice_hw *hw, struct ice_sw_recipe *recps, u8 rid, 2167fd2a6b71SDan Nowlin bool *refresh_required) 2168fd2a6b71SDan Nowlin { 2169fd2a6b71SDan Nowlin DECLARE_BITMAP(result_bm, ICE_MAX_FV_WORDS); 2170fd2a6b71SDan Nowlin struct ice_aqc_recipe_data_elem *tmp; 2171fd2a6b71SDan Nowlin u16 num_recps = ICE_MAX_NUM_RECIPES; 2172fd2a6b71SDan Nowlin struct ice_prot_lkup_ext *lkup_exts; 2173fd2a6b71SDan Nowlin u8 fv_word_idx = 0; 2174fd2a6b71SDan Nowlin u16 sub_recps; 21755518ac2aSTony Nguyen int status; 2176fd2a6b71SDan Nowlin 2177fd2a6b71SDan Nowlin bitmap_zero(result_bm, ICE_MAX_FV_WORDS); 2178fd2a6b71SDan Nowlin 2179fd2a6b71SDan Nowlin /* we need a buffer big enough to accommodate all the recipes */ 2180fd2a6b71SDan Nowlin tmp = kcalloc(ICE_MAX_NUM_RECIPES, sizeof(*tmp), GFP_KERNEL); 2181fd2a6b71SDan Nowlin if (!tmp) 2182d54699e2STony Nguyen return -ENOMEM; 2183fd2a6b71SDan Nowlin 2184fd2a6b71SDan Nowlin tmp[0].recipe_indx = rid; 2185fd2a6b71SDan Nowlin status = ice_aq_get_recipe(hw, tmp, &num_recps, rid, NULL); 2186fd2a6b71SDan Nowlin /* non-zero status meaning recipe doesn't exist */ 2187fd2a6b71SDan Nowlin if (status) 2188fd2a6b71SDan Nowlin goto err_unroll; 2189fd2a6b71SDan Nowlin 2190fd2a6b71SDan Nowlin /* Get recipe to profile map so that we can get the fv from lkups that 2191fd2a6b71SDan Nowlin * we read for a recipe from FW. Since we want to minimize the number of 2192fd2a6b71SDan Nowlin * times we make this FW call, just make one call and cache the copy 2193fd2a6b71SDan Nowlin * until a new recipe is added. This operation is only required the 2194fd2a6b71SDan Nowlin * first time to get the changes from FW. Then to search existing 2195fd2a6b71SDan Nowlin * entries we don't need to update the cache again until another recipe 2196fd2a6b71SDan Nowlin * gets added. 2197fd2a6b71SDan Nowlin */ 2198fd2a6b71SDan Nowlin if (*refresh_required) { 2199fd2a6b71SDan Nowlin ice_get_recp_to_prof_map(hw); 2200fd2a6b71SDan Nowlin *refresh_required = false; 2201fd2a6b71SDan Nowlin } 2202fd2a6b71SDan Nowlin 2203fd2a6b71SDan Nowlin /* Start populating all the entries for recps[rid] based on lkups from 2204fd2a6b71SDan Nowlin * firmware. Note that we are only creating the root recipe in our 2205fd2a6b71SDan Nowlin * database. 2206fd2a6b71SDan Nowlin */ 2207fd2a6b71SDan Nowlin lkup_exts = &recps[rid].lkup_exts; 2208fd2a6b71SDan Nowlin 2209fd2a6b71SDan Nowlin for (sub_recps = 0; sub_recps < num_recps; sub_recps++) { 2210fd2a6b71SDan Nowlin struct ice_aqc_recipe_data_elem root_bufs = tmp[sub_recps]; 2211fd2a6b71SDan Nowlin struct ice_recp_grp_entry *rg_entry; 2212fd2a6b71SDan Nowlin u8 i, prof, idx, prot = 0; 2213fd2a6b71SDan Nowlin bool is_root; 2214fd2a6b71SDan Nowlin u16 off = 0; 2215fd2a6b71SDan Nowlin 2216fd2a6b71SDan Nowlin rg_entry = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*rg_entry), 2217fd2a6b71SDan Nowlin GFP_KERNEL); 2218fd2a6b71SDan Nowlin if (!rg_entry) { 2219d54699e2STony Nguyen status = -ENOMEM; 2220fd2a6b71SDan Nowlin goto err_unroll; 2221fd2a6b71SDan Nowlin } 2222fd2a6b71SDan Nowlin 2223fd2a6b71SDan Nowlin idx = root_bufs.recipe_indx; 2224fd2a6b71SDan Nowlin is_root = root_bufs.content.rid & ICE_AQ_RECIPE_ID_IS_ROOT; 2225fd2a6b71SDan Nowlin 2226fd2a6b71SDan Nowlin /* Mark all result indices in this chain */ 2227fd2a6b71SDan Nowlin if (root_bufs.content.result_indx & ICE_AQ_RECIPE_RESULT_EN) 2228fd2a6b71SDan Nowlin set_bit(root_bufs.content.result_indx & ~ICE_AQ_RECIPE_RESULT_EN, 2229fd2a6b71SDan Nowlin result_bm); 2230fd2a6b71SDan Nowlin 2231fd2a6b71SDan Nowlin /* get the first profile that is associated with rid */ 2232fd2a6b71SDan Nowlin prof = find_first_bit(recipe_to_profile[idx], 2233fd2a6b71SDan Nowlin ICE_MAX_NUM_PROFILES); 2234fd2a6b71SDan Nowlin for (i = 0; i < ICE_NUM_WORDS_RECIPE; i++) { 2235fd2a6b71SDan Nowlin u8 lkup_indx = root_bufs.content.lkup_indx[i + 1]; 2236fd2a6b71SDan Nowlin 2237fd2a6b71SDan Nowlin rg_entry->fv_idx[i] = lkup_indx; 2238fd2a6b71SDan Nowlin rg_entry->fv_mask[i] = 2239fd2a6b71SDan Nowlin le16_to_cpu(root_bufs.content.mask[i + 1]); 2240fd2a6b71SDan Nowlin 2241fd2a6b71SDan Nowlin /* If the recipe is a chained recipe then all its 2242fd2a6b71SDan Nowlin * child recipe's result will have a result index. 2243fd2a6b71SDan Nowlin * To fill fv_words we should not use those result 2244fd2a6b71SDan Nowlin * index, we only need the protocol ids and offsets. 2245fd2a6b71SDan Nowlin * We will skip all the fv_idx which stores result 2246fd2a6b71SDan Nowlin * index in them. We also need to skip any fv_idx which 2247fd2a6b71SDan Nowlin * has ICE_AQ_RECIPE_LKUP_IGNORE or 0 since it isn't a 2248fd2a6b71SDan Nowlin * valid offset value. 2249fd2a6b71SDan Nowlin */ 2250fd2a6b71SDan Nowlin if (test_bit(rg_entry->fv_idx[i], hw->switch_info->prof_res_bm[prof]) || 2251fd2a6b71SDan Nowlin rg_entry->fv_idx[i] & ICE_AQ_RECIPE_LKUP_IGNORE || 2252fd2a6b71SDan Nowlin rg_entry->fv_idx[i] == 0) 2253fd2a6b71SDan Nowlin continue; 2254fd2a6b71SDan Nowlin 2255fd2a6b71SDan Nowlin ice_find_prot_off(hw, ICE_BLK_SW, prof, 2256fd2a6b71SDan Nowlin rg_entry->fv_idx[i], &prot, &off); 2257fd2a6b71SDan Nowlin lkup_exts->fv_words[fv_word_idx].prot_id = prot; 2258fd2a6b71SDan Nowlin lkup_exts->fv_words[fv_word_idx].off = off; 2259fd2a6b71SDan Nowlin lkup_exts->field_mask[fv_word_idx] = 2260fd2a6b71SDan Nowlin rg_entry->fv_mask[i]; 2261fd2a6b71SDan Nowlin fv_word_idx++; 2262fd2a6b71SDan Nowlin } 2263fd2a6b71SDan Nowlin /* populate rg_list with the data from the child entry of this 2264fd2a6b71SDan Nowlin * recipe 2265fd2a6b71SDan Nowlin */ 2266fd2a6b71SDan Nowlin list_add(&rg_entry->l_entry, &recps[rid].rg_list); 2267fd2a6b71SDan Nowlin 2268fd2a6b71SDan Nowlin /* Propagate some data to the recipe database */ 2269fd2a6b71SDan Nowlin recps[idx].is_root = !!is_root; 2270fd2a6b71SDan Nowlin recps[idx].priority = root_bufs.content.act_ctrl_fwd_priority; 2271bccd9bceSMarcin Szycik recps[idx].need_pass_l2 = root_bufs.content.act_ctrl & 2272bccd9bceSMarcin Szycik ICE_AQ_RECIPE_ACT_NEED_PASS_L2; 2273bccd9bceSMarcin Szycik recps[idx].allow_pass_l2 = root_bufs.content.act_ctrl & 2274bccd9bceSMarcin Szycik ICE_AQ_RECIPE_ACT_ALLOW_PASS_L2; 2275fd2a6b71SDan Nowlin bitmap_zero(recps[idx].res_idxs, ICE_MAX_FV_WORDS); 2276fd2a6b71SDan Nowlin if (root_bufs.content.result_indx & ICE_AQ_RECIPE_RESULT_EN) { 2277fd2a6b71SDan Nowlin recps[idx].chain_idx = root_bufs.content.result_indx & 2278fd2a6b71SDan Nowlin ~ICE_AQ_RECIPE_RESULT_EN; 2279fd2a6b71SDan Nowlin set_bit(recps[idx].chain_idx, recps[idx].res_idxs); 2280fd2a6b71SDan Nowlin } else { 2281fd2a6b71SDan Nowlin recps[idx].chain_idx = ICE_INVAL_CHAIN_IND; 2282fd2a6b71SDan Nowlin } 2283fd2a6b71SDan Nowlin 2284fd2a6b71SDan Nowlin if (!is_root) 2285fd2a6b71SDan Nowlin continue; 2286fd2a6b71SDan Nowlin 2287fd2a6b71SDan Nowlin /* Only do the following for root recipes entries */ 2288fd2a6b71SDan Nowlin memcpy(recps[idx].r_bitmap, root_bufs.recipe_bitmap, 2289fd2a6b71SDan Nowlin sizeof(recps[idx].r_bitmap)); 2290fd2a6b71SDan Nowlin recps[idx].root_rid = root_bufs.content.rid & 2291fd2a6b71SDan Nowlin ~ICE_AQ_RECIPE_ID_IS_ROOT; 2292fd2a6b71SDan Nowlin recps[idx].priority = root_bufs.content.act_ctrl_fwd_priority; 2293fd2a6b71SDan Nowlin } 2294fd2a6b71SDan Nowlin 2295fd2a6b71SDan Nowlin /* Complete initialization of the root recipe entry */ 2296fd2a6b71SDan Nowlin lkup_exts->n_val_words = fv_word_idx; 2297fd2a6b71SDan Nowlin recps[rid].big_recp = (num_recps > 1); 2298fd2a6b71SDan Nowlin recps[rid].n_grp_count = (u8)num_recps; 2299fd2a6b71SDan Nowlin recps[rid].root_buf = devm_kmemdup(ice_hw_to_dev(hw), tmp, 2300fd2a6b71SDan Nowlin recps[rid].n_grp_count * sizeof(*recps[rid].root_buf), 2301fd2a6b71SDan Nowlin GFP_KERNEL); 2302c8e51a01SWang Hai if (!recps[rid].root_buf) { 2303d54699e2STony Nguyen status = -ENOMEM; 2304fd2a6b71SDan Nowlin goto err_unroll; 2305c8e51a01SWang Hai } 2306fd2a6b71SDan Nowlin 2307fd2a6b71SDan Nowlin /* Copy result indexes */ 2308fd2a6b71SDan Nowlin bitmap_copy(recps[rid].res_idxs, result_bm, ICE_MAX_FV_WORDS); 2309fd2a6b71SDan Nowlin recps[rid].recp_created = true; 2310fd2a6b71SDan Nowlin 2311fd2a6b71SDan Nowlin err_unroll: 2312fd2a6b71SDan Nowlin kfree(tmp); 2313fd2a6b71SDan Nowlin return status; 2314fd2a6b71SDan Nowlin } 2315fd2a6b71SDan Nowlin 23169c20346bSAnirudh Venkataramanan /* ice_init_port_info - Initialize port_info with switch configuration data 23179c20346bSAnirudh Venkataramanan * @pi: pointer to port_info 23189c20346bSAnirudh Venkataramanan * @vsi_port_num: VSI number or port number 23199c20346bSAnirudh Venkataramanan * @type: Type of switch element (port or VSI) 23209c20346bSAnirudh Venkataramanan * @swid: switch ID of the switch the element is attached to 23219c20346bSAnirudh Venkataramanan * @pf_vf_num: PF or VF number 23229c20346bSAnirudh Venkataramanan * @is_vf: true if the element is a VF, false otherwise 23239c20346bSAnirudh Venkataramanan */ 23249c20346bSAnirudh Venkataramanan static void 23259c20346bSAnirudh Venkataramanan ice_init_port_info(struct ice_port_info *pi, u16 vsi_port_num, u8 type, 23269c20346bSAnirudh Venkataramanan u16 swid, u16 pf_vf_num, bool is_vf) 23279c20346bSAnirudh Venkataramanan { 23289c20346bSAnirudh Venkataramanan switch (type) { 23299c20346bSAnirudh Venkataramanan case ICE_AQC_GET_SW_CONF_RESP_PHYS_PORT: 23309c20346bSAnirudh Venkataramanan pi->lport = (u8)(vsi_port_num & ICE_LPORT_MASK); 23319c20346bSAnirudh Venkataramanan pi->sw_id = swid; 23329c20346bSAnirudh Venkataramanan pi->pf_vf_num = pf_vf_num; 23339c20346bSAnirudh Venkataramanan pi->is_vf = is_vf; 23349c20346bSAnirudh Venkataramanan break; 23359c20346bSAnirudh Venkataramanan default: 23369228d8b2SJacob Keller ice_debug(pi->hw, ICE_DBG_SW, "incorrect VSI/port type received\n"); 23379c20346bSAnirudh Venkataramanan break; 23389c20346bSAnirudh Venkataramanan } 23399c20346bSAnirudh Venkataramanan } 23409c20346bSAnirudh Venkataramanan 23419c20346bSAnirudh Venkataramanan /* ice_get_initial_sw_cfg - Get initial port and default VSI data 23429c20346bSAnirudh Venkataramanan * @hw: pointer to the hardware structure 23439c20346bSAnirudh Venkataramanan */ 23445e24d598STony Nguyen int ice_get_initial_sw_cfg(struct ice_hw *hw) 23459c20346bSAnirudh Venkataramanan { 2346b3c38904SBruce Allan struct ice_aqc_get_sw_cfg_resp_elem *rbuf; 23479c20346bSAnirudh Venkataramanan u16 req_desc = 0; 23489c20346bSAnirudh Venkataramanan u16 num_elems; 23495518ac2aSTony Nguyen int status; 23509c20346bSAnirudh Venkataramanan u16 i; 23519c20346bSAnirudh Venkataramanan 23521b9e740dSChristophe JAILLET rbuf = kzalloc(ICE_SW_CFG_MAX_BUF_LEN, GFP_KERNEL); 23539c20346bSAnirudh Venkataramanan if (!rbuf) 2354d54699e2STony Nguyen return -ENOMEM; 23559c20346bSAnirudh Venkataramanan 23569c20346bSAnirudh Venkataramanan /* Multiple calls to ice_aq_get_sw_cfg may be required 23579c20346bSAnirudh Venkataramanan * to get all the switch configuration information. The need 23589c20346bSAnirudh Venkataramanan * for additional calls is indicated by ice_aq_get_sw_cfg 23599c20346bSAnirudh Venkataramanan * writing a non-zero value in req_desc 23609c20346bSAnirudh Venkataramanan */ 23619c20346bSAnirudh Venkataramanan do { 2362b3c38904SBruce Allan struct ice_aqc_get_sw_cfg_resp_elem *ele; 2363b3c38904SBruce Allan 23649c20346bSAnirudh Venkataramanan status = ice_aq_get_sw_cfg(hw, rbuf, ICE_SW_CFG_MAX_BUF_LEN, 23659c20346bSAnirudh Venkataramanan &req_desc, &num_elems, NULL); 23669c20346bSAnirudh Venkataramanan 23679c20346bSAnirudh Venkataramanan if (status) 23689c20346bSAnirudh Venkataramanan break; 23699c20346bSAnirudh Venkataramanan 2370b3c38904SBruce Allan for (i = 0, ele = rbuf; i < num_elems; i++, ele++) { 23719c20346bSAnirudh Venkataramanan u16 pf_vf_num, swid, vsi_port_num; 23729c20346bSAnirudh Venkataramanan bool is_vf = false; 23736dae8aa0SBruce Allan u8 res_type; 23749c20346bSAnirudh Venkataramanan 23759c20346bSAnirudh Venkataramanan vsi_port_num = le16_to_cpu(ele->vsi_port_num) & 23769c20346bSAnirudh Venkataramanan ICE_AQC_GET_SW_CONF_RESP_VSI_PORT_NUM_M; 23779c20346bSAnirudh Venkataramanan 23789c20346bSAnirudh Venkataramanan pf_vf_num = le16_to_cpu(ele->pf_vf_num) & 23799c20346bSAnirudh Venkataramanan ICE_AQC_GET_SW_CONF_RESP_FUNC_NUM_M; 23809c20346bSAnirudh Venkataramanan 23819c20346bSAnirudh Venkataramanan swid = le16_to_cpu(ele->swid); 23829c20346bSAnirudh Venkataramanan 23839c20346bSAnirudh Venkataramanan if (le16_to_cpu(ele->pf_vf_num) & 23849c20346bSAnirudh Venkataramanan ICE_AQC_GET_SW_CONF_RESP_IS_VF) 23859c20346bSAnirudh Venkataramanan is_vf = true; 23869c20346bSAnirudh Venkataramanan 238788865fc4SKarol Kolacinski res_type = (u8)(le16_to_cpu(ele->vsi_port_num) >> 238888865fc4SKarol Kolacinski ICE_AQC_GET_SW_CONF_RESP_TYPE_S); 23899c20346bSAnirudh Venkataramanan 23906dae8aa0SBruce Allan if (res_type == ICE_AQC_GET_SW_CONF_RESP_VSI) { 23919c20346bSAnirudh Venkataramanan /* FW VSI is not needed. Just continue. */ 23929c20346bSAnirudh Venkataramanan continue; 23939c20346bSAnirudh Venkataramanan } 23949c20346bSAnirudh Venkataramanan 23959c20346bSAnirudh Venkataramanan ice_init_port_info(hw->port_info, vsi_port_num, 23966dae8aa0SBruce Allan res_type, swid, pf_vf_num, is_vf); 23979c20346bSAnirudh Venkataramanan } 23989c20346bSAnirudh Venkataramanan } while (req_desc && !status); 23999c20346bSAnirudh Venkataramanan 24001b9e740dSChristophe JAILLET kfree(rbuf); 24019c20346bSAnirudh Venkataramanan return status; 24029c20346bSAnirudh Venkataramanan } 24039daf8208SAnirudh Venkataramanan 24049daf8208SAnirudh Venkataramanan /** 24059daf8208SAnirudh Venkataramanan * ice_fill_sw_info - Helper function to populate lb_en and lan_en 24069daf8208SAnirudh Venkataramanan * @hw: pointer to the hardware structure 24076a7e6993SYashaswini Raghuram Prathivadi Bhayankaram * @fi: filter info structure to fill/update 24089daf8208SAnirudh Venkataramanan * 24099daf8208SAnirudh Venkataramanan * This helper function populates the lb_en and lan_en elements of the provided 24109daf8208SAnirudh Venkataramanan * ice_fltr_info struct using the switch's type and characteristics of the 24119daf8208SAnirudh Venkataramanan * switch rule being configured. 24129daf8208SAnirudh Venkataramanan */ 24136a7e6993SYashaswini Raghuram Prathivadi Bhayankaram static void ice_fill_sw_info(struct ice_hw *hw, struct ice_fltr_info *fi) 24149daf8208SAnirudh Venkataramanan { 24156a7e6993SYashaswini Raghuram Prathivadi Bhayankaram fi->lb_en = false; 24166a7e6993SYashaswini Raghuram Prathivadi Bhayankaram fi->lan_en = false; 24176a7e6993SYashaswini Raghuram Prathivadi Bhayankaram if ((fi->flag & ICE_FLTR_TX) && 24186a7e6993SYashaswini Raghuram Prathivadi Bhayankaram (fi->fltr_act == ICE_FWD_TO_VSI || 24196a7e6993SYashaswini Raghuram Prathivadi Bhayankaram fi->fltr_act == ICE_FWD_TO_VSI_LIST || 24206a7e6993SYashaswini Raghuram Prathivadi Bhayankaram fi->fltr_act == ICE_FWD_TO_Q || 24216a7e6993SYashaswini Raghuram Prathivadi Bhayankaram fi->fltr_act == ICE_FWD_TO_QGRP)) { 2422b58dafbcSChristopher N Bednarz /* Setting LB for prune actions will result in replicated 2423b58dafbcSChristopher N Bednarz * packets to the internal switch that will be dropped. 2424b58dafbcSChristopher N Bednarz */ 2425b58dafbcSChristopher N Bednarz if (fi->lkup_type != ICE_SW_LKUP_VLAN) 24266a7e6993SYashaswini Raghuram Prathivadi Bhayankaram fi->lb_en = true; 2427b58dafbcSChristopher N Bednarz 2428277b3a45SYashaswini Raghuram Prathivadi Bhayankaram /* Set lan_en to TRUE if 24296a7e6993SYashaswini Raghuram Prathivadi Bhayankaram * 1. The switch is a VEB AND 24306a7e6993SYashaswini Raghuram Prathivadi Bhayankaram * 2 243126069b44SYashaswini Raghuram Prathivadi Bhayankaram * 2.1 The lookup is a directional lookup like ethertype, 2432f9867df6SAnirudh Venkataramanan * promiscuous, ethertype-MAC, promiscuous-VLAN 243326069b44SYashaswini Raghuram Prathivadi Bhayankaram * and default-port OR 243426069b44SYashaswini Raghuram Prathivadi Bhayankaram * 2.2 The lookup is VLAN, OR 2435277b3a45SYashaswini Raghuram Prathivadi Bhayankaram * 2.3 The lookup is MAC with mcast or bcast addr for MAC, OR 2436277b3a45SYashaswini Raghuram Prathivadi Bhayankaram * 2.4 The lookup is MAC_VLAN with mcast or bcast addr for MAC. 24376a7e6993SYashaswini Raghuram Prathivadi Bhayankaram * 2438277b3a45SYashaswini Raghuram Prathivadi Bhayankaram * OR 2439277b3a45SYashaswini Raghuram Prathivadi Bhayankaram * 2440277b3a45SYashaswini Raghuram Prathivadi Bhayankaram * The switch is a VEPA. 2441277b3a45SYashaswini Raghuram Prathivadi Bhayankaram * 2442277b3a45SYashaswini Raghuram Prathivadi Bhayankaram * In all other cases, the LAN enable has to be set to false. 24436a7e6993SYashaswini Raghuram Prathivadi Bhayankaram */ 2444277b3a45SYashaswini Raghuram Prathivadi Bhayankaram if (hw->evb_veb) { 244526069b44SYashaswini Raghuram Prathivadi Bhayankaram if (fi->lkup_type == ICE_SW_LKUP_ETHERTYPE || 244626069b44SYashaswini Raghuram Prathivadi Bhayankaram fi->lkup_type == ICE_SW_LKUP_PROMISC || 244726069b44SYashaswini Raghuram Prathivadi Bhayankaram fi->lkup_type == ICE_SW_LKUP_ETHERTYPE_MAC || 244826069b44SYashaswini Raghuram Prathivadi Bhayankaram fi->lkup_type == ICE_SW_LKUP_PROMISC_VLAN || 2449277b3a45SYashaswini Raghuram Prathivadi Bhayankaram fi->lkup_type == ICE_SW_LKUP_DFLT || 245026069b44SYashaswini Raghuram Prathivadi Bhayankaram fi->lkup_type == ICE_SW_LKUP_VLAN || 2451277b3a45SYashaswini Raghuram Prathivadi Bhayankaram (fi->lkup_type == ICE_SW_LKUP_MAC && 2452277b3a45SYashaswini Raghuram Prathivadi Bhayankaram !is_unicast_ether_addr(fi->l_data.mac.mac_addr)) || 24536a7e6993SYashaswini Raghuram Prathivadi Bhayankaram (fi->lkup_type == ICE_SW_LKUP_MAC_VLAN && 2454277b3a45SYashaswini Raghuram Prathivadi Bhayankaram !is_unicast_ether_addr(fi->l_data.mac.mac_addr))) 24556a7e6993SYashaswini Raghuram Prathivadi Bhayankaram fi->lan_en = true; 2456277b3a45SYashaswini Raghuram Prathivadi Bhayankaram } else { 2457277b3a45SYashaswini Raghuram Prathivadi Bhayankaram fi->lan_en = true; 2458277b3a45SYashaswini Raghuram Prathivadi Bhayankaram } 24599daf8208SAnirudh Venkataramanan } 24609daf8208SAnirudh Venkataramanan } 24619daf8208SAnirudh Venkataramanan 24629daf8208SAnirudh Venkataramanan /** 2463ec5a6c5fSDave Ertman * ice_fill_eth_hdr - helper to copy dummy_eth_hdr into supplied buffer 2464ec5a6c5fSDave Ertman * @eth_hdr: pointer to buffer to populate 2465ec5a6c5fSDave Ertman */ 2466ec5a6c5fSDave Ertman void ice_fill_eth_hdr(u8 *eth_hdr) 2467ec5a6c5fSDave Ertman { 2468ec5a6c5fSDave Ertman memcpy(eth_hdr, dummy_eth_header, DUMMY_ETH_HDR_LEN); 2469ec5a6c5fSDave Ertman } 2470ec5a6c5fSDave Ertman 2471ec5a6c5fSDave Ertman /** 24729daf8208SAnirudh Venkataramanan * ice_fill_sw_rule - Helper function to fill switch rule structure 24739daf8208SAnirudh Venkataramanan * @hw: pointer to the hardware structure 24749daf8208SAnirudh Venkataramanan * @f_info: entry containing packet forwarding information 24759daf8208SAnirudh Venkataramanan * @s_rule: switch rule structure to be filled in based on mac_entry 24769daf8208SAnirudh Venkataramanan * @opc: switch rules population command type - pass in the command opcode 24779daf8208SAnirudh Venkataramanan */ 24789daf8208SAnirudh Venkataramanan static void 24799daf8208SAnirudh Venkataramanan ice_fill_sw_rule(struct ice_hw *hw, struct ice_fltr_info *f_info, 24806e1ff618SAlexander Lobakin struct ice_sw_rule_lkup_rx_tx *s_rule, 24816e1ff618SAlexander Lobakin enum ice_adminq_opc opc) 24829daf8208SAnirudh Venkataramanan { 24839daf8208SAnirudh Venkataramanan u16 vlan_id = ICE_MAX_VLAN_ID + 1; 24842bfefa2dSBrett Creeley u16 vlan_tpid = ETH_P_8021Q; 24859daf8208SAnirudh Venkataramanan void *daddr = NULL; 248674118f7aSZhenning Xiao u16 eth_hdr_sz; 248774118f7aSZhenning Xiao u8 *eth_hdr; 24889daf8208SAnirudh Venkataramanan u32 act = 0; 24899daf8208SAnirudh Venkataramanan __be16 *off; 2490be8ff000SAnirudh Venkataramanan u8 q_rgn; 24919daf8208SAnirudh Venkataramanan 24929daf8208SAnirudh Venkataramanan if (opc == ice_aqc_opc_remove_sw_rules) { 24936e1ff618SAlexander Lobakin s_rule->act = 0; 24946e1ff618SAlexander Lobakin s_rule->index = cpu_to_le16(f_info->fltr_rule_id); 24956e1ff618SAlexander Lobakin s_rule->hdr_len = 0; 24969daf8208SAnirudh Venkataramanan return; 24979daf8208SAnirudh Venkataramanan } 24989daf8208SAnirudh Venkataramanan 249974118f7aSZhenning Xiao eth_hdr_sz = sizeof(dummy_eth_header); 25006e1ff618SAlexander Lobakin eth_hdr = s_rule->hdr_data; 250174118f7aSZhenning Xiao 25029daf8208SAnirudh Venkataramanan /* initialize the ether header with a dummy header */ 250374118f7aSZhenning Xiao memcpy(eth_hdr, dummy_eth_header, eth_hdr_sz); 25049daf8208SAnirudh Venkataramanan ice_fill_sw_info(hw, f_info); 25059daf8208SAnirudh Venkataramanan 25069daf8208SAnirudh Venkataramanan switch (f_info->fltr_act) { 25079daf8208SAnirudh Venkataramanan case ICE_FWD_TO_VSI: 25085726ca0eSAnirudh Venkataramanan act |= (f_info->fwd_id.hw_vsi_id << ICE_SINGLE_ACT_VSI_ID_S) & 25099daf8208SAnirudh Venkataramanan ICE_SINGLE_ACT_VSI_ID_M; 25109daf8208SAnirudh Venkataramanan if (f_info->lkup_type != ICE_SW_LKUP_VLAN) 25119daf8208SAnirudh Venkataramanan act |= ICE_SINGLE_ACT_VSI_FORWARDING | 25129daf8208SAnirudh Venkataramanan ICE_SINGLE_ACT_VALID_BIT; 25139daf8208SAnirudh Venkataramanan break; 25149daf8208SAnirudh Venkataramanan case ICE_FWD_TO_VSI_LIST: 25159daf8208SAnirudh Venkataramanan act |= ICE_SINGLE_ACT_VSI_LIST; 25169daf8208SAnirudh Venkataramanan act |= (f_info->fwd_id.vsi_list_id << 25179daf8208SAnirudh Venkataramanan ICE_SINGLE_ACT_VSI_LIST_ID_S) & 25189daf8208SAnirudh Venkataramanan ICE_SINGLE_ACT_VSI_LIST_ID_M; 25199daf8208SAnirudh Venkataramanan if (f_info->lkup_type != ICE_SW_LKUP_VLAN) 25209daf8208SAnirudh Venkataramanan act |= ICE_SINGLE_ACT_VSI_FORWARDING | 25219daf8208SAnirudh Venkataramanan ICE_SINGLE_ACT_VALID_BIT; 25229daf8208SAnirudh Venkataramanan break; 25239daf8208SAnirudh Venkataramanan case ICE_FWD_TO_Q: 25249daf8208SAnirudh Venkataramanan act |= ICE_SINGLE_ACT_TO_Q; 25259daf8208SAnirudh Venkataramanan act |= (f_info->fwd_id.q_id << ICE_SINGLE_ACT_Q_INDEX_S) & 25269daf8208SAnirudh Venkataramanan ICE_SINGLE_ACT_Q_INDEX_M; 25279daf8208SAnirudh Venkataramanan break; 25289daf8208SAnirudh Venkataramanan case ICE_DROP_PACKET: 2529be8ff000SAnirudh Venkataramanan act |= ICE_SINGLE_ACT_VSI_FORWARDING | ICE_SINGLE_ACT_DROP | 2530be8ff000SAnirudh Venkataramanan ICE_SINGLE_ACT_VALID_BIT; 2531be8ff000SAnirudh Venkataramanan break; 2532be8ff000SAnirudh Venkataramanan case ICE_FWD_TO_QGRP: 2533be8ff000SAnirudh Venkataramanan q_rgn = f_info->qgrp_size > 0 ? 2534be8ff000SAnirudh Venkataramanan (u8)ilog2(f_info->qgrp_size) : 0; 2535be8ff000SAnirudh Venkataramanan act |= ICE_SINGLE_ACT_TO_Q; 2536be8ff000SAnirudh Venkataramanan act |= (f_info->fwd_id.q_id << ICE_SINGLE_ACT_Q_INDEX_S) & 2537be8ff000SAnirudh Venkataramanan ICE_SINGLE_ACT_Q_INDEX_M; 2538be8ff000SAnirudh Venkataramanan act |= (q_rgn << ICE_SINGLE_ACT_Q_REGION_S) & 2539be8ff000SAnirudh Venkataramanan ICE_SINGLE_ACT_Q_REGION_M; 25409daf8208SAnirudh Venkataramanan break; 25419daf8208SAnirudh Venkataramanan default: 25429daf8208SAnirudh Venkataramanan return; 25439daf8208SAnirudh Venkataramanan } 25449daf8208SAnirudh Venkataramanan 25459daf8208SAnirudh Venkataramanan if (f_info->lb_en) 25469daf8208SAnirudh Venkataramanan act |= ICE_SINGLE_ACT_LB_ENABLE; 25479daf8208SAnirudh Venkataramanan if (f_info->lan_en) 25489daf8208SAnirudh Venkataramanan act |= ICE_SINGLE_ACT_LAN_ENABLE; 25499daf8208SAnirudh Venkataramanan 25509daf8208SAnirudh Venkataramanan switch (f_info->lkup_type) { 25519daf8208SAnirudh Venkataramanan case ICE_SW_LKUP_MAC: 25529daf8208SAnirudh Venkataramanan daddr = f_info->l_data.mac.mac_addr; 25539daf8208SAnirudh Venkataramanan break; 25549daf8208SAnirudh Venkataramanan case ICE_SW_LKUP_VLAN: 25559daf8208SAnirudh Venkataramanan vlan_id = f_info->l_data.vlan.vlan_id; 25562bfefa2dSBrett Creeley if (f_info->l_data.vlan.tpid_valid) 25572bfefa2dSBrett Creeley vlan_tpid = f_info->l_data.vlan.tpid; 25589daf8208SAnirudh Venkataramanan if (f_info->fltr_act == ICE_FWD_TO_VSI || 25599daf8208SAnirudh Venkataramanan f_info->fltr_act == ICE_FWD_TO_VSI_LIST) { 25609daf8208SAnirudh Venkataramanan act |= ICE_SINGLE_ACT_PRUNE; 25619daf8208SAnirudh Venkataramanan act |= ICE_SINGLE_ACT_EGRESS | ICE_SINGLE_ACT_INGRESS; 25629daf8208SAnirudh Venkataramanan } 25639daf8208SAnirudh Venkataramanan break; 25649daf8208SAnirudh Venkataramanan case ICE_SW_LKUP_ETHERTYPE_MAC: 25659daf8208SAnirudh Venkataramanan daddr = f_info->l_data.ethertype_mac.mac_addr; 25664e83fc93SBruce Allan fallthrough; 25679daf8208SAnirudh Venkataramanan case ICE_SW_LKUP_ETHERTYPE: 2568feee3cb3SBruce Allan off = (__force __be16 *)(eth_hdr + ICE_ETH_ETHTYPE_OFFSET); 25699daf8208SAnirudh Venkataramanan *off = cpu_to_be16(f_info->l_data.ethertype_mac.ethertype); 25709daf8208SAnirudh Venkataramanan break; 25719daf8208SAnirudh Venkataramanan case ICE_SW_LKUP_MAC_VLAN: 25729daf8208SAnirudh Venkataramanan daddr = f_info->l_data.mac_vlan.mac_addr; 25739daf8208SAnirudh Venkataramanan vlan_id = f_info->l_data.mac_vlan.vlan_id; 25749daf8208SAnirudh Venkataramanan break; 25759daf8208SAnirudh Venkataramanan case ICE_SW_LKUP_PROMISC_VLAN: 25769daf8208SAnirudh Venkataramanan vlan_id = f_info->l_data.mac_vlan.vlan_id; 25774e83fc93SBruce Allan fallthrough; 25789daf8208SAnirudh Venkataramanan case ICE_SW_LKUP_PROMISC: 25799daf8208SAnirudh Venkataramanan daddr = f_info->l_data.mac_vlan.mac_addr; 25809daf8208SAnirudh Venkataramanan break; 25819daf8208SAnirudh Venkataramanan default: 25829daf8208SAnirudh Venkataramanan break; 25839daf8208SAnirudh Venkataramanan } 25849daf8208SAnirudh Venkataramanan 25856e1ff618SAlexander Lobakin s_rule->hdr.type = (f_info->flag & ICE_FLTR_RX) ? 25869daf8208SAnirudh Venkataramanan cpu_to_le16(ICE_AQC_SW_RULES_T_LKUP_RX) : 25879daf8208SAnirudh Venkataramanan cpu_to_le16(ICE_AQC_SW_RULES_T_LKUP_TX); 25889daf8208SAnirudh Venkataramanan 25899daf8208SAnirudh Venkataramanan /* Recipe set depending on lookup type */ 25906e1ff618SAlexander Lobakin s_rule->recipe_id = cpu_to_le16(f_info->lkup_type); 25916e1ff618SAlexander Lobakin s_rule->src = cpu_to_le16(f_info->src); 25926e1ff618SAlexander Lobakin s_rule->act = cpu_to_le32(act); 25939daf8208SAnirudh Venkataramanan 25949daf8208SAnirudh Venkataramanan if (daddr) 259574118f7aSZhenning Xiao ether_addr_copy(eth_hdr + ICE_ETH_DA_OFFSET, daddr); 25969daf8208SAnirudh Venkataramanan 25979daf8208SAnirudh Venkataramanan if (!(vlan_id > ICE_MAX_VLAN_ID)) { 2598feee3cb3SBruce Allan off = (__force __be16 *)(eth_hdr + ICE_ETH_VLAN_TCI_OFFSET); 25999daf8208SAnirudh Venkataramanan *off = cpu_to_be16(vlan_id); 26002bfefa2dSBrett Creeley off = (__force __be16 *)(eth_hdr + ICE_ETH_ETHTYPE_OFFSET); 26012bfefa2dSBrett Creeley *off = cpu_to_be16(vlan_tpid); 26029daf8208SAnirudh Venkataramanan } 26039daf8208SAnirudh Venkataramanan 26049daf8208SAnirudh Venkataramanan /* Create the switch rule with the final dummy Ethernet header */ 26059daf8208SAnirudh Venkataramanan if (opc != ice_aqc_opc_update_sw_rules) 26066e1ff618SAlexander Lobakin s_rule->hdr_len = cpu_to_le16(eth_hdr_sz); 26079daf8208SAnirudh Venkataramanan } 26089daf8208SAnirudh Venkataramanan 26099daf8208SAnirudh Venkataramanan /** 26109daf8208SAnirudh Venkataramanan * ice_add_marker_act 26119daf8208SAnirudh Venkataramanan * @hw: pointer to the hardware structure 26129daf8208SAnirudh Venkataramanan * @m_ent: the management entry for which sw marker needs to be added 26139daf8208SAnirudh Venkataramanan * @sw_marker: sw marker to tag the Rx descriptor with 2614f9867df6SAnirudh Venkataramanan * @l_id: large action resource ID 26159daf8208SAnirudh Venkataramanan * 26169daf8208SAnirudh Venkataramanan * Create a large action to hold software marker and update the switch rule 26179daf8208SAnirudh Venkataramanan * entry pointed by m_ent with newly created large action 26189daf8208SAnirudh Venkataramanan */ 26195e24d598STony Nguyen static int 26209daf8208SAnirudh Venkataramanan ice_add_marker_act(struct ice_hw *hw, struct ice_fltr_mgmt_list_entry *m_ent, 26219daf8208SAnirudh Venkataramanan u16 sw_marker, u16 l_id) 26229daf8208SAnirudh Venkataramanan { 26236e1ff618SAlexander Lobakin struct ice_sw_rule_lkup_rx_tx *rx_tx; 26246e1ff618SAlexander Lobakin struct ice_sw_rule_lg_act *lg_act; 26259daf8208SAnirudh Venkataramanan /* For software marker we need 3 large actions 26269daf8208SAnirudh Venkataramanan * 1. FWD action: FWD TO VSI or VSI LIST 2627f9867df6SAnirudh Venkataramanan * 2. GENERIC VALUE action to hold the profile ID 2628f9867df6SAnirudh Venkataramanan * 3. GENERIC VALUE action to hold the software marker ID 26299daf8208SAnirudh Venkataramanan */ 26309daf8208SAnirudh Venkataramanan const u16 num_lg_acts = 3; 26319daf8208SAnirudh Venkataramanan u16 lg_act_size; 26329daf8208SAnirudh Venkataramanan u16 rules_size; 26335518ac2aSTony Nguyen int status; 26349daf8208SAnirudh Venkataramanan u32 act; 26355726ca0eSAnirudh Venkataramanan u16 id; 26369daf8208SAnirudh Venkataramanan 26379daf8208SAnirudh Venkataramanan if (m_ent->fltr_info.lkup_type != ICE_SW_LKUP_MAC) 2638d54699e2STony Nguyen return -EINVAL; 26399daf8208SAnirudh Venkataramanan 26409daf8208SAnirudh Venkataramanan /* Create two back-to-back switch rules and submit them to the HW using 26419daf8208SAnirudh Venkataramanan * one memory buffer: 26429daf8208SAnirudh Venkataramanan * 1. Large Action 2643d337f2afSAnirudh Venkataramanan * 2. Look up Tx Rx 26449daf8208SAnirudh Venkataramanan */ 26456e1ff618SAlexander Lobakin lg_act_size = (u16)ICE_SW_RULE_LG_ACT_SIZE(lg_act, num_lg_acts); 26466e1ff618SAlexander Lobakin rules_size = lg_act_size + ICE_SW_RULE_RX_TX_ETH_HDR_SIZE(rx_tx); 26479daf8208SAnirudh Venkataramanan lg_act = devm_kzalloc(ice_hw_to_dev(hw), rules_size, GFP_KERNEL); 26489daf8208SAnirudh Venkataramanan if (!lg_act) 2649d54699e2STony Nguyen return -ENOMEM; 26509daf8208SAnirudh Venkataramanan 26516e1ff618SAlexander Lobakin rx_tx = (typeof(rx_tx))((u8 *)lg_act + lg_act_size); 26529daf8208SAnirudh Venkataramanan 26539daf8208SAnirudh Venkataramanan /* Fill in the first switch rule i.e. large action */ 26546e1ff618SAlexander Lobakin lg_act->hdr.type = cpu_to_le16(ICE_AQC_SW_RULES_T_LG_ACT); 26556e1ff618SAlexander Lobakin lg_act->index = cpu_to_le16(l_id); 26566e1ff618SAlexander Lobakin lg_act->size = cpu_to_le16(num_lg_acts); 26579daf8208SAnirudh Venkataramanan 26589daf8208SAnirudh Venkataramanan /* First action VSI forwarding or VSI list forwarding depending on how 26599daf8208SAnirudh Venkataramanan * many VSIs 26609daf8208SAnirudh Venkataramanan */ 26615726ca0eSAnirudh Venkataramanan id = (m_ent->vsi_count > 1) ? m_ent->fltr_info.fwd_id.vsi_list_id : 26625726ca0eSAnirudh Venkataramanan m_ent->fltr_info.fwd_id.hw_vsi_id; 26639daf8208SAnirudh Venkataramanan 26649daf8208SAnirudh Venkataramanan act = ICE_LG_ACT_VSI_FORWARDING | ICE_LG_ACT_VALID_BIT; 266566486d89SBruce Allan act |= (id << ICE_LG_ACT_VSI_LIST_ID_S) & ICE_LG_ACT_VSI_LIST_ID_M; 26669daf8208SAnirudh Venkataramanan if (m_ent->vsi_count > 1) 26679daf8208SAnirudh Venkataramanan act |= ICE_LG_ACT_VSI_LIST; 26686e1ff618SAlexander Lobakin lg_act->act[0] = cpu_to_le32(act); 26699daf8208SAnirudh Venkataramanan 26709daf8208SAnirudh Venkataramanan /* Second action descriptor type */ 26719daf8208SAnirudh Venkataramanan act = ICE_LG_ACT_GENERIC; 26729daf8208SAnirudh Venkataramanan 26739daf8208SAnirudh Venkataramanan act |= (1 << ICE_LG_ACT_GENERIC_VALUE_S) & ICE_LG_ACT_GENERIC_VALUE_M; 26746e1ff618SAlexander Lobakin lg_act->act[1] = cpu_to_le32(act); 26759daf8208SAnirudh Venkataramanan 26764381147dSAnirudh Venkataramanan act = (ICE_LG_ACT_GENERIC_OFF_RX_DESC_PROF_IDX << 26774381147dSAnirudh Venkataramanan ICE_LG_ACT_GENERIC_OFFSET_S) & ICE_LG_ACT_GENERIC_OFFSET_M; 26789daf8208SAnirudh Venkataramanan 26799daf8208SAnirudh Venkataramanan /* Third action Marker value */ 26809daf8208SAnirudh Venkataramanan act |= ICE_LG_ACT_GENERIC; 26819daf8208SAnirudh Venkataramanan act |= (sw_marker << ICE_LG_ACT_GENERIC_VALUE_S) & 26829daf8208SAnirudh Venkataramanan ICE_LG_ACT_GENERIC_VALUE_M; 26839daf8208SAnirudh Venkataramanan 26846e1ff618SAlexander Lobakin lg_act->act[2] = cpu_to_le32(act); 26859daf8208SAnirudh Venkataramanan 2686d337f2afSAnirudh Venkataramanan /* call the fill switch rule to fill the lookup Tx Rx structure */ 26879daf8208SAnirudh Venkataramanan ice_fill_sw_rule(hw, &m_ent->fltr_info, rx_tx, 26889daf8208SAnirudh Venkataramanan ice_aqc_opc_update_sw_rules); 26899daf8208SAnirudh Venkataramanan 2690f9867df6SAnirudh Venkataramanan /* Update the action to point to the large action ID */ 26916e1ff618SAlexander Lobakin rx_tx->act = cpu_to_le32(ICE_SINGLE_ACT_PTR | 26929daf8208SAnirudh Venkataramanan ((l_id << ICE_SINGLE_ACT_PTR_VAL_S) & 26939daf8208SAnirudh Venkataramanan ICE_SINGLE_ACT_PTR_VAL_M)); 26949daf8208SAnirudh Venkataramanan 2695f9867df6SAnirudh Venkataramanan /* Use the filter rule ID of the previously created rule with single 26969daf8208SAnirudh Venkataramanan * act. Once the update happens, hardware will treat this as large 26979daf8208SAnirudh Venkataramanan * action 26989daf8208SAnirudh Venkataramanan */ 26996e1ff618SAlexander Lobakin rx_tx->index = cpu_to_le16(m_ent->fltr_info.fltr_rule_id); 27009daf8208SAnirudh Venkataramanan 27019daf8208SAnirudh Venkataramanan status = ice_aq_sw_rules(hw, lg_act, rules_size, 2, 27029daf8208SAnirudh Venkataramanan ice_aqc_opc_update_sw_rules, NULL); 27039daf8208SAnirudh Venkataramanan if (!status) { 27049daf8208SAnirudh Venkataramanan m_ent->lg_act_idx = l_id; 27059daf8208SAnirudh Venkataramanan m_ent->sw_marker_id = sw_marker; 27069daf8208SAnirudh Venkataramanan } 27079daf8208SAnirudh Venkataramanan 27089daf8208SAnirudh Venkataramanan devm_kfree(ice_hw_to_dev(hw), lg_act); 27099daf8208SAnirudh Venkataramanan return status; 27109daf8208SAnirudh Venkataramanan } 27119daf8208SAnirudh Venkataramanan 27129daf8208SAnirudh Venkataramanan /** 27139daf8208SAnirudh Venkataramanan * ice_create_vsi_list_map 27149daf8208SAnirudh Venkataramanan * @hw: pointer to the hardware structure 27155726ca0eSAnirudh Venkataramanan * @vsi_handle_arr: array of VSI handles to set in the VSI mapping 27165726ca0eSAnirudh Venkataramanan * @num_vsi: number of VSI handles in the array 2717f9867df6SAnirudh Venkataramanan * @vsi_list_id: VSI list ID generated as part of allocate resource 27189daf8208SAnirudh Venkataramanan * 2719f9867df6SAnirudh Venkataramanan * Helper function to create a new entry of VSI list ID to VSI mapping 2720f9867df6SAnirudh Venkataramanan * using the given VSI list ID 27219daf8208SAnirudh Venkataramanan */ 27229daf8208SAnirudh Venkataramanan static struct ice_vsi_list_map_info * 27235726ca0eSAnirudh Venkataramanan ice_create_vsi_list_map(struct ice_hw *hw, u16 *vsi_handle_arr, u16 num_vsi, 27249daf8208SAnirudh Venkataramanan u16 vsi_list_id) 27259daf8208SAnirudh Venkataramanan { 27269daf8208SAnirudh Venkataramanan struct ice_switch_info *sw = hw->switch_info; 27279daf8208SAnirudh Venkataramanan struct ice_vsi_list_map_info *v_map; 27289daf8208SAnirudh Venkataramanan int i; 27299daf8208SAnirudh Venkataramanan 273036ac7911SBruce Allan v_map = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*v_map), GFP_KERNEL); 27319daf8208SAnirudh Venkataramanan if (!v_map) 27329daf8208SAnirudh Venkataramanan return NULL; 27339daf8208SAnirudh Venkataramanan 27349daf8208SAnirudh Venkataramanan v_map->vsi_list_id = vsi_list_id; 27355726ca0eSAnirudh Venkataramanan v_map->ref_cnt = 1; 27369daf8208SAnirudh Venkataramanan for (i = 0; i < num_vsi; i++) 27375726ca0eSAnirudh Venkataramanan set_bit(vsi_handle_arr[i], v_map->vsi_map); 27389daf8208SAnirudh Venkataramanan 27399daf8208SAnirudh Venkataramanan list_add(&v_map->list_entry, &sw->vsi_list_map_head); 27409daf8208SAnirudh Venkataramanan return v_map; 27419daf8208SAnirudh Venkataramanan } 27429daf8208SAnirudh Venkataramanan 27439daf8208SAnirudh Venkataramanan /** 27449daf8208SAnirudh Venkataramanan * ice_update_vsi_list_rule 27459daf8208SAnirudh Venkataramanan * @hw: pointer to the hardware structure 27465726ca0eSAnirudh Venkataramanan * @vsi_handle_arr: array of VSI handles to form a VSI list 27475726ca0eSAnirudh Venkataramanan * @num_vsi: number of VSI handles in the array 2748f9867df6SAnirudh Venkataramanan * @vsi_list_id: VSI list ID generated as part of allocate resource 27499daf8208SAnirudh Venkataramanan * @remove: Boolean value to indicate if this is a remove action 27509daf8208SAnirudh Venkataramanan * @opc: switch rules population command type - pass in the command opcode 27519daf8208SAnirudh Venkataramanan * @lkup_type: lookup type of the filter 27529daf8208SAnirudh Venkataramanan * 27539daf8208SAnirudh Venkataramanan * Call AQ command to add a new switch rule or update existing switch rule 2754f9867df6SAnirudh Venkataramanan * using the given VSI list ID 27559daf8208SAnirudh Venkataramanan */ 27565e24d598STony Nguyen static int 27575726ca0eSAnirudh Venkataramanan ice_update_vsi_list_rule(struct ice_hw *hw, u16 *vsi_handle_arr, u16 num_vsi, 27589daf8208SAnirudh Venkataramanan u16 vsi_list_id, bool remove, enum ice_adminq_opc opc, 27599daf8208SAnirudh Venkataramanan enum ice_sw_lkup_type lkup_type) 27609daf8208SAnirudh Venkataramanan { 27616e1ff618SAlexander Lobakin struct ice_sw_rule_vsi_list *s_rule; 27629daf8208SAnirudh Venkataramanan u16 s_rule_size; 27636dae8aa0SBruce Allan u16 rule_type; 27645518ac2aSTony Nguyen int status; 27659daf8208SAnirudh Venkataramanan int i; 27669daf8208SAnirudh Venkataramanan 27679daf8208SAnirudh Venkataramanan if (!num_vsi) 2768d54699e2STony Nguyen return -EINVAL; 27699daf8208SAnirudh Venkataramanan 27709daf8208SAnirudh Venkataramanan if (lkup_type == ICE_SW_LKUP_MAC || 27719daf8208SAnirudh Venkataramanan lkup_type == ICE_SW_LKUP_MAC_VLAN || 27729daf8208SAnirudh Venkataramanan lkup_type == ICE_SW_LKUP_ETHERTYPE || 27739daf8208SAnirudh Venkataramanan lkup_type == ICE_SW_LKUP_ETHERTYPE_MAC || 27749daf8208SAnirudh Venkataramanan lkup_type == ICE_SW_LKUP_PROMISC || 2775d7393425SMichal Wilczynski lkup_type == ICE_SW_LKUP_PROMISC_VLAN || 2776d7393425SMichal Wilczynski lkup_type == ICE_SW_LKUP_DFLT) 27776dae8aa0SBruce Allan rule_type = remove ? ICE_AQC_SW_RULES_T_VSI_LIST_CLEAR : 27789daf8208SAnirudh Venkataramanan ICE_AQC_SW_RULES_T_VSI_LIST_SET; 27799daf8208SAnirudh Venkataramanan else if (lkup_type == ICE_SW_LKUP_VLAN) 27806dae8aa0SBruce Allan rule_type = remove ? ICE_AQC_SW_RULES_T_PRUNE_LIST_CLEAR : 27819daf8208SAnirudh Venkataramanan ICE_AQC_SW_RULES_T_PRUNE_LIST_SET; 27829daf8208SAnirudh Venkataramanan else 2783d54699e2STony Nguyen return -EINVAL; 27849daf8208SAnirudh Venkataramanan 27856e1ff618SAlexander Lobakin s_rule_size = (u16)ICE_SW_RULE_VSI_LIST_SIZE(s_rule, num_vsi); 27869daf8208SAnirudh Venkataramanan s_rule = devm_kzalloc(ice_hw_to_dev(hw), s_rule_size, GFP_KERNEL); 27879daf8208SAnirudh Venkataramanan if (!s_rule) 2788d54699e2STony Nguyen return -ENOMEM; 27895726ca0eSAnirudh Venkataramanan for (i = 0; i < num_vsi; i++) { 27905726ca0eSAnirudh Venkataramanan if (!ice_is_vsi_valid(hw, vsi_handle_arr[i])) { 2791d54699e2STony Nguyen status = -EINVAL; 27925726ca0eSAnirudh Venkataramanan goto exit; 27935726ca0eSAnirudh Venkataramanan } 27945726ca0eSAnirudh Venkataramanan /* AQ call requires hw_vsi_id(s) */ 27956e1ff618SAlexander Lobakin s_rule->vsi[i] = 27965726ca0eSAnirudh Venkataramanan cpu_to_le16(ice_get_hw_vsi_num(hw, vsi_handle_arr[i])); 27975726ca0eSAnirudh Venkataramanan } 27989daf8208SAnirudh Venkataramanan 27996e1ff618SAlexander Lobakin s_rule->hdr.type = cpu_to_le16(rule_type); 28006e1ff618SAlexander Lobakin s_rule->number_vsi = cpu_to_le16(num_vsi); 28016e1ff618SAlexander Lobakin s_rule->index = cpu_to_le16(vsi_list_id); 28029daf8208SAnirudh Venkataramanan 28039daf8208SAnirudh Venkataramanan status = ice_aq_sw_rules(hw, s_rule, s_rule_size, 1, opc, NULL); 28049daf8208SAnirudh Venkataramanan 28055726ca0eSAnirudh Venkataramanan exit: 28069daf8208SAnirudh Venkataramanan devm_kfree(ice_hw_to_dev(hw), s_rule); 28079daf8208SAnirudh Venkataramanan return status; 28089daf8208SAnirudh Venkataramanan } 28099daf8208SAnirudh Venkataramanan 28109daf8208SAnirudh Venkataramanan /** 28119daf8208SAnirudh Venkataramanan * ice_create_vsi_list_rule - Creates and populates a VSI list rule 2812f9867df6SAnirudh Venkataramanan * @hw: pointer to the HW struct 28135726ca0eSAnirudh Venkataramanan * @vsi_handle_arr: array of VSI handles to form a VSI list 28145726ca0eSAnirudh Venkataramanan * @num_vsi: number of VSI handles in the array 28159daf8208SAnirudh Venkataramanan * @vsi_list_id: stores the ID of the VSI list to be created 28169daf8208SAnirudh Venkataramanan * @lkup_type: switch rule filter's lookup type 28179daf8208SAnirudh Venkataramanan */ 28185e24d598STony Nguyen static int 28195726ca0eSAnirudh Venkataramanan ice_create_vsi_list_rule(struct ice_hw *hw, u16 *vsi_handle_arr, u16 num_vsi, 28209daf8208SAnirudh Venkataramanan u16 *vsi_list_id, enum ice_sw_lkup_type lkup_type) 28219daf8208SAnirudh Venkataramanan { 28225e24d598STony Nguyen int status; 28239daf8208SAnirudh Venkataramanan 28249daf8208SAnirudh Venkataramanan status = ice_aq_alloc_free_vsi_list(hw, vsi_list_id, lkup_type, 28259daf8208SAnirudh Venkataramanan ice_aqc_opc_alloc_res); 28269daf8208SAnirudh Venkataramanan if (status) 28279daf8208SAnirudh Venkataramanan return status; 28289daf8208SAnirudh Venkataramanan 28299daf8208SAnirudh Venkataramanan /* Update the newly created VSI list to include the specified VSIs */ 28305726ca0eSAnirudh Venkataramanan return ice_update_vsi_list_rule(hw, vsi_handle_arr, num_vsi, 28315726ca0eSAnirudh Venkataramanan *vsi_list_id, false, 28325726ca0eSAnirudh Venkataramanan ice_aqc_opc_add_sw_rules, lkup_type); 28339daf8208SAnirudh Venkataramanan } 28349daf8208SAnirudh Venkataramanan 28359daf8208SAnirudh Venkataramanan /** 28369daf8208SAnirudh Venkataramanan * ice_create_pkt_fwd_rule 28379daf8208SAnirudh Venkataramanan * @hw: pointer to the hardware structure 28389daf8208SAnirudh Venkataramanan * @f_entry: entry containing packet forwarding information 28399daf8208SAnirudh Venkataramanan * 28409daf8208SAnirudh Venkataramanan * Create switch rule with given filter information and add an entry 28419daf8208SAnirudh Venkataramanan * to the corresponding filter management list to track this switch rule 28429daf8208SAnirudh Venkataramanan * and VSI mapping 28439daf8208SAnirudh Venkataramanan */ 28445e24d598STony Nguyen static int 28459daf8208SAnirudh Venkataramanan ice_create_pkt_fwd_rule(struct ice_hw *hw, 28469daf8208SAnirudh Venkataramanan struct ice_fltr_list_entry *f_entry) 28479daf8208SAnirudh Venkataramanan { 28489daf8208SAnirudh Venkataramanan struct ice_fltr_mgmt_list_entry *fm_entry; 28496e1ff618SAlexander Lobakin struct ice_sw_rule_lkup_rx_tx *s_rule; 28509daf8208SAnirudh Venkataramanan enum ice_sw_lkup_type l_type; 285180d144c9SAnirudh Venkataramanan struct ice_sw_recipe *recp; 28525e24d598STony Nguyen int status; 28539daf8208SAnirudh Venkataramanan 28549daf8208SAnirudh Venkataramanan s_rule = devm_kzalloc(ice_hw_to_dev(hw), 28556e1ff618SAlexander Lobakin ICE_SW_RULE_RX_TX_ETH_HDR_SIZE(s_rule), 28566e1ff618SAlexander Lobakin GFP_KERNEL); 28579daf8208SAnirudh Venkataramanan if (!s_rule) 2858d54699e2STony Nguyen return -ENOMEM; 28599daf8208SAnirudh Venkataramanan fm_entry = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*fm_entry), 28609daf8208SAnirudh Venkataramanan GFP_KERNEL); 28619daf8208SAnirudh Venkataramanan if (!fm_entry) { 2862d54699e2STony Nguyen status = -ENOMEM; 28639daf8208SAnirudh Venkataramanan goto ice_create_pkt_fwd_rule_exit; 28649daf8208SAnirudh Venkataramanan } 28659daf8208SAnirudh Venkataramanan 28669daf8208SAnirudh Venkataramanan fm_entry->fltr_info = f_entry->fltr_info; 28679daf8208SAnirudh Venkataramanan 28689daf8208SAnirudh Venkataramanan /* Initialize all the fields for the management entry */ 28699daf8208SAnirudh Venkataramanan fm_entry->vsi_count = 1; 28709daf8208SAnirudh Venkataramanan fm_entry->lg_act_idx = ICE_INVAL_LG_ACT_INDEX; 28719daf8208SAnirudh Venkataramanan fm_entry->sw_marker_id = ICE_INVAL_SW_MARKER_ID; 28729daf8208SAnirudh Venkataramanan fm_entry->counter_index = ICE_INVAL_COUNTER_ID; 28739daf8208SAnirudh Venkataramanan 28749daf8208SAnirudh Venkataramanan ice_fill_sw_rule(hw, &fm_entry->fltr_info, s_rule, 28759daf8208SAnirudh Venkataramanan ice_aqc_opc_add_sw_rules); 28769daf8208SAnirudh Venkataramanan 28776e1ff618SAlexander Lobakin status = ice_aq_sw_rules(hw, s_rule, 28786e1ff618SAlexander Lobakin ICE_SW_RULE_RX_TX_ETH_HDR_SIZE(s_rule), 1, 28799daf8208SAnirudh Venkataramanan ice_aqc_opc_add_sw_rules, NULL); 28809daf8208SAnirudh Venkataramanan if (status) { 28819daf8208SAnirudh Venkataramanan devm_kfree(ice_hw_to_dev(hw), fm_entry); 28829daf8208SAnirudh Venkataramanan goto ice_create_pkt_fwd_rule_exit; 28839daf8208SAnirudh Venkataramanan } 28849daf8208SAnirudh Venkataramanan 28856e1ff618SAlexander Lobakin f_entry->fltr_info.fltr_rule_id = le16_to_cpu(s_rule->index); 28866e1ff618SAlexander Lobakin fm_entry->fltr_info.fltr_rule_id = le16_to_cpu(s_rule->index); 28879daf8208SAnirudh Venkataramanan 28889daf8208SAnirudh Venkataramanan /* The book keeping entries will get removed when base driver 28899daf8208SAnirudh Venkataramanan * calls remove filter AQ command 28909daf8208SAnirudh Venkataramanan */ 28919daf8208SAnirudh Venkataramanan l_type = fm_entry->fltr_info.lkup_type; 289280d144c9SAnirudh Venkataramanan recp = &hw->switch_info->recp_list[l_type]; 289380d144c9SAnirudh Venkataramanan list_add(&fm_entry->list_entry, &recp->filt_rules); 289480d144c9SAnirudh Venkataramanan 28959daf8208SAnirudh Venkataramanan ice_create_pkt_fwd_rule_exit: 28969daf8208SAnirudh Venkataramanan devm_kfree(ice_hw_to_dev(hw), s_rule); 28979daf8208SAnirudh Venkataramanan return status; 28989daf8208SAnirudh Venkataramanan } 28999daf8208SAnirudh Venkataramanan 29009daf8208SAnirudh Venkataramanan /** 29019daf8208SAnirudh Venkataramanan * ice_update_pkt_fwd_rule 29029daf8208SAnirudh Venkataramanan * @hw: pointer to the hardware structure 290380d144c9SAnirudh Venkataramanan * @f_info: filter information for switch rule 29049daf8208SAnirudh Venkataramanan * 29059daf8208SAnirudh Venkataramanan * Call AQ command to update a previously created switch rule with a 2906f9867df6SAnirudh Venkataramanan * VSI list ID 29079daf8208SAnirudh Venkataramanan */ 29085e24d598STony Nguyen static int 290980d144c9SAnirudh Venkataramanan ice_update_pkt_fwd_rule(struct ice_hw *hw, struct ice_fltr_info *f_info) 29109daf8208SAnirudh Venkataramanan { 29116e1ff618SAlexander Lobakin struct ice_sw_rule_lkup_rx_tx *s_rule; 29125e24d598STony Nguyen int status; 29139daf8208SAnirudh Venkataramanan 29149daf8208SAnirudh Venkataramanan s_rule = devm_kzalloc(ice_hw_to_dev(hw), 29156e1ff618SAlexander Lobakin ICE_SW_RULE_RX_TX_ETH_HDR_SIZE(s_rule), 29166e1ff618SAlexander Lobakin GFP_KERNEL); 29179daf8208SAnirudh Venkataramanan if (!s_rule) 2918d54699e2STony Nguyen return -ENOMEM; 29199daf8208SAnirudh Venkataramanan 292080d144c9SAnirudh Venkataramanan ice_fill_sw_rule(hw, f_info, s_rule, ice_aqc_opc_update_sw_rules); 29219daf8208SAnirudh Venkataramanan 29226e1ff618SAlexander Lobakin s_rule->index = cpu_to_le16(f_info->fltr_rule_id); 29239daf8208SAnirudh Venkataramanan 29249daf8208SAnirudh Venkataramanan /* Update switch rule with new rule set to forward VSI list */ 29256e1ff618SAlexander Lobakin status = ice_aq_sw_rules(hw, s_rule, 29266e1ff618SAlexander Lobakin ICE_SW_RULE_RX_TX_ETH_HDR_SIZE(s_rule), 1, 29279daf8208SAnirudh Venkataramanan ice_aqc_opc_update_sw_rules, NULL); 29289daf8208SAnirudh Venkataramanan 29299daf8208SAnirudh Venkataramanan devm_kfree(ice_hw_to_dev(hw), s_rule); 29309daf8208SAnirudh Venkataramanan return status; 29319daf8208SAnirudh Venkataramanan } 29329daf8208SAnirudh Venkataramanan 29339daf8208SAnirudh Venkataramanan /** 2934b1edc14aSMd Fahad Iqbal Polash * ice_update_sw_rule_bridge_mode 2935f9867df6SAnirudh Venkataramanan * @hw: pointer to the HW struct 2936b1edc14aSMd Fahad Iqbal Polash * 2937b1edc14aSMd Fahad Iqbal Polash * Updates unicast switch filter rules based on VEB/VEPA mode 2938b1edc14aSMd Fahad Iqbal Polash */ 29395e24d598STony Nguyen int ice_update_sw_rule_bridge_mode(struct ice_hw *hw) 2940b1edc14aSMd Fahad Iqbal Polash { 2941b1edc14aSMd Fahad Iqbal Polash struct ice_switch_info *sw = hw->switch_info; 2942b1edc14aSMd Fahad Iqbal Polash struct ice_fltr_mgmt_list_entry *fm_entry; 2943b1edc14aSMd Fahad Iqbal Polash struct list_head *rule_head; 2944b1edc14aSMd Fahad Iqbal Polash struct mutex *rule_lock; /* Lock to protect filter rule list */ 29455518ac2aSTony Nguyen int status = 0; 2946b1edc14aSMd Fahad Iqbal Polash 2947b1edc14aSMd Fahad Iqbal Polash rule_lock = &sw->recp_list[ICE_SW_LKUP_MAC].filt_rule_lock; 2948b1edc14aSMd Fahad Iqbal Polash rule_head = &sw->recp_list[ICE_SW_LKUP_MAC].filt_rules; 2949b1edc14aSMd Fahad Iqbal Polash 2950b1edc14aSMd Fahad Iqbal Polash mutex_lock(rule_lock); 2951b1edc14aSMd Fahad Iqbal Polash list_for_each_entry(fm_entry, rule_head, list_entry) { 2952b1edc14aSMd Fahad Iqbal Polash struct ice_fltr_info *fi = &fm_entry->fltr_info; 2953b1edc14aSMd Fahad Iqbal Polash u8 *addr = fi->l_data.mac.mac_addr; 2954b1edc14aSMd Fahad Iqbal Polash 2955b1edc14aSMd Fahad Iqbal Polash /* Update unicast Tx rules to reflect the selected 2956b1edc14aSMd Fahad Iqbal Polash * VEB/VEPA mode 2957b1edc14aSMd Fahad Iqbal Polash */ 2958b1edc14aSMd Fahad Iqbal Polash if ((fi->flag & ICE_FLTR_TX) && is_unicast_ether_addr(addr) && 2959b1edc14aSMd Fahad Iqbal Polash (fi->fltr_act == ICE_FWD_TO_VSI || 2960b1edc14aSMd Fahad Iqbal Polash fi->fltr_act == ICE_FWD_TO_VSI_LIST || 2961b1edc14aSMd Fahad Iqbal Polash fi->fltr_act == ICE_FWD_TO_Q || 2962b1edc14aSMd Fahad Iqbal Polash fi->fltr_act == ICE_FWD_TO_QGRP)) { 2963b1edc14aSMd Fahad Iqbal Polash status = ice_update_pkt_fwd_rule(hw, fi); 2964b1edc14aSMd Fahad Iqbal Polash if (status) 2965b1edc14aSMd Fahad Iqbal Polash break; 2966b1edc14aSMd Fahad Iqbal Polash } 2967b1edc14aSMd Fahad Iqbal Polash } 2968b1edc14aSMd Fahad Iqbal Polash 2969b1edc14aSMd Fahad Iqbal Polash mutex_unlock(rule_lock); 2970b1edc14aSMd Fahad Iqbal Polash 2971b1edc14aSMd Fahad Iqbal Polash return status; 2972b1edc14aSMd Fahad Iqbal Polash } 2973b1edc14aSMd Fahad Iqbal Polash 2974b1edc14aSMd Fahad Iqbal Polash /** 297580d144c9SAnirudh Venkataramanan * ice_add_update_vsi_list 29769daf8208SAnirudh Venkataramanan * @hw: pointer to the hardware structure 29779daf8208SAnirudh Venkataramanan * @m_entry: pointer to current filter management list entry 29789daf8208SAnirudh Venkataramanan * @cur_fltr: filter information from the book keeping entry 29799daf8208SAnirudh Venkataramanan * @new_fltr: filter information with the new VSI to be added 29809daf8208SAnirudh Venkataramanan * 29819daf8208SAnirudh Venkataramanan * Call AQ command to add or update previously created VSI list with new VSI. 29829daf8208SAnirudh Venkataramanan * 29839daf8208SAnirudh Venkataramanan * Helper function to do book keeping associated with adding filter information 2984d337f2afSAnirudh Venkataramanan * The algorithm to do the book keeping is described below : 29859daf8208SAnirudh Venkataramanan * When a VSI needs to subscribe to a given filter (MAC/VLAN/Ethtype etc.) 29869daf8208SAnirudh Venkataramanan * if only one VSI has been added till now 29879daf8208SAnirudh Venkataramanan * Allocate a new VSI list and add two VSIs 29889daf8208SAnirudh Venkataramanan * to this list using switch rule command 29899daf8208SAnirudh Venkataramanan * Update the previously created switch rule with the 2990f9867df6SAnirudh Venkataramanan * newly created VSI list ID 29919daf8208SAnirudh Venkataramanan * if a VSI list was previously created 29929daf8208SAnirudh Venkataramanan * Add the new VSI to the previously created VSI list set 29939daf8208SAnirudh Venkataramanan * using the update switch rule command 29949daf8208SAnirudh Venkataramanan */ 29955e24d598STony Nguyen static int 299680d144c9SAnirudh Venkataramanan ice_add_update_vsi_list(struct ice_hw *hw, 29979daf8208SAnirudh Venkataramanan struct ice_fltr_mgmt_list_entry *m_entry, 29989daf8208SAnirudh Venkataramanan struct ice_fltr_info *cur_fltr, 29999daf8208SAnirudh Venkataramanan struct ice_fltr_info *new_fltr) 30009daf8208SAnirudh Venkataramanan { 30019daf8208SAnirudh Venkataramanan u16 vsi_list_id = 0; 30025518ac2aSTony Nguyen int status = 0; 30039daf8208SAnirudh Venkataramanan 30049daf8208SAnirudh Venkataramanan if ((cur_fltr->fltr_act == ICE_FWD_TO_Q || 30059daf8208SAnirudh Venkataramanan cur_fltr->fltr_act == ICE_FWD_TO_QGRP)) 3006d54699e2STony Nguyen return -EOPNOTSUPP; 30079daf8208SAnirudh Venkataramanan 30089daf8208SAnirudh Venkataramanan if ((new_fltr->fltr_act == ICE_FWD_TO_Q || 30099daf8208SAnirudh Venkataramanan new_fltr->fltr_act == ICE_FWD_TO_QGRP) && 30109daf8208SAnirudh Venkataramanan (cur_fltr->fltr_act == ICE_FWD_TO_VSI || 30119daf8208SAnirudh Venkataramanan cur_fltr->fltr_act == ICE_FWD_TO_VSI_LIST)) 3012d54699e2STony Nguyen return -EOPNOTSUPP; 30139daf8208SAnirudh Venkataramanan 30149daf8208SAnirudh Venkataramanan if (m_entry->vsi_count < 2 && !m_entry->vsi_list_info) { 30159daf8208SAnirudh Venkataramanan /* Only one entry existed in the mapping and it was not already 30169daf8208SAnirudh Venkataramanan * a part of a VSI list. So, create a VSI list with the old and 30179daf8208SAnirudh Venkataramanan * new VSIs. 30189daf8208SAnirudh Venkataramanan */ 301980d144c9SAnirudh Venkataramanan struct ice_fltr_info tmp_fltr; 30205726ca0eSAnirudh Venkataramanan u16 vsi_handle_arr[2]; 30219daf8208SAnirudh Venkataramanan 30229daf8208SAnirudh Venkataramanan /* A rule already exists with the new VSI being added */ 30235726ca0eSAnirudh Venkataramanan if (cur_fltr->fwd_id.hw_vsi_id == new_fltr->fwd_id.hw_vsi_id) 3024d54699e2STony Nguyen return -EEXIST; 30259daf8208SAnirudh Venkataramanan 30265726ca0eSAnirudh Venkataramanan vsi_handle_arr[0] = cur_fltr->vsi_handle; 30275726ca0eSAnirudh Venkataramanan vsi_handle_arr[1] = new_fltr->vsi_handle; 30285726ca0eSAnirudh Venkataramanan status = ice_create_vsi_list_rule(hw, &vsi_handle_arr[0], 2, 30299daf8208SAnirudh Venkataramanan &vsi_list_id, 30309daf8208SAnirudh Venkataramanan new_fltr->lkup_type); 30319daf8208SAnirudh Venkataramanan if (status) 30329daf8208SAnirudh Venkataramanan return status; 30339daf8208SAnirudh Venkataramanan 303480d144c9SAnirudh Venkataramanan tmp_fltr = *new_fltr; 303580d144c9SAnirudh Venkataramanan tmp_fltr.fltr_rule_id = cur_fltr->fltr_rule_id; 303680d144c9SAnirudh Venkataramanan tmp_fltr.fltr_act = ICE_FWD_TO_VSI_LIST; 303780d144c9SAnirudh Venkataramanan tmp_fltr.fwd_id.vsi_list_id = vsi_list_id; 30389daf8208SAnirudh Venkataramanan /* Update the previous switch rule of "MAC forward to VSI" to 30399daf8208SAnirudh Venkataramanan * "MAC fwd to VSI list" 30409daf8208SAnirudh Venkataramanan */ 304180d144c9SAnirudh Venkataramanan status = ice_update_pkt_fwd_rule(hw, &tmp_fltr); 30429daf8208SAnirudh Venkataramanan if (status) 30439daf8208SAnirudh Venkataramanan return status; 30449daf8208SAnirudh Venkataramanan 30459daf8208SAnirudh Venkataramanan cur_fltr->fwd_id.vsi_list_id = vsi_list_id; 30469daf8208SAnirudh Venkataramanan cur_fltr->fltr_act = ICE_FWD_TO_VSI_LIST; 30479daf8208SAnirudh Venkataramanan m_entry->vsi_list_info = 30485726ca0eSAnirudh Venkataramanan ice_create_vsi_list_map(hw, &vsi_handle_arr[0], 2, 30499daf8208SAnirudh Venkataramanan vsi_list_id); 30509daf8208SAnirudh Venkataramanan 30517a91d3f0SJacek Bułatek if (!m_entry->vsi_list_info) 3052d54699e2STony Nguyen return -ENOMEM; 30537a91d3f0SJacek Bułatek 30549daf8208SAnirudh Venkataramanan /* If this entry was large action then the large action needs 30559daf8208SAnirudh Venkataramanan * to be updated to point to FWD to VSI list 30569daf8208SAnirudh Venkataramanan */ 30579daf8208SAnirudh Venkataramanan if (m_entry->sw_marker_id != ICE_INVAL_SW_MARKER_ID) 30589daf8208SAnirudh Venkataramanan status = 30599daf8208SAnirudh Venkataramanan ice_add_marker_act(hw, m_entry, 30609daf8208SAnirudh Venkataramanan m_entry->sw_marker_id, 30619daf8208SAnirudh Venkataramanan m_entry->lg_act_idx); 30629daf8208SAnirudh Venkataramanan } else { 30635726ca0eSAnirudh Venkataramanan u16 vsi_handle = new_fltr->vsi_handle; 30649daf8208SAnirudh Venkataramanan enum ice_adminq_opc opcode; 30659daf8208SAnirudh Venkataramanan 3066f25dad19SBruce Allan if (!m_entry->vsi_list_info) 3067d54699e2STony Nguyen return -EIO; 3068f25dad19SBruce Allan 30699daf8208SAnirudh Venkataramanan /* A rule already exists with the new VSI being added */ 30705726ca0eSAnirudh Venkataramanan if (test_bit(vsi_handle, m_entry->vsi_list_info->vsi_map)) 30719daf8208SAnirudh Venkataramanan return 0; 30729daf8208SAnirudh Venkataramanan 30739daf8208SAnirudh Venkataramanan /* Update the previously created VSI list set with 3074f9867df6SAnirudh Venkataramanan * the new VSI ID passed in 30759daf8208SAnirudh Venkataramanan */ 30769daf8208SAnirudh Venkataramanan vsi_list_id = cur_fltr->fwd_id.vsi_list_id; 30779daf8208SAnirudh Venkataramanan opcode = ice_aqc_opc_update_sw_rules; 30789daf8208SAnirudh Venkataramanan 30795726ca0eSAnirudh Venkataramanan status = ice_update_vsi_list_rule(hw, &vsi_handle, 1, 30805726ca0eSAnirudh Venkataramanan vsi_list_id, false, opcode, 30819daf8208SAnirudh Venkataramanan new_fltr->lkup_type); 3082f9867df6SAnirudh Venkataramanan /* update VSI list mapping info with new VSI ID */ 30839daf8208SAnirudh Venkataramanan if (!status) 30845726ca0eSAnirudh Venkataramanan set_bit(vsi_handle, m_entry->vsi_list_info->vsi_map); 30859daf8208SAnirudh Venkataramanan } 30869daf8208SAnirudh Venkataramanan if (!status) 30879daf8208SAnirudh Venkataramanan m_entry->vsi_count++; 30889daf8208SAnirudh Venkataramanan return status; 30899daf8208SAnirudh Venkataramanan } 30909daf8208SAnirudh Venkataramanan 30919daf8208SAnirudh Venkataramanan /** 309280d144c9SAnirudh Venkataramanan * ice_find_rule_entry - Search a rule entry 30939daf8208SAnirudh Venkataramanan * @hw: pointer to the hardware structure 309480d144c9SAnirudh Venkataramanan * @recp_id: lookup type for which the specified rule needs to be searched 309580d144c9SAnirudh Venkataramanan * @f_info: rule information 30969daf8208SAnirudh Venkataramanan * 309780d144c9SAnirudh Venkataramanan * Helper function to search for a given rule entry 309880d144c9SAnirudh Venkataramanan * Returns pointer to entry storing the rule if found 30999daf8208SAnirudh Venkataramanan */ 31009daf8208SAnirudh Venkataramanan static struct ice_fltr_mgmt_list_entry * 310180d144c9SAnirudh Venkataramanan ice_find_rule_entry(struct ice_hw *hw, u8 recp_id, struct ice_fltr_info *f_info) 31029daf8208SAnirudh Venkataramanan { 310380d144c9SAnirudh Venkataramanan struct ice_fltr_mgmt_list_entry *list_itr, *ret = NULL; 31049daf8208SAnirudh Venkataramanan struct ice_switch_info *sw = hw->switch_info; 310580d144c9SAnirudh Venkataramanan struct list_head *list_head; 31069daf8208SAnirudh Venkataramanan 310780d144c9SAnirudh Venkataramanan list_head = &sw->recp_list[recp_id].filt_rules; 310880d144c9SAnirudh Venkataramanan list_for_each_entry(list_itr, list_head, list_entry) { 310980d144c9SAnirudh Venkataramanan if (!memcmp(&f_info->l_data, &list_itr->fltr_info.l_data, 311080d144c9SAnirudh Venkataramanan sizeof(f_info->l_data)) && 311180d144c9SAnirudh Venkataramanan f_info->flag == list_itr->fltr_info.flag) { 311280d144c9SAnirudh Venkataramanan ret = list_itr; 31139daf8208SAnirudh Venkataramanan break; 31149daf8208SAnirudh Venkataramanan } 31159daf8208SAnirudh Venkataramanan } 311680d144c9SAnirudh Venkataramanan return ret; 31179daf8208SAnirudh Venkataramanan } 31189daf8208SAnirudh Venkataramanan 31199daf8208SAnirudh Venkataramanan /** 31205726ca0eSAnirudh Venkataramanan * ice_find_vsi_list_entry - Search VSI list map with VSI count 1 31215726ca0eSAnirudh Venkataramanan * @hw: pointer to the hardware structure 31225726ca0eSAnirudh Venkataramanan * @recp_id: lookup type for which VSI lists needs to be searched 31235726ca0eSAnirudh Venkataramanan * @vsi_handle: VSI handle to be found in VSI list 3124f9867df6SAnirudh Venkataramanan * @vsi_list_id: VSI list ID found containing vsi_handle 31255726ca0eSAnirudh Venkataramanan * 31265726ca0eSAnirudh Venkataramanan * Helper function to search a VSI list with single entry containing given VSI 31275726ca0eSAnirudh Venkataramanan * handle element. This can be extended further to search VSI list with more 31285726ca0eSAnirudh Venkataramanan * than 1 vsi_count. Returns pointer to VSI list entry if found. 31295726ca0eSAnirudh Venkataramanan */ 313023ccae5cSDave Ertman struct ice_vsi_list_map_info * 31315726ca0eSAnirudh Venkataramanan ice_find_vsi_list_entry(struct ice_hw *hw, u8 recp_id, u16 vsi_handle, 31325726ca0eSAnirudh Venkataramanan u16 *vsi_list_id) 31335726ca0eSAnirudh Venkataramanan { 31345726ca0eSAnirudh Venkataramanan struct ice_vsi_list_map_info *map_info = NULL; 31355726ca0eSAnirudh Venkataramanan struct ice_switch_info *sw = hw->switch_info; 31365726ca0eSAnirudh Venkataramanan struct ice_fltr_mgmt_list_entry *list_itr; 31375726ca0eSAnirudh Venkataramanan struct list_head *list_head; 31385726ca0eSAnirudh Venkataramanan 31395726ca0eSAnirudh Venkataramanan list_head = &sw->recp_list[recp_id].filt_rules; 31405726ca0eSAnirudh Venkataramanan list_for_each_entry(list_itr, list_head, list_entry) { 314123ccae5cSDave Ertman if (list_itr->vsi_list_info) { 31425726ca0eSAnirudh Venkataramanan map_info = list_itr->vsi_list_info; 31435726ca0eSAnirudh Venkataramanan if (test_bit(vsi_handle, map_info->vsi_map)) { 31445726ca0eSAnirudh Venkataramanan *vsi_list_id = map_info->vsi_list_id; 31455726ca0eSAnirudh Venkataramanan return map_info; 31465726ca0eSAnirudh Venkataramanan } 31475726ca0eSAnirudh Venkataramanan } 31485726ca0eSAnirudh Venkataramanan } 31495726ca0eSAnirudh Venkataramanan return NULL; 31505726ca0eSAnirudh Venkataramanan } 31515726ca0eSAnirudh Venkataramanan 31525726ca0eSAnirudh Venkataramanan /** 315380d144c9SAnirudh Venkataramanan * ice_add_rule_internal - add rule for a given lookup type 31549daf8208SAnirudh Venkataramanan * @hw: pointer to the hardware structure 3155f9867df6SAnirudh Venkataramanan * @recp_id: lookup type (recipe ID) for which rule has to be added 31569daf8208SAnirudh Venkataramanan * @f_entry: structure containing MAC forwarding information 31579daf8208SAnirudh Venkataramanan * 315880d144c9SAnirudh Venkataramanan * Adds or updates the rule lists for a given recipe 31599daf8208SAnirudh Venkataramanan */ 31605e24d598STony Nguyen static int 316180d144c9SAnirudh Venkataramanan ice_add_rule_internal(struct ice_hw *hw, u8 recp_id, 316280d144c9SAnirudh Venkataramanan struct ice_fltr_list_entry *f_entry) 31639daf8208SAnirudh Venkataramanan { 316480d144c9SAnirudh Venkataramanan struct ice_switch_info *sw = hw->switch_info; 31659daf8208SAnirudh Venkataramanan struct ice_fltr_info *new_fltr, *cur_fltr; 31669daf8208SAnirudh Venkataramanan struct ice_fltr_mgmt_list_entry *m_entry; 316780d144c9SAnirudh Venkataramanan struct mutex *rule_lock; /* Lock to protect filter rule list */ 31685e24d598STony Nguyen int status = 0; 31699daf8208SAnirudh Venkataramanan 31705726ca0eSAnirudh Venkataramanan if (!ice_is_vsi_valid(hw, f_entry->fltr_info.vsi_handle)) 3171d54699e2STony Nguyen return -EINVAL; 31725726ca0eSAnirudh Venkataramanan f_entry->fltr_info.fwd_id.hw_vsi_id = 31735726ca0eSAnirudh Venkataramanan ice_get_hw_vsi_num(hw, f_entry->fltr_info.vsi_handle); 31745726ca0eSAnirudh Venkataramanan 317580d144c9SAnirudh Venkataramanan rule_lock = &sw->recp_list[recp_id].filt_rule_lock; 317680d144c9SAnirudh Venkataramanan 317780d144c9SAnirudh Venkataramanan mutex_lock(rule_lock); 31789daf8208SAnirudh Venkataramanan new_fltr = &f_entry->fltr_info; 317980d144c9SAnirudh Venkataramanan if (new_fltr->flag & ICE_FLTR_RX) 318080d144c9SAnirudh Venkataramanan new_fltr->src = hw->port_info->lport; 318180d144c9SAnirudh Venkataramanan else if (new_fltr->flag & ICE_FLTR_TX) 31825726ca0eSAnirudh Venkataramanan new_fltr->src = f_entry->fltr_info.fwd_id.hw_vsi_id; 31839daf8208SAnirudh Venkataramanan 318480d144c9SAnirudh Venkataramanan m_entry = ice_find_rule_entry(hw, recp_id, new_fltr); 318580d144c9SAnirudh Venkataramanan if (!m_entry) { 318680d144c9SAnirudh Venkataramanan mutex_unlock(rule_lock); 31879daf8208SAnirudh Venkataramanan return ice_create_pkt_fwd_rule(hw, f_entry); 318880d144c9SAnirudh Venkataramanan } 31899daf8208SAnirudh Venkataramanan 31909daf8208SAnirudh Venkataramanan cur_fltr = &m_entry->fltr_info; 319180d144c9SAnirudh Venkataramanan status = ice_add_update_vsi_list(hw, m_entry, cur_fltr, new_fltr); 319280d144c9SAnirudh Venkataramanan mutex_unlock(rule_lock); 31939daf8208SAnirudh Venkataramanan 319480d144c9SAnirudh Venkataramanan return status; 319580d144c9SAnirudh Venkataramanan } 319680d144c9SAnirudh Venkataramanan 319780d144c9SAnirudh Venkataramanan /** 319880d144c9SAnirudh Venkataramanan * ice_remove_vsi_list_rule 319980d144c9SAnirudh Venkataramanan * @hw: pointer to the hardware structure 3200f9867df6SAnirudh Venkataramanan * @vsi_list_id: VSI list ID generated as part of allocate resource 320180d144c9SAnirudh Venkataramanan * @lkup_type: switch rule filter lookup type 320280d144c9SAnirudh Venkataramanan * 320380d144c9SAnirudh Venkataramanan * The VSI list should be emptied before this function is called to remove the 320480d144c9SAnirudh Venkataramanan * VSI list. 320580d144c9SAnirudh Venkataramanan */ 32065e24d598STony Nguyen static int 320780d144c9SAnirudh Venkataramanan ice_remove_vsi_list_rule(struct ice_hw *hw, u16 vsi_list_id, 320880d144c9SAnirudh Venkataramanan enum ice_sw_lkup_type lkup_type) 320980d144c9SAnirudh Venkataramanan { 32106e1ff618SAlexander Lobakin struct ice_sw_rule_vsi_list *s_rule; 321180d144c9SAnirudh Venkataramanan u16 s_rule_size; 32125518ac2aSTony Nguyen int status; 321380d144c9SAnirudh Venkataramanan 32146e1ff618SAlexander Lobakin s_rule_size = (u16)ICE_SW_RULE_VSI_LIST_SIZE(s_rule, 0); 321580d144c9SAnirudh Venkataramanan s_rule = devm_kzalloc(ice_hw_to_dev(hw), s_rule_size, GFP_KERNEL); 321680d144c9SAnirudh Venkataramanan if (!s_rule) 3217d54699e2STony Nguyen return -ENOMEM; 321880d144c9SAnirudh Venkataramanan 32196e1ff618SAlexander Lobakin s_rule->hdr.type = cpu_to_le16(ICE_AQC_SW_RULES_T_VSI_LIST_CLEAR); 32206e1ff618SAlexander Lobakin s_rule->index = cpu_to_le16(vsi_list_id); 322180d144c9SAnirudh Venkataramanan 322280d144c9SAnirudh Venkataramanan /* Free the vsi_list resource that we allocated. It is assumed that the 322380d144c9SAnirudh Venkataramanan * list is empty at this point. 322480d144c9SAnirudh Venkataramanan */ 322580d144c9SAnirudh Venkataramanan status = ice_aq_alloc_free_vsi_list(hw, &vsi_list_id, lkup_type, 322680d144c9SAnirudh Venkataramanan ice_aqc_opc_free_res); 322780d144c9SAnirudh Venkataramanan 322880d144c9SAnirudh Venkataramanan devm_kfree(ice_hw_to_dev(hw), s_rule); 322980d144c9SAnirudh Venkataramanan return status; 323080d144c9SAnirudh Venkataramanan } 323180d144c9SAnirudh Venkataramanan 323280d144c9SAnirudh Venkataramanan /** 323380d144c9SAnirudh Venkataramanan * ice_rem_update_vsi_list 323480d144c9SAnirudh Venkataramanan * @hw: pointer to the hardware structure 32355726ca0eSAnirudh Venkataramanan * @vsi_handle: VSI handle of the VSI to remove 323680d144c9SAnirudh Venkataramanan * @fm_list: filter management entry for which the VSI list management needs to 323780d144c9SAnirudh Venkataramanan * be done 323880d144c9SAnirudh Venkataramanan */ 32395e24d598STony Nguyen static int 32405726ca0eSAnirudh Venkataramanan ice_rem_update_vsi_list(struct ice_hw *hw, u16 vsi_handle, 324180d144c9SAnirudh Venkataramanan struct ice_fltr_mgmt_list_entry *fm_list) 324280d144c9SAnirudh Venkataramanan { 324380d144c9SAnirudh Venkataramanan enum ice_sw_lkup_type lkup_type; 324480d144c9SAnirudh Venkataramanan u16 vsi_list_id; 32455518ac2aSTony Nguyen int status = 0; 324680d144c9SAnirudh Venkataramanan 324780d144c9SAnirudh Venkataramanan if (fm_list->fltr_info.fltr_act != ICE_FWD_TO_VSI_LIST || 324880d144c9SAnirudh Venkataramanan fm_list->vsi_count == 0) 3249d54699e2STony Nguyen return -EINVAL; 325080d144c9SAnirudh Venkataramanan 325180d144c9SAnirudh Venkataramanan /* A rule with the VSI being removed does not exist */ 32525726ca0eSAnirudh Venkataramanan if (!test_bit(vsi_handle, fm_list->vsi_list_info->vsi_map)) 3253d54699e2STony Nguyen return -ENOENT; 325480d144c9SAnirudh Venkataramanan 325580d144c9SAnirudh Venkataramanan lkup_type = fm_list->fltr_info.lkup_type; 325680d144c9SAnirudh Venkataramanan vsi_list_id = fm_list->fltr_info.fwd_id.vsi_list_id; 32575726ca0eSAnirudh Venkataramanan status = ice_update_vsi_list_rule(hw, &vsi_handle, 1, vsi_list_id, true, 325880d144c9SAnirudh Venkataramanan ice_aqc_opc_update_sw_rules, 325980d144c9SAnirudh Venkataramanan lkup_type); 326080d144c9SAnirudh Venkataramanan if (status) 326180d144c9SAnirudh Venkataramanan return status; 326280d144c9SAnirudh Venkataramanan 326380d144c9SAnirudh Venkataramanan fm_list->vsi_count--; 32645726ca0eSAnirudh Venkataramanan clear_bit(vsi_handle, fm_list->vsi_list_info->vsi_map); 326580d144c9SAnirudh Venkataramanan 3266c60cdb13SBrett Creeley if (fm_list->vsi_count == 1 && lkup_type != ICE_SW_LKUP_VLAN) { 3267c60cdb13SBrett Creeley struct ice_fltr_info tmp_fltr_info = fm_list->fltr_info; 326880d144c9SAnirudh Venkataramanan struct ice_vsi_list_map_info *vsi_list_info = 326980d144c9SAnirudh Venkataramanan fm_list->vsi_list_info; 32705726ca0eSAnirudh Venkataramanan u16 rem_vsi_handle; 327180d144c9SAnirudh Venkataramanan 32725726ca0eSAnirudh Venkataramanan rem_vsi_handle = find_first_bit(vsi_list_info->vsi_map, 327380d144c9SAnirudh Venkataramanan ICE_MAX_VSI); 32745726ca0eSAnirudh Venkataramanan if (!ice_is_vsi_valid(hw, rem_vsi_handle)) 3275d54699e2STony Nguyen return -EIO; 3276c60cdb13SBrett Creeley 3277c60cdb13SBrett Creeley /* Make sure VSI list is empty before removing it below */ 32785726ca0eSAnirudh Venkataramanan status = ice_update_vsi_list_rule(hw, &rem_vsi_handle, 1, 327980d144c9SAnirudh Venkataramanan vsi_list_id, true, 328080d144c9SAnirudh Venkataramanan ice_aqc_opc_update_sw_rules, 328180d144c9SAnirudh Venkataramanan lkup_type); 328280d144c9SAnirudh Venkataramanan if (status) 328380d144c9SAnirudh Venkataramanan return status; 328480d144c9SAnirudh Venkataramanan 3285c60cdb13SBrett Creeley tmp_fltr_info.fltr_act = ICE_FWD_TO_VSI; 3286c60cdb13SBrett Creeley tmp_fltr_info.fwd_id.hw_vsi_id = 3287c60cdb13SBrett Creeley ice_get_hw_vsi_num(hw, rem_vsi_handle); 3288c60cdb13SBrett Creeley tmp_fltr_info.vsi_handle = rem_vsi_handle; 3289c60cdb13SBrett Creeley status = ice_update_pkt_fwd_rule(hw, &tmp_fltr_info); 3290c60cdb13SBrett Creeley if (status) { 32919228d8b2SJacob Keller ice_debug(hw, ICE_DBG_SW, "Failed to update pkt fwd rule to FWD_TO_VSI on HW VSI %d, error %d\n", 3292c60cdb13SBrett Creeley tmp_fltr_info.fwd_id.hw_vsi_id, status); 3293c60cdb13SBrett Creeley return status; 3294c60cdb13SBrett Creeley } 3295c60cdb13SBrett Creeley 3296c60cdb13SBrett Creeley fm_list->fltr_info = tmp_fltr_info; 3297c60cdb13SBrett Creeley } 3298c60cdb13SBrett Creeley 3299c60cdb13SBrett Creeley if ((fm_list->vsi_count == 1 && lkup_type != ICE_SW_LKUP_VLAN) || 3300c60cdb13SBrett Creeley (fm_list->vsi_count == 0 && lkup_type == ICE_SW_LKUP_VLAN)) { 3301c60cdb13SBrett Creeley struct ice_vsi_list_map_info *vsi_list_info = 3302c60cdb13SBrett Creeley fm_list->vsi_list_info; 3303c60cdb13SBrett Creeley 330480d144c9SAnirudh Venkataramanan /* Remove the VSI list since it is no longer used */ 330580d144c9SAnirudh Venkataramanan status = ice_remove_vsi_list_rule(hw, vsi_list_id, lkup_type); 3306c60cdb13SBrett Creeley if (status) { 33079228d8b2SJacob Keller ice_debug(hw, ICE_DBG_SW, "Failed to remove VSI list %d, error %d\n", 3308c60cdb13SBrett Creeley vsi_list_id, status); 330980d144c9SAnirudh Venkataramanan return status; 3310c60cdb13SBrett Creeley } 331180d144c9SAnirudh Venkataramanan 331280d144c9SAnirudh Venkataramanan list_del(&vsi_list_info->list_entry); 331380d144c9SAnirudh Venkataramanan devm_kfree(ice_hw_to_dev(hw), vsi_list_info); 331480d144c9SAnirudh Venkataramanan fm_list->vsi_list_info = NULL; 331580d144c9SAnirudh Venkataramanan } 331680d144c9SAnirudh Venkataramanan 331780d144c9SAnirudh Venkataramanan return status; 331880d144c9SAnirudh Venkataramanan } 331980d144c9SAnirudh Venkataramanan 332080d144c9SAnirudh Venkataramanan /** 332180d144c9SAnirudh Venkataramanan * ice_remove_rule_internal - Remove a filter rule of a given type 332280d144c9SAnirudh Venkataramanan * @hw: pointer to the hardware structure 3323f9867df6SAnirudh Venkataramanan * @recp_id: recipe ID for which the rule needs to removed 332480d144c9SAnirudh Venkataramanan * @f_entry: rule entry containing filter information 332580d144c9SAnirudh Venkataramanan */ 33265e24d598STony Nguyen static int 332780d144c9SAnirudh Venkataramanan ice_remove_rule_internal(struct ice_hw *hw, u8 recp_id, 332880d144c9SAnirudh Venkataramanan struct ice_fltr_list_entry *f_entry) 332980d144c9SAnirudh Venkataramanan { 333080d144c9SAnirudh Venkataramanan struct ice_switch_info *sw = hw->switch_info; 333180d144c9SAnirudh Venkataramanan struct ice_fltr_mgmt_list_entry *list_elem; 333280d144c9SAnirudh Venkataramanan struct mutex *rule_lock; /* Lock to protect filter rule list */ 333380d144c9SAnirudh Venkataramanan bool remove_rule = false; 33345726ca0eSAnirudh Venkataramanan u16 vsi_handle; 33355518ac2aSTony Nguyen int status = 0; 33365726ca0eSAnirudh Venkataramanan 33375726ca0eSAnirudh Venkataramanan if (!ice_is_vsi_valid(hw, f_entry->fltr_info.vsi_handle)) 3338d54699e2STony Nguyen return -EINVAL; 33395726ca0eSAnirudh Venkataramanan f_entry->fltr_info.fwd_id.hw_vsi_id = 33405726ca0eSAnirudh Venkataramanan ice_get_hw_vsi_num(hw, f_entry->fltr_info.vsi_handle); 334180d144c9SAnirudh Venkataramanan 334280d144c9SAnirudh Venkataramanan rule_lock = &sw->recp_list[recp_id].filt_rule_lock; 334380d144c9SAnirudh Venkataramanan mutex_lock(rule_lock); 334480d144c9SAnirudh Venkataramanan list_elem = ice_find_rule_entry(hw, recp_id, &f_entry->fltr_info); 334580d144c9SAnirudh Venkataramanan if (!list_elem) { 3346d54699e2STony Nguyen status = -ENOENT; 334780d144c9SAnirudh Venkataramanan goto exit; 334880d144c9SAnirudh Venkataramanan } 334980d144c9SAnirudh Venkataramanan 335080d144c9SAnirudh Venkataramanan if (list_elem->fltr_info.fltr_act != ICE_FWD_TO_VSI_LIST) { 335180d144c9SAnirudh Venkataramanan remove_rule = true; 33525726ca0eSAnirudh Venkataramanan } else if (!list_elem->vsi_list_info) { 3353d54699e2STony Nguyen status = -ENOENT; 33545726ca0eSAnirudh Venkataramanan goto exit; 3355f9264dd6SJacob Keller } else if (list_elem->vsi_list_info->ref_cnt > 1) { 3356f9264dd6SJacob Keller /* a ref_cnt > 1 indicates that the vsi_list is being 3357f9264dd6SJacob Keller * shared by multiple rules. Decrement the ref_cnt and 3358f9264dd6SJacob Keller * remove this rule, but do not modify the list, as it 3359f9264dd6SJacob Keller * is in-use by other rules. 3360f9264dd6SJacob Keller */ 33615726ca0eSAnirudh Venkataramanan list_elem->vsi_list_info->ref_cnt--; 3362f9264dd6SJacob Keller remove_rule = true; 3363f9264dd6SJacob Keller } else { 3364f9264dd6SJacob Keller /* a ref_cnt of 1 indicates the vsi_list is only used 3365f9264dd6SJacob Keller * by one rule. However, the original removal request is only 3366f9264dd6SJacob Keller * for a single VSI. Update the vsi_list first, and only 3367f9264dd6SJacob Keller * remove the rule if there are no further VSIs in this list. 3368f9264dd6SJacob Keller */ 33695726ca0eSAnirudh Venkataramanan vsi_handle = f_entry->fltr_info.vsi_handle; 33705726ca0eSAnirudh Venkataramanan status = ice_rem_update_vsi_list(hw, vsi_handle, list_elem); 337180d144c9SAnirudh Venkataramanan if (status) 337280d144c9SAnirudh Venkataramanan goto exit; 3373f9867df6SAnirudh Venkataramanan /* if VSI count goes to zero after updating the VSI list */ 337480d144c9SAnirudh Venkataramanan if (list_elem->vsi_count == 0) 337580d144c9SAnirudh Venkataramanan remove_rule = true; 337680d144c9SAnirudh Venkataramanan } 337780d144c9SAnirudh Venkataramanan 337880d144c9SAnirudh Venkataramanan if (remove_rule) { 337980d144c9SAnirudh Venkataramanan /* Remove the lookup rule */ 33806e1ff618SAlexander Lobakin struct ice_sw_rule_lkup_rx_tx *s_rule; 338180d144c9SAnirudh Venkataramanan 338280d144c9SAnirudh Venkataramanan s_rule = devm_kzalloc(ice_hw_to_dev(hw), 33836e1ff618SAlexander Lobakin ICE_SW_RULE_RX_TX_NO_HDR_SIZE(s_rule), 338480d144c9SAnirudh Venkataramanan GFP_KERNEL); 338580d144c9SAnirudh Venkataramanan if (!s_rule) { 3386d54699e2STony Nguyen status = -ENOMEM; 338780d144c9SAnirudh Venkataramanan goto exit; 338880d144c9SAnirudh Venkataramanan } 338980d144c9SAnirudh Venkataramanan 339080d144c9SAnirudh Venkataramanan ice_fill_sw_rule(hw, &list_elem->fltr_info, s_rule, 339180d144c9SAnirudh Venkataramanan ice_aqc_opc_remove_sw_rules); 339280d144c9SAnirudh Venkataramanan 339380d144c9SAnirudh Venkataramanan status = ice_aq_sw_rules(hw, s_rule, 33946e1ff618SAlexander Lobakin ICE_SW_RULE_RX_TX_NO_HDR_SIZE(s_rule), 33956e1ff618SAlexander Lobakin 1, ice_aqc_opc_remove_sw_rules, NULL); 339680d144c9SAnirudh Venkataramanan 339780d144c9SAnirudh Venkataramanan /* Remove a book keeping from the list */ 339880d144c9SAnirudh Venkataramanan devm_kfree(ice_hw_to_dev(hw), s_rule); 339980d144c9SAnirudh Venkataramanan 34008132e17dSJeb Cramer if (status) 34018132e17dSJeb Cramer goto exit; 34028132e17dSJeb Cramer 340380d144c9SAnirudh Venkataramanan list_del(&list_elem->list_entry); 340480d144c9SAnirudh Venkataramanan devm_kfree(ice_hw_to_dev(hw), list_elem); 340580d144c9SAnirudh Venkataramanan } 340680d144c9SAnirudh Venkataramanan exit: 340780d144c9SAnirudh Venkataramanan mutex_unlock(rule_lock); 340880d144c9SAnirudh Venkataramanan return status; 34099daf8208SAnirudh Venkataramanan } 34109daf8208SAnirudh Venkataramanan 34119daf8208SAnirudh Venkataramanan /** 34129fea7498SKiran Patil * ice_vlan_fltr_exist - does this VLAN filter exist for given VSI 34139fea7498SKiran Patil * @hw: pointer to the hardware structure 34149fea7498SKiran Patil * @vlan_id: VLAN ID 34159fea7498SKiran Patil * @vsi_handle: check MAC filter for this VSI 34169fea7498SKiran Patil */ 34179fea7498SKiran Patil bool ice_vlan_fltr_exist(struct ice_hw *hw, u16 vlan_id, u16 vsi_handle) 34189fea7498SKiran Patil { 34199fea7498SKiran Patil struct ice_fltr_mgmt_list_entry *entry; 34209fea7498SKiran Patil struct list_head *rule_head; 34219fea7498SKiran Patil struct ice_switch_info *sw; 34229fea7498SKiran Patil struct mutex *rule_lock; /* Lock to protect filter rule list */ 34239fea7498SKiran Patil u16 hw_vsi_id; 34249fea7498SKiran Patil 34259fea7498SKiran Patil if (vlan_id > ICE_MAX_VLAN_ID) 34269fea7498SKiran Patil return false; 34279fea7498SKiran Patil 34289fea7498SKiran Patil if (!ice_is_vsi_valid(hw, vsi_handle)) 34299fea7498SKiran Patil return false; 34309fea7498SKiran Patil 34319fea7498SKiran Patil hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle); 34329fea7498SKiran Patil sw = hw->switch_info; 34339fea7498SKiran Patil rule_head = &sw->recp_list[ICE_SW_LKUP_VLAN].filt_rules; 34349fea7498SKiran Patil if (!rule_head) 34359fea7498SKiran Patil return false; 34369fea7498SKiran Patil 34379fea7498SKiran Patil rule_lock = &sw->recp_list[ICE_SW_LKUP_VLAN].filt_rule_lock; 34389fea7498SKiran Patil mutex_lock(rule_lock); 34399fea7498SKiran Patil list_for_each_entry(entry, rule_head, list_entry) { 34409fea7498SKiran Patil struct ice_fltr_info *f_info = &entry->fltr_info; 34419fea7498SKiran Patil u16 entry_vlan_id = f_info->l_data.vlan.vlan_id; 34429fea7498SKiran Patil struct ice_vsi_list_map_info *map_info; 34439fea7498SKiran Patil 34449fea7498SKiran Patil if (entry_vlan_id > ICE_MAX_VLAN_ID) 34459fea7498SKiran Patil continue; 34469fea7498SKiran Patil 34479fea7498SKiran Patil if (f_info->flag != ICE_FLTR_TX || 34489fea7498SKiran Patil f_info->src_id != ICE_SRC_ID_VSI || 34499fea7498SKiran Patil f_info->lkup_type != ICE_SW_LKUP_VLAN) 34509fea7498SKiran Patil continue; 34519fea7498SKiran Patil 34529fea7498SKiran Patil /* Only allowed filter action are FWD_TO_VSI/_VSI_LIST */ 34539fea7498SKiran Patil if (f_info->fltr_act != ICE_FWD_TO_VSI && 34549fea7498SKiran Patil f_info->fltr_act != ICE_FWD_TO_VSI_LIST) 34559fea7498SKiran Patil continue; 34569fea7498SKiran Patil 34579fea7498SKiran Patil if (f_info->fltr_act == ICE_FWD_TO_VSI) { 34589fea7498SKiran Patil if (hw_vsi_id != f_info->fwd_id.hw_vsi_id) 34599fea7498SKiran Patil continue; 34609fea7498SKiran Patil } else if (f_info->fltr_act == ICE_FWD_TO_VSI_LIST) { 34619fea7498SKiran Patil /* If filter_action is FWD_TO_VSI_LIST, make sure 34629fea7498SKiran Patil * that VSI being checked is part of VSI list 34639fea7498SKiran Patil */ 34649fea7498SKiran Patil if (entry->vsi_count == 1 && 34659fea7498SKiran Patil entry->vsi_list_info) { 34669fea7498SKiran Patil map_info = entry->vsi_list_info; 34679fea7498SKiran Patil if (!test_bit(vsi_handle, map_info->vsi_map)) 34689fea7498SKiran Patil continue; 34699fea7498SKiran Patil } 34709fea7498SKiran Patil } 34719fea7498SKiran Patil 34729fea7498SKiran Patil if (vlan_id == entry_vlan_id) { 34739fea7498SKiran Patil mutex_unlock(rule_lock); 34749fea7498SKiran Patil return true; 34759fea7498SKiran Patil } 34769fea7498SKiran Patil } 34779fea7498SKiran Patil mutex_unlock(rule_lock); 34789fea7498SKiran Patil 34799fea7498SKiran Patil return false; 34809fea7498SKiran Patil } 34819fea7498SKiran Patil 34829fea7498SKiran Patil /** 34839daf8208SAnirudh Venkataramanan * ice_add_mac - Add a MAC address based filter rule 34849daf8208SAnirudh Venkataramanan * @hw: pointer to the hardware structure 34859daf8208SAnirudh Venkataramanan * @m_list: list of MAC addresses and forwarding information 34869daf8208SAnirudh Venkataramanan */ 34875e24d598STony Nguyen int ice_add_mac(struct ice_hw *hw, struct list_head *m_list) 34889daf8208SAnirudh Venkataramanan { 34899daf8208SAnirudh Venkataramanan struct ice_fltr_list_entry *m_list_itr; 34905518ac2aSTony Nguyen int status = 0; 34919daf8208SAnirudh Venkataramanan 34929daf8208SAnirudh Venkataramanan if (!m_list || !hw) 3493d54699e2STony Nguyen return -EINVAL; 34949daf8208SAnirudh Venkataramanan 34959daf8208SAnirudh Venkataramanan list_for_each_entry(m_list_itr, m_list, list_entry) { 34969daf8208SAnirudh Venkataramanan u8 *add = &m_list_itr->fltr_info.l_data.mac.mac_addr[0]; 34975726ca0eSAnirudh Venkataramanan u16 vsi_handle; 34985726ca0eSAnirudh Venkataramanan u16 hw_vsi_id; 34999daf8208SAnirudh Venkataramanan 350080d144c9SAnirudh Venkataramanan m_list_itr->fltr_info.flag = ICE_FLTR_TX; 35015726ca0eSAnirudh Venkataramanan vsi_handle = m_list_itr->fltr_info.vsi_handle; 35025726ca0eSAnirudh Venkataramanan if (!ice_is_vsi_valid(hw, vsi_handle)) 3503d54699e2STony Nguyen return -EINVAL; 35045726ca0eSAnirudh Venkataramanan hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle); 35055726ca0eSAnirudh Venkataramanan m_list_itr->fltr_info.fwd_id.hw_vsi_id = hw_vsi_id; 3506f9867df6SAnirudh Venkataramanan /* update the src in case it is VSI num */ 35075726ca0eSAnirudh Venkataramanan if (m_list_itr->fltr_info.src_id != ICE_SRC_ID_VSI) 3508d54699e2STony Nguyen return -EINVAL; 35095726ca0eSAnirudh Venkataramanan m_list_itr->fltr_info.src = hw_vsi_id; 351080d144c9SAnirudh Venkataramanan if (m_list_itr->fltr_info.lkup_type != ICE_SW_LKUP_MAC || 351180d144c9SAnirudh Venkataramanan is_zero_ether_addr(add)) 3512d54699e2STony Nguyen return -EINVAL; 3513e1e9db57SSylwester Dziedziuch 3514e1e9db57SSylwester Dziedziuch m_list_itr->status = ice_add_rule_internal(hw, ICE_SW_LKUP_MAC, 351580d144c9SAnirudh Venkataramanan m_list_itr); 351680d144c9SAnirudh Venkataramanan if (m_list_itr->status) 351780d144c9SAnirudh Venkataramanan return m_list_itr->status; 35189daf8208SAnirudh Venkataramanan } 35199daf8208SAnirudh Venkataramanan 35209daf8208SAnirudh Venkataramanan return status; 35219daf8208SAnirudh Venkataramanan } 35229daf8208SAnirudh Venkataramanan 35239daf8208SAnirudh Venkataramanan /** 3524d76a60baSAnirudh Venkataramanan * ice_add_vlan_internal - Add one VLAN based filter rule 3525d76a60baSAnirudh Venkataramanan * @hw: pointer to the hardware structure 3526d76a60baSAnirudh Venkataramanan * @f_entry: filter entry containing one VLAN information 3527d76a60baSAnirudh Venkataramanan */ 35285e24d598STony Nguyen static int 3529d76a60baSAnirudh Venkataramanan ice_add_vlan_internal(struct ice_hw *hw, struct ice_fltr_list_entry *f_entry) 3530d76a60baSAnirudh Venkataramanan { 353180d144c9SAnirudh Venkataramanan struct ice_switch_info *sw = hw->switch_info; 3532d76a60baSAnirudh Venkataramanan struct ice_fltr_mgmt_list_entry *v_list_itr; 35335726ca0eSAnirudh Venkataramanan struct ice_fltr_info *new_fltr, *cur_fltr; 35345726ca0eSAnirudh Venkataramanan enum ice_sw_lkup_type lkup_type; 35355726ca0eSAnirudh Venkataramanan u16 vsi_list_id = 0, vsi_handle; 353680d144c9SAnirudh Venkataramanan struct mutex *rule_lock; /* Lock to protect filter rule list */ 35375e24d598STony Nguyen int status = 0; 3538d76a60baSAnirudh Venkataramanan 35395726ca0eSAnirudh Venkataramanan if (!ice_is_vsi_valid(hw, f_entry->fltr_info.vsi_handle)) 3540d54699e2STony Nguyen return -EINVAL; 35415726ca0eSAnirudh Venkataramanan 35425726ca0eSAnirudh Venkataramanan f_entry->fltr_info.fwd_id.hw_vsi_id = 35435726ca0eSAnirudh Venkataramanan ice_get_hw_vsi_num(hw, f_entry->fltr_info.vsi_handle); 3544d76a60baSAnirudh Venkataramanan new_fltr = &f_entry->fltr_info; 35455726ca0eSAnirudh Venkataramanan 3546f9867df6SAnirudh Venkataramanan /* VLAN ID should only be 12 bits */ 3547d76a60baSAnirudh Venkataramanan if (new_fltr->l_data.vlan.vlan_id > ICE_MAX_VLAN_ID) 3548d54699e2STony Nguyen return -EINVAL; 3549d76a60baSAnirudh Venkataramanan 35505726ca0eSAnirudh Venkataramanan if (new_fltr->src_id != ICE_SRC_ID_VSI) 3551d54699e2STony Nguyen return -EINVAL; 35525726ca0eSAnirudh Venkataramanan 35535726ca0eSAnirudh Venkataramanan new_fltr->src = new_fltr->fwd_id.hw_vsi_id; 35545726ca0eSAnirudh Venkataramanan lkup_type = new_fltr->lkup_type; 35555726ca0eSAnirudh Venkataramanan vsi_handle = new_fltr->vsi_handle; 355680d144c9SAnirudh Venkataramanan rule_lock = &sw->recp_list[ICE_SW_LKUP_VLAN].filt_rule_lock; 355780d144c9SAnirudh Venkataramanan mutex_lock(rule_lock); 355880d144c9SAnirudh Venkataramanan v_list_itr = ice_find_rule_entry(hw, ICE_SW_LKUP_VLAN, new_fltr); 3559d76a60baSAnirudh Venkataramanan if (!v_list_itr) { 35605726ca0eSAnirudh Venkataramanan struct ice_vsi_list_map_info *map_info = NULL; 3561d76a60baSAnirudh Venkataramanan 3562d76a60baSAnirudh Venkataramanan if (new_fltr->fltr_act == ICE_FWD_TO_VSI) { 35635726ca0eSAnirudh Venkataramanan /* All VLAN pruning rules use a VSI list. Check if 35645726ca0eSAnirudh Venkataramanan * there is already a VSI list containing VSI that we 35655726ca0eSAnirudh Venkataramanan * want to add. If found, use the same vsi_list_id for 35665726ca0eSAnirudh Venkataramanan * this new VLAN rule or else create a new list. 3567d76a60baSAnirudh Venkataramanan */ 35685726ca0eSAnirudh Venkataramanan map_info = ice_find_vsi_list_entry(hw, ICE_SW_LKUP_VLAN, 35695726ca0eSAnirudh Venkataramanan vsi_handle, 35705726ca0eSAnirudh Venkataramanan &vsi_list_id); 35715726ca0eSAnirudh Venkataramanan if (!map_info) { 35725726ca0eSAnirudh Venkataramanan status = ice_create_vsi_list_rule(hw, 35735726ca0eSAnirudh Venkataramanan &vsi_handle, 35745726ca0eSAnirudh Venkataramanan 1, 3575d76a60baSAnirudh Venkataramanan &vsi_list_id, 3576d76a60baSAnirudh Venkataramanan lkup_type); 3577d76a60baSAnirudh Venkataramanan if (status) 357880d144c9SAnirudh Venkataramanan goto exit; 35795726ca0eSAnirudh Venkataramanan } 35805726ca0eSAnirudh Venkataramanan /* Convert the action to forwarding to a VSI list. */ 3581d76a60baSAnirudh Venkataramanan new_fltr->fltr_act = ICE_FWD_TO_VSI_LIST; 3582d76a60baSAnirudh Venkataramanan new_fltr->fwd_id.vsi_list_id = vsi_list_id; 3583d76a60baSAnirudh Venkataramanan } 3584d76a60baSAnirudh Venkataramanan 3585d76a60baSAnirudh Venkataramanan status = ice_create_pkt_fwd_rule(hw, f_entry); 35865726ca0eSAnirudh Venkataramanan if (!status) { 358780d144c9SAnirudh Venkataramanan v_list_itr = ice_find_rule_entry(hw, ICE_SW_LKUP_VLAN, 358880d144c9SAnirudh Venkataramanan new_fltr); 358980d144c9SAnirudh Venkataramanan if (!v_list_itr) { 3590d54699e2STony Nguyen status = -ENOENT; 359180d144c9SAnirudh Venkataramanan goto exit; 359280d144c9SAnirudh Venkataramanan } 35935726ca0eSAnirudh Venkataramanan /* reuse VSI list for new rule and increment ref_cnt */ 35945726ca0eSAnirudh Venkataramanan if (map_info) { 35955726ca0eSAnirudh Venkataramanan v_list_itr->vsi_list_info = map_info; 35965726ca0eSAnirudh Venkataramanan map_info->ref_cnt++; 35975726ca0eSAnirudh Venkataramanan } else { 3598d76a60baSAnirudh Venkataramanan v_list_itr->vsi_list_info = 35995726ca0eSAnirudh Venkataramanan ice_create_vsi_list_map(hw, &vsi_handle, 36005726ca0eSAnirudh Venkataramanan 1, vsi_list_id); 3601d76a60baSAnirudh Venkataramanan } 36025726ca0eSAnirudh Venkataramanan } 36035726ca0eSAnirudh Venkataramanan } else if (v_list_itr->vsi_list_info->ref_cnt == 1) { 3604f9867df6SAnirudh Venkataramanan /* Update existing VSI list to add new VSI ID only if it used 36055726ca0eSAnirudh Venkataramanan * by one VLAN rule. 36065726ca0eSAnirudh Venkataramanan */ 36075726ca0eSAnirudh Venkataramanan cur_fltr = &v_list_itr->fltr_info; 36085726ca0eSAnirudh Venkataramanan status = ice_add_update_vsi_list(hw, v_list_itr, cur_fltr, 36095726ca0eSAnirudh Venkataramanan new_fltr); 36105726ca0eSAnirudh Venkataramanan } else { 36115726ca0eSAnirudh Venkataramanan /* If VLAN rule exists and VSI list being used by this rule is 36125726ca0eSAnirudh Venkataramanan * referenced by more than 1 VLAN rule. Then create a new VSI 36135726ca0eSAnirudh Venkataramanan * list appending previous VSI with new VSI and update existing 3614f9867df6SAnirudh Venkataramanan * VLAN rule to point to new VSI list ID 36155726ca0eSAnirudh Venkataramanan */ 36165726ca0eSAnirudh Venkataramanan struct ice_fltr_info tmp_fltr; 36175726ca0eSAnirudh Venkataramanan u16 vsi_handle_arr[2]; 36185726ca0eSAnirudh Venkataramanan u16 cur_handle; 3619d76a60baSAnirudh Venkataramanan 36205726ca0eSAnirudh Venkataramanan /* Current implementation only supports reusing VSI list with 36215726ca0eSAnirudh Venkataramanan * one VSI count. We should never hit below condition 36225726ca0eSAnirudh Venkataramanan */ 36235726ca0eSAnirudh Venkataramanan if (v_list_itr->vsi_count > 1 && 36245726ca0eSAnirudh Venkataramanan v_list_itr->vsi_list_info->ref_cnt > 1) { 36259228d8b2SJacob Keller ice_debug(hw, ICE_DBG_SW, "Invalid configuration: Optimization to reuse VSI list with more than one VSI is not being done yet\n"); 3626d54699e2STony Nguyen status = -EIO; 362780d144c9SAnirudh Venkataramanan goto exit; 3628d76a60baSAnirudh Venkataramanan } 3629d76a60baSAnirudh Venkataramanan 36305726ca0eSAnirudh Venkataramanan cur_handle = 36315726ca0eSAnirudh Venkataramanan find_first_bit(v_list_itr->vsi_list_info->vsi_map, 36325726ca0eSAnirudh Venkataramanan ICE_MAX_VSI); 36335726ca0eSAnirudh Venkataramanan 36345726ca0eSAnirudh Venkataramanan /* A rule already exists with the new VSI being added */ 36355726ca0eSAnirudh Venkataramanan if (cur_handle == vsi_handle) { 3636d54699e2STony Nguyen status = -EEXIST; 36375726ca0eSAnirudh Venkataramanan goto exit; 36385726ca0eSAnirudh Venkataramanan } 36395726ca0eSAnirudh Venkataramanan 36405726ca0eSAnirudh Venkataramanan vsi_handle_arr[0] = cur_handle; 36415726ca0eSAnirudh Venkataramanan vsi_handle_arr[1] = vsi_handle; 36425726ca0eSAnirudh Venkataramanan status = ice_create_vsi_list_rule(hw, &vsi_handle_arr[0], 2, 36435726ca0eSAnirudh Venkataramanan &vsi_list_id, lkup_type); 36445726ca0eSAnirudh Venkataramanan if (status) 36455726ca0eSAnirudh Venkataramanan goto exit; 36465726ca0eSAnirudh Venkataramanan 36475726ca0eSAnirudh Venkataramanan tmp_fltr = v_list_itr->fltr_info; 36485726ca0eSAnirudh Venkataramanan tmp_fltr.fltr_rule_id = v_list_itr->fltr_info.fltr_rule_id; 36495726ca0eSAnirudh Venkataramanan tmp_fltr.fwd_id.vsi_list_id = vsi_list_id; 36505726ca0eSAnirudh Venkataramanan tmp_fltr.fltr_act = ICE_FWD_TO_VSI_LIST; 36515726ca0eSAnirudh Venkataramanan /* Update the previous switch rule to a new VSI list which 3652df17b7e0SAnirudh Venkataramanan * includes current VSI that is requested 36535726ca0eSAnirudh Venkataramanan */ 36545726ca0eSAnirudh Venkataramanan status = ice_update_pkt_fwd_rule(hw, &tmp_fltr); 36555726ca0eSAnirudh Venkataramanan if (status) 36565726ca0eSAnirudh Venkataramanan goto exit; 36575726ca0eSAnirudh Venkataramanan 36585726ca0eSAnirudh Venkataramanan /* before overriding VSI list map info. decrement ref_cnt of 36595726ca0eSAnirudh Venkataramanan * previous VSI list 36605726ca0eSAnirudh Venkataramanan */ 36615726ca0eSAnirudh Venkataramanan v_list_itr->vsi_list_info->ref_cnt--; 36625726ca0eSAnirudh Venkataramanan 36635726ca0eSAnirudh Venkataramanan /* now update to newly created list */ 36645726ca0eSAnirudh Venkataramanan v_list_itr->fltr_info.fwd_id.vsi_list_id = vsi_list_id; 36655726ca0eSAnirudh Venkataramanan v_list_itr->vsi_list_info = 36665726ca0eSAnirudh Venkataramanan ice_create_vsi_list_map(hw, &vsi_handle_arr[0], 2, 36675726ca0eSAnirudh Venkataramanan vsi_list_id); 36685726ca0eSAnirudh Venkataramanan v_list_itr->vsi_count++; 36695726ca0eSAnirudh Venkataramanan } 367080d144c9SAnirudh Venkataramanan 367180d144c9SAnirudh Venkataramanan exit: 367280d144c9SAnirudh Venkataramanan mutex_unlock(rule_lock); 367380d144c9SAnirudh Venkataramanan return status; 3674d76a60baSAnirudh Venkataramanan } 3675d76a60baSAnirudh Venkataramanan 3676d76a60baSAnirudh Venkataramanan /** 3677d76a60baSAnirudh Venkataramanan * ice_add_vlan - Add VLAN based filter rule 3678d76a60baSAnirudh Venkataramanan * @hw: pointer to the hardware structure 3679d76a60baSAnirudh Venkataramanan * @v_list: list of VLAN entries and forwarding information 3680d76a60baSAnirudh Venkataramanan */ 36815e24d598STony Nguyen int ice_add_vlan(struct ice_hw *hw, struct list_head *v_list) 3682d76a60baSAnirudh Venkataramanan { 3683d76a60baSAnirudh Venkataramanan struct ice_fltr_list_entry *v_list_itr; 3684d76a60baSAnirudh Venkataramanan 3685d76a60baSAnirudh Venkataramanan if (!v_list || !hw) 3686d54699e2STony Nguyen return -EINVAL; 3687d76a60baSAnirudh Venkataramanan 3688d76a60baSAnirudh Venkataramanan list_for_each_entry(v_list_itr, v_list, list_entry) { 3689d76a60baSAnirudh Venkataramanan if (v_list_itr->fltr_info.lkup_type != ICE_SW_LKUP_VLAN) 3690d54699e2STony Nguyen return -EINVAL; 369180d144c9SAnirudh Venkataramanan v_list_itr->fltr_info.flag = ICE_FLTR_TX; 369280d144c9SAnirudh Venkataramanan v_list_itr->status = ice_add_vlan_internal(hw, v_list_itr); 369380d144c9SAnirudh Venkataramanan if (v_list_itr->status) 369480d144c9SAnirudh Venkataramanan return v_list_itr->status; 3695d76a60baSAnirudh Venkataramanan } 3696d76a60baSAnirudh Venkataramanan return 0; 3697d76a60baSAnirudh Venkataramanan } 3698d76a60baSAnirudh Venkataramanan 3699d76a60baSAnirudh Venkataramanan /** 3700d95276ceSAkeem G Abodunrin * ice_add_eth_mac - Add ethertype and MAC based filter rule 3701d95276ceSAkeem G Abodunrin * @hw: pointer to the hardware structure 3702d95276ceSAkeem G Abodunrin * @em_list: list of ether type MAC filter, MAC is optional 37032e0e6228SDave Ertman * 37042e0e6228SDave Ertman * This function requires the caller to populate the entries in 37052e0e6228SDave Ertman * the filter list with the necessary fields (including flags to 37062e0e6228SDave Ertman * indicate Tx or Rx rules). 3707d95276ceSAkeem G Abodunrin */ 37085518ac2aSTony Nguyen int ice_add_eth_mac(struct ice_hw *hw, struct list_head *em_list) 3709d95276ceSAkeem G Abodunrin { 3710d95276ceSAkeem G Abodunrin struct ice_fltr_list_entry *em_list_itr; 3711d95276ceSAkeem G Abodunrin 3712d95276ceSAkeem G Abodunrin if (!em_list || !hw) 3713d54699e2STony Nguyen return -EINVAL; 3714d95276ceSAkeem G Abodunrin 3715d95276ceSAkeem G Abodunrin list_for_each_entry(em_list_itr, em_list, list_entry) { 3716d95276ceSAkeem G Abodunrin enum ice_sw_lkup_type l_type = 3717d95276ceSAkeem G Abodunrin em_list_itr->fltr_info.lkup_type; 3718d95276ceSAkeem G Abodunrin 3719d95276ceSAkeem G Abodunrin if (l_type != ICE_SW_LKUP_ETHERTYPE_MAC && 3720d95276ceSAkeem G Abodunrin l_type != ICE_SW_LKUP_ETHERTYPE) 3721d54699e2STony Nguyen return -EINVAL; 3722d95276ceSAkeem G Abodunrin 3723d95276ceSAkeem G Abodunrin em_list_itr->status = ice_add_rule_internal(hw, l_type, 3724d95276ceSAkeem G Abodunrin em_list_itr); 3725d95276ceSAkeem G Abodunrin if (em_list_itr->status) 3726d95276ceSAkeem G Abodunrin return em_list_itr->status; 3727d95276ceSAkeem G Abodunrin } 3728d95276ceSAkeem G Abodunrin return 0; 3729d95276ceSAkeem G Abodunrin } 3730d95276ceSAkeem G Abodunrin 3731d95276ceSAkeem G Abodunrin /** 3732d95276ceSAkeem G Abodunrin * ice_remove_eth_mac - Remove an ethertype (or MAC) based filter rule 3733d95276ceSAkeem G Abodunrin * @hw: pointer to the hardware structure 3734d95276ceSAkeem G Abodunrin * @em_list: list of ethertype or ethertype MAC entries 3735d95276ceSAkeem G Abodunrin */ 37365518ac2aSTony Nguyen int ice_remove_eth_mac(struct ice_hw *hw, struct list_head *em_list) 3737d95276ceSAkeem G Abodunrin { 3738d95276ceSAkeem G Abodunrin struct ice_fltr_list_entry *em_list_itr, *tmp; 3739d95276ceSAkeem G Abodunrin 3740d95276ceSAkeem G Abodunrin if (!em_list || !hw) 3741d54699e2STony Nguyen return -EINVAL; 3742d95276ceSAkeem G Abodunrin 3743d95276ceSAkeem G Abodunrin list_for_each_entry_safe(em_list_itr, tmp, em_list, list_entry) { 3744d95276ceSAkeem G Abodunrin enum ice_sw_lkup_type l_type = 3745d95276ceSAkeem G Abodunrin em_list_itr->fltr_info.lkup_type; 3746d95276ceSAkeem G Abodunrin 3747d95276ceSAkeem G Abodunrin if (l_type != ICE_SW_LKUP_ETHERTYPE_MAC && 3748d95276ceSAkeem G Abodunrin l_type != ICE_SW_LKUP_ETHERTYPE) 3749d54699e2STony Nguyen return -EINVAL; 3750d95276ceSAkeem G Abodunrin 3751d95276ceSAkeem G Abodunrin em_list_itr->status = ice_remove_rule_internal(hw, l_type, 3752d95276ceSAkeem G Abodunrin em_list_itr); 3753d95276ceSAkeem G Abodunrin if (em_list_itr->status) 3754d95276ceSAkeem G Abodunrin return em_list_itr->status; 3755d95276ceSAkeem G Abodunrin } 3756d95276ceSAkeem G Abodunrin return 0; 3757d95276ceSAkeem G Abodunrin } 3758d95276ceSAkeem G Abodunrin 3759d95276ceSAkeem G Abodunrin /** 37600f9d5027SAnirudh Venkataramanan * ice_rem_sw_rule_info 37610f9d5027SAnirudh Venkataramanan * @hw: pointer to the hardware structure 37620f9d5027SAnirudh Venkataramanan * @rule_head: pointer to the switch list structure that we want to delete 37630f9d5027SAnirudh Venkataramanan */ 37640f9d5027SAnirudh Venkataramanan static void 37650f9d5027SAnirudh Venkataramanan ice_rem_sw_rule_info(struct ice_hw *hw, struct list_head *rule_head) 37660f9d5027SAnirudh Venkataramanan { 37670f9d5027SAnirudh Venkataramanan if (!list_empty(rule_head)) { 37680f9d5027SAnirudh Venkataramanan struct ice_fltr_mgmt_list_entry *entry; 37690f9d5027SAnirudh Venkataramanan struct ice_fltr_mgmt_list_entry *tmp; 37700f9d5027SAnirudh Venkataramanan 37710f9d5027SAnirudh Venkataramanan list_for_each_entry_safe(entry, tmp, rule_head, list_entry) { 37720f9d5027SAnirudh Venkataramanan list_del(&entry->list_entry); 37730f9d5027SAnirudh Venkataramanan devm_kfree(ice_hw_to_dev(hw), entry); 37740f9d5027SAnirudh Venkataramanan } 37750f9d5027SAnirudh Venkataramanan } 37760f9d5027SAnirudh Venkataramanan } 37770f9d5027SAnirudh Venkataramanan 37780f9d5027SAnirudh Venkataramanan /** 37798b8ef05bSVictor Raj * ice_rem_adv_rule_info 37808b8ef05bSVictor Raj * @hw: pointer to the hardware structure 37818b8ef05bSVictor Raj * @rule_head: pointer to the switch list structure that we want to delete 37828b8ef05bSVictor Raj */ 37838b8ef05bSVictor Raj static void 37848b8ef05bSVictor Raj ice_rem_adv_rule_info(struct ice_hw *hw, struct list_head *rule_head) 37858b8ef05bSVictor Raj { 37868b8ef05bSVictor Raj struct ice_adv_fltr_mgmt_list_entry *tmp_entry; 37878b8ef05bSVictor Raj struct ice_adv_fltr_mgmt_list_entry *lst_itr; 37888b8ef05bSVictor Raj 37898b8ef05bSVictor Raj if (list_empty(rule_head)) 37908b8ef05bSVictor Raj return; 37918b8ef05bSVictor Raj 37928b8ef05bSVictor Raj list_for_each_entry_safe(lst_itr, tmp_entry, rule_head, list_entry) { 37938b8ef05bSVictor Raj list_del(&lst_itr->list_entry); 37948b8ef05bSVictor Raj devm_kfree(ice_hw_to_dev(hw), lst_itr->lkups); 37958b8ef05bSVictor Raj devm_kfree(ice_hw_to_dev(hw), lst_itr); 37968b8ef05bSVictor Raj } 37978b8ef05bSVictor Raj } 37988b8ef05bSVictor Raj 37998b8ef05bSVictor Raj /** 380080d144c9SAnirudh Venkataramanan * ice_cfg_dflt_vsi - change state of VSI to set/clear default 3801d7393425SMichal Wilczynski * @pi: pointer to the port_info structure 38025726ca0eSAnirudh Venkataramanan * @vsi_handle: VSI handle to set as default 3803e94d4478SAnirudh Venkataramanan * @set: true to add the above mentioned switch rule, false to remove it 3804e94d4478SAnirudh Venkataramanan * @direction: ICE_FLTR_RX or ICE_FLTR_TX 380580d144c9SAnirudh Venkataramanan * 380680d144c9SAnirudh Venkataramanan * add filter rule to set/unset given VSI as default VSI for the switch 380780d144c9SAnirudh Venkataramanan * (represented by swid) 3808e94d4478SAnirudh Venkataramanan */ 3809d7393425SMichal Wilczynski int 3810d7393425SMichal Wilczynski ice_cfg_dflt_vsi(struct ice_port_info *pi, u16 vsi_handle, bool set, 3811d7393425SMichal Wilczynski u8 direction) 3812e94d4478SAnirudh Venkataramanan { 3813d7393425SMichal Wilczynski struct ice_fltr_list_entry f_list_entry; 3814e94d4478SAnirudh Venkataramanan struct ice_fltr_info f_info; 3815d7393425SMichal Wilczynski struct ice_hw *hw = pi->hw; 38165726ca0eSAnirudh Venkataramanan u16 hw_vsi_id; 38175518ac2aSTony Nguyen int status; 38185726ca0eSAnirudh Venkataramanan 38195726ca0eSAnirudh Venkataramanan if (!ice_is_vsi_valid(hw, vsi_handle)) 3820d54699e2STony Nguyen return -EINVAL; 3821d7393425SMichal Wilczynski 38225726ca0eSAnirudh Venkataramanan hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle); 3823e94d4478SAnirudh Venkataramanan 3824e94d4478SAnirudh Venkataramanan memset(&f_info, 0, sizeof(f_info)); 3825e94d4478SAnirudh Venkataramanan 3826e94d4478SAnirudh Venkataramanan f_info.lkup_type = ICE_SW_LKUP_DFLT; 3827e94d4478SAnirudh Venkataramanan f_info.flag = direction; 3828e94d4478SAnirudh Venkataramanan f_info.fltr_act = ICE_FWD_TO_VSI; 38295726ca0eSAnirudh Venkataramanan f_info.fwd_id.hw_vsi_id = hw_vsi_id; 3830d7393425SMichal Wilczynski f_info.vsi_handle = vsi_handle; 3831e94d4478SAnirudh Venkataramanan 3832e94d4478SAnirudh Venkataramanan if (f_info.flag & ICE_FLTR_RX) { 3833e94d4478SAnirudh Venkataramanan f_info.src = hw->port_info->lport; 38345726ca0eSAnirudh Venkataramanan f_info.src_id = ICE_SRC_ID_LPORT; 3835e94d4478SAnirudh Venkataramanan } else if (f_info.flag & ICE_FLTR_TX) { 38365726ca0eSAnirudh Venkataramanan f_info.src_id = ICE_SRC_ID_VSI; 38375726ca0eSAnirudh Venkataramanan f_info.src = hw_vsi_id; 3838e94d4478SAnirudh Venkataramanan } 3839d7393425SMichal Wilczynski f_list_entry.fltr_info = f_info; 3840e94d4478SAnirudh Venkataramanan 3841e94d4478SAnirudh Venkataramanan if (set) 3842d7393425SMichal Wilczynski status = ice_add_rule_internal(hw, ICE_SW_LKUP_DFLT, 3843d7393425SMichal Wilczynski &f_list_entry); 3844e94d4478SAnirudh Venkataramanan else 3845d7393425SMichal Wilczynski status = ice_remove_rule_internal(hw, ICE_SW_LKUP_DFLT, 3846d7393425SMichal Wilczynski &f_list_entry); 3847e94d4478SAnirudh Venkataramanan 3848e94d4478SAnirudh Venkataramanan return status; 3849e94d4478SAnirudh Venkataramanan } 3850e94d4478SAnirudh Venkataramanan 3851e94d4478SAnirudh Venkataramanan /** 3852d7393425SMichal Wilczynski * ice_vsi_uses_fltr - Determine if given VSI uses specified filter 3853d7393425SMichal Wilczynski * @fm_entry: filter entry to inspect 3854d7393425SMichal Wilczynski * @vsi_handle: VSI handle to compare with filter info 3855d7393425SMichal Wilczynski */ 3856d7393425SMichal Wilczynski static bool 3857d7393425SMichal Wilczynski ice_vsi_uses_fltr(struct ice_fltr_mgmt_list_entry *fm_entry, u16 vsi_handle) 3858d7393425SMichal Wilczynski { 3859d7393425SMichal Wilczynski return ((fm_entry->fltr_info.fltr_act == ICE_FWD_TO_VSI && 3860d7393425SMichal Wilczynski fm_entry->fltr_info.vsi_handle == vsi_handle) || 3861d7393425SMichal Wilczynski (fm_entry->fltr_info.fltr_act == ICE_FWD_TO_VSI_LIST && 3862d7393425SMichal Wilczynski fm_entry->vsi_list_info && 3863d7393425SMichal Wilczynski (test_bit(vsi_handle, fm_entry->vsi_list_info->vsi_map)))); 3864d7393425SMichal Wilczynski } 3865d7393425SMichal Wilczynski 3866d7393425SMichal Wilczynski /** 3867d7393425SMichal Wilczynski * ice_check_if_dflt_vsi - check if VSI is default VSI 3868d7393425SMichal Wilczynski * @pi: pointer to the port_info structure 3869d7393425SMichal Wilczynski * @vsi_handle: vsi handle to check for in filter list 3870d7393425SMichal Wilczynski * @rule_exists: indicates if there are any VSI's in the rule list 3871d7393425SMichal Wilczynski * 3872d7393425SMichal Wilczynski * checks if the VSI is in a default VSI list, and also indicates 3873d7393425SMichal Wilczynski * if the default VSI list is empty 3874d7393425SMichal Wilczynski */ 3875d7393425SMichal Wilczynski bool 3876d7393425SMichal Wilczynski ice_check_if_dflt_vsi(struct ice_port_info *pi, u16 vsi_handle, 3877d7393425SMichal Wilczynski bool *rule_exists) 3878d7393425SMichal Wilczynski { 3879d7393425SMichal Wilczynski struct ice_fltr_mgmt_list_entry *fm_entry; 3880d7393425SMichal Wilczynski struct ice_sw_recipe *recp_list; 3881d7393425SMichal Wilczynski struct list_head *rule_head; 3882d7393425SMichal Wilczynski struct mutex *rule_lock; /* Lock to protect filter rule list */ 3883d7393425SMichal Wilczynski bool ret = false; 3884d7393425SMichal Wilczynski 3885d7393425SMichal Wilczynski recp_list = &pi->hw->switch_info->recp_list[ICE_SW_LKUP_DFLT]; 3886d7393425SMichal Wilczynski rule_lock = &recp_list->filt_rule_lock; 3887d7393425SMichal Wilczynski rule_head = &recp_list->filt_rules; 3888d7393425SMichal Wilczynski 3889d7393425SMichal Wilczynski mutex_lock(rule_lock); 3890d7393425SMichal Wilczynski 3891d7393425SMichal Wilczynski if (rule_exists && !list_empty(rule_head)) 3892d7393425SMichal Wilczynski *rule_exists = true; 3893d7393425SMichal Wilczynski 3894d7393425SMichal Wilczynski list_for_each_entry(fm_entry, rule_head, list_entry) { 3895d7393425SMichal Wilczynski if (ice_vsi_uses_fltr(fm_entry, vsi_handle)) { 3896d7393425SMichal Wilczynski ret = true; 3897d7393425SMichal Wilczynski break; 3898d7393425SMichal Wilczynski } 3899d7393425SMichal Wilczynski } 3900d7393425SMichal Wilczynski 3901d7393425SMichal Wilczynski mutex_unlock(rule_lock); 3902d7393425SMichal Wilczynski 3903d7393425SMichal Wilczynski return ret; 3904d7393425SMichal Wilczynski } 3905d7393425SMichal Wilczynski 3906d7393425SMichal Wilczynski /** 390780d144c9SAnirudh Venkataramanan * ice_remove_mac - remove a MAC address based filter rule 3908d76a60baSAnirudh Venkataramanan * @hw: pointer to the hardware structure 390980d144c9SAnirudh Venkataramanan * @m_list: list of MAC addresses and forwarding information 391080d144c9SAnirudh Venkataramanan * 391180d144c9SAnirudh Venkataramanan * This function removes either a MAC filter rule or a specific VSI from a 391280d144c9SAnirudh Venkataramanan * VSI list for a multicast MAC address. 391380d144c9SAnirudh Venkataramanan * 39145518ac2aSTony Nguyen * Returns -ENOENT if a given entry was not added by ice_add_mac. Caller should 39155518ac2aSTony Nguyen * be aware that this call will only work if all the entries passed into m_list 39165518ac2aSTony Nguyen * were added previously. It will not attempt to do a partial remove of entries 39175518ac2aSTony Nguyen * that were found. 3918d76a60baSAnirudh Venkataramanan */ 39195e24d598STony Nguyen int ice_remove_mac(struct ice_hw *hw, struct list_head *m_list) 3920d76a60baSAnirudh Venkataramanan { 3921072f0c3dSDave Ertman struct ice_fltr_list_entry *list_itr, *tmp; 3922d76a60baSAnirudh Venkataramanan 392380d144c9SAnirudh Venkataramanan if (!m_list) 3924d54699e2STony Nguyen return -EINVAL; 3925d76a60baSAnirudh Venkataramanan 3926072f0c3dSDave Ertman list_for_each_entry_safe(list_itr, tmp, m_list, list_entry) { 392780d144c9SAnirudh Venkataramanan enum ice_sw_lkup_type l_type = list_itr->fltr_info.lkup_type; 39288b2c8582SAkeem G Abodunrin u16 vsi_handle; 392980d144c9SAnirudh Venkataramanan 393080d144c9SAnirudh Venkataramanan if (l_type != ICE_SW_LKUP_MAC) 3931d54699e2STony Nguyen return -EINVAL; 39328b2c8582SAkeem G Abodunrin 39338b2c8582SAkeem G Abodunrin vsi_handle = list_itr->fltr_info.vsi_handle; 39348b2c8582SAkeem G Abodunrin if (!ice_is_vsi_valid(hw, vsi_handle)) 3935d54699e2STony Nguyen return -EINVAL; 39368b2c8582SAkeem G Abodunrin 39378b2c8582SAkeem G Abodunrin list_itr->fltr_info.fwd_id.hw_vsi_id = 39388b2c8582SAkeem G Abodunrin ice_get_hw_vsi_num(hw, vsi_handle); 3939e1e9db57SSylwester Dziedziuch 394080d144c9SAnirudh Venkataramanan list_itr->status = ice_remove_rule_internal(hw, 394180d144c9SAnirudh Venkataramanan ICE_SW_LKUP_MAC, 394280d144c9SAnirudh Venkataramanan list_itr); 394380d144c9SAnirudh Venkataramanan if (list_itr->status) 394480d144c9SAnirudh Venkataramanan return list_itr->status; 394580d144c9SAnirudh Venkataramanan } 394680d144c9SAnirudh Venkataramanan return 0; 3947d76a60baSAnirudh Venkataramanan } 3948d76a60baSAnirudh Venkataramanan 3949d76a60baSAnirudh Venkataramanan /** 3950d76a60baSAnirudh Venkataramanan * ice_remove_vlan - Remove VLAN based filter rule 3951d76a60baSAnirudh Venkataramanan * @hw: pointer to the hardware structure 3952d76a60baSAnirudh Venkataramanan * @v_list: list of VLAN entries and forwarding information 3953d76a60baSAnirudh Venkataramanan */ 39545518ac2aSTony Nguyen int ice_remove_vlan(struct ice_hw *hw, struct list_head *v_list) 3955d76a60baSAnirudh Venkataramanan { 3956072f0c3dSDave Ertman struct ice_fltr_list_entry *v_list_itr, *tmp; 3957d76a60baSAnirudh Venkataramanan 3958d76a60baSAnirudh Venkataramanan if (!v_list || !hw) 3959d54699e2STony Nguyen return -EINVAL; 3960d76a60baSAnirudh Venkataramanan 3961072f0c3dSDave Ertman list_for_each_entry_safe(v_list_itr, tmp, v_list, list_entry) { 396280d144c9SAnirudh Venkataramanan enum ice_sw_lkup_type l_type = v_list_itr->fltr_info.lkup_type; 396380d144c9SAnirudh Venkataramanan 396480d144c9SAnirudh Venkataramanan if (l_type != ICE_SW_LKUP_VLAN) 3965d54699e2STony Nguyen return -EINVAL; 396680d144c9SAnirudh Venkataramanan v_list_itr->status = ice_remove_rule_internal(hw, 396780d144c9SAnirudh Venkataramanan ICE_SW_LKUP_VLAN, 396880d144c9SAnirudh Venkataramanan v_list_itr); 396980d144c9SAnirudh Venkataramanan if (v_list_itr->status) 397080d144c9SAnirudh Venkataramanan return v_list_itr->status; 3971d76a60baSAnirudh Venkataramanan } 397280d144c9SAnirudh Venkataramanan return 0; 3973d76a60baSAnirudh Venkataramanan } 397480d144c9SAnirudh Venkataramanan 397580d144c9SAnirudh Venkataramanan /** 397680d144c9SAnirudh Venkataramanan * ice_add_entry_to_vsi_fltr_list - Add copy of fltr_list_entry to remove list 397780d144c9SAnirudh Venkataramanan * @hw: pointer to the hardware structure 39785726ca0eSAnirudh Venkataramanan * @vsi_handle: VSI handle to remove filters from 397980d144c9SAnirudh Venkataramanan * @vsi_list_head: pointer to the list to add entry to 398080d144c9SAnirudh Venkataramanan * @fi: pointer to fltr_info of filter entry to copy & add 398180d144c9SAnirudh Venkataramanan * 398280d144c9SAnirudh Venkataramanan * Helper function, used when creating a list of filters to remove from 398380d144c9SAnirudh Venkataramanan * a specific VSI. The entry added to vsi_list_head is a COPY of the 398480d144c9SAnirudh Venkataramanan * original filter entry, with the exception of fltr_info.fltr_act and 398580d144c9SAnirudh Venkataramanan * fltr_info.fwd_id fields. These are set such that later logic can 398680d144c9SAnirudh Venkataramanan * extract which VSI to remove the fltr from, and pass on that information. 398780d144c9SAnirudh Venkataramanan */ 39885e24d598STony Nguyen static int 39895726ca0eSAnirudh Venkataramanan ice_add_entry_to_vsi_fltr_list(struct ice_hw *hw, u16 vsi_handle, 399080d144c9SAnirudh Venkataramanan struct list_head *vsi_list_head, 399180d144c9SAnirudh Venkataramanan struct ice_fltr_info *fi) 399280d144c9SAnirudh Venkataramanan { 399380d144c9SAnirudh Venkataramanan struct ice_fltr_list_entry *tmp; 399480d144c9SAnirudh Venkataramanan 399580d144c9SAnirudh Venkataramanan /* this memory is freed up in the caller function 399680d144c9SAnirudh Venkataramanan * once filters for this VSI are removed 399780d144c9SAnirudh Venkataramanan */ 399880d144c9SAnirudh Venkataramanan tmp = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*tmp), GFP_KERNEL); 399980d144c9SAnirudh Venkataramanan if (!tmp) 4000d54699e2STony Nguyen return -ENOMEM; 400180d144c9SAnirudh Venkataramanan 400280d144c9SAnirudh Venkataramanan tmp->fltr_info = *fi; 400380d144c9SAnirudh Venkataramanan 400480d144c9SAnirudh Venkataramanan /* Overwrite these fields to indicate which VSI to remove filter from, 400580d144c9SAnirudh Venkataramanan * so find and remove logic can extract the information from the 400680d144c9SAnirudh Venkataramanan * list entries. Note that original entries will still have proper 400780d144c9SAnirudh Venkataramanan * values. 400880d144c9SAnirudh Venkataramanan */ 400980d144c9SAnirudh Venkataramanan tmp->fltr_info.fltr_act = ICE_FWD_TO_VSI; 40105726ca0eSAnirudh Venkataramanan tmp->fltr_info.vsi_handle = vsi_handle; 40115726ca0eSAnirudh Venkataramanan tmp->fltr_info.fwd_id.hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle); 401280d144c9SAnirudh Venkataramanan 401380d144c9SAnirudh Venkataramanan list_add(&tmp->list_entry, vsi_list_head); 401480d144c9SAnirudh Venkataramanan 401580d144c9SAnirudh Venkataramanan return 0; 4016d76a60baSAnirudh Venkataramanan } 4017d76a60baSAnirudh Venkataramanan 4018d76a60baSAnirudh Venkataramanan /** 40199daf8208SAnirudh Venkataramanan * ice_add_to_vsi_fltr_list - Add VSI filters to the list 40209daf8208SAnirudh Venkataramanan * @hw: pointer to the hardware structure 40215726ca0eSAnirudh Venkataramanan * @vsi_handle: VSI handle to remove filters from 40229daf8208SAnirudh Venkataramanan * @lkup_list_head: pointer to the list that has certain lookup type filters 40235726ca0eSAnirudh Venkataramanan * @vsi_list_head: pointer to the list pertaining to VSI with vsi_handle 402480d144c9SAnirudh Venkataramanan * 402580d144c9SAnirudh Venkataramanan * Locates all filters in lkup_list_head that are used by the given VSI, 402680d144c9SAnirudh Venkataramanan * and adds COPIES of those entries to vsi_list_head (intended to be used 402780d144c9SAnirudh Venkataramanan * to remove the listed filters). 402880d144c9SAnirudh Venkataramanan * Note that this means all entries in vsi_list_head must be explicitly 402980d144c9SAnirudh Venkataramanan * deallocated by the caller when done with list. 40309daf8208SAnirudh Venkataramanan */ 40315e24d598STony Nguyen static int 40325726ca0eSAnirudh Venkataramanan ice_add_to_vsi_fltr_list(struct ice_hw *hw, u16 vsi_handle, 40339daf8208SAnirudh Venkataramanan struct list_head *lkup_list_head, 40349daf8208SAnirudh Venkataramanan struct list_head *vsi_list_head) 40359daf8208SAnirudh Venkataramanan { 40369daf8208SAnirudh Venkataramanan struct ice_fltr_mgmt_list_entry *fm_entry; 40375e24d598STony Nguyen int status = 0; 40389daf8208SAnirudh Venkataramanan 4039f9867df6SAnirudh Venkataramanan /* check to make sure VSI ID is valid and within boundary */ 40405726ca0eSAnirudh Venkataramanan if (!ice_is_vsi_valid(hw, vsi_handle)) 4041d54699e2STony Nguyen return -EINVAL; 40429daf8208SAnirudh Venkataramanan 40439daf8208SAnirudh Venkataramanan list_for_each_entry(fm_entry, lkup_list_head, list_entry) { 40447a91d3f0SJacek Bułatek if (!ice_vsi_uses_fltr(fm_entry, vsi_handle)) 404580d144c9SAnirudh Venkataramanan continue; 40469daf8208SAnirudh Venkataramanan 40475726ca0eSAnirudh Venkataramanan status = ice_add_entry_to_vsi_fltr_list(hw, vsi_handle, 40487a91d3f0SJacek Bułatek vsi_list_head, 40497a91d3f0SJacek Bułatek &fm_entry->fltr_info); 405080d144c9SAnirudh Venkataramanan if (status) 405180d144c9SAnirudh Venkataramanan return status; 40529daf8208SAnirudh Venkataramanan } 405380d144c9SAnirudh Venkataramanan return status; 40549daf8208SAnirudh Venkataramanan } 40559daf8208SAnirudh Venkataramanan 40569daf8208SAnirudh Venkataramanan /** 40575eda8afdSAkeem G Abodunrin * ice_determine_promisc_mask 40585eda8afdSAkeem G Abodunrin * @fi: filter info to parse 40595eda8afdSAkeem G Abodunrin * 40605eda8afdSAkeem G Abodunrin * Helper function to determine which ICE_PROMISC_ mask corresponds 40615eda8afdSAkeem G Abodunrin * to given filter into. 40625eda8afdSAkeem G Abodunrin */ 40635eda8afdSAkeem G Abodunrin static u8 ice_determine_promisc_mask(struct ice_fltr_info *fi) 40645eda8afdSAkeem G Abodunrin { 40655eda8afdSAkeem G Abodunrin u16 vid = fi->l_data.mac_vlan.vlan_id; 40665eda8afdSAkeem G Abodunrin u8 *macaddr = fi->l_data.mac.mac_addr; 40675eda8afdSAkeem G Abodunrin bool is_tx_fltr = false; 40685eda8afdSAkeem G Abodunrin u8 promisc_mask = 0; 40695eda8afdSAkeem G Abodunrin 40705eda8afdSAkeem G Abodunrin if (fi->flag == ICE_FLTR_TX) 40715eda8afdSAkeem G Abodunrin is_tx_fltr = true; 40725eda8afdSAkeem G Abodunrin 40735eda8afdSAkeem G Abodunrin if (is_broadcast_ether_addr(macaddr)) 40745eda8afdSAkeem G Abodunrin promisc_mask |= is_tx_fltr ? 40755eda8afdSAkeem G Abodunrin ICE_PROMISC_BCAST_TX : ICE_PROMISC_BCAST_RX; 40765eda8afdSAkeem G Abodunrin else if (is_multicast_ether_addr(macaddr)) 40775eda8afdSAkeem G Abodunrin promisc_mask |= is_tx_fltr ? 40785eda8afdSAkeem G Abodunrin ICE_PROMISC_MCAST_TX : ICE_PROMISC_MCAST_RX; 40795eda8afdSAkeem G Abodunrin else if (is_unicast_ether_addr(macaddr)) 40805eda8afdSAkeem G Abodunrin promisc_mask |= is_tx_fltr ? 40815eda8afdSAkeem G Abodunrin ICE_PROMISC_UCAST_TX : ICE_PROMISC_UCAST_RX; 40825eda8afdSAkeem G Abodunrin if (vid) 40835eda8afdSAkeem G Abodunrin promisc_mask |= is_tx_fltr ? 40845eda8afdSAkeem G Abodunrin ICE_PROMISC_VLAN_TX : ICE_PROMISC_VLAN_RX; 40855eda8afdSAkeem G Abodunrin 40865eda8afdSAkeem G Abodunrin return promisc_mask; 40875eda8afdSAkeem G Abodunrin } 40885eda8afdSAkeem G Abodunrin 40895eda8afdSAkeem G Abodunrin /** 40905eda8afdSAkeem G Abodunrin * ice_remove_promisc - Remove promisc based filter rules 40915eda8afdSAkeem G Abodunrin * @hw: pointer to the hardware structure 4092f9867df6SAnirudh Venkataramanan * @recp_id: recipe ID for which the rule needs to removed 40935eda8afdSAkeem G Abodunrin * @v_list: list of promisc entries 40945eda8afdSAkeem G Abodunrin */ 40955e24d598STony Nguyen static int 40965518ac2aSTony Nguyen ice_remove_promisc(struct ice_hw *hw, u8 recp_id, struct list_head *v_list) 40975eda8afdSAkeem G Abodunrin { 40985eda8afdSAkeem G Abodunrin struct ice_fltr_list_entry *v_list_itr, *tmp; 40995eda8afdSAkeem G Abodunrin 41005eda8afdSAkeem G Abodunrin list_for_each_entry_safe(v_list_itr, tmp, v_list, list_entry) { 41015eda8afdSAkeem G Abodunrin v_list_itr->status = 41025eda8afdSAkeem G Abodunrin ice_remove_rule_internal(hw, recp_id, v_list_itr); 41035eda8afdSAkeem G Abodunrin if (v_list_itr->status) 41045eda8afdSAkeem G Abodunrin return v_list_itr->status; 41055eda8afdSAkeem G Abodunrin } 41065eda8afdSAkeem G Abodunrin return 0; 41075eda8afdSAkeem G Abodunrin } 41085eda8afdSAkeem G Abodunrin 41095eda8afdSAkeem G Abodunrin /** 41105eda8afdSAkeem G Abodunrin * ice_clear_vsi_promisc - clear specified promiscuous mode(s) for given VSI 41115eda8afdSAkeem G Abodunrin * @hw: pointer to the hardware structure 41125eda8afdSAkeem G Abodunrin * @vsi_handle: VSI handle to clear mode 41135eda8afdSAkeem G Abodunrin * @promisc_mask: mask of promiscuous config bits to clear 41145eda8afdSAkeem G Abodunrin * @vid: VLAN ID to clear VLAN promiscuous 41155eda8afdSAkeem G Abodunrin */ 41165e24d598STony Nguyen int 41175eda8afdSAkeem G Abodunrin ice_clear_vsi_promisc(struct ice_hw *hw, u16 vsi_handle, u8 promisc_mask, 41185eda8afdSAkeem G Abodunrin u16 vid) 41195eda8afdSAkeem G Abodunrin { 41205eda8afdSAkeem G Abodunrin struct ice_switch_info *sw = hw->switch_info; 41215eda8afdSAkeem G Abodunrin struct ice_fltr_list_entry *fm_entry, *tmp; 41225eda8afdSAkeem G Abodunrin struct list_head remove_list_head; 41235eda8afdSAkeem G Abodunrin struct ice_fltr_mgmt_list_entry *itr; 41245eda8afdSAkeem G Abodunrin struct list_head *rule_head; 41255eda8afdSAkeem G Abodunrin struct mutex *rule_lock; /* Lock to protect filter rule list */ 41265e24d598STony Nguyen int status = 0; 41275eda8afdSAkeem G Abodunrin u8 recipe_id; 41285eda8afdSAkeem G Abodunrin 41295eda8afdSAkeem G Abodunrin if (!ice_is_vsi_valid(hw, vsi_handle)) 4130d54699e2STony Nguyen return -EINVAL; 41315eda8afdSAkeem G Abodunrin 41321bc7a4abSBrett Creeley if (promisc_mask & (ICE_PROMISC_VLAN_RX | ICE_PROMISC_VLAN_TX)) 41335eda8afdSAkeem G Abodunrin recipe_id = ICE_SW_LKUP_PROMISC_VLAN; 41345eda8afdSAkeem G Abodunrin else 41355eda8afdSAkeem G Abodunrin recipe_id = ICE_SW_LKUP_PROMISC; 41365eda8afdSAkeem G Abodunrin 41375eda8afdSAkeem G Abodunrin rule_head = &sw->recp_list[recipe_id].filt_rules; 41385eda8afdSAkeem G Abodunrin rule_lock = &sw->recp_list[recipe_id].filt_rule_lock; 41395eda8afdSAkeem G Abodunrin 41405eda8afdSAkeem G Abodunrin INIT_LIST_HEAD(&remove_list_head); 41415eda8afdSAkeem G Abodunrin 41425eda8afdSAkeem G Abodunrin mutex_lock(rule_lock); 41435eda8afdSAkeem G Abodunrin list_for_each_entry(itr, rule_head, list_entry) { 41441bc7a4abSBrett Creeley struct ice_fltr_info *fltr_info; 41455eda8afdSAkeem G Abodunrin u8 fltr_promisc_mask = 0; 41465eda8afdSAkeem G Abodunrin 41475eda8afdSAkeem G Abodunrin if (!ice_vsi_uses_fltr(itr, vsi_handle)) 41485eda8afdSAkeem G Abodunrin continue; 41491bc7a4abSBrett Creeley fltr_info = &itr->fltr_info; 41505eda8afdSAkeem G Abodunrin 41511bc7a4abSBrett Creeley if (recipe_id == ICE_SW_LKUP_PROMISC_VLAN && 41521bc7a4abSBrett Creeley vid != fltr_info->l_data.mac_vlan.vlan_id) 41531bc7a4abSBrett Creeley continue; 41541bc7a4abSBrett Creeley 41551bc7a4abSBrett Creeley fltr_promisc_mask |= ice_determine_promisc_mask(fltr_info); 41565eda8afdSAkeem G Abodunrin 41575eda8afdSAkeem G Abodunrin /* Skip if filter is not completely specified by given mask */ 41585eda8afdSAkeem G Abodunrin if (fltr_promisc_mask & ~promisc_mask) 41595eda8afdSAkeem G Abodunrin continue; 41605eda8afdSAkeem G Abodunrin 41615eda8afdSAkeem G Abodunrin status = ice_add_entry_to_vsi_fltr_list(hw, vsi_handle, 41625eda8afdSAkeem G Abodunrin &remove_list_head, 41631bc7a4abSBrett Creeley fltr_info); 41645eda8afdSAkeem G Abodunrin if (status) { 41655eda8afdSAkeem G Abodunrin mutex_unlock(rule_lock); 41665eda8afdSAkeem G Abodunrin goto free_fltr_list; 41675eda8afdSAkeem G Abodunrin } 41685eda8afdSAkeem G Abodunrin } 41695eda8afdSAkeem G Abodunrin mutex_unlock(rule_lock); 41705eda8afdSAkeem G Abodunrin 41715eda8afdSAkeem G Abodunrin status = ice_remove_promisc(hw, recipe_id, &remove_list_head); 41725eda8afdSAkeem G Abodunrin 41735eda8afdSAkeem G Abodunrin free_fltr_list: 41745eda8afdSAkeem G Abodunrin list_for_each_entry_safe(fm_entry, tmp, &remove_list_head, list_entry) { 41755eda8afdSAkeem G Abodunrin list_del(&fm_entry->list_entry); 41765eda8afdSAkeem G Abodunrin devm_kfree(ice_hw_to_dev(hw), fm_entry); 41775eda8afdSAkeem G Abodunrin } 41785eda8afdSAkeem G Abodunrin 41795eda8afdSAkeem G Abodunrin return status; 41805eda8afdSAkeem G Abodunrin } 41815eda8afdSAkeem G Abodunrin 41825eda8afdSAkeem G Abodunrin /** 41835eda8afdSAkeem G Abodunrin * ice_set_vsi_promisc - set given VSI to given promiscuous mode(s) 41845eda8afdSAkeem G Abodunrin * @hw: pointer to the hardware structure 41855eda8afdSAkeem G Abodunrin * @vsi_handle: VSI handle to configure 41865eda8afdSAkeem G Abodunrin * @promisc_mask: mask of promiscuous config bits 41875eda8afdSAkeem G Abodunrin * @vid: VLAN ID to set VLAN promiscuous 41885eda8afdSAkeem G Abodunrin */ 41895e24d598STony Nguyen int 41905eda8afdSAkeem G Abodunrin ice_set_vsi_promisc(struct ice_hw *hw, u16 vsi_handle, u8 promisc_mask, u16 vid) 41915eda8afdSAkeem G Abodunrin { 41925eda8afdSAkeem G Abodunrin enum { UCAST_FLTR = 1, MCAST_FLTR, BCAST_FLTR }; 41935eda8afdSAkeem G Abodunrin struct ice_fltr_list_entry f_list_entry; 41945eda8afdSAkeem G Abodunrin struct ice_fltr_info new_fltr; 41955eda8afdSAkeem G Abodunrin bool is_tx_fltr; 41965518ac2aSTony Nguyen int status = 0; 41975eda8afdSAkeem G Abodunrin u16 hw_vsi_id; 41985eda8afdSAkeem G Abodunrin int pkt_type; 41995eda8afdSAkeem G Abodunrin u8 recipe_id; 42005eda8afdSAkeem G Abodunrin 42015eda8afdSAkeem G Abodunrin if (!ice_is_vsi_valid(hw, vsi_handle)) 4202d54699e2STony Nguyen return -EINVAL; 42035eda8afdSAkeem G Abodunrin hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle); 42045eda8afdSAkeem G Abodunrin 42055eda8afdSAkeem G Abodunrin memset(&new_fltr, 0, sizeof(new_fltr)); 42065eda8afdSAkeem G Abodunrin 42075eda8afdSAkeem G Abodunrin if (promisc_mask & (ICE_PROMISC_VLAN_RX | ICE_PROMISC_VLAN_TX)) { 42085eda8afdSAkeem G Abodunrin new_fltr.lkup_type = ICE_SW_LKUP_PROMISC_VLAN; 42095eda8afdSAkeem G Abodunrin new_fltr.l_data.mac_vlan.vlan_id = vid; 42105eda8afdSAkeem G Abodunrin recipe_id = ICE_SW_LKUP_PROMISC_VLAN; 42115eda8afdSAkeem G Abodunrin } else { 42125eda8afdSAkeem G Abodunrin new_fltr.lkup_type = ICE_SW_LKUP_PROMISC; 42135eda8afdSAkeem G Abodunrin recipe_id = ICE_SW_LKUP_PROMISC; 42145eda8afdSAkeem G Abodunrin } 42155eda8afdSAkeem G Abodunrin 42165eda8afdSAkeem G Abodunrin /* Separate filters must be set for each direction/packet type 42175eda8afdSAkeem G Abodunrin * combination, so we will loop over the mask value, store the 42185eda8afdSAkeem G Abodunrin * individual type, and clear it out in the input mask as it 42195eda8afdSAkeem G Abodunrin * is found. 42205eda8afdSAkeem G Abodunrin */ 42215eda8afdSAkeem G Abodunrin while (promisc_mask) { 42225eda8afdSAkeem G Abodunrin u8 *mac_addr; 42235eda8afdSAkeem G Abodunrin 42245eda8afdSAkeem G Abodunrin pkt_type = 0; 42255eda8afdSAkeem G Abodunrin is_tx_fltr = false; 42265eda8afdSAkeem G Abodunrin 42275eda8afdSAkeem G Abodunrin if (promisc_mask & ICE_PROMISC_UCAST_RX) { 42285eda8afdSAkeem G Abodunrin promisc_mask &= ~ICE_PROMISC_UCAST_RX; 42295eda8afdSAkeem G Abodunrin pkt_type = UCAST_FLTR; 42305eda8afdSAkeem G Abodunrin } else if (promisc_mask & ICE_PROMISC_UCAST_TX) { 42315eda8afdSAkeem G Abodunrin promisc_mask &= ~ICE_PROMISC_UCAST_TX; 42325eda8afdSAkeem G Abodunrin pkt_type = UCAST_FLTR; 42335eda8afdSAkeem G Abodunrin is_tx_fltr = true; 42345eda8afdSAkeem G Abodunrin } else if (promisc_mask & ICE_PROMISC_MCAST_RX) { 42355eda8afdSAkeem G Abodunrin promisc_mask &= ~ICE_PROMISC_MCAST_RX; 42365eda8afdSAkeem G Abodunrin pkt_type = MCAST_FLTR; 42375eda8afdSAkeem G Abodunrin } else if (promisc_mask & ICE_PROMISC_MCAST_TX) { 42385eda8afdSAkeem G Abodunrin promisc_mask &= ~ICE_PROMISC_MCAST_TX; 42395eda8afdSAkeem G Abodunrin pkt_type = MCAST_FLTR; 42405eda8afdSAkeem G Abodunrin is_tx_fltr = true; 42415eda8afdSAkeem G Abodunrin } else if (promisc_mask & ICE_PROMISC_BCAST_RX) { 42425eda8afdSAkeem G Abodunrin promisc_mask &= ~ICE_PROMISC_BCAST_RX; 42435eda8afdSAkeem G Abodunrin pkt_type = BCAST_FLTR; 42445eda8afdSAkeem G Abodunrin } else if (promisc_mask & ICE_PROMISC_BCAST_TX) { 42455eda8afdSAkeem G Abodunrin promisc_mask &= ~ICE_PROMISC_BCAST_TX; 42465eda8afdSAkeem G Abodunrin pkt_type = BCAST_FLTR; 42475eda8afdSAkeem G Abodunrin is_tx_fltr = true; 42485eda8afdSAkeem G Abodunrin } 42495eda8afdSAkeem G Abodunrin 42505eda8afdSAkeem G Abodunrin /* Check for VLAN promiscuous flag */ 42515eda8afdSAkeem G Abodunrin if (promisc_mask & ICE_PROMISC_VLAN_RX) { 42525eda8afdSAkeem G Abodunrin promisc_mask &= ~ICE_PROMISC_VLAN_RX; 42535eda8afdSAkeem G Abodunrin } else if (promisc_mask & ICE_PROMISC_VLAN_TX) { 42545eda8afdSAkeem G Abodunrin promisc_mask &= ~ICE_PROMISC_VLAN_TX; 42555eda8afdSAkeem G Abodunrin is_tx_fltr = true; 42565eda8afdSAkeem G Abodunrin } 42575eda8afdSAkeem G Abodunrin 42585eda8afdSAkeem G Abodunrin /* Set filter DA based on packet type */ 42595eda8afdSAkeem G Abodunrin mac_addr = new_fltr.l_data.mac.mac_addr; 42605eda8afdSAkeem G Abodunrin if (pkt_type == BCAST_FLTR) { 42615eda8afdSAkeem G Abodunrin eth_broadcast_addr(mac_addr); 42625eda8afdSAkeem G Abodunrin } else if (pkt_type == MCAST_FLTR || 42635eda8afdSAkeem G Abodunrin pkt_type == UCAST_FLTR) { 42645eda8afdSAkeem G Abodunrin /* Use the dummy ether header DA */ 42655eda8afdSAkeem G Abodunrin ether_addr_copy(mac_addr, dummy_eth_header); 42665eda8afdSAkeem G Abodunrin if (pkt_type == MCAST_FLTR) 42675eda8afdSAkeem G Abodunrin mac_addr[0] |= 0x1; /* Set multicast bit */ 42685eda8afdSAkeem G Abodunrin } 42695eda8afdSAkeem G Abodunrin 42705eda8afdSAkeem G Abodunrin /* Need to reset this to zero for all iterations */ 42715eda8afdSAkeem G Abodunrin new_fltr.flag = 0; 42725eda8afdSAkeem G Abodunrin if (is_tx_fltr) { 42735eda8afdSAkeem G Abodunrin new_fltr.flag |= ICE_FLTR_TX; 42745eda8afdSAkeem G Abodunrin new_fltr.src = hw_vsi_id; 42755eda8afdSAkeem G Abodunrin } else { 42765eda8afdSAkeem G Abodunrin new_fltr.flag |= ICE_FLTR_RX; 42775eda8afdSAkeem G Abodunrin new_fltr.src = hw->port_info->lport; 42785eda8afdSAkeem G Abodunrin } 42795eda8afdSAkeem G Abodunrin 42805eda8afdSAkeem G Abodunrin new_fltr.fltr_act = ICE_FWD_TO_VSI; 42815eda8afdSAkeem G Abodunrin new_fltr.vsi_handle = vsi_handle; 42825eda8afdSAkeem G Abodunrin new_fltr.fwd_id.hw_vsi_id = hw_vsi_id; 42835eda8afdSAkeem G Abodunrin f_list_entry.fltr_info = new_fltr; 42845eda8afdSAkeem G Abodunrin 42855eda8afdSAkeem G Abodunrin status = ice_add_rule_internal(hw, recipe_id, &f_list_entry); 42865eda8afdSAkeem G Abodunrin if (status) 42875eda8afdSAkeem G Abodunrin goto set_promisc_exit; 42885eda8afdSAkeem G Abodunrin } 42895eda8afdSAkeem G Abodunrin 42905eda8afdSAkeem G Abodunrin set_promisc_exit: 42915eda8afdSAkeem G Abodunrin return status; 42925eda8afdSAkeem G Abodunrin } 42935eda8afdSAkeem G Abodunrin 42945eda8afdSAkeem G Abodunrin /** 42955eda8afdSAkeem G Abodunrin * ice_set_vlan_vsi_promisc 42965eda8afdSAkeem G Abodunrin * @hw: pointer to the hardware structure 42975eda8afdSAkeem G Abodunrin * @vsi_handle: VSI handle to configure 42985eda8afdSAkeem G Abodunrin * @promisc_mask: mask of promiscuous config bits 42995eda8afdSAkeem G Abodunrin * @rm_vlan_promisc: Clear VLANs VSI promisc mode 43005eda8afdSAkeem G Abodunrin * 43015eda8afdSAkeem G Abodunrin * Configure VSI with all associated VLANs to given promiscuous mode(s) 43025eda8afdSAkeem G Abodunrin */ 43035e24d598STony Nguyen int 43045eda8afdSAkeem G Abodunrin ice_set_vlan_vsi_promisc(struct ice_hw *hw, u16 vsi_handle, u8 promisc_mask, 43055eda8afdSAkeem G Abodunrin bool rm_vlan_promisc) 43065eda8afdSAkeem G Abodunrin { 43075eda8afdSAkeem G Abodunrin struct ice_switch_info *sw = hw->switch_info; 43085eda8afdSAkeem G Abodunrin struct ice_fltr_list_entry *list_itr, *tmp; 43095eda8afdSAkeem G Abodunrin struct list_head vsi_list_head; 43105eda8afdSAkeem G Abodunrin struct list_head *vlan_head; 43115eda8afdSAkeem G Abodunrin struct mutex *vlan_lock; /* Lock to protect filter rule list */ 43125eda8afdSAkeem G Abodunrin u16 vlan_id; 43135518ac2aSTony Nguyen int status; 43145eda8afdSAkeem G Abodunrin 43155eda8afdSAkeem G Abodunrin INIT_LIST_HEAD(&vsi_list_head); 43165eda8afdSAkeem G Abodunrin vlan_lock = &sw->recp_list[ICE_SW_LKUP_VLAN].filt_rule_lock; 43175eda8afdSAkeem G Abodunrin vlan_head = &sw->recp_list[ICE_SW_LKUP_VLAN].filt_rules; 43185eda8afdSAkeem G Abodunrin mutex_lock(vlan_lock); 43195eda8afdSAkeem G Abodunrin status = ice_add_to_vsi_fltr_list(hw, vsi_handle, vlan_head, 43205eda8afdSAkeem G Abodunrin &vsi_list_head); 43215eda8afdSAkeem G Abodunrin mutex_unlock(vlan_lock); 43225eda8afdSAkeem G Abodunrin if (status) 43235eda8afdSAkeem G Abodunrin goto free_fltr_list; 43245eda8afdSAkeem G Abodunrin 43255eda8afdSAkeem G Abodunrin list_for_each_entry(list_itr, &vsi_list_head, list_entry) { 4326ffa9ed86SGrzegorz Siwik /* Avoid enabling or disabling VLAN zero twice when in double 4327ffa9ed86SGrzegorz Siwik * VLAN mode 4328ffa9ed86SGrzegorz Siwik */ 4329ffa9ed86SGrzegorz Siwik if (ice_is_dvm_ena(hw) && 4330ffa9ed86SGrzegorz Siwik list_itr->fltr_info.l_data.vlan.tpid == 0) 4331ffa9ed86SGrzegorz Siwik continue; 4332ffa9ed86SGrzegorz Siwik 43335eda8afdSAkeem G Abodunrin vlan_id = list_itr->fltr_info.l_data.vlan.vlan_id; 43345eda8afdSAkeem G Abodunrin if (rm_vlan_promisc) 43355eda8afdSAkeem G Abodunrin status = ice_clear_vsi_promisc(hw, vsi_handle, 43365eda8afdSAkeem G Abodunrin promisc_mask, vlan_id); 43375eda8afdSAkeem G Abodunrin else 43385eda8afdSAkeem G Abodunrin status = ice_set_vsi_promisc(hw, vsi_handle, 43395eda8afdSAkeem G Abodunrin promisc_mask, vlan_id); 434011e551a2SGrzegorz Siwik if (status && status != -EEXIST) 43415eda8afdSAkeem G Abodunrin break; 43425eda8afdSAkeem G Abodunrin } 43435eda8afdSAkeem G Abodunrin 43445eda8afdSAkeem G Abodunrin free_fltr_list: 43455eda8afdSAkeem G Abodunrin list_for_each_entry_safe(list_itr, tmp, &vsi_list_head, list_entry) { 43465eda8afdSAkeem G Abodunrin list_del(&list_itr->list_entry); 43475eda8afdSAkeem G Abodunrin devm_kfree(ice_hw_to_dev(hw), list_itr); 43485eda8afdSAkeem G Abodunrin } 43495eda8afdSAkeem G Abodunrin return status; 43505eda8afdSAkeem G Abodunrin } 43515eda8afdSAkeem G Abodunrin 43525eda8afdSAkeem G Abodunrin /** 43539daf8208SAnirudh Venkataramanan * ice_remove_vsi_lkup_fltr - Remove lookup type filters for a VSI 43549daf8208SAnirudh Venkataramanan * @hw: pointer to the hardware structure 43555726ca0eSAnirudh Venkataramanan * @vsi_handle: VSI handle to remove filters from 43569daf8208SAnirudh Venkataramanan * @lkup: switch rule filter lookup type 43579daf8208SAnirudh Venkataramanan */ 43589daf8208SAnirudh Venkataramanan static void 43595726ca0eSAnirudh Venkataramanan ice_remove_vsi_lkup_fltr(struct ice_hw *hw, u16 vsi_handle, 43609daf8208SAnirudh Venkataramanan enum ice_sw_lkup_type lkup) 43619daf8208SAnirudh Venkataramanan { 43629daf8208SAnirudh Venkataramanan struct ice_switch_info *sw = hw->switch_info; 43639daf8208SAnirudh Venkataramanan struct ice_fltr_list_entry *fm_entry; 43649daf8208SAnirudh Venkataramanan struct list_head remove_list_head; 436580d144c9SAnirudh Venkataramanan struct list_head *rule_head; 43669daf8208SAnirudh Venkataramanan struct ice_fltr_list_entry *tmp; 436780d144c9SAnirudh Venkataramanan struct mutex *rule_lock; /* Lock to protect filter rule list */ 43685e24d598STony Nguyen int status; 43699daf8208SAnirudh Venkataramanan 43709daf8208SAnirudh Venkataramanan INIT_LIST_HEAD(&remove_list_head); 437180d144c9SAnirudh Venkataramanan rule_lock = &sw->recp_list[lkup].filt_rule_lock; 437280d144c9SAnirudh Venkataramanan rule_head = &sw->recp_list[lkup].filt_rules; 437380d144c9SAnirudh Venkataramanan mutex_lock(rule_lock); 43745726ca0eSAnirudh Venkataramanan status = ice_add_to_vsi_fltr_list(hw, vsi_handle, rule_head, 437580d144c9SAnirudh Venkataramanan &remove_list_head); 437680d144c9SAnirudh Venkataramanan mutex_unlock(rule_lock); 437780d144c9SAnirudh Venkataramanan if (status) 4378b7eeb527SRobert Malz goto free_fltr_list; 437980d144c9SAnirudh Venkataramanan 43809daf8208SAnirudh Venkataramanan switch (lkup) { 43819daf8208SAnirudh Venkataramanan case ICE_SW_LKUP_MAC: 43829daf8208SAnirudh Venkataramanan ice_remove_mac(hw, &remove_list_head); 43839daf8208SAnirudh Venkataramanan break; 43849daf8208SAnirudh Venkataramanan case ICE_SW_LKUP_VLAN: 4385d76a60baSAnirudh Venkataramanan ice_remove_vlan(hw, &remove_list_head); 4386d76a60baSAnirudh Venkataramanan break; 43875eda8afdSAkeem G Abodunrin case ICE_SW_LKUP_PROMISC: 43885eda8afdSAkeem G Abodunrin case ICE_SW_LKUP_PROMISC_VLAN: 43895eda8afdSAkeem G Abodunrin ice_remove_promisc(hw, lkup, &remove_list_head); 43905eda8afdSAkeem G Abodunrin break; 43919daf8208SAnirudh Venkataramanan case ICE_SW_LKUP_MAC_VLAN: 43929daf8208SAnirudh Venkataramanan case ICE_SW_LKUP_ETHERTYPE: 43939daf8208SAnirudh Venkataramanan case ICE_SW_LKUP_ETHERTYPE_MAC: 43949daf8208SAnirudh Venkataramanan case ICE_SW_LKUP_DFLT: 439580d144c9SAnirudh Venkataramanan case ICE_SW_LKUP_LAST: 439680d144c9SAnirudh Venkataramanan default: 439780d144c9SAnirudh Venkataramanan ice_debug(hw, ICE_DBG_SW, "Unsupported lookup type %d\n", lkup); 43989daf8208SAnirudh Venkataramanan break; 43999daf8208SAnirudh Venkataramanan } 44009daf8208SAnirudh Venkataramanan 4401b7eeb527SRobert Malz free_fltr_list: 44029daf8208SAnirudh Venkataramanan list_for_each_entry_safe(fm_entry, tmp, &remove_list_head, list_entry) { 44039daf8208SAnirudh Venkataramanan list_del(&fm_entry->list_entry); 44049daf8208SAnirudh Venkataramanan devm_kfree(ice_hw_to_dev(hw), fm_entry); 44059daf8208SAnirudh Venkataramanan } 44069daf8208SAnirudh Venkataramanan } 44079daf8208SAnirudh Venkataramanan 44089daf8208SAnirudh Venkataramanan /** 44099daf8208SAnirudh Venkataramanan * ice_remove_vsi_fltr - Remove all filters for a VSI 44109daf8208SAnirudh Venkataramanan * @hw: pointer to the hardware structure 44115726ca0eSAnirudh Venkataramanan * @vsi_handle: VSI handle to remove filters from 44129daf8208SAnirudh Venkataramanan */ 44135726ca0eSAnirudh Venkataramanan void ice_remove_vsi_fltr(struct ice_hw *hw, u16 vsi_handle) 44149daf8208SAnirudh Venkataramanan { 44155726ca0eSAnirudh Venkataramanan ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_MAC); 44165726ca0eSAnirudh Venkataramanan ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_MAC_VLAN); 44175726ca0eSAnirudh Venkataramanan ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_PROMISC); 44185726ca0eSAnirudh Venkataramanan ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_VLAN); 44195726ca0eSAnirudh Venkataramanan ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_DFLT); 44205726ca0eSAnirudh Venkataramanan ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_ETHERTYPE); 44215726ca0eSAnirudh Venkataramanan ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_ETHERTYPE_MAC); 44225726ca0eSAnirudh Venkataramanan ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_PROMISC_VLAN); 44239daf8208SAnirudh Venkataramanan } 44240f9d5027SAnirudh Venkataramanan 44250f9d5027SAnirudh Venkataramanan /** 4426148beb61SHenry Tieman * ice_alloc_res_cntr - allocating resource counter 4427148beb61SHenry Tieman * @hw: pointer to the hardware structure 4428148beb61SHenry Tieman * @type: type of resource 4429148beb61SHenry Tieman * @alloc_shared: if set it is shared else dedicated 4430148beb61SHenry Tieman * @num_items: number of entries requested for FD resource type 4431148beb61SHenry Tieman * @counter_id: counter index returned by AQ call 4432148beb61SHenry Tieman */ 44335e24d598STony Nguyen int 4434148beb61SHenry Tieman ice_alloc_res_cntr(struct ice_hw *hw, u8 type, u8 alloc_shared, u16 num_items, 4435148beb61SHenry Tieman u16 *counter_id) 4436148beb61SHenry Tieman { 4437148beb61SHenry Tieman struct ice_aqc_alloc_free_res_elem *buf; 4438148beb61SHenry Tieman u16 buf_len; 44395518ac2aSTony Nguyen int status; 4440148beb61SHenry Tieman 4441148beb61SHenry Tieman /* Allocate resource */ 444266486d89SBruce Allan buf_len = struct_size(buf, elem, 1); 4443148beb61SHenry Tieman buf = kzalloc(buf_len, GFP_KERNEL); 4444148beb61SHenry Tieman if (!buf) 4445d54699e2STony Nguyen return -ENOMEM; 4446148beb61SHenry Tieman 4447148beb61SHenry Tieman buf->num_elems = cpu_to_le16(num_items); 4448148beb61SHenry Tieman buf->res_type = cpu_to_le16(((type << ICE_AQC_RES_TYPE_S) & 4449148beb61SHenry Tieman ICE_AQC_RES_TYPE_M) | alloc_shared); 4450148beb61SHenry Tieman 4451*52da2fb2SPrzemek Kitszel status = ice_aq_alloc_free_res(hw, buf, buf_len, ice_aqc_opc_alloc_res); 4452148beb61SHenry Tieman if (status) 4453148beb61SHenry Tieman goto exit; 4454148beb61SHenry Tieman 4455148beb61SHenry Tieman *counter_id = le16_to_cpu(buf->elem[0].e.sw_resp); 4456148beb61SHenry Tieman 4457148beb61SHenry Tieman exit: 4458148beb61SHenry Tieman kfree(buf); 4459148beb61SHenry Tieman return status; 4460148beb61SHenry Tieman } 4461148beb61SHenry Tieman 4462148beb61SHenry Tieman /** 4463148beb61SHenry Tieman * ice_free_res_cntr - free resource counter 4464148beb61SHenry Tieman * @hw: pointer to the hardware structure 4465148beb61SHenry Tieman * @type: type of resource 4466148beb61SHenry Tieman * @alloc_shared: if set it is shared else dedicated 4467148beb61SHenry Tieman * @num_items: number of entries to be freed for FD resource type 4468148beb61SHenry Tieman * @counter_id: counter ID resource which needs to be freed 4469148beb61SHenry Tieman */ 44705e24d598STony Nguyen int 4471148beb61SHenry Tieman ice_free_res_cntr(struct ice_hw *hw, u8 type, u8 alloc_shared, u16 num_items, 4472148beb61SHenry Tieman u16 counter_id) 4473148beb61SHenry Tieman { 4474148beb61SHenry Tieman struct ice_aqc_alloc_free_res_elem *buf; 4475148beb61SHenry Tieman u16 buf_len; 44765518ac2aSTony Nguyen int status; 4477148beb61SHenry Tieman 4478148beb61SHenry Tieman /* Free resource */ 447966486d89SBruce Allan buf_len = struct_size(buf, elem, 1); 4480148beb61SHenry Tieman buf = kzalloc(buf_len, GFP_KERNEL); 4481148beb61SHenry Tieman if (!buf) 4482d54699e2STony Nguyen return -ENOMEM; 4483148beb61SHenry Tieman 4484148beb61SHenry Tieman buf->num_elems = cpu_to_le16(num_items); 4485148beb61SHenry Tieman buf->res_type = cpu_to_le16(((type << ICE_AQC_RES_TYPE_S) & 4486148beb61SHenry Tieman ICE_AQC_RES_TYPE_M) | alloc_shared); 4487148beb61SHenry Tieman buf->elem[0].e.sw_resp = cpu_to_le16(counter_id); 4488148beb61SHenry Tieman 4489*52da2fb2SPrzemek Kitszel status = ice_aq_alloc_free_res(hw, buf, buf_len, ice_aqc_opc_free_res); 4490148beb61SHenry Tieman if (status) 44919228d8b2SJacob Keller ice_debug(hw, ICE_DBG_SW, "counter resource could not be freed\n"); 4492148beb61SHenry Tieman 4493148beb61SHenry Tieman kfree(buf); 4494148beb61SHenry Tieman return status; 4495148beb61SHenry Tieman } 4496148beb61SHenry Tieman 449717c6d835SMichal Swiatkowski #define ICE_PROTOCOL_ENTRY(id, ...) { \ 449817c6d835SMichal Swiatkowski .prot_type = id, \ 449917c6d835SMichal Swiatkowski .offs = {__VA_ARGS__}, \ 450017c6d835SMichal Swiatkowski } 450117c6d835SMichal Swiatkowski 450223ccae5cSDave Ertman /** 450323ccae5cSDave Ertman * ice_share_res - set a resource as shared or dedicated 450423ccae5cSDave Ertman * @hw: hw struct of original owner of resource 450523ccae5cSDave Ertman * @type: resource type 450623ccae5cSDave Ertman * @shared: is the resource being set to shared 450723ccae5cSDave Ertman * @res_id: resource id (descriptor) 450823ccae5cSDave Ertman */ 450923ccae5cSDave Ertman int ice_share_res(struct ice_hw *hw, u16 type, u8 shared, u16 res_id) 451023ccae5cSDave Ertman { 451123ccae5cSDave Ertman struct ice_aqc_alloc_free_res_elem *buf; 451223ccae5cSDave Ertman u16 buf_len; 451323ccae5cSDave Ertman int status; 451423ccae5cSDave Ertman 451523ccae5cSDave Ertman buf_len = struct_size(buf, elem, 1); 451623ccae5cSDave Ertman buf = kzalloc(buf_len, GFP_KERNEL); 451723ccae5cSDave Ertman if (!buf) 451823ccae5cSDave Ertman return -ENOMEM; 451923ccae5cSDave Ertman 452023ccae5cSDave Ertman buf->num_elems = cpu_to_le16(1); 452123ccae5cSDave Ertman if (shared) 452223ccae5cSDave Ertman buf->res_type = cpu_to_le16(((type << ICE_AQC_RES_TYPE_S) & 452323ccae5cSDave Ertman ICE_AQC_RES_TYPE_M) | 452423ccae5cSDave Ertman ICE_AQC_RES_TYPE_FLAG_SHARED); 452523ccae5cSDave Ertman else 452623ccae5cSDave Ertman buf->res_type = cpu_to_le16(((type << ICE_AQC_RES_TYPE_S) & 452723ccae5cSDave Ertman ICE_AQC_RES_TYPE_M) & 452823ccae5cSDave Ertman ~ICE_AQC_RES_TYPE_FLAG_SHARED); 452923ccae5cSDave Ertman 453023ccae5cSDave Ertman buf->elem[0].e.sw_resp = cpu_to_le16(res_id); 4531*52da2fb2SPrzemek Kitszel status = ice_aq_alloc_free_res(hw, buf, buf_len, 4532*52da2fb2SPrzemek Kitszel ice_aqc_opc_share_res); 453323ccae5cSDave Ertman if (status) 453423ccae5cSDave Ertman ice_debug(hw, ICE_DBG_SW, "Could not set resource type %u id %u to %s\n", 453523ccae5cSDave Ertman type, res_id, shared ? "SHARED" : "DEDICATED"); 453623ccae5cSDave Ertman 453723ccae5cSDave Ertman kfree(buf); 453823ccae5cSDave Ertman return status; 453923ccae5cSDave Ertman } 454023ccae5cSDave Ertman 4541fd2a6b71SDan Nowlin /* This is mapping table entry that maps every word within a given protocol 4542fd2a6b71SDan Nowlin * structure to the real byte offset as per the specification of that 4543fd2a6b71SDan Nowlin * protocol header. 4544fd2a6b71SDan Nowlin * for example dst address is 3 words in ethertype header and corresponding 4545fd2a6b71SDan Nowlin * bytes are 0, 2, 3 in the actual packet header and src address is at 4, 6, 8 4546fd2a6b71SDan Nowlin * IMPORTANT: Every structure part of "ice_prot_hdr" union should have a 4547fd2a6b71SDan Nowlin * matching entry describing its field. This needs to be updated if new 4548fd2a6b71SDan Nowlin * structure is added to that union. 4549fd2a6b71SDan Nowlin */ 4550fd2a6b71SDan Nowlin static const struct ice_prot_ext_tbl_entry ice_prot_ext[ICE_PROTOCOL_LAST] = { 455117c6d835SMichal Swiatkowski ICE_PROTOCOL_ENTRY(ICE_MAC_OFOS, 0, 2, 4, 6, 8, 10, 12), 455217c6d835SMichal Swiatkowski ICE_PROTOCOL_ENTRY(ICE_MAC_IL, 0, 2, 4, 6, 8, 10, 12), 455317c6d835SMichal Swiatkowski ICE_PROTOCOL_ENTRY(ICE_ETYPE_OL, 0), 455417c6d835SMichal Swiatkowski ICE_PROTOCOL_ENTRY(ICE_ETYPE_IL, 0), 455517c6d835SMichal Swiatkowski ICE_PROTOCOL_ENTRY(ICE_VLAN_OFOS, 2, 0), 455617c6d835SMichal Swiatkowski ICE_PROTOCOL_ENTRY(ICE_IPV4_OFOS, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18), 455717c6d835SMichal Swiatkowski ICE_PROTOCOL_ENTRY(ICE_IPV4_IL, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18), 455817c6d835SMichal Swiatkowski ICE_PROTOCOL_ENTRY(ICE_IPV6_OFOS, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 455917c6d835SMichal Swiatkowski 20, 22, 24, 26, 28, 30, 32, 34, 36, 38), 456017c6d835SMichal Swiatkowski ICE_PROTOCOL_ENTRY(ICE_IPV6_IL, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 456117c6d835SMichal Swiatkowski 22, 24, 26, 28, 30, 32, 34, 36, 38), 456217c6d835SMichal Swiatkowski ICE_PROTOCOL_ENTRY(ICE_TCP_IL, 0, 2), 456317c6d835SMichal Swiatkowski ICE_PROTOCOL_ENTRY(ICE_UDP_OF, 0, 2), 456417c6d835SMichal Swiatkowski ICE_PROTOCOL_ENTRY(ICE_UDP_ILOS, 0, 2), 456517c6d835SMichal Swiatkowski ICE_PROTOCOL_ENTRY(ICE_VXLAN, 8, 10, 12, 14), 456617c6d835SMichal Swiatkowski ICE_PROTOCOL_ENTRY(ICE_GENEVE, 8, 10, 12, 14), 456717c6d835SMichal Swiatkowski ICE_PROTOCOL_ENTRY(ICE_NVGRE, 0, 2, 4, 6), 456817c6d835SMichal Swiatkowski ICE_PROTOCOL_ENTRY(ICE_GTP, 8, 10, 12, 14, 16, 18, 20, 22), 456917c6d835SMichal Swiatkowski ICE_PROTOCOL_ENTRY(ICE_GTP_NO_PAY, 8, 10, 12, 14), 457017c6d835SMichal Swiatkowski ICE_PROTOCOL_ENTRY(ICE_PPPOE, 0, 2, 4, 6), 457117c6d835SMichal Swiatkowski ICE_PROTOCOL_ENTRY(ICE_L2TPV3, 0, 2, 4, 6, 8, 10), 457217c6d835SMichal Swiatkowski ICE_PROTOCOL_ENTRY(ICE_VLAN_EX, 2, 0), 457317c6d835SMichal Swiatkowski ICE_PROTOCOL_ENTRY(ICE_VLAN_IN, 2, 0), 457403592a14SMichal Swiatkowski ICE_PROTOCOL_ENTRY(ICE_HW_METADATA, 457503592a14SMichal Swiatkowski ICE_SOURCE_PORT_MDID_OFFSET, 457603592a14SMichal Swiatkowski ICE_PTYPE_MDID_OFFSET, 457703592a14SMichal Swiatkowski ICE_PACKET_LENGTH_MDID_OFFSET, 457803592a14SMichal Swiatkowski ICE_SOURCE_VSI_MDID_OFFSET, 457903592a14SMichal Swiatkowski ICE_PKT_VLAN_MDID_OFFSET, 458003592a14SMichal Swiatkowski ICE_PKT_TUNNEL_MDID_OFFSET, 458103592a14SMichal Swiatkowski ICE_PKT_TCP_MDID_OFFSET, 458203592a14SMichal Swiatkowski ICE_PKT_ERROR_MDID_OFFSET), 4583fd2a6b71SDan Nowlin }; 4584fd2a6b71SDan Nowlin 4585fd2a6b71SDan Nowlin static struct ice_protocol_entry ice_prot_id_tbl[ICE_PROTOCOL_LAST] = { 4586fd2a6b71SDan Nowlin { ICE_MAC_OFOS, ICE_MAC_OFOS_HW }, 4587fd2a6b71SDan Nowlin { ICE_MAC_IL, ICE_MAC_IL_HW }, 4588fd2a6b71SDan Nowlin { ICE_ETYPE_OL, ICE_ETYPE_OL_HW }, 458934a89775SMartyna Szapar-Mudlaw { ICE_ETYPE_IL, ICE_ETYPE_IL_HW }, 4590fd2a6b71SDan Nowlin { ICE_VLAN_OFOS, ICE_VLAN_OL_HW }, 4591fd2a6b71SDan Nowlin { ICE_IPV4_OFOS, ICE_IPV4_OFOS_HW }, 4592fd2a6b71SDan Nowlin { ICE_IPV4_IL, ICE_IPV4_IL_HW }, 4593fd2a6b71SDan Nowlin { ICE_IPV6_OFOS, ICE_IPV6_OFOS_HW }, 4594fd2a6b71SDan Nowlin { ICE_IPV6_IL, ICE_IPV6_IL_HW }, 4595fd2a6b71SDan Nowlin { ICE_TCP_IL, ICE_TCP_IL_HW }, 4596fd2a6b71SDan Nowlin { ICE_UDP_OF, ICE_UDP_OF_HW }, 4597fd2a6b71SDan Nowlin { ICE_UDP_ILOS, ICE_UDP_ILOS_HW }, 45988b032a55SMichal Swiatkowski { ICE_VXLAN, ICE_UDP_OF_HW }, 45998b032a55SMichal Swiatkowski { ICE_GENEVE, ICE_UDP_OF_HW }, 4600f0a35040SMichal Swiatkowski { ICE_NVGRE, ICE_GRE_OF_HW }, 46019a225f81SMarcin Szycik { ICE_GTP, ICE_UDP_OF_HW }, 46029a225f81SMarcin Szycik { ICE_GTP_NO_PAY, ICE_UDP_ILOS_HW }, 4603cd8efeeeSMarcin Szycik { ICE_PPPOE, ICE_PPPOE_HW }, 4604cd634549SMarcin Szycik { ICE_L2TPV3, ICE_L2TPV3_HW }, 460506bca7c2SMartyna Szapar-Mudlaw { ICE_VLAN_EX, ICE_VLAN_OF_HW }, 460606bca7c2SMartyna Szapar-Mudlaw { ICE_VLAN_IN, ICE_VLAN_OL_HW }, 460703592a14SMichal Swiatkowski { ICE_HW_METADATA, ICE_META_DATA_ID_HW }, 4608fd2a6b71SDan Nowlin }; 4609fd2a6b71SDan Nowlin 4610fd2a6b71SDan Nowlin /** 4611fd2a6b71SDan Nowlin * ice_find_recp - find a recipe 4612fd2a6b71SDan Nowlin * @hw: pointer to the hardware structure 4613fd2a6b71SDan Nowlin * @lkup_exts: extension sequence to match 4614bccd9bceSMarcin Szycik * @rinfo: information regarding the rule e.g. priority and action info 4615fd2a6b71SDan Nowlin * 4616fd2a6b71SDan Nowlin * Returns index of matching recipe, or ICE_MAX_NUM_RECIPES if not found. 4617fd2a6b71SDan Nowlin */ 4618de6acd1cSMichal Swiatkowski static u16 4619de6acd1cSMichal Swiatkowski ice_find_recp(struct ice_hw *hw, struct ice_prot_lkup_ext *lkup_exts, 4620bccd9bceSMarcin Szycik const struct ice_adv_rule_info *rinfo) 4621fd2a6b71SDan Nowlin { 4622fd2a6b71SDan Nowlin bool refresh_required = true; 4623fd2a6b71SDan Nowlin struct ice_sw_recipe *recp; 4624fd2a6b71SDan Nowlin u8 i; 4625fd2a6b71SDan Nowlin 4626fd2a6b71SDan Nowlin /* Walk through existing recipes to find a match */ 4627fd2a6b71SDan Nowlin recp = hw->switch_info->recp_list; 4628fd2a6b71SDan Nowlin for (i = 0; i < ICE_MAX_NUM_RECIPES; i++) { 4629fd2a6b71SDan Nowlin /* If recipe was not created for this ID, in SW bookkeeping, 4630fd2a6b71SDan Nowlin * check if FW has an entry for this recipe. If the FW has an 4631fd2a6b71SDan Nowlin * entry update it in our SW bookkeeping and continue with the 4632fd2a6b71SDan Nowlin * matching. 4633fd2a6b71SDan Nowlin */ 4634fd2a6b71SDan Nowlin if (!recp[i].recp_created) 4635fd2a6b71SDan Nowlin if (ice_get_recp_frm_fw(hw, 4636fd2a6b71SDan Nowlin hw->switch_info->recp_list, i, 4637fd2a6b71SDan Nowlin &refresh_required)) 4638fd2a6b71SDan Nowlin continue; 4639fd2a6b71SDan Nowlin 4640fd2a6b71SDan Nowlin /* Skip inverse action recipes */ 4641fd2a6b71SDan Nowlin if (recp[i].root_buf && recp[i].root_buf->content.act_ctrl & 4642fd2a6b71SDan Nowlin ICE_AQ_RECIPE_ACT_INV_ACT) 4643fd2a6b71SDan Nowlin continue; 4644fd2a6b71SDan Nowlin 4645fd2a6b71SDan Nowlin /* if number of words we are looking for match */ 4646fd2a6b71SDan Nowlin if (lkup_exts->n_val_words == recp[i].lkup_exts.n_val_words) { 4647fd2a6b71SDan Nowlin struct ice_fv_word *ar = recp[i].lkup_exts.fv_words; 4648fd2a6b71SDan Nowlin struct ice_fv_word *be = lkup_exts->fv_words; 4649fd2a6b71SDan Nowlin u16 *cr = recp[i].lkup_exts.field_mask; 4650fd2a6b71SDan Nowlin u16 *de = lkup_exts->field_mask; 4651fd2a6b71SDan Nowlin bool found = true; 4652fd2a6b71SDan Nowlin u8 pe, qr; 4653fd2a6b71SDan Nowlin 4654fd2a6b71SDan Nowlin /* ar, cr, and qr are related to the recipe words, while 4655fd2a6b71SDan Nowlin * be, de, and pe are related to the lookup words 4656fd2a6b71SDan Nowlin */ 4657fd2a6b71SDan Nowlin for (pe = 0; pe < lkup_exts->n_val_words; pe++) { 4658fd2a6b71SDan Nowlin for (qr = 0; qr < recp[i].lkup_exts.n_val_words; 4659fd2a6b71SDan Nowlin qr++) { 4660fd2a6b71SDan Nowlin if (ar[qr].off == be[pe].off && 4661fd2a6b71SDan Nowlin ar[qr].prot_id == be[pe].prot_id && 4662fd2a6b71SDan Nowlin cr[qr] == de[pe]) 4663fd2a6b71SDan Nowlin /* Found the "pe"th word in the 4664fd2a6b71SDan Nowlin * given recipe 4665fd2a6b71SDan Nowlin */ 4666fd2a6b71SDan Nowlin break; 4667fd2a6b71SDan Nowlin } 4668fd2a6b71SDan Nowlin /* After walking through all the words in the 4669fd2a6b71SDan Nowlin * "i"th recipe if "p"th word was not found then 4670fd2a6b71SDan Nowlin * this recipe is not what we are looking for. 4671fd2a6b71SDan Nowlin * So break out from this loop and try the next 4672fd2a6b71SDan Nowlin * recipe 4673fd2a6b71SDan Nowlin */ 4674fd2a6b71SDan Nowlin if (qr >= recp[i].lkup_exts.n_val_words) { 4675fd2a6b71SDan Nowlin found = false; 4676fd2a6b71SDan Nowlin break; 4677fd2a6b71SDan Nowlin } 4678fd2a6b71SDan Nowlin } 4679fd2a6b71SDan Nowlin /* If for "i"th recipe the found was never set to false 4680fd2a6b71SDan Nowlin * then it means we found our match 4681bccd9bceSMarcin Szycik * Also tun type and *_pass_l2 of recipe needs to be 4682bccd9bceSMarcin Szycik * checked 4683fd2a6b71SDan Nowlin */ 4684bccd9bceSMarcin Szycik if (found && recp[i].tun_type == rinfo->tun_type && 4685bccd9bceSMarcin Szycik recp[i].need_pass_l2 == rinfo->need_pass_l2 && 4686bccd9bceSMarcin Szycik recp[i].allow_pass_l2 == rinfo->allow_pass_l2) 4687fd2a6b71SDan Nowlin return i; /* Return the recipe ID */ 4688fd2a6b71SDan Nowlin } 4689fd2a6b71SDan Nowlin } 4690fd2a6b71SDan Nowlin return ICE_MAX_NUM_RECIPES; 4691fd2a6b71SDan Nowlin } 4692fd2a6b71SDan Nowlin 4693fd2a6b71SDan Nowlin /** 4694a1ffafb0SBrett Creeley * ice_change_proto_id_to_dvm - change proto id in prot_id_tbl 4695a1ffafb0SBrett Creeley * 4696a1ffafb0SBrett Creeley * As protocol id for outer vlan is different in dvm and svm, if dvm is 4697a1ffafb0SBrett Creeley * supported protocol array record for outer vlan has to be modified to 4698a1ffafb0SBrett Creeley * reflect the value proper for DVM. 4699a1ffafb0SBrett Creeley */ 4700a1ffafb0SBrett Creeley void ice_change_proto_id_to_dvm(void) 4701a1ffafb0SBrett Creeley { 4702a1ffafb0SBrett Creeley u8 i; 4703a1ffafb0SBrett Creeley 4704a1ffafb0SBrett Creeley for (i = 0; i < ARRAY_SIZE(ice_prot_id_tbl); i++) 4705a1ffafb0SBrett Creeley if (ice_prot_id_tbl[i].type == ICE_VLAN_OFOS && 4706a1ffafb0SBrett Creeley ice_prot_id_tbl[i].protocol_id != ICE_VLAN_OF_HW) 4707a1ffafb0SBrett Creeley ice_prot_id_tbl[i].protocol_id = ICE_VLAN_OF_HW; 4708a1ffafb0SBrett Creeley } 4709a1ffafb0SBrett Creeley 4710a1ffafb0SBrett Creeley /** 4711fd2a6b71SDan Nowlin * ice_prot_type_to_id - get protocol ID from protocol type 4712fd2a6b71SDan Nowlin * @type: protocol type 4713fd2a6b71SDan Nowlin * @id: pointer to variable that will receive the ID 4714fd2a6b71SDan Nowlin * 4715fd2a6b71SDan Nowlin * Returns true if found, false otherwise 4716fd2a6b71SDan Nowlin */ 4717fd2a6b71SDan Nowlin static bool ice_prot_type_to_id(enum ice_protocol_type type, u8 *id) 4718fd2a6b71SDan Nowlin { 4719fd2a6b71SDan Nowlin u8 i; 4720fd2a6b71SDan Nowlin 4721fd2a6b71SDan Nowlin for (i = 0; i < ARRAY_SIZE(ice_prot_id_tbl); i++) 4722fd2a6b71SDan Nowlin if (ice_prot_id_tbl[i].type == type) { 4723fd2a6b71SDan Nowlin *id = ice_prot_id_tbl[i].protocol_id; 4724fd2a6b71SDan Nowlin return true; 4725fd2a6b71SDan Nowlin } 4726fd2a6b71SDan Nowlin return false; 4727fd2a6b71SDan Nowlin } 4728fd2a6b71SDan Nowlin 4729fd2a6b71SDan Nowlin /** 4730fd2a6b71SDan Nowlin * ice_fill_valid_words - count valid words 4731fd2a6b71SDan Nowlin * @rule: advanced rule with lookup information 4732fd2a6b71SDan Nowlin * @lkup_exts: byte offset extractions of the words that are valid 4733fd2a6b71SDan Nowlin * 4734fd2a6b71SDan Nowlin * calculate valid words in a lookup rule using mask value 4735fd2a6b71SDan Nowlin */ 4736fd2a6b71SDan Nowlin static u8 4737fd2a6b71SDan Nowlin ice_fill_valid_words(struct ice_adv_lkup_elem *rule, 4738fd2a6b71SDan Nowlin struct ice_prot_lkup_ext *lkup_exts) 4739fd2a6b71SDan Nowlin { 4740fd2a6b71SDan Nowlin u8 j, word, prot_id, ret_val; 4741fd2a6b71SDan Nowlin 4742fd2a6b71SDan Nowlin if (!ice_prot_type_to_id(rule->type, &prot_id)) 4743fd2a6b71SDan Nowlin return 0; 4744fd2a6b71SDan Nowlin 4745fd2a6b71SDan Nowlin word = lkup_exts->n_val_words; 4746fd2a6b71SDan Nowlin 4747fd2a6b71SDan Nowlin for (j = 0; j < sizeof(rule->m_u) / sizeof(u16); j++) 4748fd2a6b71SDan Nowlin if (((u16 *)&rule->m_u)[j] && 4749fd2a6b71SDan Nowlin rule->type < ARRAY_SIZE(ice_prot_ext)) { 4750fd2a6b71SDan Nowlin /* No more space to accommodate */ 4751fd2a6b71SDan Nowlin if (word >= ICE_MAX_CHAIN_WORDS) 4752fd2a6b71SDan Nowlin return 0; 4753fd2a6b71SDan Nowlin lkup_exts->fv_words[word].off = 4754fd2a6b71SDan Nowlin ice_prot_ext[rule->type].offs[j]; 4755fd2a6b71SDan Nowlin lkup_exts->fv_words[word].prot_id = 4756fd2a6b71SDan Nowlin ice_prot_id_tbl[rule->type].protocol_id; 4757fd2a6b71SDan Nowlin lkup_exts->field_mask[word] = 4758fd2a6b71SDan Nowlin be16_to_cpu(((__force __be16 *)&rule->m_u)[j]); 4759fd2a6b71SDan Nowlin word++; 4760fd2a6b71SDan Nowlin } 4761fd2a6b71SDan Nowlin 4762fd2a6b71SDan Nowlin ret_val = word - lkup_exts->n_val_words; 4763fd2a6b71SDan Nowlin lkup_exts->n_val_words = word; 4764fd2a6b71SDan Nowlin 4765fd2a6b71SDan Nowlin return ret_val; 4766fd2a6b71SDan Nowlin } 4767fd2a6b71SDan Nowlin 4768fd2a6b71SDan Nowlin /** 4769fd2a6b71SDan Nowlin * ice_create_first_fit_recp_def - Create a recipe grouping 4770fd2a6b71SDan Nowlin * @hw: pointer to the hardware structure 4771fd2a6b71SDan Nowlin * @lkup_exts: an array of protocol header extractions 4772fd2a6b71SDan Nowlin * @rg_list: pointer to a list that stores new recipe groups 4773fd2a6b71SDan Nowlin * @recp_cnt: pointer to a variable that stores returned number of recipe groups 4774fd2a6b71SDan Nowlin * 4775fd2a6b71SDan Nowlin * Using first fit algorithm, take all the words that are still not done 4776fd2a6b71SDan Nowlin * and start grouping them in 4-word groups. Each group makes up one 4777fd2a6b71SDan Nowlin * recipe. 4778fd2a6b71SDan Nowlin */ 47795e24d598STony Nguyen static int 4780fd2a6b71SDan Nowlin ice_create_first_fit_recp_def(struct ice_hw *hw, 4781fd2a6b71SDan Nowlin struct ice_prot_lkup_ext *lkup_exts, 4782fd2a6b71SDan Nowlin struct list_head *rg_list, 4783fd2a6b71SDan Nowlin u8 *recp_cnt) 4784fd2a6b71SDan Nowlin { 4785fd2a6b71SDan Nowlin struct ice_pref_recipe_group *grp = NULL; 4786fd2a6b71SDan Nowlin u8 j; 4787fd2a6b71SDan Nowlin 4788fd2a6b71SDan Nowlin *recp_cnt = 0; 4789fd2a6b71SDan Nowlin 4790fd2a6b71SDan Nowlin /* Walk through every word in the rule to check if it is not done. If so 4791fd2a6b71SDan Nowlin * then this word needs to be part of a new recipe. 4792fd2a6b71SDan Nowlin */ 4793fd2a6b71SDan Nowlin for (j = 0; j < lkup_exts->n_val_words; j++) 4794fd2a6b71SDan Nowlin if (!test_bit(j, lkup_exts->done)) { 4795fd2a6b71SDan Nowlin if (!grp || 4796fd2a6b71SDan Nowlin grp->n_val_pairs == ICE_NUM_WORDS_RECIPE) { 4797fd2a6b71SDan Nowlin struct ice_recp_grp_entry *entry; 4798fd2a6b71SDan Nowlin 4799fd2a6b71SDan Nowlin entry = devm_kzalloc(ice_hw_to_dev(hw), 4800fd2a6b71SDan Nowlin sizeof(*entry), 4801fd2a6b71SDan Nowlin GFP_KERNEL); 4802fd2a6b71SDan Nowlin if (!entry) 4803d54699e2STony Nguyen return -ENOMEM; 4804fd2a6b71SDan Nowlin list_add(&entry->l_entry, rg_list); 4805fd2a6b71SDan Nowlin grp = &entry->r_group; 4806fd2a6b71SDan Nowlin (*recp_cnt)++; 4807fd2a6b71SDan Nowlin } 4808fd2a6b71SDan Nowlin 4809fd2a6b71SDan Nowlin grp->pairs[grp->n_val_pairs].prot_id = 4810fd2a6b71SDan Nowlin lkup_exts->fv_words[j].prot_id; 4811fd2a6b71SDan Nowlin grp->pairs[grp->n_val_pairs].off = 4812fd2a6b71SDan Nowlin lkup_exts->fv_words[j].off; 4813fd2a6b71SDan Nowlin grp->mask[grp->n_val_pairs] = lkup_exts->field_mask[j]; 4814fd2a6b71SDan Nowlin grp->n_val_pairs++; 4815fd2a6b71SDan Nowlin } 4816fd2a6b71SDan Nowlin 4817fd2a6b71SDan Nowlin return 0; 4818fd2a6b71SDan Nowlin } 4819fd2a6b71SDan Nowlin 4820fd2a6b71SDan Nowlin /** 4821fd2a6b71SDan Nowlin * ice_fill_fv_word_index - fill in the field vector indices for a recipe group 4822fd2a6b71SDan Nowlin * @hw: pointer to the hardware structure 4823fd2a6b71SDan Nowlin * @fv_list: field vector with the extraction sequence information 4824fd2a6b71SDan Nowlin * @rg_list: recipe groupings with protocol-offset pairs 4825fd2a6b71SDan Nowlin * 4826fd2a6b71SDan Nowlin * Helper function to fill in the field vector indices for protocol-offset 4827fd2a6b71SDan Nowlin * pairs. These indexes are then ultimately programmed into a recipe. 4828fd2a6b71SDan Nowlin */ 48295e24d598STony Nguyen static int 4830fd2a6b71SDan Nowlin ice_fill_fv_word_index(struct ice_hw *hw, struct list_head *fv_list, 4831fd2a6b71SDan Nowlin struct list_head *rg_list) 4832fd2a6b71SDan Nowlin { 4833fd2a6b71SDan Nowlin struct ice_sw_fv_list_entry *fv; 4834fd2a6b71SDan Nowlin struct ice_recp_grp_entry *rg; 4835fd2a6b71SDan Nowlin struct ice_fv_word *fv_ext; 4836fd2a6b71SDan Nowlin 4837fd2a6b71SDan Nowlin if (list_empty(fv_list)) 4838fd2a6b71SDan Nowlin return 0; 4839fd2a6b71SDan Nowlin 4840fd2a6b71SDan Nowlin fv = list_first_entry(fv_list, struct ice_sw_fv_list_entry, 4841fd2a6b71SDan Nowlin list_entry); 4842fd2a6b71SDan Nowlin fv_ext = fv->fv_ptr->ew; 4843fd2a6b71SDan Nowlin 4844fd2a6b71SDan Nowlin list_for_each_entry(rg, rg_list, l_entry) { 4845fd2a6b71SDan Nowlin u8 i; 4846fd2a6b71SDan Nowlin 4847fd2a6b71SDan Nowlin for (i = 0; i < rg->r_group.n_val_pairs; i++) { 4848fd2a6b71SDan Nowlin struct ice_fv_word *pr; 4849fd2a6b71SDan Nowlin bool found = false; 4850fd2a6b71SDan Nowlin u16 mask; 4851fd2a6b71SDan Nowlin u8 j; 4852fd2a6b71SDan Nowlin 4853fd2a6b71SDan Nowlin pr = &rg->r_group.pairs[i]; 4854fd2a6b71SDan Nowlin mask = rg->r_group.mask[i]; 4855fd2a6b71SDan Nowlin 4856fd2a6b71SDan Nowlin for (j = 0; j < hw->blk[ICE_BLK_SW].es.fvw; j++) 4857fd2a6b71SDan Nowlin if (fv_ext[j].prot_id == pr->prot_id && 4858fd2a6b71SDan Nowlin fv_ext[j].off == pr->off) { 4859fd2a6b71SDan Nowlin found = true; 4860fd2a6b71SDan Nowlin 4861fd2a6b71SDan Nowlin /* Store index of field vector */ 4862fd2a6b71SDan Nowlin rg->fv_idx[i] = j; 4863fd2a6b71SDan Nowlin rg->fv_mask[i] = mask; 4864fd2a6b71SDan Nowlin break; 4865fd2a6b71SDan Nowlin } 4866fd2a6b71SDan Nowlin 4867fd2a6b71SDan Nowlin /* Protocol/offset could not be found, caller gave an 4868fd2a6b71SDan Nowlin * invalid pair 4869fd2a6b71SDan Nowlin */ 4870fd2a6b71SDan Nowlin if (!found) 4871d54699e2STony Nguyen return -EINVAL; 4872fd2a6b71SDan Nowlin } 4873fd2a6b71SDan Nowlin } 4874fd2a6b71SDan Nowlin 4875fd2a6b71SDan Nowlin return 0; 4876fd2a6b71SDan Nowlin } 4877fd2a6b71SDan Nowlin 4878fd2a6b71SDan Nowlin /** 4879fd2a6b71SDan Nowlin * ice_find_free_recp_res_idx - find free result indexes for recipe 4880fd2a6b71SDan Nowlin * @hw: pointer to hardware structure 4881fd2a6b71SDan Nowlin * @profiles: bitmap of profiles that will be associated with the new recipe 4882fd2a6b71SDan Nowlin * @free_idx: pointer to variable to receive the free index bitmap 4883fd2a6b71SDan Nowlin * 4884fd2a6b71SDan Nowlin * The algorithm used here is: 4885fd2a6b71SDan Nowlin * 1. When creating a new recipe, create a set P which contains all 4886fd2a6b71SDan Nowlin * Profiles that will be associated with our new recipe 4887fd2a6b71SDan Nowlin * 4888fd2a6b71SDan Nowlin * 2. For each Profile p in set P: 4889fd2a6b71SDan Nowlin * a. Add all recipes associated with Profile p into set R 4890fd2a6b71SDan Nowlin * b. Optional : PossibleIndexes &= profile[p].possibleIndexes 4891fd2a6b71SDan Nowlin * [initially PossibleIndexes should be 0xFFFFFFFFFFFFFFFF] 4892fd2a6b71SDan Nowlin * i. Or just assume they all have the same possible indexes: 4893fd2a6b71SDan Nowlin * 44, 45, 46, 47 4894fd2a6b71SDan Nowlin * i.e., PossibleIndexes = 0x0000F00000000000 4895fd2a6b71SDan Nowlin * 4896fd2a6b71SDan Nowlin * 3. For each Recipe r in set R: 4897fd2a6b71SDan Nowlin * a. UsedIndexes |= (bitwise or ) recipe[r].res_indexes 4898fd2a6b71SDan Nowlin * b. FreeIndexes = UsedIndexes ^ PossibleIndexes 4899fd2a6b71SDan Nowlin * 4900fd2a6b71SDan Nowlin * FreeIndexes will contain the bits indicating the indexes free for use, 4901fd2a6b71SDan Nowlin * then the code needs to update the recipe[r].used_result_idx_bits to 4902fd2a6b71SDan Nowlin * indicate which indexes were selected for use by this recipe. 4903fd2a6b71SDan Nowlin */ 4904fd2a6b71SDan Nowlin static u16 4905fd2a6b71SDan Nowlin ice_find_free_recp_res_idx(struct ice_hw *hw, const unsigned long *profiles, 4906fd2a6b71SDan Nowlin unsigned long *free_idx) 4907fd2a6b71SDan Nowlin { 4908fd2a6b71SDan Nowlin DECLARE_BITMAP(possible_idx, ICE_MAX_FV_WORDS); 4909fd2a6b71SDan Nowlin DECLARE_BITMAP(recipes, ICE_MAX_NUM_RECIPES); 4910fd2a6b71SDan Nowlin DECLARE_BITMAP(used_idx, ICE_MAX_FV_WORDS); 4911fd2a6b71SDan Nowlin u16 bit; 4912fd2a6b71SDan Nowlin 4913fd2a6b71SDan Nowlin bitmap_zero(recipes, ICE_MAX_NUM_RECIPES); 4914fd2a6b71SDan Nowlin bitmap_zero(used_idx, ICE_MAX_FV_WORDS); 4915fd2a6b71SDan Nowlin 49162f7ee2a7SAlexander Lobakin bitmap_fill(possible_idx, ICE_MAX_FV_WORDS); 4917fd2a6b71SDan Nowlin 4918fd2a6b71SDan Nowlin /* For each profile we are going to associate the recipe with, add the 4919fd2a6b71SDan Nowlin * recipes that are associated with that profile. This will give us 4920fd2a6b71SDan Nowlin * the set of recipes that our recipe may collide with. Also, determine 4921fd2a6b71SDan Nowlin * what possible result indexes are usable given this set of profiles. 4922fd2a6b71SDan Nowlin */ 4923fd2a6b71SDan Nowlin for_each_set_bit(bit, profiles, ICE_MAX_NUM_PROFILES) { 4924fd2a6b71SDan Nowlin bitmap_or(recipes, recipes, profile_to_recipe[bit], 4925fd2a6b71SDan Nowlin ICE_MAX_NUM_RECIPES); 4926fd2a6b71SDan Nowlin bitmap_and(possible_idx, possible_idx, 4927fd2a6b71SDan Nowlin hw->switch_info->prof_res_bm[bit], 4928fd2a6b71SDan Nowlin ICE_MAX_FV_WORDS); 4929fd2a6b71SDan Nowlin } 4930fd2a6b71SDan Nowlin 4931fd2a6b71SDan Nowlin /* For each recipe that our new recipe may collide with, determine 4932fd2a6b71SDan Nowlin * which indexes have been used. 4933fd2a6b71SDan Nowlin */ 4934fd2a6b71SDan Nowlin for_each_set_bit(bit, recipes, ICE_MAX_NUM_RECIPES) 4935fd2a6b71SDan Nowlin bitmap_or(used_idx, used_idx, 4936fd2a6b71SDan Nowlin hw->switch_info->recp_list[bit].res_idxs, 4937fd2a6b71SDan Nowlin ICE_MAX_FV_WORDS); 4938fd2a6b71SDan Nowlin 4939fd2a6b71SDan Nowlin bitmap_xor(free_idx, used_idx, possible_idx, ICE_MAX_FV_WORDS); 4940fd2a6b71SDan Nowlin 4941fd2a6b71SDan Nowlin /* return number of free indexes */ 4942fd2a6b71SDan Nowlin return (u16)bitmap_weight(free_idx, ICE_MAX_FV_WORDS); 4943fd2a6b71SDan Nowlin } 4944fd2a6b71SDan Nowlin 4945fd2a6b71SDan Nowlin /** 4946fd2a6b71SDan Nowlin * ice_add_sw_recipe - function to call AQ calls to create switch recipe 4947fd2a6b71SDan Nowlin * @hw: pointer to hardware structure 4948fd2a6b71SDan Nowlin * @rm: recipe management list entry 4949fd2a6b71SDan Nowlin * @profiles: bitmap of profiles that will be associated. 4950fd2a6b71SDan Nowlin */ 49515e24d598STony Nguyen static int 4952fd2a6b71SDan Nowlin ice_add_sw_recipe(struct ice_hw *hw, struct ice_sw_recipe *rm, 49538b032a55SMichal Swiatkowski unsigned long *profiles) 4954fd2a6b71SDan Nowlin { 4955fd2a6b71SDan Nowlin DECLARE_BITMAP(result_idx_bm, ICE_MAX_FV_WORDS); 4956bccd9bceSMarcin Szycik struct ice_aqc_recipe_content *content; 4957fd2a6b71SDan Nowlin struct ice_aqc_recipe_data_elem *tmp; 4958fd2a6b71SDan Nowlin struct ice_aqc_recipe_data_elem *buf; 4959fd2a6b71SDan Nowlin struct ice_recp_grp_entry *entry; 4960fd2a6b71SDan Nowlin u16 free_res_idx; 4961fd2a6b71SDan Nowlin u16 recipe_count; 4962fd2a6b71SDan Nowlin u8 chain_idx; 4963fd2a6b71SDan Nowlin u8 recps = 0; 49645518ac2aSTony Nguyen int status; 4965fd2a6b71SDan Nowlin 4966fd2a6b71SDan Nowlin /* When more than one recipe are required, another recipe is needed to 4967fd2a6b71SDan Nowlin * chain them together. Matching a tunnel metadata ID takes up one of 4968fd2a6b71SDan Nowlin * the match fields in the chaining recipe reducing the number of 4969fd2a6b71SDan Nowlin * chained recipes by one. 4970fd2a6b71SDan Nowlin */ 4971fd2a6b71SDan Nowlin /* check number of free result indices */ 4972fd2a6b71SDan Nowlin bitmap_zero(result_idx_bm, ICE_MAX_FV_WORDS); 4973fd2a6b71SDan Nowlin free_res_idx = ice_find_free_recp_res_idx(hw, profiles, result_idx_bm); 4974fd2a6b71SDan Nowlin 4975fd2a6b71SDan Nowlin ice_debug(hw, ICE_DBG_SW, "Result idx slots: %d, need %d\n", 4976fd2a6b71SDan Nowlin free_res_idx, rm->n_grp_count); 4977fd2a6b71SDan Nowlin 4978fd2a6b71SDan Nowlin if (rm->n_grp_count > 1) { 4979fd2a6b71SDan Nowlin if (rm->n_grp_count > free_res_idx) 4980d54699e2STony Nguyen return -ENOSPC; 4981fd2a6b71SDan Nowlin 4982fd2a6b71SDan Nowlin rm->n_grp_count++; 4983fd2a6b71SDan Nowlin } 4984fd2a6b71SDan Nowlin 4985fd2a6b71SDan Nowlin if (rm->n_grp_count > ICE_MAX_CHAIN_RECIPE) 4986d54699e2STony Nguyen return -ENOSPC; 4987fd2a6b71SDan Nowlin 4988fd2a6b71SDan Nowlin tmp = kcalloc(ICE_MAX_NUM_RECIPES, sizeof(*tmp), GFP_KERNEL); 4989fd2a6b71SDan Nowlin if (!tmp) 4990d54699e2STony Nguyen return -ENOMEM; 4991fd2a6b71SDan Nowlin 4992fd2a6b71SDan Nowlin buf = devm_kcalloc(ice_hw_to_dev(hw), rm->n_grp_count, sizeof(*buf), 4993fd2a6b71SDan Nowlin GFP_KERNEL); 4994fd2a6b71SDan Nowlin if (!buf) { 4995d54699e2STony Nguyen status = -ENOMEM; 4996fd2a6b71SDan Nowlin goto err_mem; 4997fd2a6b71SDan Nowlin } 4998fd2a6b71SDan Nowlin 4999fd2a6b71SDan Nowlin bitmap_zero(rm->r_bitmap, ICE_MAX_NUM_RECIPES); 5000fd2a6b71SDan Nowlin recipe_count = ICE_MAX_NUM_RECIPES; 5001fd2a6b71SDan Nowlin status = ice_aq_get_recipe(hw, tmp, &recipe_count, ICE_SW_LKUP_MAC, 5002fd2a6b71SDan Nowlin NULL); 5003fd2a6b71SDan Nowlin if (status || recipe_count == 0) 5004fd2a6b71SDan Nowlin goto err_unroll; 5005fd2a6b71SDan Nowlin 5006fd2a6b71SDan Nowlin /* Allocate the recipe resources, and configure them according to the 5007fd2a6b71SDan Nowlin * match fields from protocol headers and extracted field vectors. 5008fd2a6b71SDan Nowlin */ 5009fd2a6b71SDan Nowlin chain_idx = find_first_bit(result_idx_bm, ICE_MAX_FV_WORDS); 5010fd2a6b71SDan Nowlin list_for_each_entry(entry, &rm->rg_list, l_entry) { 5011fd2a6b71SDan Nowlin u8 i; 5012fd2a6b71SDan Nowlin 5013fd2a6b71SDan Nowlin status = ice_alloc_recipe(hw, &entry->rid); 5014fd2a6b71SDan Nowlin if (status) 5015fd2a6b71SDan Nowlin goto err_unroll; 5016fd2a6b71SDan Nowlin 5017bccd9bceSMarcin Szycik content = &buf[recps].content; 5018bccd9bceSMarcin Szycik 5019fd2a6b71SDan Nowlin /* Clear the result index of the located recipe, as this will be 5020fd2a6b71SDan Nowlin * updated, if needed, later in the recipe creation process. 5021fd2a6b71SDan Nowlin */ 5022fd2a6b71SDan Nowlin tmp[0].content.result_indx = 0; 5023fd2a6b71SDan Nowlin 5024fd2a6b71SDan Nowlin buf[recps] = tmp[0]; 5025fd2a6b71SDan Nowlin buf[recps].recipe_indx = (u8)entry->rid; 5026fd2a6b71SDan Nowlin /* if the recipe is a non-root recipe RID should be programmed 5027fd2a6b71SDan Nowlin * as 0 for the rules to be applied correctly. 5028fd2a6b71SDan Nowlin */ 5029bccd9bceSMarcin Szycik content->rid = 0; 5030bccd9bceSMarcin Szycik memset(&content->lkup_indx, 0, 5031bccd9bceSMarcin Szycik sizeof(content->lkup_indx)); 5032fd2a6b71SDan Nowlin 5033fd2a6b71SDan Nowlin /* All recipes use look-up index 0 to match switch ID. */ 5034bccd9bceSMarcin Szycik content->lkup_indx[0] = ICE_AQ_SW_ID_LKUP_IDX; 5035bccd9bceSMarcin Szycik content->mask[0] = cpu_to_le16(ICE_AQ_SW_ID_LKUP_MASK); 5036fd2a6b71SDan Nowlin /* Setup lkup_indx 1..4 to INVALID/ignore and set the mask 5037fd2a6b71SDan Nowlin * to be 0 5038fd2a6b71SDan Nowlin */ 5039fd2a6b71SDan Nowlin for (i = 1; i <= ICE_NUM_WORDS_RECIPE; i++) { 5040bccd9bceSMarcin Szycik content->lkup_indx[i] = 0x80; 5041bccd9bceSMarcin Szycik content->mask[i] = 0; 5042fd2a6b71SDan Nowlin } 5043fd2a6b71SDan Nowlin 5044fd2a6b71SDan Nowlin for (i = 0; i < entry->r_group.n_val_pairs; i++) { 5045bccd9bceSMarcin Szycik content->lkup_indx[i + 1] = entry->fv_idx[i]; 5046bccd9bceSMarcin Szycik content->mask[i + 1] = cpu_to_le16(entry->fv_mask[i]); 5047fd2a6b71SDan Nowlin } 5048fd2a6b71SDan Nowlin 5049fd2a6b71SDan Nowlin if (rm->n_grp_count > 1) { 5050fd2a6b71SDan Nowlin /* Checks to see if there really is a valid result index 5051fd2a6b71SDan Nowlin * that can be used. 5052fd2a6b71SDan Nowlin */ 5053fd2a6b71SDan Nowlin if (chain_idx >= ICE_MAX_FV_WORDS) { 5054fd2a6b71SDan Nowlin ice_debug(hw, ICE_DBG_SW, "No chain index available\n"); 5055d54699e2STony Nguyen status = -ENOSPC; 5056fd2a6b71SDan Nowlin goto err_unroll; 5057fd2a6b71SDan Nowlin } 5058fd2a6b71SDan Nowlin 5059fd2a6b71SDan Nowlin entry->chain_idx = chain_idx; 5060bccd9bceSMarcin Szycik content->result_indx = 5061fd2a6b71SDan Nowlin ICE_AQ_RECIPE_RESULT_EN | 5062fd2a6b71SDan Nowlin ((chain_idx << ICE_AQ_RECIPE_RESULT_DATA_S) & 5063fd2a6b71SDan Nowlin ICE_AQ_RECIPE_RESULT_DATA_M); 5064fd2a6b71SDan Nowlin clear_bit(chain_idx, result_idx_bm); 5065fd2a6b71SDan Nowlin chain_idx = find_first_bit(result_idx_bm, 5066fd2a6b71SDan Nowlin ICE_MAX_FV_WORDS); 5067fd2a6b71SDan Nowlin } 5068fd2a6b71SDan Nowlin 5069fd2a6b71SDan Nowlin /* fill recipe dependencies */ 5070fd2a6b71SDan Nowlin bitmap_zero((unsigned long *)buf[recps].recipe_bitmap, 5071fd2a6b71SDan Nowlin ICE_MAX_NUM_RECIPES); 5072fd2a6b71SDan Nowlin set_bit(buf[recps].recipe_indx, 5073fd2a6b71SDan Nowlin (unsigned long *)buf[recps].recipe_bitmap); 5074bccd9bceSMarcin Szycik content->act_ctrl_fwd_priority = rm->priority; 5075bccd9bceSMarcin Szycik 5076bccd9bceSMarcin Szycik if (rm->need_pass_l2) 5077bccd9bceSMarcin Szycik content->act_ctrl |= ICE_AQ_RECIPE_ACT_NEED_PASS_L2; 5078bccd9bceSMarcin Szycik 5079bccd9bceSMarcin Szycik if (rm->allow_pass_l2) 5080bccd9bceSMarcin Szycik content->act_ctrl |= ICE_AQ_RECIPE_ACT_ALLOW_PASS_L2; 5081fd2a6b71SDan Nowlin recps++; 5082fd2a6b71SDan Nowlin } 5083fd2a6b71SDan Nowlin 5084fd2a6b71SDan Nowlin if (rm->n_grp_count == 1) { 5085fd2a6b71SDan Nowlin rm->root_rid = buf[0].recipe_indx; 5086fd2a6b71SDan Nowlin set_bit(buf[0].recipe_indx, rm->r_bitmap); 5087fd2a6b71SDan Nowlin buf[0].content.rid = rm->root_rid | ICE_AQ_RECIPE_ID_IS_ROOT; 5088fd2a6b71SDan Nowlin if (sizeof(buf[0].recipe_bitmap) >= sizeof(rm->r_bitmap)) { 5089fd2a6b71SDan Nowlin memcpy(buf[0].recipe_bitmap, rm->r_bitmap, 5090fd2a6b71SDan Nowlin sizeof(buf[0].recipe_bitmap)); 5091fd2a6b71SDan Nowlin } else { 5092d54699e2STony Nguyen status = -EINVAL; 5093fd2a6b71SDan Nowlin goto err_unroll; 5094fd2a6b71SDan Nowlin } 5095fd2a6b71SDan Nowlin /* Applicable only for ROOT_RECIPE, set the fwd_priority for 5096fd2a6b71SDan Nowlin * the recipe which is getting created if specified 5097fd2a6b71SDan Nowlin * by user. Usually any advanced switch filter, which results 5098fd2a6b71SDan Nowlin * into new extraction sequence, ended up creating a new recipe 5099fd2a6b71SDan Nowlin * of type ROOT and usually recipes are associated with profiles 5100fd2a6b71SDan Nowlin * Switch rule referreing newly created recipe, needs to have 5101fd2a6b71SDan Nowlin * either/or 'fwd' or 'join' priority, otherwise switch rule 5102fd2a6b71SDan Nowlin * evaluation will not happen correctly. In other words, if 5103fd2a6b71SDan Nowlin * switch rule to be evaluated on priority basis, then recipe 5104fd2a6b71SDan Nowlin * needs to have priority, otherwise it will be evaluated last. 5105fd2a6b71SDan Nowlin */ 5106fd2a6b71SDan Nowlin buf[0].content.act_ctrl_fwd_priority = rm->priority; 5107fd2a6b71SDan Nowlin } else { 5108fd2a6b71SDan Nowlin struct ice_recp_grp_entry *last_chain_entry; 5109fd2a6b71SDan Nowlin u16 rid, i; 5110fd2a6b71SDan Nowlin 5111fd2a6b71SDan Nowlin /* Allocate the last recipe that will chain the outcomes of the 5112fd2a6b71SDan Nowlin * other recipes together 5113fd2a6b71SDan Nowlin */ 5114fd2a6b71SDan Nowlin status = ice_alloc_recipe(hw, &rid); 5115fd2a6b71SDan Nowlin if (status) 5116fd2a6b71SDan Nowlin goto err_unroll; 5117fd2a6b71SDan Nowlin 5118bccd9bceSMarcin Szycik content = &buf[recps].content; 5119bccd9bceSMarcin Szycik 5120fd2a6b71SDan Nowlin buf[recps].recipe_indx = (u8)rid; 5121bccd9bceSMarcin Szycik content->rid = (u8)rid; 5122bccd9bceSMarcin Szycik content->rid |= ICE_AQ_RECIPE_ID_IS_ROOT; 5123fd2a6b71SDan Nowlin /* the new entry created should also be part of rg_list to 5124fd2a6b71SDan Nowlin * make sure we have complete recipe 5125fd2a6b71SDan Nowlin */ 5126fd2a6b71SDan Nowlin last_chain_entry = devm_kzalloc(ice_hw_to_dev(hw), 5127fd2a6b71SDan Nowlin sizeof(*last_chain_entry), 5128fd2a6b71SDan Nowlin GFP_KERNEL); 5129fd2a6b71SDan Nowlin if (!last_chain_entry) { 5130d54699e2STony Nguyen status = -ENOMEM; 5131fd2a6b71SDan Nowlin goto err_unroll; 5132fd2a6b71SDan Nowlin } 5133fd2a6b71SDan Nowlin last_chain_entry->rid = rid; 5134bccd9bceSMarcin Szycik memset(&content->lkup_indx, 0, sizeof(content->lkup_indx)); 5135fd2a6b71SDan Nowlin /* All recipes use look-up index 0 to match switch ID. */ 5136bccd9bceSMarcin Szycik content->lkup_indx[0] = ICE_AQ_SW_ID_LKUP_IDX; 5137bccd9bceSMarcin Szycik content->mask[0] = cpu_to_le16(ICE_AQ_SW_ID_LKUP_MASK); 5138fd2a6b71SDan Nowlin for (i = 1; i <= ICE_NUM_WORDS_RECIPE; i++) { 5139bccd9bceSMarcin Szycik content->lkup_indx[i] = ICE_AQ_RECIPE_LKUP_IGNORE; 5140bccd9bceSMarcin Szycik content->mask[i] = 0; 5141fd2a6b71SDan Nowlin } 5142fd2a6b71SDan Nowlin 5143fd2a6b71SDan Nowlin i = 1; 5144fd2a6b71SDan Nowlin /* update r_bitmap with the recp that is used for chaining */ 5145fd2a6b71SDan Nowlin set_bit(rid, rm->r_bitmap); 5146fd2a6b71SDan Nowlin /* this is the recipe that chains all the other recipes so it 5147fd2a6b71SDan Nowlin * should not have a chaining ID to indicate the same 5148fd2a6b71SDan Nowlin */ 5149fd2a6b71SDan Nowlin last_chain_entry->chain_idx = ICE_INVAL_CHAIN_IND; 5150fd2a6b71SDan Nowlin list_for_each_entry(entry, &rm->rg_list, l_entry) { 5151fd2a6b71SDan Nowlin last_chain_entry->fv_idx[i] = entry->chain_idx; 5152bccd9bceSMarcin Szycik content->lkup_indx[i] = entry->chain_idx; 5153bccd9bceSMarcin Szycik content->mask[i++] = cpu_to_le16(0xFFFF); 5154fd2a6b71SDan Nowlin set_bit(entry->rid, rm->r_bitmap); 5155fd2a6b71SDan Nowlin } 5156fd2a6b71SDan Nowlin list_add(&last_chain_entry->l_entry, &rm->rg_list); 5157fd2a6b71SDan Nowlin if (sizeof(buf[recps].recipe_bitmap) >= 5158fd2a6b71SDan Nowlin sizeof(rm->r_bitmap)) { 5159fd2a6b71SDan Nowlin memcpy(buf[recps].recipe_bitmap, rm->r_bitmap, 5160fd2a6b71SDan Nowlin sizeof(buf[recps].recipe_bitmap)); 5161fd2a6b71SDan Nowlin } else { 5162d54699e2STony Nguyen status = -EINVAL; 5163fd2a6b71SDan Nowlin goto err_unroll; 5164fd2a6b71SDan Nowlin } 5165bccd9bceSMarcin Szycik content->act_ctrl_fwd_priority = rm->priority; 5166fd2a6b71SDan Nowlin 5167fd2a6b71SDan Nowlin recps++; 5168fd2a6b71SDan Nowlin rm->root_rid = (u8)rid; 5169fd2a6b71SDan Nowlin } 5170fd2a6b71SDan Nowlin status = ice_acquire_change_lock(hw, ICE_RES_WRITE); 5171fd2a6b71SDan Nowlin if (status) 5172fd2a6b71SDan Nowlin goto err_unroll; 5173fd2a6b71SDan Nowlin 5174fd2a6b71SDan Nowlin status = ice_aq_add_recipe(hw, buf, rm->n_grp_count, NULL); 5175fd2a6b71SDan Nowlin ice_release_change_lock(hw); 5176fd2a6b71SDan Nowlin if (status) 5177fd2a6b71SDan Nowlin goto err_unroll; 5178fd2a6b71SDan Nowlin 5179fd2a6b71SDan Nowlin /* Every recipe that just got created add it to the recipe 5180fd2a6b71SDan Nowlin * book keeping list 5181fd2a6b71SDan Nowlin */ 5182fd2a6b71SDan Nowlin list_for_each_entry(entry, &rm->rg_list, l_entry) { 5183fd2a6b71SDan Nowlin struct ice_switch_info *sw = hw->switch_info; 5184fd2a6b71SDan Nowlin bool is_root, idx_found = false; 5185fd2a6b71SDan Nowlin struct ice_sw_recipe *recp; 5186fd2a6b71SDan Nowlin u16 idx, buf_idx = 0; 5187fd2a6b71SDan Nowlin 5188fd2a6b71SDan Nowlin /* find buffer index for copying some data */ 5189fd2a6b71SDan Nowlin for (idx = 0; idx < rm->n_grp_count; idx++) 5190fd2a6b71SDan Nowlin if (buf[idx].recipe_indx == entry->rid) { 5191fd2a6b71SDan Nowlin buf_idx = idx; 5192fd2a6b71SDan Nowlin idx_found = true; 5193fd2a6b71SDan Nowlin } 5194fd2a6b71SDan Nowlin 5195fd2a6b71SDan Nowlin if (!idx_found) { 5196d54699e2STony Nguyen status = -EIO; 5197fd2a6b71SDan Nowlin goto err_unroll; 5198fd2a6b71SDan Nowlin } 5199fd2a6b71SDan Nowlin 5200fd2a6b71SDan Nowlin recp = &sw->recp_list[entry->rid]; 5201fd2a6b71SDan Nowlin is_root = (rm->root_rid == entry->rid); 5202fd2a6b71SDan Nowlin recp->is_root = is_root; 5203fd2a6b71SDan Nowlin 5204fd2a6b71SDan Nowlin recp->root_rid = entry->rid; 5205fd2a6b71SDan Nowlin recp->big_recp = (is_root && rm->n_grp_count > 1); 5206fd2a6b71SDan Nowlin 5207fd2a6b71SDan Nowlin memcpy(&recp->ext_words, entry->r_group.pairs, 5208fd2a6b71SDan Nowlin entry->r_group.n_val_pairs * sizeof(struct ice_fv_word)); 5209fd2a6b71SDan Nowlin 5210fd2a6b71SDan Nowlin memcpy(recp->r_bitmap, buf[buf_idx].recipe_bitmap, 5211fd2a6b71SDan Nowlin sizeof(recp->r_bitmap)); 5212fd2a6b71SDan Nowlin 5213fd2a6b71SDan Nowlin /* Copy non-result fv index values and masks to recipe. This 5214fd2a6b71SDan Nowlin * call will also update the result recipe bitmask. 5215fd2a6b71SDan Nowlin */ 5216fd2a6b71SDan Nowlin ice_collect_result_idx(&buf[buf_idx], recp); 5217fd2a6b71SDan Nowlin 5218fd2a6b71SDan Nowlin /* for non-root recipes, also copy to the root, this allows 5219fd2a6b71SDan Nowlin * easier matching of a complete chained recipe 5220fd2a6b71SDan Nowlin */ 5221fd2a6b71SDan Nowlin if (!is_root) 5222fd2a6b71SDan Nowlin ice_collect_result_idx(&buf[buf_idx], 5223fd2a6b71SDan Nowlin &sw->recp_list[rm->root_rid]); 5224fd2a6b71SDan Nowlin 5225fd2a6b71SDan Nowlin recp->n_ext_words = entry->r_group.n_val_pairs; 5226fd2a6b71SDan Nowlin recp->chain_idx = entry->chain_idx; 5227fd2a6b71SDan Nowlin recp->priority = buf[buf_idx].content.act_ctrl_fwd_priority; 5228fd2a6b71SDan Nowlin recp->n_grp_count = rm->n_grp_count; 52298b032a55SMichal Swiatkowski recp->tun_type = rm->tun_type; 5230bccd9bceSMarcin Szycik recp->need_pass_l2 = rm->need_pass_l2; 5231bccd9bceSMarcin Szycik recp->allow_pass_l2 = rm->allow_pass_l2; 5232fd2a6b71SDan Nowlin recp->recp_created = true; 5233fd2a6b71SDan Nowlin } 5234fd2a6b71SDan Nowlin rm->root_buf = buf; 5235fd2a6b71SDan Nowlin kfree(tmp); 5236fd2a6b71SDan Nowlin return status; 5237fd2a6b71SDan Nowlin 5238fd2a6b71SDan Nowlin err_unroll: 5239fd2a6b71SDan Nowlin err_mem: 5240fd2a6b71SDan Nowlin kfree(tmp); 5241fd2a6b71SDan Nowlin devm_kfree(ice_hw_to_dev(hw), buf); 5242fd2a6b71SDan Nowlin return status; 5243fd2a6b71SDan Nowlin } 5244fd2a6b71SDan Nowlin 5245fd2a6b71SDan Nowlin /** 5246fd2a6b71SDan Nowlin * ice_create_recipe_group - creates recipe group 5247fd2a6b71SDan Nowlin * @hw: pointer to hardware structure 5248fd2a6b71SDan Nowlin * @rm: recipe management list entry 5249fd2a6b71SDan Nowlin * @lkup_exts: lookup elements 5250fd2a6b71SDan Nowlin */ 52515e24d598STony Nguyen static int 5252fd2a6b71SDan Nowlin ice_create_recipe_group(struct ice_hw *hw, struct ice_sw_recipe *rm, 5253fd2a6b71SDan Nowlin struct ice_prot_lkup_ext *lkup_exts) 5254fd2a6b71SDan Nowlin { 5255fd2a6b71SDan Nowlin u8 recp_count = 0; 52565518ac2aSTony Nguyen int status; 5257fd2a6b71SDan Nowlin 5258fd2a6b71SDan Nowlin rm->n_grp_count = 0; 5259fd2a6b71SDan Nowlin 5260fd2a6b71SDan Nowlin /* Create recipes for words that are marked not done by packing them 5261fd2a6b71SDan Nowlin * as best fit. 5262fd2a6b71SDan Nowlin */ 5263fd2a6b71SDan Nowlin status = ice_create_first_fit_recp_def(hw, lkup_exts, 5264fd2a6b71SDan Nowlin &rm->rg_list, &recp_count); 5265fd2a6b71SDan Nowlin if (!status) { 5266fd2a6b71SDan Nowlin rm->n_grp_count += recp_count; 5267fd2a6b71SDan Nowlin rm->n_ext_words = lkup_exts->n_val_words; 5268fd2a6b71SDan Nowlin memcpy(&rm->ext_words, lkup_exts->fv_words, 5269fd2a6b71SDan Nowlin sizeof(rm->ext_words)); 5270fd2a6b71SDan Nowlin memcpy(rm->word_masks, lkup_exts->field_mask, 5271fd2a6b71SDan Nowlin sizeof(rm->word_masks)); 5272fd2a6b71SDan Nowlin } 5273fd2a6b71SDan Nowlin 5274fd2a6b71SDan Nowlin return status; 5275fd2a6b71SDan Nowlin } 5276fd2a6b71SDan Nowlin 5277fd2a6b71SDan Nowlin /* ice_get_compat_fv_bitmap - Get compatible field vector bitmap for rule 5278fd2a6b71SDan Nowlin * @hw: pointer to hardware structure 5279fd2a6b71SDan Nowlin * @rinfo: other information regarding the rule e.g. priority and action info 5280fd2a6b71SDan Nowlin * @bm: pointer to memory for returning the bitmap of field vectors 5281fd2a6b71SDan Nowlin */ 5282fd2a6b71SDan Nowlin static void 5283fd2a6b71SDan Nowlin ice_get_compat_fv_bitmap(struct ice_hw *hw, struct ice_adv_rule_info *rinfo, 5284fd2a6b71SDan Nowlin unsigned long *bm) 5285fd2a6b71SDan Nowlin { 52868b032a55SMichal Swiatkowski enum ice_prof_type prof_type; 52878b032a55SMichal Swiatkowski 5288fd2a6b71SDan Nowlin bitmap_zero(bm, ICE_MAX_NUM_PROFILES); 5289fd2a6b71SDan Nowlin 52908b032a55SMichal Swiatkowski switch (rinfo->tun_type) { 52918b032a55SMichal Swiatkowski case ICE_NON_TUN: 52928b032a55SMichal Swiatkowski prof_type = ICE_PROF_NON_TUN; 52938b032a55SMichal Swiatkowski break; 52948b032a55SMichal Swiatkowski case ICE_ALL_TUNNELS: 52958b032a55SMichal Swiatkowski prof_type = ICE_PROF_TUN_ALL; 52968b032a55SMichal Swiatkowski break; 52978b032a55SMichal Swiatkowski case ICE_SW_TUN_GENEVE: 52988b032a55SMichal Swiatkowski case ICE_SW_TUN_VXLAN: 52998b032a55SMichal Swiatkowski prof_type = ICE_PROF_TUN_UDP; 53008b032a55SMichal Swiatkowski break; 5301f0a35040SMichal Swiatkowski case ICE_SW_TUN_NVGRE: 5302f0a35040SMichal Swiatkowski prof_type = ICE_PROF_TUN_GRE; 5303f0a35040SMichal Swiatkowski break; 53049a225f81SMarcin Szycik case ICE_SW_TUN_GTPU: 53059a225f81SMarcin Szycik prof_type = ICE_PROF_TUN_GTPU; 53069a225f81SMarcin Szycik break; 53079a225f81SMarcin Szycik case ICE_SW_TUN_GTPC: 53089a225f81SMarcin Szycik prof_type = ICE_PROF_TUN_GTPC; 53099a225f81SMarcin Szycik break; 5310b70bc066SWojciech Drewek case ICE_SW_TUN_AND_NON_TUN: 53118b032a55SMichal Swiatkowski default: 53128b032a55SMichal Swiatkowski prof_type = ICE_PROF_ALL; 53138b032a55SMichal Swiatkowski break; 53148b032a55SMichal Swiatkowski } 53158b032a55SMichal Swiatkowski 53168b032a55SMichal Swiatkowski ice_get_sw_fv_bitmap(hw, prof_type, bm); 5317fd2a6b71SDan Nowlin } 5318fd2a6b71SDan Nowlin 5319fd2a6b71SDan Nowlin /** 5320fd2a6b71SDan Nowlin * ice_add_adv_recipe - Add an advanced recipe that is not part of the default 5321fd2a6b71SDan Nowlin * @hw: pointer to hardware structure 5322fd2a6b71SDan Nowlin * @lkups: lookup elements or match criteria for the advanced recipe, one 5323fd2a6b71SDan Nowlin * structure per protocol header 5324fd2a6b71SDan Nowlin * @lkups_cnt: number of protocols 5325fd2a6b71SDan Nowlin * @rinfo: other information regarding the rule e.g. priority and action info 5326fd2a6b71SDan Nowlin * @rid: return the recipe ID of the recipe created 5327fd2a6b71SDan Nowlin */ 53285e24d598STony Nguyen static int 5329fd2a6b71SDan Nowlin ice_add_adv_recipe(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups, 5330fd2a6b71SDan Nowlin u16 lkups_cnt, struct ice_adv_rule_info *rinfo, u16 *rid) 5331fd2a6b71SDan Nowlin { 5332fd2a6b71SDan Nowlin DECLARE_BITMAP(fv_bitmap, ICE_MAX_NUM_PROFILES); 5333fd2a6b71SDan Nowlin DECLARE_BITMAP(profiles, ICE_MAX_NUM_PROFILES); 5334fd2a6b71SDan Nowlin struct ice_prot_lkup_ext *lkup_exts; 5335fd2a6b71SDan Nowlin struct ice_recp_grp_entry *r_entry; 5336fd2a6b71SDan Nowlin struct ice_sw_fv_list_entry *fvit; 5337fd2a6b71SDan Nowlin struct ice_recp_grp_entry *r_tmp; 5338fd2a6b71SDan Nowlin struct ice_sw_fv_list_entry *tmp; 5339fd2a6b71SDan Nowlin struct ice_sw_recipe *rm; 53405518ac2aSTony Nguyen int status = 0; 5341fd2a6b71SDan Nowlin u8 i; 5342fd2a6b71SDan Nowlin 5343fd2a6b71SDan Nowlin if (!lkups_cnt) 5344d54699e2STony Nguyen return -EINVAL; 5345fd2a6b71SDan Nowlin 5346fd2a6b71SDan Nowlin lkup_exts = kzalloc(sizeof(*lkup_exts), GFP_KERNEL); 5347fd2a6b71SDan Nowlin if (!lkup_exts) 5348d54699e2STony Nguyen return -ENOMEM; 5349fd2a6b71SDan Nowlin 5350fd2a6b71SDan Nowlin /* Determine the number of words to be matched and if it exceeds a 5351fd2a6b71SDan Nowlin * recipe's restrictions 5352fd2a6b71SDan Nowlin */ 5353fd2a6b71SDan Nowlin for (i = 0; i < lkups_cnt; i++) { 5354fd2a6b71SDan Nowlin u16 count; 5355fd2a6b71SDan Nowlin 5356fd2a6b71SDan Nowlin if (lkups[i].type >= ICE_PROTOCOL_LAST) { 5357d54699e2STony Nguyen status = -EIO; 5358fd2a6b71SDan Nowlin goto err_free_lkup_exts; 5359fd2a6b71SDan Nowlin } 5360fd2a6b71SDan Nowlin 5361fd2a6b71SDan Nowlin count = ice_fill_valid_words(&lkups[i], lkup_exts); 5362fd2a6b71SDan Nowlin if (!count) { 5363d54699e2STony Nguyen status = -EIO; 5364fd2a6b71SDan Nowlin goto err_free_lkup_exts; 5365fd2a6b71SDan Nowlin } 5366fd2a6b71SDan Nowlin } 5367fd2a6b71SDan Nowlin 5368fd2a6b71SDan Nowlin rm = kzalloc(sizeof(*rm), GFP_KERNEL); 5369fd2a6b71SDan Nowlin if (!rm) { 5370d54699e2STony Nguyen status = -ENOMEM; 5371fd2a6b71SDan Nowlin goto err_free_lkup_exts; 5372fd2a6b71SDan Nowlin } 5373fd2a6b71SDan Nowlin 5374fd2a6b71SDan Nowlin /* Get field vectors that contain fields extracted from all the protocol 5375fd2a6b71SDan Nowlin * headers being programmed. 5376fd2a6b71SDan Nowlin */ 5377fd2a6b71SDan Nowlin INIT_LIST_HEAD(&rm->fv_list); 5378fd2a6b71SDan Nowlin INIT_LIST_HEAD(&rm->rg_list); 5379fd2a6b71SDan Nowlin 5380fd2a6b71SDan Nowlin /* Get bitmap of field vectors (profiles) that are compatible with the 5381fd2a6b71SDan Nowlin * rule request; only these will be searched in the subsequent call to 5382e5dd661bSMichal Swiatkowski * ice_get_sw_fv_list. 5383fd2a6b71SDan Nowlin */ 5384fd2a6b71SDan Nowlin ice_get_compat_fv_bitmap(hw, rinfo, fv_bitmap); 5385fd2a6b71SDan Nowlin 5386e5dd661bSMichal Swiatkowski status = ice_get_sw_fv_list(hw, lkup_exts, fv_bitmap, &rm->fv_list); 5387fd2a6b71SDan Nowlin if (status) 5388fd2a6b71SDan Nowlin goto err_unroll; 5389fd2a6b71SDan Nowlin 5390fd2a6b71SDan Nowlin /* Group match words into recipes using preferred recipe grouping 5391fd2a6b71SDan Nowlin * criteria. 5392fd2a6b71SDan Nowlin */ 5393fd2a6b71SDan Nowlin status = ice_create_recipe_group(hw, rm, lkup_exts); 5394fd2a6b71SDan Nowlin if (status) 5395fd2a6b71SDan Nowlin goto err_unroll; 5396fd2a6b71SDan Nowlin 5397fd2a6b71SDan Nowlin /* set the recipe priority if specified */ 5398fd2a6b71SDan Nowlin rm->priority = (u8)rinfo->priority; 5399fd2a6b71SDan Nowlin 5400bccd9bceSMarcin Szycik rm->need_pass_l2 = rinfo->need_pass_l2; 5401bccd9bceSMarcin Szycik rm->allow_pass_l2 = rinfo->allow_pass_l2; 5402bccd9bceSMarcin Szycik 5403fd2a6b71SDan Nowlin /* Find offsets from the field vector. Pick the first one for all the 5404fd2a6b71SDan Nowlin * recipes. 5405fd2a6b71SDan Nowlin */ 5406fd2a6b71SDan Nowlin status = ice_fill_fv_word_index(hw, &rm->fv_list, &rm->rg_list); 5407fd2a6b71SDan Nowlin if (status) 5408fd2a6b71SDan Nowlin goto err_unroll; 5409fd2a6b71SDan Nowlin 5410fd2a6b71SDan Nowlin /* get bitmap of all profiles the recipe will be associated with */ 5411fd2a6b71SDan Nowlin bitmap_zero(profiles, ICE_MAX_NUM_PROFILES); 5412fd2a6b71SDan Nowlin list_for_each_entry(fvit, &rm->fv_list, list_entry) { 5413fd2a6b71SDan Nowlin ice_debug(hw, ICE_DBG_SW, "profile: %d\n", fvit->profile_id); 5414fd2a6b71SDan Nowlin set_bit((u16)fvit->profile_id, profiles); 5415fd2a6b71SDan Nowlin } 5416fd2a6b71SDan Nowlin 5417fd2a6b71SDan Nowlin /* Look for a recipe which matches our requested fv / mask list */ 5418bccd9bceSMarcin Szycik *rid = ice_find_recp(hw, lkup_exts, rinfo); 5419fd2a6b71SDan Nowlin if (*rid < ICE_MAX_NUM_RECIPES) 5420fd2a6b71SDan Nowlin /* Success if found a recipe that match the existing criteria */ 5421fd2a6b71SDan Nowlin goto err_unroll; 5422fd2a6b71SDan Nowlin 5423de6acd1cSMichal Swiatkowski rm->tun_type = rinfo->tun_type; 5424fd2a6b71SDan Nowlin /* Recipe we need does not exist, add a recipe */ 54258b032a55SMichal Swiatkowski status = ice_add_sw_recipe(hw, rm, profiles); 5426fd2a6b71SDan Nowlin if (status) 5427fd2a6b71SDan Nowlin goto err_unroll; 5428fd2a6b71SDan Nowlin 5429fd2a6b71SDan Nowlin /* Associate all the recipes created with all the profiles in the 5430fd2a6b71SDan Nowlin * common field vector. 5431fd2a6b71SDan Nowlin */ 5432fd2a6b71SDan Nowlin list_for_each_entry(fvit, &rm->fv_list, list_entry) { 5433fd2a6b71SDan Nowlin DECLARE_BITMAP(r_bitmap, ICE_MAX_NUM_RECIPES); 5434fd2a6b71SDan Nowlin u16 j; 5435fd2a6b71SDan Nowlin 5436fd2a6b71SDan Nowlin status = ice_aq_get_recipe_to_profile(hw, fvit->profile_id, 5437fd2a6b71SDan Nowlin (u8 *)r_bitmap, NULL); 5438fd2a6b71SDan Nowlin if (status) 5439fd2a6b71SDan Nowlin goto err_unroll; 5440fd2a6b71SDan Nowlin 5441fd2a6b71SDan Nowlin bitmap_or(r_bitmap, r_bitmap, rm->r_bitmap, 5442fd2a6b71SDan Nowlin ICE_MAX_NUM_RECIPES); 5443fd2a6b71SDan Nowlin status = ice_acquire_change_lock(hw, ICE_RES_WRITE); 5444fd2a6b71SDan Nowlin if (status) 5445fd2a6b71SDan Nowlin goto err_unroll; 5446fd2a6b71SDan Nowlin 5447fd2a6b71SDan Nowlin status = ice_aq_map_recipe_to_profile(hw, fvit->profile_id, 5448fd2a6b71SDan Nowlin (u8 *)r_bitmap, 5449fd2a6b71SDan Nowlin NULL); 5450fd2a6b71SDan Nowlin ice_release_change_lock(hw); 5451fd2a6b71SDan Nowlin 5452fd2a6b71SDan Nowlin if (status) 5453fd2a6b71SDan Nowlin goto err_unroll; 5454fd2a6b71SDan Nowlin 5455fd2a6b71SDan Nowlin /* Update profile to recipe bitmap array */ 5456fd2a6b71SDan Nowlin bitmap_copy(profile_to_recipe[fvit->profile_id], r_bitmap, 5457fd2a6b71SDan Nowlin ICE_MAX_NUM_RECIPES); 5458fd2a6b71SDan Nowlin 5459fd2a6b71SDan Nowlin /* Update recipe to profile bitmap array */ 5460fd2a6b71SDan Nowlin for_each_set_bit(j, rm->r_bitmap, ICE_MAX_NUM_RECIPES) 5461fd2a6b71SDan Nowlin set_bit((u16)fvit->profile_id, recipe_to_profile[j]); 5462fd2a6b71SDan Nowlin } 5463fd2a6b71SDan Nowlin 5464fd2a6b71SDan Nowlin *rid = rm->root_rid; 5465fd2a6b71SDan Nowlin memcpy(&hw->switch_info->recp_list[*rid].lkup_exts, lkup_exts, 5466fd2a6b71SDan Nowlin sizeof(*lkup_exts)); 5467fd2a6b71SDan Nowlin err_unroll: 5468fd2a6b71SDan Nowlin list_for_each_entry_safe(r_entry, r_tmp, &rm->rg_list, l_entry) { 5469fd2a6b71SDan Nowlin list_del(&r_entry->l_entry); 5470fd2a6b71SDan Nowlin devm_kfree(ice_hw_to_dev(hw), r_entry); 5471fd2a6b71SDan Nowlin } 5472fd2a6b71SDan Nowlin 5473fd2a6b71SDan Nowlin list_for_each_entry_safe(fvit, tmp, &rm->fv_list, list_entry) { 5474fd2a6b71SDan Nowlin list_del(&fvit->list_entry); 5475fd2a6b71SDan Nowlin devm_kfree(ice_hw_to_dev(hw), fvit); 5476fd2a6b71SDan Nowlin } 5477fd2a6b71SDan Nowlin 5478fd2a6b71SDan Nowlin devm_kfree(ice_hw_to_dev(hw), rm->root_buf); 5479fd2a6b71SDan Nowlin kfree(rm); 5480fd2a6b71SDan Nowlin 5481fd2a6b71SDan Nowlin err_free_lkup_exts: 5482fd2a6b71SDan Nowlin kfree(lkup_exts); 5483fd2a6b71SDan Nowlin 5484fd2a6b71SDan Nowlin return status; 5485fd2a6b71SDan Nowlin } 5486fd2a6b71SDan Nowlin 5487148beb61SHenry Tieman /** 548826395726SMartyna Szapar-Mudlaw * ice_dummy_packet_add_vlan - insert VLAN header to dummy pkt 548926395726SMartyna Szapar-Mudlaw * 549026395726SMartyna Szapar-Mudlaw * @dummy_pkt: dummy packet profile pattern to which VLAN tag(s) will be added 549126395726SMartyna Szapar-Mudlaw * @num_vlan: number of VLAN tags 549226395726SMartyna Szapar-Mudlaw */ 549326395726SMartyna Szapar-Mudlaw static struct ice_dummy_pkt_profile * 549426395726SMartyna Szapar-Mudlaw ice_dummy_packet_add_vlan(const struct ice_dummy_pkt_profile *dummy_pkt, 549526395726SMartyna Szapar-Mudlaw u32 num_vlan) 549626395726SMartyna Szapar-Mudlaw { 549726395726SMartyna Szapar-Mudlaw struct ice_dummy_pkt_profile *profile; 549826395726SMartyna Szapar-Mudlaw struct ice_dummy_pkt_offsets *offsets; 549926395726SMartyna Szapar-Mudlaw u32 buf_len, off, etype_off, i; 550026395726SMartyna Szapar-Mudlaw u8 *pkt; 550126395726SMartyna Szapar-Mudlaw 550226395726SMartyna Szapar-Mudlaw if (num_vlan < 1 || num_vlan > 2) 550326395726SMartyna Szapar-Mudlaw return ERR_PTR(-EINVAL); 550426395726SMartyna Szapar-Mudlaw 550526395726SMartyna Szapar-Mudlaw off = num_vlan * VLAN_HLEN; 550626395726SMartyna Szapar-Mudlaw 550726395726SMartyna Szapar-Mudlaw buf_len = array_size(num_vlan, sizeof(ice_dummy_vlan_packet_offsets)) + 550826395726SMartyna Szapar-Mudlaw dummy_pkt->offsets_len; 550926395726SMartyna Szapar-Mudlaw offsets = kzalloc(buf_len, GFP_KERNEL); 551026395726SMartyna Szapar-Mudlaw if (!offsets) 551126395726SMartyna Szapar-Mudlaw return ERR_PTR(-ENOMEM); 551226395726SMartyna Szapar-Mudlaw 551326395726SMartyna Szapar-Mudlaw offsets[0] = dummy_pkt->offsets[0]; 551426395726SMartyna Szapar-Mudlaw if (num_vlan == 2) { 551526395726SMartyna Szapar-Mudlaw offsets[1] = ice_dummy_qinq_packet_offsets[0]; 551626395726SMartyna Szapar-Mudlaw offsets[2] = ice_dummy_qinq_packet_offsets[1]; 551726395726SMartyna Szapar-Mudlaw } else if (num_vlan == 1) { 551826395726SMartyna Szapar-Mudlaw offsets[1] = ice_dummy_vlan_packet_offsets[0]; 551926395726SMartyna Szapar-Mudlaw } 552026395726SMartyna Szapar-Mudlaw 552126395726SMartyna Szapar-Mudlaw for (i = 1; dummy_pkt->offsets[i].type != ICE_PROTOCOL_LAST; i++) { 552226395726SMartyna Szapar-Mudlaw offsets[i + num_vlan].type = dummy_pkt->offsets[i].type; 552326395726SMartyna Szapar-Mudlaw offsets[i + num_vlan].offset = 552426395726SMartyna Szapar-Mudlaw dummy_pkt->offsets[i].offset + off; 552526395726SMartyna Szapar-Mudlaw } 552626395726SMartyna Szapar-Mudlaw offsets[i + num_vlan] = dummy_pkt->offsets[i]; 552726395726SMartyna Szapar-Mudlaw 552826395726SMartyna Szapar-Mudlaw etype_off = dummy_pkt->offsets[1].offset; 552926395726SMartyna Szapar-Mudlaw 553026395726SMartyna Szapar-Mudlaw buf_len = array_size(num_vlan, sizeof(ice_dummy_vlan_packet)) + 553126395726SMartyna Szapar-Mudlaw dummy_pkt->pkt_len; 553226395726SMartyna Szapar-Mudlaw pkt = kzalloc(buf_len, GFP_KERNEL); 553326395726SMartyna Szapar-Mudlaw if (!pkt) { 553426395726SMartyna Szapar-Mudlaw kfree(offsets); 553526395726SMartyna Szapar-Mudlaw return ERR_PTR(-ENOMEM); 553626395726SMartyna Szapar-Mudlaw } 553726395726SMartyna Szapar-Mudlaw 553826395726SMartyna Szapar-Mudlaw memcpy(pkt, dummy_pkt->pkt, etype_off); 553926395726SMartyna Szapar-Mudlaw memcpy(pkt + etype_off, 554026395726SMartyna Szapar-Mudlaw num_vlan == 2 ? ice_dummy_qinq_packet : ice_dummy_vlan_packet, 554126395726SMartyna Szapar-Mudlaw off); 554226395726SMartyna Szapar-Mudlaw memcpy(pkt + etype_off + off, dummy_pkt->pkt + etype_off, 554326395726SMartyna Szapar-Mudlaw dummy_pkt->pkt_len - etype_off); 554426395726SMartyna Szapar-Mudlaw 554526395726SMartyna Szapar-Mudlaw profile = kzalloc(sizeof(*profile), GFP_KERNEL); 554626395726SMartyna Szapar-Mudlaw if (!profile) { 554726395726SMartyna Szapar-Mudlaw kfree(offsets); 554826395726SMartyna Szapar-Mudlaw kfree(pkt); 554926395726SMartyna Szapar-Mudlaw return ERR_PTR(-ENOMEM); 555026395726SMartyna Szapar-Mudlaw } 555126395726SMartyna Szapar-Mudlaw 555226395726SMartyna Szapar-Mudlaw profile->offsets = offsets; 555326395726SMartyna Szapar-Mudlaw profile->pkt = pkt; 555426395726SMartyna Szapar-Mudlaw profile->pkt_len = buf_len; 555526395726SMartyna Szapar-Mudlaw profile->match |= ICE_PKT_KMALLOC; 555626395726SMartyna Szapar-Mudlaw 555726395726SMartyna Szapar-Mudlaw return profile; 555826395726SMartyna Szapar-Mudlaw } 555926395726SMartyna Szapar-Mudlaw 556026395726SMartyna Szapar-Mudlaw /** 55610f94570dSGrishma Kotecha * ice_find_dummy_packet - find dummy packet 55620f94570dSGrishma Kotecha * 55630f94570dSGrishma Kotecha * @lkups: lookup elements or match criteria for the advanced recipe, one 55640f94570dSGrishma Kotecha * structure per protocol header 55650f94570dSGrishma Kotecha * @lkups_cnt: number of protocols 55668b032a55SMichal Swiatkowski * @tun_type: tunnel type 55671b699f81SAlexander Lobakin * 55681b699f81SAlexander Lobakin * Returns the &ice_dummy_pkt_profile corresponding to these lookup params. 55690f94570dSGrishma Kotecha */ 5570e33163a4SAlexander Lobakin static const struct ice_dummy_pkt_profile * 55710f94570dSGrishma Kotecha ice_find_dummy_packet(struct ice_adv_lkup_elem *lkups, u16 lkups_cnt, 55721b699f81SAlexander Lobakin enum ice_sw_tunnel_type tun_type) 55730f94570dSGrishma Kotecha { 5574e33163a4SAlexander Lobakin const struct ice_dummy_pkt_profile *ret = ice_dummy_pkt_profiles; 557526395726SMartyna Szapar-Mudlaw u32 match = 0, vlan_count = 0; 55760f94570dSGrishma Kotecha u16 i; 55770f94570dSGrishma Kotecha 5578e33163a4SAlexander Lobakin switch (tun_type) { 5579e33163a4SAlexander Lobakin case ICE_SW_TUN_GTPC: 5580e33163a4SAlexander Lobakin match |= ICE_PKT_TUN_GTPC; 5581e33163a4SAlexander Lobakin break; 5582e33163a4SAlexander Lobakin case ICE_SW_TUN_GTPU: 5583e33163a4SAlexander Lobakin match |= ICE_PKT_TUN_GTPU; 5584e33163a4SAlexander Lobakin break; 5585e33163a4SAlexander Lobakin case ICE_SW_TUN_NVGRE: 5586e33163a4SAlexander Lobakin match |= ICE_PKT_TUN_NVGRE; 5587e33163a4SAlexander Lobakin break; 5588e33163a4SAlexander Lobakin case ICE_SW_TUN_GENEVE: 5589e33163a4SAlexander Lobakin case ICE_SW_TUN_VXLAN: 5590e33163a4SAlexander Lobakin match |= ICE_PKT_TUN_UDP; 5591e33163a4SAlexander Lobakin break; 5592e33163a4SAlexander Lobakin default: 5593e33163a4SAlexander Lobakin break; 5594e33163a4SAlexander Lobakin } 5595e33163a4SAlexander Lobakin 55960f94570dSGrishma Kotecha for (i = 0; i < lkups_cnt; i++) { 55970f94570dSGrishma Kotecha if (lkups[i].type == ICE_UDP_ILOS) 5598e33163a4SAlexander Lobakin match |= ICE_PKT_INNER_UDP; 55990f94570dSGrishma Kotecha else if (lkups[i].type == ICE_TCP_IL) 5600e33163a4SAlexander Lobakin match |= ICE_PKT_INNER_TCP; 56010f94570dSGrishma Kotecha else if (lkups[i].type == ICE_IPV6_OFOS) 5602e33163a4SAlexander Lobakin match |= ICE_PKT_OUTER_IPV6; 560306bca7c2SMartyna Szapar-Mudlaw else if (lkups[i].type == ICE_VLAN_OFOS || 560406bca7c2SMartyna Szapar-Mudlaw lkups[i].type == ICE_VLAN_EX) 560526395726SMartyna Szapar-Mudlaw vlan_count++; 560606bca7c2SMartyna Szapar-Mudlaw else if (lkups[i].type == ICE_VLAN_IN) 560726395726SMartyna Szapar-Mudlaw vlan_count++; 56080f94570dSGrishma Kotecha else if (lkups[i].type == ICE_ETYPE_OL && 56090f94570dSGrishma Kotecha lkups[i].h_u.ethertype.ethtype_id == 56100f94570dSGrishma Kotecha cpu_to_be16(ICE_IPV6_ETHER_ID) && 56110f94570dSGrishma Kotecha lkups[i].m_u.ethertype.ethtype_id == 56120f94570dSGrishma Kotecha cpu_to_be16(0xFFFF)) 5613e33163a4SAlexander Lobakin match |= ICE_PKT_OUTER_IPV6; 561434a89775SMartyna Szapar-Mudlaw else if (lkups[i].type == ICE_ETYPE_IL && 561534a89775SMartyna Szapar-Mudlaw lkups[i].h_u.ethertype.ethtype_id == 561634a89775SMartyna Szapar-Mudlaw cpu_to_be16(ICE_IPV6_ETHER_ID) && 561734a89775SMartyna Szapar-Mudlaw lkups[i].m_u.ethertype.ethtype_id == 561834a89775SMartyna Szapar-Mudlaw cpu_to_be16(0xFFFF)) 5619e33163a4SAlexander Lobakin match |= ICE_PKT_INNER_IPV6; 56209a225f81SMarcin Szycik else if (lkups[i].type == ICE_IPV6_IL) 5621e33163a4SAlexander Lobakin match |= ICE_PKT_INNER_IPV6; 56229a225f81SMarcin Szycik else if (lkups[i].type == ICE_GTP_NO_PAY) 5623e33163a4SAlexander Lobakin match |= ICE_PKT_GTP_NOPAY; 5624cd8efeeeSMarcin Szycik else if (lkups[i].type == ICE_PPPOE) { 5625cd8efeeeSMarcin Szycik match |= ICE_PKT_PPPOE; 5626cd8efeeeSMarcin Szycik if (lkups[i].h_u.pppoe_hdr.ppp_prot_id == 5627cd8efeeeSMarcin Szycik htons(PPP_IPV6)) 5628cd8efeeeSMarcin Szycik match |= ICE_PKT_OUTER_IPV6; 5629cd634549SMarcin Szycik } else if (lkups[i].type == ICE_L2TPV3) 5630cd634549SMarcin Szycik match |= ICE_PKT_L2TPV3; 56319a225f81SMarcin Szycik } 56329a225f81SMarcin Szycik 5633e33163a4SAlexander Lobakin while (ret->match && (match & ret->match) != ret->match) 5634e33163a4SAlexander Lobakin ret++; 56359a225f81SMarcin Szycik 563626395726SMartyna Szapar-Mudlaw if (vlan_count != 0) 563726395726SMartyna Szapar-Mudlaw ret = ice_dummy_packet_add_vlan(ret, vlan_count); 563826395726SMartyna Szapar-Mudlaw 5639e33163a4SAlexander Lobakin return ret; 56400f94570dSGrishma Kotecha } 56410f94570dSGrishma Kotecha 56420f94570dSGrishma Kotecha /** 56430f94570dSGrishma Kotecha * ice_fill_adv_dummy_packet - fill a dummy packet with given match criteria 56440f94570dSGrishma Kotecha * 56450f94570dSGrishma Kotecha * @lkups: lookup elements or match criteria for the advanced recipe, one 56460f94570dSGrishma Kotecha * structure per protocol header 56470f94570dSGrishma Kotecha * @lkups_cnt: number of protocols 56480f94570dSGrishma Kotecha * @s_rule: stores rule information from the match criteria 56491b699f81SAlexander Lobakin * @profile: dummy packet profile (the template, its size and header offsets) 56500f94570dSGrishma Kotecha */ 56515e24d598STony Nguyen static int 56520f94570dSGrishma Kotecha ice_fill_adv_dummy_packet(struct ice_adv_lkup_elem *lkups, u16 lkups_cnt, 56536e1ff618SAlexander Lobakin struct ice_sw_rule_lkup_rx_tx *s_rule, 56541b699f81SAlexander Lobakin const struct ice_dummy_pkt_profile *profile) 56550f94570dSGrishma Kotecha { 56560f94570dSGrishma Kotecha u8 *pkt; 56570f94570dSGrishma Kotecha u16 i; 56580f94570dSGrishma Kotecha 56590f94570dSGrishma Kotecha /* Start with a packet with a pre-defined/dummy content. Then, fill 56600f94570dSGrishma Kotecha * in the header values to be looked up or matched. 56610f94570dSGrishma Kotecha */ 56626e1ff618SAlexander Lobakin pkt = s_rule->hdr_data; 56630f94570dSGrishma Kotecha 56641b699f81SAlexander Lobakin memcpy(pkt, profile->pkt, profile->pkt_len); 56650f94570dSGrishma Kotecha 56660f94570dSGrishma Kotecha for (i = 0; i < lkups_cnt; i++) { 56671b699f81SAlexander Lobakin const struct ice_dummy_pkt_offsets *offsets = profile->offsets; 56680f94570dSGrishma Kotecha enum ice_protocol_type type; 56690f94570dSGrishma Kotecha u16 offset = 0, len = 0, j; 56700f94570dSGrishma Kotecha bool found = false; 56710f94570dSGrishma Kotecha 56720f94570dSGrishma Kotecha /* find the start of this layer; it should be found since this 56730f94570dSGrishma Kotecha * was already checked when search for the dummy packet 56740f94570dSGrishma Kotecha */ 56750f94570dSGrishma Kotecha type = lkups[i].type; 567603592a14SMichal Swiatkowski /* metadata isn't present in the packet */ 567703592a14SMichal Swiatkowski if (type == ICE_HW_METADATA) 567803592a14SMichal Swiatkowski continue; 567903592a14SMichal Swiatkowski 56800f94570dSGrishma Kotecha for (j = 0; offsets[j].type != ICE_PROTOCOL_LAST; j++) { 56810f94570dSGrishma Kotecha if (type == offsets[j].type) { 56820f94570dSGrishma Kotecha offset = offsets[j].offset; 56830f94570dSGrishma Kotecha found = true; 56840f94570dSGrishma Kotecha break; 56850f94570dSGrishma Kotecha } 56860f94570dSGrishma Kotecha } 56870f94570dSGrishma Kotecha /* this should never happen in a correct calling sequence */ 56880f94570dSGrishma Kotecha if (!found) 5689d54699e2STony Nguyen return -EINVAL; 56900f94570dSGrishma Kotecha 56910f94570dSGrishma Kotecha switch (lkups[i].type) { 56920f94570dSGrishma Kotecha case ICE_MAC_OFOS: 56930f94570dSGrishma Kotecha case ICE_MAC_IL: 56940f94570dSGrishma Kotecha len = sizeof(struct ice_ether_hdr); 56950f94570dSGrishma Kotecha break; 56960f94570dSGrishma Kotecha case ICE_ETYPE_OL: 569734a89775SMartyna Szapar-Mudlaw case ICE_ETYPE_IL: 56980f94570dSGrishma Kotecha len = sizeof(struct ice_ethtype_hdr); 56990f94570dSGrishma Kotecha break; 57000f94570dSGrishma Kotecha case ICE_VLAN_OFOS: 570106bca7c2SMartyna Szapar-Mudlaw case ICE_VLAN_EX: 570206bca7c2SMartyna Szapar-Mudlaw case ICE_VLAN_IN: 57030f94570dSGrishma Kotecha len = sizeof(struct ice_vlan_hdr); 57040f94570dSGrishma Kotecha break; 57050f94570dSGrishma Kotecha case ICE_IPV4_OFOS: 57060f94570dSGrishma Kotecha case ICE_IPV4_IL: 57070f94570dSGrishma Kotecha len = sizeof(struct ice_ipv4_hdr); 57080f94570dSGrishma Kotecha break; 57090f94570dSGrishma Kotecha case ICE_IPV6_OFOS: 57100f94570dSGrishma Kotecha case ICE_IPV6_IL: 57110f94570dSGrishma Kotecha len = sizeof(struct ice_ipv6_hdr); 57120f94570dSGrishma Kotecha break; 57130f94570dSGrishma Kotecha case ICE_TCP_IL: 57140f94570dSGrishma Kotecha case ICE_UDP_OF: 57150f94570dSGrishma Kotecha case ICE_UDP_ILOS: 57160f94570dSGrishma Kotecha len = sizeof(struct ice_l4_hdr); 57170f94570dSGrishma Kotecha break; 57180f94570dSGrishma Kotecha case ICE_SCTP_IL: 57190f94570dSGrishma Kotecha len = sizeof(struct ice_sctp_hdr); 57200f94570dSGrishma Kotecha break; 5721f0a35040SMichal Swiatkowski case ICE_NVGRE: 5722f0a35040SMichal Swiatkowski len = sizeof(struct ice_nvgre_hdr); 5723f0a35040SMichal Swiatkowski break; 57248b032a55SMichal Swiatkowski case ICE_VXLAN: 57258b032a55SMichal Swiatkowski case ICE_GENEVE: 57268b032a55SMichal Swiatkowski len = sizeof(struct ice_udp_tnl_hdr); 57278b032a55SMichal Swiatkowski break; 57289a225f81SMarcin Szycik case ICE_GTP_NO_PAY: 57299a225f81SMarcin Szycik case ICE_GTP: 57309a225f81SMarcin Szycik len = sizeof(struct ice_udp_gtp_hdr); 57319a225f81SMarcin Szycik break; 5732cd8efeeeSMarcin Szycik case ICE_PPPOE: 5733cd8efeeeSMarcin Szycik len = sizeof(struct ice_pppoe_hdr); 5734cd8efeeeSMarcin Szycik break; 5735cd634549SMarcin Szycik case ICE_L2TPV3: 5736cd634549SMarcin Szycik len = sizeof(struct ice_l2tpv3_sess_hdr); 5737cd634549SMarcin Szycik break; 57380f94570dSGrishma Kotecha default: 5739d54699e2STony Nguyen return -EINVAL; 57400f94570dSGrishma Kotecha } 57410f94570dSGrishma Kotecha 57420f94570dSGrishma Kotecha /* the length should be a word multiple */ 57430f94570dSGrishma Kotecha if (len % ICE_BYTES_PER_WORD) 5744d54699e2STony Nguyen return -EIO; 57450f94570dSGrishma Kotecha 57460f94570dSGrishma Kotecha /* We have the offset to the header start, the length, the 57470f94570dSGrishma Kotecha * caller's header values and mask. Use this information to 57480f94570dSGrishma Kotecha * copy the data into the dummy packet appropriately based on 57490f94570dSGrishma Kotecha * the mask. Note that we need to only write the bits as 57500f94570dSGrishma Kotecha * indicated by the mask to make sure we don't improperly write 57510f94570dSGrishma Kotecha * over any significant packet data. 57520f94570dSGrishma Kotecha */ 575327ffa273SAlexander Lobakin for (j = 0; j < len / sizeof(u16); j++) { 575427ffa273SAlexander Lobakin u16 *ptr = (u16 *)(pkt + offset); 575527ffa273SAlexander Lobakin u16 mask = lkups[i].m_raw[j]; 575627ffa273SAlexander Lobakin 575727ffa273SAlexander Lobakin if (!mask) 575827ffa273SAlexander Lobakin continue; 575927ffa273SAlexander Lobakin 576027ffa273SAlexander Lobakin ptr[j] = (ptr[j] & ~mask) | (lkups[i].h_raw[j] & mask); 576127ffa273SAlexander Lobakin } 57620f94570dSGrishma Kotecha } 57630f94570dSGrishma Kotecha 57646e1ff618SAlexander Lobakin s_rule->hdr_len = cpu_to_le16(profile->pkt_len); 57650f94570dSGrishma Kotecha 57660f94570dSGrishma Kotecha return 0; 57670f94570dSGrishma Kotecha } 57680f94570dSGrishma Kotecha 57690f94570dSGrishma Kotecha /** 57708b032a55SMichal Swiatkowski * ice_fill_adv_packet_tun - fill dummy packet with udp tunnel port 57718b032a55SMichal Swiatkowski * @hw: pointer to the hardware structure 57728b032a55SMichal Swiatkowski * @tun_type: tunnel type 57738b032a55SMichal Swiatkowski * @pkt: dummy packet to fill in 57748b032a55SMichal Swiatkowski * @offsets: offset info for the dummy packet 57758b032a55SMichal Swiatkowski */ 5776d54699e2STony Nguyen static int 57778b032a55SMichal Swiatkowski ice_fill_adv_packet_tun(struct ice_hw *hw, enum ice_sw_tunnel_type tun_type, 57788b032a55SMichal Swiatkowski u8 *pkt, const struct ice_dummy_pkt_offsets *offsets) 57798b032a55SMichal Swiatkowski { 57808b032a55SMichal Swiatkowski u16 open_port, i; 57818b032a55SMichal Swiatkowski 57828b032a55SMichal Swiatkowski switch (tun_type) { 57838b032a55SMichal Swiatkowski case ICE_SW_TUN_VXLAN: 5784de6acd1cSMichal Swiatkowski if (!ice_get_open_tunnel_port(hw, &open_port, TNL_VXLAN)) 5785d54699e2STony Nguyen return -EIO; 57868b032a55SMichal Swiatkowski break; 5787de6acd1cSMichal Swiatkowski case ICE_SW_TUN_GENEVE: 5788de6acd1cSMichal Swiatkowski if (!ice_get_open_tunnel_port(hw, &open_port, TNL_GENEVE)) 5789d54699e2STony Nguyen return -EIO; 5790de6acd1cSMichal Swiatkowski break; 57918b032a55SMichal Swiatkowski default: 57928b032a55SMichal Swiatkowski /* Nothing needs to be done for this tunnel type */ 57938b032a55SMichal Swiatkowski return 0; 57948b032a55SMichal Swiatkowski } 57958b032a55SMichal Swiatkowski 57968b032a55SMichal Swiatkowski /* Find the outer UDP protocol header and insert the port number */ 57978b032a55SMichal Swiatkowski for (i = 0; offsets[i].type != ICE_PROTOCOL_LAST; i++) { 57988b032a55SMichal Swiatkowski if (offsets[i].type == ICE_UDP_OF) { 57998b032a55SMichal Swiatkowski struct ice_l4_hdr *hdr; 58008b032a55SMichal Swiatkowski u16 offset; 58018b032a55SMichal Swiatkowski 58028b032a55SMichal Swiatkowski offset = offsets[i].offset; 58038b032a55SMichal Swiatkowski hdr = (struct ice_l4_hdr *)&pkt[offset]; 58048b032a55SMichal Swiatkowski hdr->dst_port = cpu_to_be16(open_port); 58058b032a55SMichal Swiatkowski 58068b032a55SMichal Swiatkowski return 0; 58078b032a55SMichal Swiatkowski } 58088b032a55SMichal Swiatkowski } 58098b032a55SMichal Swiatkowski 5810d54699e2STony Nguyen return -EIO; 58118b032a55SMichal Swiatkowski } 58128b032a55SMichal Swiatkowski 58138b032a55SMichal Swiatkowski /** 5814ea71b967SMartyna Szapar-Mudlaw * ice_fill_adv_packet_vlan - fill dummy packet with VLAN tag type 581503592a14SMichal Swiatkowski * @hw: pointer to hw structure 5816ea71b967SMartyna Szapar-Mudlaw * @vlan_type: VLAN tag type 5817ea71b967SMartyna Szapar-Mudlaw * @pkt: dummy packet to fill in 5818ea71b967SMartyna Szapar-Mudlaw * @offsets: offset info for the dummy packet 5819ea71b967SMartyna Szapar-Mudlaw */ 5820ea71b967SMartyna Szapar-Mudlaw static int 582103592a14SMichal Swiatkowski ice_fill_adv_packet_vlan(struct ice_hw *hw, u16 vlan_type, u8 *pkt, 5822ea71b967SMartyna Szapar-Mudlaw const struct ice_dummy_pkt_offsets *offsets) 5823ea71b967SMartyna Szapar-Mudlaw { 5824ea71b967SMartyna Szapar-Mudlaw u16 i; 5825ea71b967SMartyna Szapar-Mudlaw 582603592a14SMichal Swiatkowski /* Check if there is something to do */ 582703592a14SMichal Swiatkowski if (!vlan_type || !ice_is_dvm_ena(hw)) 582803592a14SMichal Swiatkowski return 0; 582903592a14SMichal Swiatkowski 5830ea71b967SMartyna Szapar-Mudlaw /* Find VLAN header and insert VLAN TPID */ 5831ea71b967SMartyna Szapar-Mudlaw for (i = 0; offsets[i].type != ICE_PROTOCOL_LAST; i++) { 5832ea71b967SMartyna Szapar-Mudlaw if (offsets[i].type == ICE_VLAN_OFOS || 5833ea71b967SMartyna Szapar-Mudlaw offsets[i].type == ICE_VLAN_EX) { 5834ea71b967SMartyna Szapar-Mudlaw struct ice_vlan_hdr *hdr; 5835ea71b967SMartyna Szapar-Mudlaw u16 offset; 5836ea71b967SMartyna Szapar-Mudlaw 5837ea71b967SMartyna Szapar-Mudlaw offset = offsets[i].offset; 5838ea71b967SMartyna Szapar-Mudlaw hdr = (struct ice_vlan_hdr *)&pkt[offset]; 5839ea71b967SMartyna Szapar-Mudlaw hdr->type = cpu_to_be16(vlan_type); 5840ea71b967SMartyna Szapar-Mudlaw 5841ea71b967SMartyna Szapar-Mudlaw return 0; 5842ea71b967SMartyna Szapar-Mudlaw } 5843ea71b967SMartyna Szapar-Mudlaw } 5844ea71b967SMartyna Szapar-Mudlaw 5845ea71b967SMartyna Szapar-Mudlaw return -EIO; 5846ea71b967SMartyna Szapar-Mudlaw } 5847ea71b967SMartyna Szapar-Mudlaw 584803592a14SMichal Swiatkowski static bool ice_rules_equal(const struct ice_adv_rule_info *first, 584903592a14SMichal Swiatkowski const struct ice_adv_rule_info *second) 585003592a14SMichal Swiatkowski { 585103592a14SMichal Swiatkowski return first->sw_act.flag == second->sw_act.flag && 585203592a14SMichal Swiatkowski first->tun_type == second->tun_type && 585303592a14SMichal Swiatkowski first->vlan_type == second->vlan_type && 5854bccd9bceSMarcin Szycik first->src_vsi == second->src_vsi && 5855bccd9bceSMarcin Szycik first->need_pass_l2 == second->need_pass_l2 && 5856bccd9bceSMarcin Szycik first->allow_pass_l2 == second->allow_pass_l2; 585703592a14SMichal Swiatkowski } 585803592a14SMichal Swiatkowski 5859ea71b967SMartyna Szapar-Mudlaw /** 58600f94570dSGrishma Kotecha * ice_find_adv_rule_entry - Search a rule entry 58610f94570dSGrishma Kotecha * @hw: pointer to the hardware structure 58620f94570dSGrishma Kotecha * @lkups: lookup elements or match criteria for the advanced recipe, one 58630f94570dSGrishma Kotecha * structure per protocol header 58640f94570dSGrishma Kotecha * @lkups_cnt: number of protocols 58650f94570dSGrishma Kotecha * @recp_id: recipe ID for which we are finding the rule 58660f94570dSGrishma Kotecha * @rinfo: other information regarding the rule e.g. priority and action info 58670f94570dSGrishma Kotecha * 58680f94570dSGrishma Kotecha * Helper function to search for a given advance rule entry 58690f94570dSGrishma Kotecha * Returns pointer to entry storing the rule if found 58700f94570dSGrishma Kotecha */ 58710f94570dSGrishma Kotecha static struct ice_adv_fltr_mgmt_list_entry * 58720f94570dSGrishma Kotecha ice_find_adv_rule_entry(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups, 58730f94570dSGrishma Kotecha u16 lkups_cnt, u16 recp_id, 58740f94570dSGrishma Kotecha struct ice_adv_rule_info *rinfo) 58750f94570dSGrishma Kotecha { 58760f94570dSGrishma Kotecha struct ice_adv_fltr_mgmt_list_entry *list_itr; 58770f94570dSGrishma Kotecha struct ice_switch_info *sw = hw->switch_info; 58780f94570dSGrishma Kotecha int i; 58790f94570dSGrishma Kotecha 58800f94570dSGrishma Kotecha list_for_each_entry(list_itr, &sw->recp_list[recp_id].filt_rules, 58810f94570dSGrishma Kotecha list_entry) { 58820f94570dSGrishma Kotecha bool lkups_matched = true; 58830f94570dSGrishma Kotecha 58840f94570dSGrishma Kotecha if (lkups_cnt != list_itr->lkups_cnt) 58850f94570dSGrishma Kotecha continue; 58860f94570dSGrishma Kotecha for (i = 0; i < list_itr->lkups_cnt; i++) 58870f94570dSGrishma Kotecha if (memcmp(&list_itr->lkups[i], &lkups[i], 58880f94570dSGrishma Kotecha sizeof(*lkups))) { 58890f94570dSGrishma Kotecha lkups_matched = false; 58900f94570dSGrishma Kotecha break; 58910f94570dSGrishma Kotecha } 589203592a14SMichal Swiatkowski if (ice_rules_equal(rinfo, &list_itr->rule_info) && 58930f94570dSGrishma Kotecha lkups_matched) 58940f94570dSGrishma Kotecha return list_itr; 58950f94570dSGrishma Kotecha } 58960f94570dSGrishma Kotecha return NULL; 58970f94570dSGrishma Kotecha } 58980f94570dSGrishma Kotecha 58990f94570dSGrishma Kotecha /** 59000f94570dSGrishma Kotecha * ice_adv_add_update_vsi_list 59010f94570dSGrishma Kotecha * @hw: pointer to the hardware structure 59020f94570dSGrishma Kotecha * @m_entry: pointer to current adv filter management list entry 59030f94570dSGrishma Kotecha * @cur_fltr: filter information from the book keeping entry 59040f94570dSGrishma Kotecha * @new_fltr: filter information with the new VSI to be added 59050f94570dSGrishma Kotecha * 59060f94570dSGrishma Kotecha * Call AQ command to add or update previously created VSI list with new VSI. 59070f94570dSGrishma Kotecha * 59080f94570dSGrishma Kotecha * Helper function to do book keeping associated with adding filter information 59090f94570dSGrishma Kotecha * The algorithm to do the booking keeping is described below : 59100f94570dSGrishma Kotecha * When a VSI needs to subscribe to a given advanced filter 59110f94570dSGrishma Kotecha * if only one VSI has been added till now 59120f94570dSGrishma Kotecha * Allocate a new VSI list and add two VSIs 59130f94570dSGrishma Kotecha * to this list using switch rule command 59140f94570dSGrishma Kotecha * Update the previously created switch rule with the 59150f94570dSGrishma Kotecha * newly created VSI list ID 59160f94570dSGrishma Kotecha * if a VSI list was previously created 59170f94570dSGrishma Kotecha * Add the new VSI to the previously created VSI list set 59180f94570dSGrishma Kotecha * using the update switch rule command 59190f94570dSGrishma Kotecha */ 59205e24d598STony Nguyen static int 59210f94570dSGrishma Kotecha ice_adv_add_update_vsi_list(struct ice_hw *hw, 59220f94570dSGrishma Kotecha struct ice_adv_fltr_mgmt_list_entry *m_entry, 59230f94570dSGrishma Kotecha struct ice_adv_rule_info *cur_fltr, 59240f94570dSGrishma Kotecha struct ice_adv_rule_info *new_fltr) 59250f94570dSGrishma Kotecha { 59260f94570dSGrishma Kotecha u16 vsi_list_id = 0; 59275518ac2aSTony Nguyen int status; 59280f94570dSGrishma Kotecha 59290f94570dSGrishma Kotecha if (cur_fltr->sw_act.fltr_act == ICE_FWD_TO_Q || 59300f94570dSGrishma Kotecha cur_fltr->sw_act.fltr_act == ICE_FWD_TO_QGRP || 59310f94570dSGrishma Kotecha cur_fltr->sw_act.fltr_act == ICE_DROP_PACKET) 5932d54699e2STony Nguyen return -EOPNOTSUPP; 59330f94570dSGrishma Kotecha 59340f94570dSGrishma Kotecha if ((new_fltr->sw_act.fltr_act == ICE_FWD_TO_Q || 59350f94570dSGrishma Kotecha new_fltr->sw_act.fltr_act == ICE_FWD_TO_QGRP) && 59360f94570dSGrishma Kotecha (cur_fltr->sw_act.fltr_act == ICE_FWD_TO_VSI || 59370f94570dSGrishma Kotecha cur_fltr->sw_act.fltr_act == ICE_FWD_TO_VSI_LIST)) 5938d54699e2STony Nguyen return -EOPNOTSUPP; 59390f94570dSGrishma Kotecha 59400f94570dSGrishma Kotecha if (m_entry->vsi_count < 2 && !m_entry->vsi_list_info) { 59410f94570dSGrishma Kotecha /* Only one entry existed in the mapping and it was not already 59420f94570dSGrishma Kotecha * a part of a VSI list. So, create a VSI list with the old and 59430f94570dSGrishma Kotecha * new VSIs. 59440f94570dSGrishma Kotecha */ 59450f94570dSGrishma Kotecha struct ice_fltr_info tmp_fltr; 59460f94570dSGrishma Kotecha u16 vsi_handle_arr[2]; 59470f94570dSGrishma Kotecha 59480f94570dSGrishma Kotecha /* A rule already exists with the new VSI being added */ 59490f94570dSGrishma Kotecha if (cur_fltr->sw_act.fwd_id.hw_vsi_id == 59500f94570dSGrishma Kotecha new_fltr->sw_act.fwd_id.hw_vsi_id) 5951d54699e2STony Nguyen return -EEXIST; 59520f94570dSGrishma Kotecha 59530f94570dSGrishma Kotecha vsi_handle_arr[0] = cur_fltr->sw_act.vsi_handle; 59540f94570dSGrishma Kotecha vsi_handle_arr[1] = new_fltr->sw_act.vsi_handle; 59550f94570dSGrishma Kotecha status = ice_create_vsi_list_rule(hw, &vsi_handle_arr[0], 2, 59560f94570dSGrishma Kotecha &vsi_list_id, 59570f94570dSGrishma Kotecha ICE_SW_LKUP_LAST); 59580f94570dSGrishma Kotecha if (status) 59590f94570dSGrishma Kotecha return status; 59600f94570dSGrishma Kotecha 59610f94570dSGrishma Kotecha memset(&tmp_fltr, 0, sizeof(tmp_fltr)); 59620f94570dSGrishma Kotecha tmp_fltr.flag = m_entry->rule_info.sw_act.flag; 59630f94570dSGrishma Kotecha tmp_fltr.fltr_rule_id = cur_fltr->fltr_rule_id; 59640f94570dSGrishma Kotecha tmp_fltr.fltr_act = ICE_FWD_TO_VSI_LIST; 59650f94570dSGrishma Kotecha tmp_fltr.fwd_id.vsi_list_id = vsi_list_id; 59660f94570dSGrishma Kotecha tmp_fltr.lkup_type = ICE_SW_LKUP_LAST; 59670f94570dSGrishma Kotecha 59680f94570dSGrishma Kotecha /* Update the previous switch rule of "forward to VSI" to 59690f94570dSGrishma Kotecha * "fwd to VSI list" 59700f94570dSGrishma Kotecha */ 59710f94570dSGrishma Kotecha status = ice_update_pkt_fwd_rule(hw, &tmp_fltr); 59720f94570dSGrishma Kotecha if (status) 59730f94570dSGrishma Kotecha return status; 59740f94570dSGrishma Kotecha 59750f94570dSGrishma Kotecha cur_fltr->sw_act.fwd_id.vsi_list_id = vsi_list_id; 59760f94570dSGrishma Kotecha cur_fltr->sw_act.fltr_act = ICE_FWD_TO_VSI_LIST; 59770f94570dSGrishma Kotecha m_entry->vsi_list_info = 59780f94570dSGrishma Kotecha ice_create_vsi_list_map(hw, &vsi_handle_arr[0], 2, 59790f94570dSGrishma Kotecha vsi_list_id); 59800f94570dSGrishma Kotecha } else { 59810f94570dSGrishma Kotecha u16 vsi_handle = new_fltr->sw_act.vsi_handle; 59820f94570dSGrishma Kotecha 59830f94570dSGrishma Kotecha if (!m_entry->vsi_list_info) 5984d54699e2STony Nguyen return -EIO; 59850f94570dSGrishma Kotecha 59860f94570dSGrishma Kotecha /* A rule already exists with the new VSI being added */ 59870f94570dSGrishma Kotecha if (test_bit(vsi_handle, m_entry->vsi_list_info->vsi_map)) 59880f94570dSGrishma Kotecha return 0; 59890f94570dSGrishma Kotecha 59900f94570dSGrishma Kotecha /* Update the previously created VSI list set with 59910f94570dSGrishma Kotecha * the new VSI ID passed in 59920f94570dSGrishma Kotecha */ 59930f94570dSGrishma Kotecha vsi_list_id = cur_fltr->sw_act.fwd_id.vsi_list_id; 59940f94570dSGrishma Kotecha 59950f94570dSGrishma Kotecha status = ice_update_vsi_list_rule(hw, &vsi_handle, 1, 59960f94570dSGrishma Kotecha vsi_list_id, false, 59970f94570dSGrishma Kotecha ice_aqc_opc_update_sw_rules, 59980f94570dSGrishma Kotecha ICE_SW_LKUP_LAST); 59990f94570dSGrishma Kotecha /* update VSI list mapping info with new VSI ID */ 60000f94570dSGrishma Kotecha if (!status) 60010f94570dSGrishma Kotecha set_bit(vsi_handle, m_entry->vsi_list_info->vsi_map); 60020f94570dSGrishma Kotecha } 60030f94570dSGrishma Kotecha if (!status) 60040f94570dSGrishma Kotecha m_entry->vsi_count++; 60050f94570dSGrishma Kotecha return status; 60060f94570dSGrishma Kotecha } 60070f94570dSGrishma Kotecha 600803592a14SMichal Swiatkowski void ice_rule_add_tunnel_metadata(struct ice_adv_lkup_elem *lkup) 600903592a14SMichal Swiatkowski { 601003592a14SMichal Swiatkowski lkup->type = ICE_HW_METADATA; 601141ad9f8eSMarcin Szycik lkup->m_u.metadata.flags[ICE_PKT_FLAGS_MDID21] |= 601203592a14SMichal Swiatkowski cpu_to_be16(ICE_PKT_TUNNEL_MASK); 601303592a14SMichal Swiatkowski } 601403592a14SMichal Swiatkowski 60150960a27bSMarcin Szycik void ice_rule_add_direction_metadata(struct ice_adv_lkup_elem *lkup) 60160960a27bSMarcin Szycik { 60170960a27bSMarcin Szycik lkup->type = ICE_HW_METADATA; 601841ad9f8eSMarcin Szycik lkup->m_u.metadata.flags[ICE_PKT_FLAGS_MDID20] |= 60190960a27bSMarcin Szycik cpu_to_be16(ICE_PKT_FROM_NETWORK); 60200960a27bSMarcin Szycik } 60210960a27bSMarcin Szycik 602203592a14SMichal Swiatkowski void ice_rule_add_vlan_metadata(struct ice_adv_lkup_elem *lkup) 602303592a14SMichal Swiatkowski { 602403592a14SMichal Swiatkowski lkup->type = ICE_HW_METADATA; 602541ad9f8eSMarcin Szycik lkup->m_u.metadata.flags[ICE_PKT_FLAGS_MDID20] |= 602603592a14SMichal Swiatkowski cpu_to_be16(ICE_PKT_VLAN_MASK); 602703592a14SMichal Swiatkowski } 602803592a14SMichal Swiatkowski 60290ef4479dSMichal Swiatkowski void ice_rule_add_src_vsi_metadata(struct ice_adv_lkup_elem *lkup) 60300ef4479dSMichal Swiatkowski { 60310ef4479dSMichal Swiatkowski lkup->type = ICE_HW_METADATA; 60320ef4479dSMichal Swiatkowski lkup->m_u.metadata.source_vsi = cpu_to_be16(ICE_MDID_SOURCE_VSI_MASK); 60330ef4479dSMichal Swiatkowski } 60340ef4479dSMichal Swiatkowski 60350f94570dSGrishma Kotecha /** 60360f94570dSGrishma Kotecha * ice_add_adv_rule - helper function to create an advanced switch rule 60370f94570dSGrishma Kotecha * @hw: pointer to the hardware structure 60380f94570dSGrishma Kotecha * @lkups: information on the words that needs to be looked up. All words 60390f94570dSGrishma Kotecha * together makes one recipe 60400f94570dSGrishma Kotecha * @lkups_cnt: num of entries in the lkups array 60410f94570dSGrishma Kotecha * @rinfo: other information related to the rule that needs to be programmed 60420f94570dSGrishma Kotecha * @added_entry: this will return recipe_id, rule_id and vsi_handle. should be 60430f94570dSGrishma Kotecha * ignored is case of error. 60440f94570dSGrishma Kotecha * 60450f94570dSGrishma Kotecha * This function can program only 1 rule at a time. The lkups is used to 60460f94570dSGrishma Kotecha * describe the all the words that forms the "lookup" portion of the recipe. 60470f94570dSGrishma Kotecha * These words can span multiple protocols. Callers to this function need to 60480f94570dSGrishma Kotecha * pass in a list of protocol headers with lookup information along and mask 60490f94570dSGrishma Kotecha * that determines which words are valid from the given protocol header. 60500f94570dSGrishma Kotecha * rinfo describes other information related to this rule such as forwarding 60510f94570dSGrishma Kotecha * IDs, priority of this rule, etc. 60520f94570dSGrishma Kotecha */ 60535e24d598STony Nguyen int 60540f94570dSGrishma Kotecha ice_add_adv_rule(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups, 60550f94570dSGrishma Kotecha u16 lkups_cnt, struct ice_adv_rule_info *rinfo, 60560f94570dSGrishma Kotecha struct ice_rule_query_data *added_entry) 60570f94570dSGrishma Kotecha { 60580f94570dSGrishma Kotecha struct ice_adv_fltr_mgmt_list_entry *m_entry, *adv_fltr = NULL; 60596e1ff618SAlexander Lobakin struct ice_sw_rule_lkup_rx_tx *s_rule = NULL; 6060e33163a4SAlexander Lobakin const struct ice_dummy_pkt_profile *profile; 60611b699f81SAlexander Lobakin u16 rid = 0, i, rule_buf_sz, vsi_handle; 60620f94570dSGrishma Kotecha struct list_head *rule_head; 60630f94570dSGrishma Kotecha struct ice_switch_info *sw; 60640f94570dSGrishma Kotecha u16 word_cnt; 60650f94570dSGrishma Kotecha u32 act = 0; 60665518ac2aSTony Nguyen int status; 60670f94570dSGrishma Kotecha u8 q_rgn; 60680f94570dSGrishma Kotecha 60690f94570dSGrishma Kotecha /* Initialize profile to result index bitmap */ 60700f94570dSGrishma Kotecha if (!hw->switch_info->prof_res_bm_init) { 60710f94570dSGrishma Kotecha hw->switch_info->prof_res_bm_init = 1; 60720f94570dSGrishma Kotecha ice_init_prof_result_bm(hw); 60730f94570dSGrishma Kotecha } 60740f94570dSGrishma Kotecha 60750f94570dSGrishma Kotecha if (!lkups_cnt) 6076d54699e2STony Nguyen return -EINVAL; 60770f94570dSGrishma Kotecha 60780f94570dSGrishma Kotecha /* get # of words we need to match */ 60790f94570dSGrishma Kotecha word_cnt = 0; 60800f94570dSGrishma Kotecha for (i = 0; i < lkups_cnt; i++) { 6081135a161aSAlexander Lobakin u16 j; 60820f94570dSGrishma Kotecha 6083135a161aSAlexander Lobakin for (j = 0; j < ARRAY_SIZE(lkups->m_raw); j++) 6084135a161aSAlexander Lobakin if (lkups[i].m_raw[j]) 60850f94570dSGrishma Kotecha word_cnt++; 60860f94570dSGrishma Kotecha } 60870f94570dSGrishma Kotecha 6088bd1ffe8eSWojciech Drewek if (!word_cnt) 6089d54699e2STony Nguyen return -EINVAL; 60900f94570dSGrishma Kotecha 6091bd1ffe8eSWojciech Drewek if (word_cnt > ICE_MAX_CHAIN_WORDS) 6092bd1ffe8eSWojciech Drewek return -ENOSPC; 6093bd1ffe8eSWojciech Drewek 60941b699f81SAlexander Lobakin /* locate a dummy packet */ 60951b699f81SAlexander Lobakin profile = ice_find_dummy_packet(lkups, lkups_cnt, rinfo->tun_type); 609626395726SMartyna Szapar-Mudlaw if (IS_ERR(profile)) 609726395726SMartyna Szapar-Mudlaw return PTR_ERR(profile); 60980f94570dSGrishma Kotecha 60990f94570dSGrishma Kotecha if (!(rinfo->sw_act.fltr_act == ICE_FWD_TO_VSI || 61000f94570dSGrishma Kotecha rinfo->sw_act.fltr_act == ICE_FWD_TO_Q || 61010f94570dSGrishma Kotecha rinfo->sw_act.fltr_act == ICE_FWD_TO_QGRP || 6102bccd9bceSMarcin Szycik rinfo->sw_act.fltr_act == ICE_DROP_PACKET || 6103bccd9bceSMarcin Szycik rinfo->sw_act.fltr_act == ICE_NOP)) { 610426395726SMartyna Szapar-Mudlaw status = -EIO; 610526395726SMartyna Szapar-Mudlaw goto free_pkt_profile; 610626395726SMartyna Szapar-Mudlaw } 61070f94570dSGrishma Kotecha 61080f94570dSGrishma Kotecha vsi_handle = rinfo->sw_act.vsi_handle; 610926395726SMartyna Szapar-Mudlaw if (!ice_is_vsi_valid(hw, vsi_handle)) { 611026395726SMartyna Szapar-Mudlaw status = -EINVAL; 611126395726SMartyna Szapar-Mudlaw goto free_pkt_profile; 611226395726SMartyna Szapar-Mudlaw } 61130f94570dSGrishma Kotecha 6114bccd9bceSMarcin Szycik if (rinfo->sw_act.fltr_act == ICE_FWD_TO_VSI || 6115bccd9bceSMarcin Szycik rinfo->sw_act.fltr_act == ICE_NOP) 61160f94570dSGrishma Kotecha rinfo->sw_act.fwd_id.hw_vsi_id = 61170f94570dSGrishma Kotecha ice_get_hw_vsi_num(hw, vsi_handle); 611803592a14SMichal Swiatkowski 611903592a14SMichal Swiatkowski if (rinfo->src_vsi) 612003592a14SMichal Swiatkowski rinfo->sw_act.src = ice_get_hw_vsi_num(hw, rinfo->src_vsi); 612103592a14SMichal Swiatkowski else 61220f94570dSGrishma Kotecha rinfo->sw_act.src = ice_get_hw_vsi_num(hw, vsi_handle); 61230f94570dSGrishma Kotecha 61240f94570dSGrishma Kotecha status = ice_add_adv_recipe(hw, lkups, lkups_cnt, rinfo, &rid); 61250f94570dSGrishma Kotecha if (status) 612626395726SMartyna Szapar-Mudlaw goto free_pkt_profile; 61270f94570dSGrishma Kotecha m_entry = ice_find_adv_rule_entry(hw, lkups, lkups_cnt, rid, rinfo); 61280f94570dSGrishma Kotecha if (m_entry) { 61290f94570dSGrishma Kotecha /* we have to add VSI to VSI_LIST and increment vsi_count. 61300f94570dSGrishma Kotecha * Also Update VSI list so that we can change forwarding rule 61310f94570dSGrishma Kotecha * if the rule already exists, we will check if it exists with 61320f94570dSGrishma Kotecha * same vsi_id, if not then add it to the VSI list if it already 61330f94570dSGrishma Kotecha * exists if not then create a VSI list and add the existing VSI 61340f94570dSGrishma Kotecha * ID and the new VSI ID to the list 61350f94570dSGrishma Kotecha * We will add that VSI to the list 61360f94570dSGrishma Kotecha */ 61370f94570dSGrishma Kotecha status = ice_adv_add_update_vsi_list(hw, m_entry, 61380f94570dSGrishma Kotecha &m_entry->rule_info, 61390f94570dSGrishma Kotecha rinfo); 61400f94570dSGrishma Kotecha if (added_entry) { 61410f94570dSGrishma Kotecha added_entry->rid = rid; 61420f94570dSGrishma Kotecha added_entry->rule_id = m_entry->rule_info.fltr_rule_id; 61430f94570dSGrishma Kotecha added_entry->vsi_handle = rinfo->sw_act.vsi_handle; 61440f94570dSGrishma Kotecha } 614526395726SMartyna Szapar-Mudlaw goto free_pkt_profile; 61460f94570dSGrishma Kotecha } 61476e1ff618SAlexander Lobakin rule_buf_sz = ICE_SW_RULE_RX_TX_HDR_SIZE(s_rule, profile->pkt_len); 61480f94570dSGrishma Kotecha s_rule = kzalloc(rule_buf_sz, GFP_KERNEL); 614926395726SMartyna Szapar-Mudlaw if (!s_rule) { 615026395726SMartyna Szapar-Mudlaw status = -ENOMEM; 615126395726SMartyna Szapar-Mudlaw goto free_pkt_profile; 615226395726SMartyna Szapar-Mudlaw } 615373b483b7SWojciech Drewek if (!rinfo->flags_info.act_valid) { 615473b483b7SWojciech Drewek act |= ICE_SINGLE_ACT_LAN_ENABLE; 615573b483b7SWojciech Drewek act |= ICE_SINGLE_ACT_LB_ENABLE; 615673b483b7SWojciech Drewek } else { 615773b483b7SWojciech Drewek act |= rinfo->flags_info.act & (ICE_SINGLE_ACT_LAN_ENABLE | 615873b483b7SWojciech Drewek ICE_SINGLE_ACT_LB_ENABLE); 615973b483b7SWojciech Drewek } 616073b483b7SWojciech Drewek 61610f94570dSGrishma Kotecha switch (rinfo->sw_act.fltr_act) { 61620f94570dSGrishma Kotecha case ICE_FWD_TO_VSI: 61630f94570dSGrishma Kotecha act |= (rinfo->sw_act.fwd_id.hw_vsi_id << 61640f94570dSGrishma Kotecha ICE_SINGLE_ACT_VSI_ID_S) & ICE_SINGLE_ACT_VSI_ID_M; 61650f94570dSGrishma Kotecha act |= ICE_SINGLE_ACT_VSI_FORWARDING | ICE_SINGLE_ACT_VALID_BIT; 61660f94570dSGrishma Kotecha break; 61670f94570dSGrishma Kotecha case ICE_FWD_TO_Q: 61680f94570dSGrishma Kotecha act |= ICE_SINGLE_ACT_TO_Q; 61690f94570dSGrishma Kotecha act |= (rinfo->sw_act.fwd_id.q_id << ICE_SINGLE_ACT_Q_INDEX_S) & 61700f94570dSGrishma Kotecha ICE_SINGLE_ACT_Q_INDEX_M; 61710f94570dSGrishma Kotecha break; 61720f94570dSGrishma Kotecha case ICE_FWD_TO_QGRP: 61730f94570dSGrishma Kotecha q_rgn = rinfo->sw_act.qgrp_size > 0 ? 61740f94570dSGrishma Kotecha (u8)ilog2(rinfo->sw_act.qgrp_size) : 0; 61750f94570dSGrishma Kotecha act |= ICE_SINGLE_ACT_TO_Q; 61760f94570dSGrishma Kotecha act |= (rinfo->sw_act.fwd_id.q_id << ICE_SINGLE_ACT_Q_INDEX_S) & 61770f94570dSGrishma Kotecha ICE_SINGLE_ACT_Q_INDEX_M; 61780f94570dSGrishma Kotecha act |= (q_rgn << ICE_SINGLE_ACT_Q_REGION_S) & 61790f94570dSGrishma Kotecha ICE_SINGLE_ACT_Q_REGION_M; 61800f94570dSGrishma Kotecha break; 61810f94570dSGrishma Kotecha case ICE_DROP_PACKET: 61820f94570dSGrishma Kotecha act |= ICE_SINGLE_ACT_VSI_FORWARDING | ICE_SINGLE_ACT_DROP | 61830f94570dSGrishma Kotecha ICE_SINGLE_ACT_VALID_BIT; 61840f94570dSGrishma Kotecha break; 6185bccd9bceSMarcin Szycik case ICE_NOP: 6186bccd9bceSMarcin Szycik act |= FIELD_PREP(ICE_SINGLE_ACT_VSI_ID_M, 6187bccd9bceSMarcin Szycik rinfo->sw_act.fwd_id.hw_vsi_id); 6188bccd9bceSMarcin Szycik act &= ~ICE_SINGLE_ACT_VALID_BIT; 6189bccd9bceSMarcin Szycik break; 61900f94570dSGrishma Kotecha default: 6191d54699e2STony Nguyen status = -EIO; 61920f94570dSGrishma Kotecha goto err_ice_add_adv_rule; 61930f94570dSGrishma Kotecha } 61940f94570dSGrishma Kotecha 619540fd7492SMichal Swiatkowski /* If there is no matching criteria for direction there 619640fd7492SMichal Swiatkowski * is only one difference between Rx and Tx: 619740fd7492SMichal Swiatkowski * - get switch id base on VSI number from source field (Tx) 619840fd7492SMichal Swiatkowski * - get switch id base on port number (Rx) 61990f94570dSGrishma Kotecha * 620040fd7492SMichal Swiatkowski * If matching on direction metadata is chose rule direction is 620140fd7492SMichal Swiatkowski * extracted from type value set here. 62020f94570dSGrishma Kotecha */ 620340fd7492SMichal Swiatkowski if (rinfo->sw_act.flag & ICE_FLTR_TX) { 62046e1ff618SAlexander Lobakin s_rule->hdr.type = cpu_to_le16(ICE_AQC_SW_RULES_T_LKUP_TX); 62056e1ff618SAlexander Lobakin s_rule->src = cpu_to_le16(rinfo->sw_act.src); 620640fd7492SMichal Swiatkowski } else { 620740fd7492SMichal Swiatkowski s_rule->hdr.type = cpu_to_le16(ICE_AQC_SW_RULES_T_LKUP_RX); 620840fd7492SMichal Swiatkowski s_rule->src = cpu_to_le16(hw->port_info->lport); 62090f94570dSGrishma Kotecha } 62100f94570dSGrishma Kotecha 62116e1ff618SAlexander Lobakin s_rule->recipe_id = cpu_to_le16(rid); 62126e1ff618SAlexander Lobakin s_rule->act = cpu_to_le32(act); 62130f94570dSGrishma Kotecha 6214e33163a4SAlexander Lobakin status = ice_fill_adv_dummy_packet(lkups, lkups_cnt, s_rule, profile); 62150f94570dSGrishma Kotecha if (status) 62160f94570dSGrishma Kotecha goto err_ice_add_adv_rule; 62170f94570dSGrishma Kotecha 621803592a14SMichal Swiatkowski status = ice_fill_adv_packet_tun(hw, rinfo->tun_type, s_rule->hdr_data, 6219e33163a4SAlexander Lobakin profile->offsets); 62208b032a55SMichal Swiatkowski if (status) 62218b032a55SMichal Swiatkowski goto err_ice_add_adv_rule; 62228b032a55SMichal Swiatkowski 622303592a14SMichal Swiatkowski status = ice_fill_adv_packet_vlan(hw, rinfo->vlan_type, 6224ea71b967SMartyna Szapar-Mudlaw s_rule->hdr_data, 6225ea71b967SMartyna Szapar-Mudlaw profile->offsets); 6226ea71b967SMartyna Szapar-Mudlaw if (status) 6227ea71b967SMartyna Szapar-Mudlaw goto err_ice_add_adv_rule; 6228ea71b967SMartyna Szapar-Mudlaw 62290f94570dSGrishma Kotecha status = ice_aq_sw_rules(hw, (struct ice_aqc_sw_rules *)s_rule, 62300f94570dSGrishma Kotecha rule_buf_sz, 1, ice_aqc_opc_add_sw_rules, 62310f94570dSGrishma Kotecha NULL); 62320f94570dSGrishma Kotecha if (status) 62330f94570dSGrishma Kotecha goto err_ice_add_adv_rule; 62340f94570dSGrishma Kotecha adv_fltr = devm_kzalloc(ice_hw_to_dev(hw), 62350f94570dSGrishma Kotecha sizeof(struct ice_adv_fltr_mgmt_list_entry), 62360f94570dSGrishma Kotecha GFP_KERNEL); 62370f94570dSGrishma Kotecha if (!adv_fltr) { 6238d54699e2STony Nguyen status = -ENOMEM; 62390f94570dSGrishma Kotecha goto err_ice_add_adv_rule; 62400f94570dSGrishma Kotecha } 62410f94570dSGrishma Kotecha 62420f94570dSGrishma Kotecha adv_fltr->lkups = devm_kmemdup(ice_hw_to_dev(hw), lkups, 62430f94570dSGrishma Kotecha lkups_cnt * sizeof(*lkups), GFP_KERNEL); 62440f94570dSGrishma Kotecha if (!adv_fltr->lkups) { 6245d54699e2STony Nguyen status = -ENOMEM; 62460f94570dSGrishma Kotecha goto err_ice_add_adv_rule; 62470f94570dSGrishma Kotecha } 62480f94570dSGrishma Kotecha 62490f94570dSGrishma Kotecha adv_fltr->lkups_cnt = lkups_cnt; 62500f94570dSGrishma Kotecha adv_fltr->rule_info = *rinfo; 62516e1ff618SAlexander Lobakin adv_fltr->rule_info.fltr_rule_id = le16_to_cpu(s_rule->index); 62520f94570dSGrishma Kotecha sw = hw->switch_info; 62530f94570dSGrishma Kotecha sw->recp_list[rid].adv_rule = true; 62540f94570dSGrishma Kotecha rule_head = &sw->recp_list[rid].filt_rules; 62550f94570dSGrishma Kotecha 62560f94570dSGrishma Kotecha if (rinfo->sw_act.fltr_act == ICE_FWD_TO_VSI) 62570f94570dSGrishma Kotecha adv_fltr->vsi_count = 1; 62580f94570dSGrishma Kotecha 62590f94570dSGrishma Kotecha /* Add rule entry to book keeping list */ 62600f94570dSGrishma Kotecha list_add(&adv_fltr->list_entry, rule_head); 62610f94570dSGrishma Kotecha if (added_entry) { 62620f94570dSGrishma Kotecha added_entry->rid = rid; 62630f94570dSGrishma Kotecha added_entry->rule_id = adv_fltr->rule_info.fltr_rule_id; 62640f94570dSGrishma Kotecha added_entry->vsi_handle = rinfo->sw_act.vsi_handle; 62650f94570dSGrishma Kotecha } 62660f94570dSGrishma Kotecha err_ice_add_adv_rule: 62670f94570dSGrishma Kotecha if (status && adv_fltr) { 62680f94570dSGrishma Kotecha devm_kfree(ice_hw_to_dev(hw), adv_fltr->lkups); 62690f94570dSGrishma Kotecha devm_kfree(ice_hw_to_dev(hw), adv_fltr); 62700f94570dSGrishma Kotecha } 62710f94570dSGrishma Kotecha 62720f94570dSGrishma Kotecha kfree(s_rule); 62730f94570dSGrishma Kotecha 627426395726SMartyna Szapar-Mudlaw free_pkt_profile: 627526395726SMartyna Szapar-Mudlaw if (profile->match & ICE_PKT_KMALLOC) { 627626395726SMartyna Szapar-Mudlaw kfree(profile->offsets); 627726395726SMartyna Szapar-Mudlaw kfree(profile->pkt); 627826395726SMartyna Szapar-Mudlaw kfree(profile); 627926395726SMartyna Szapar-Mudlaw } 628026395726SMartyna Szapar-Mudlaw 62810f94570dSGrishma Kotecha return status; 62820f94570dSGrishma Kotecha } 62830f94570dSGrishma Kotecha 62840f94570dSGrishma Kotecha /** 6285334cb062SAnirudh Venkataramanan * ice_replay_vsi_fltr - Replay filters for requested VSI 62860f9d5027SAnirudh Venkataramanan * @hw: pointer to the hardware structure 6287334cb062SAnirudh Venkataramanan * @vsi_handle: driver VSI handle 6288f9867df6SAnirudh Venkataramanan * @recp_id: Recipe ID for which rules need to be replayed 6289334cb062SAnirudh Venkataramanan * @list_head: list for which filters need to be replayed 6290334cb062SAnirudh Venkataramanan * 6291334cb062SAnirudh Venkataramanan * Replays the filter of recipe recp_id for a VSI represented via vsi_handle. 6292334cb062SAnirudh Venkataramanan * It is required to pass valid VSI handle. 62930f9d5027SAnirudh Venkataramanan */ 62945e24d598STony Nguyen static int 6295334cb062SAnirudh Venkataramanan ice_replay_vsi_fltr(struct ice_hw *hw, u16 vsi_handle, u8 recp_id, 6296334cb062SAnirudh Venkataramanan struct list_head *list_head) 62970f9d5027SAnirudh Venkataramanan { 62980f9d5027SAnirudh Venkataramanan struct ice_fltr_mgmt_list_entry *itr; 62995e24d598STony Nguyen int status = 0; 6300334cb062SAnirudh Venkataramanan u16 hw_vsi_id; 63010f9d5027SAnirudh Venkataramanan 63020f9d5027SAnirudh Venkataramanan if (list_empty(list_head)) 63030f9d5027SAnirudh Venkataramanan return status; 6304334cb062SAnirudh Venkataramanan hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle); 63050f9d5027SAnirudh Venkataramanan 6306334cb062SAnirudh Venkataramanan list_for_each_entry(itr, list_head, list_entry) { 63070f9d5027SAnirudh Venkataramanan struct ice_fltr_list_entry f_entry; 63080f9d5027SAnirudh Venkataramanan 63090f9d5027SAnirudh Venkataramanan f_entry.fltr_info = itr->fltr_info; 6310334cb062SAnirudh Venkataramanan if (itr->vsi_count < 2 && recp_id != ICE_SW_LKUP_VLAN && 6311334cb062SAnirudh Venkataramanan itr->fltr_info.vsi_handle == vsi_handle) { 6312f9867df6SAnirudh Venkataramanan /* update the src in case it is VSI num */ 6313334cb062SAnirudh Venkataramanan if (f_entry.fltr_info.src_id == ICE_SRC_ID_VSI) 6314334cb062SAnirudh Venkataramanan f_entry.fltr_info.src = hw_vsi_id; 63150f9d5027SAnirudh Venkataramanan status = ice_add_rule_internal(hw, recp_id, &f_entry); 63160f9d5027SAnirudh Venkataramanan if (status) 63170f9d5027SAnirudh Venkataramanan goto end; 63180f9d5027SAnirudh Venkataramanan continue; 63190f9d5027SAnirudh Venkataramanan } 6320072f0c3dSDave Ertman if (!itr->vsi_list_info || 6321072f0c3dSDave Ertman !test_bit(vsi_handle, itr->vsi_list_info->vsi_map)) 6322334cb062SAnirudh Venkataramanan continue; 6323334cb062SAnirudh Venkataramanan /* Clearing it so that the logic can add it back */ 6324334cb062SAnirudh Venkataramanan clear_bit(vsi_handle, itr->vsi_list_info->vsi_map); 6325334cb062SAnirudh Venkataramanan f_entry.fltr_info.vsi_handle = vsi_handle; 63260f9d5027SAnirudh Venkataramanan f_entry.fltr_info.fltr_act = ICE_FWD_TO_VSI; 6327f9867df6SAnirudh Venkataramanan /* update the src in case it is VSI num */ 6328334cb062SAnirudh Venkataramanan if (f_entry.fltr_info.src_id == ICE_SRC_ID_VSI) 6329334cb062SAnirudh Venkataramanan f_entry.fltr_info.src = hw_vsi_id; 63300f9d5027SAnirudh Venkataramanan if (recp_id == ICE_SW_LKUP_VLAN) 63310f9d5027SAnirudh Venkataramanan status = ice_add_vlan_internal(hw, &f_entry); 63320f9d5027SAnirudh Venkataramanan else 6333334cb062SAnirudh Venkataramanan status = ice_add_rule_internal(hw, recp_id, &f_entry); 63340f9d5027SAnirudh Venkataramanan if (status) 63350f9d5027SAnirudh Venkataramanan goto end; 63360f9d5027SAnirudh Venkataramanan } 63370f9d5027SAnirudh Venkataramanan end: 63380f9d5027SAnirudh Venkataramanan return status; 63390f9d5027SAnirudh Venkataramanan } 63400f9d5027SAnirudh Venkataramanan 63410f9d5027SAnirudh Venkataramanan /** 63428bb98f33SShivanshu Shukla * ice_adv_rem_update_vsi_list 63438bb98f33SShivanshu Shukla * @hw: pointer to the hardware structure 63448bb98f33SShivanshu Shukla * @vsi_handle: VSI handle of the VSI to remove 63458bb98f33SShivanshu Shukla * @fm_list: filter management entry for which the VSI list management needs to 63468bb98f33SShivanshu Shukla * be done 63478bb98f33SShivanshu Shukla */ 63485e24d598STony Nguyen static int 63498bb98f33SShivanshu Shukla ice_adv_rem_update_vsi_list(struct ice_hw *hw, u16 vsi_handle, 63508bb98f33SShivanshu Shukla struct ice_adv_fltr_mgmt_list_entry *fm_list) 63518bb98f33SShivanshu Shukla { 63528bb98f33SShivanshu Shukla struct ice_vsi_list_map_info *vsi_list_info; 63538bb98f33SShivanshu Shukla enum ice_sw_lkup_type lkup_type; 63548bb98f33SShivanshu Shukla u16 vsi_list_id; 63555518ac2aSTony Nguyen int status; 63568bb98f33SShivanshu Shukla 63578bb98f33SShivanshu Shukla if (fm_list->rule_info.sw_act.fltr_act != ICE_FWD_TO_VSI_LIST || 63588bb98f33SShivanshu Shukla fm_list->vsi_count == 0) 6359d54699e2STony Nguyen return -EINVAL; 63608bb98f33SShivanshu Shukla 63618bb98f33SShivanshu Shukla /* A rule with the VSI being removed does not exist */ 63628bb98f33SShivanshu Shukla if (!test_bit(vsi_handle, fm_list->vsi_list_info->vsi_map)) 6363d54699e2STony Nguyen return -ENOENT; 63648bb98f33SShivanshu Shukla 63658bb98f33SShivanshu Shukla lkup_type = ICE_SW_LKUP_LAST; 63668bb98f33SShivanshu Shukla vsi_list_id = fm_list->rule_info.sw_act.fwd_id.vsi_list_id; 63678bb98f33SShivanshu Shukla status = ice_update_vsi_list_rule(hw, &vsi_handle, 1, vsi_list_id, true, 63688bb98f33SShivanshu Shukla ice_aqc_opc_update_sw_rules, 63698bb98f33SShivanshu Shukla lkup_type); 63708bb98f33SShivanshu Shukla if (status) 63718bb98f33SShivanshu Shukla return status; 63728bb98f33SShivanshu Shukla 63738bb98f33SShivanshu Shukla fm_list->vsi_count--; 63748bb98f33SShivanshu Shukla clear_bit(vsi_handle, fm_list->vsi_list_info->vsi_map); 63758bb98f33SShivanshu Shukla vsi_list_info = fm_list->vsi_list_info; 63768bb98f33SShivanshu Shukla if (fm_list->vsi_count == 1) { 63778bb98f33SShivanshu Shukla struct ice_fltr_info tmp_fltr; 63788bb98f33SShivanshu Shukla u16 rem_vsi_handle; 63798bb98f33SShivanshu Shukla 63808bb98f33SShivanshu Shukla rem_vsi_handle = find_first_bit(vsi_list_info->vsi_map, 63818bb98f33SShivanshu Shukla ICE_MAX_VSI); 63828bb98f33SShivanshu Shukla if (!ice_is_vsi_valid(hw, rem_vsi_handle)) 6383d54699e2STony Nguyen return -EIO; 63848bb98f33SShivanshu Shukla 63858bb98f33SShivanshu Shukla /* Make sure VSI list is empty before removing it below */ 63868bb98f33SShivanshu Shukla status = ice_update_vsi_list_rule(hw, &rem_vsi_handle, 1, 63878bb98f33SShivanshu Shukla vsi_list_id, true, 63888bb98f33SShivanshu Shukla ice_aqc_opc_update_sw_rules, 63898bb98f33SShivanshu Shukla lkup_type); 63908bb98f33SShivanshu Shukla if (status) 63918bb98f33SShivanshu Shukla return status; 63928bb98f33SShivanshu Shukla 63938bb98f33SShivanshu Shukla memset(&tmp_fltr, 0, sizeof(tmp_fltr)); 63948bb98f33SShivanshu Shukla tmp_fltr.flag = fm_list->rule_info.sw_act.flag; 63958bb98f33SShivanshu Shukla tmp_fltr.fltr_rule_id = fm_list->rule_info.fltr_rule_id; 63968bb98f33SShivanshu Shukla fm_list->rule_info.sw_act.fltr_act = ICE_FWD_TO_VSI; 63978bb98f33SShivanshu Shukla tmp_fltr.fltr_act = ICE_FWD_TO_VSI; 63988bb98f33SShivanshu Shukla tmp_fltr.fwd_id.hw_vsi_id = 63998bb98f33SShivanshu Shukla ice_get_hw_vsi_num(hw, rem_vsi_handle); 64008bb98f33SShivanshu Shukla fm_list->rule_info.sw_act.fwd_id.hw_vsi_id = 64018bb98f33SShivanshu Shukla ice_get_hw_vsi_num(hw, rem_vsi_handle); 64028bb98f33SShivanshu Shukla fm_list->rule_info.sw_act.vsi_handle = rem_vsi_handle; 64038bb98f33SShivanshu Shukla 64048bb98f33SShivanshu Shukla /* Update the previous switch rule of "MAC forward to VSI" to 64058bb98f33SShivanshu Shukla * "MAC fwd to VSI list" 64068bb98f33SShivanshu Shukla */ 64078bb98f33SShivanshu Shukla status = ice_update_pkt_fwd_rule(hw, &tmp_fltr); 64088bb98f33SShivanshu Shukla if (status) { 64098bb98f33SShivanshu Shukla ice_debug(hw, ICE_DBG_SW, "Failed to update pkt fwd rule to FWD_TO_VSI on HW VSI %d, error %d\n", 64108bb98f33SShivanshu Shukla tmp_fltr.fwd_id.hw_vsi_id, status); 64118bb98f33SShivanshu Shukla return status; 64128bb98f33SShivanshu Shukla } 64138bb98f33SShivanshu Shukla fm_list->vsi_list_info->ref_cnt--; 64148bb98f33SShivanshu Shukla 64158bb98f33SShivanshu Shukla /* Remove the VSI list since it is no longer used */ 64168bb98f33SShivanshu Shukla status = ice_remove_vsi_list_rule(hw, vsi_list_id, lkup_type); 64178bb98f33SShivanshu Shukla if (status) { 64188bb98f33SShivanshu Shukla ice_debug(hw, ICE_DBG_SW, "Failed to remove VSI list %d, error %d\n", 64198bb98f33SShivanshu Shukla vsi_list_id, status); 64208bb98f33SShivanshu Shukla return status; 64218bb98f33SShivanshu Shukla } 64228bb98f33SShivanshu Shukla 64238bb98f33SShivanshu Shukla list_del(&vsi_list_info->list_entry); 64248bb98f33SShivanshu Shukla devm_kfree(ice_hw_to_dev(hw), vsi_list_info); 64258bb98f33SShivanshu Shukla fm_list->vsi_list_info = NULL; 64268bb98f33SShivanshu Shukla } 64278bb98f33SShivanshu Shukla 64288bb98f33SShivanshu Shukla return status; 64298bb98f33SShivanshu Shukla } 64308bb98f33SShivanshu Shukla 64318bb98f33SShivanshu Shukla /** 64328bb98f33SShivanshu Shukla * ice_rem_adv_rule - removes existing advanced switch rule 64338bb98f33SShivanshu Shukla * @hw: pointer to the hardware structure 64348bb98f33SShivanshu Shukla * @lkups: information on the words that needs to be looked up. All words 64358bb98f33SShivanshu Shukla * together makes one recipe 64368bb98f33SShivanshu Shukla * @lkups_cnt: num of entries in the lkups array 64378bb98f33SShivanshu Shukla * @rinfo: Its the pointer to the rule information for the rule 64388bb98f33SShivanshu Shukla * 64398bb98f33SShivanshu Shukla * This function can be used to remove 1 rule at a time. The lkups is 64408bb98f33SShivanshu Shukla * used to describe all the words that forms the "lookup" portion of the 64418bb98f33SShivanshu Shukla * rule. These words can span multiple protocols. Callers to this function 64428bb98f33SShivanshu Shukla * need to pass in a list of protocol headers with lookup information along 64438bb98f33SShivanshu Shukla * and mask that determines which words are valid from the given protocol 64448bb98f33SShivanshu Shukla * header. rinfo describes other information related to this rule such as 64458bb98f33SShivanshu Shukla * forwarding IDs, priority of this rule, etc. 64468bb98f33SShivanshu Shukla */ 64475e24d598STony Nguyen static int 64488bb98f33SShivanshu Shukla ice_rem_adv_rule(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups, 64498bb98f33SShivanshu Shukla u16 lkups_cnt, struct ice_adv_rule_info *rinfo) 64508bb98f33SShivanshu Shukla { 64518bb98f33SShivanshu Shukla struct ice_adv_fltr_mgmt_list_entry *list_elem; 64528bb98f33SShivanshu Shukla struct ice_prot_lkup_ext lkup_exts; 64538bb98f33SShivanshu Shukla bool remove_rule = false; 64548bb98f33SShivanshu Shukla struct mutex *rule_lock; /* Lock to protect filter rule list */ 64558bb98f33SShivanshu Shukla u16 i, rid, vsi_handle; 64565518ac2aSTony Nguyen int status = 0; 64578bb98f33SShivanshu Shukla 64588bb98f33SShivanshu Shukla memset(&lkup_exts, 0, sizeof(lkup_exts)); 64598bb98f33SShivanshu Shukla for (i = 0; i < lkups_cnt; i++) { 64608bb98f33SShivanshu Shukla u16 count; 64618bb98f33SShivanshu Shukla 64628bb98f33SShivanshu Shukla if (lkups[i].type >= ICE_PROTOCOL_LAST) 6463d54699e2STony Nguyen return -EIO; 64648bb98f33SShivanshu Shukla 64658bb98f33SShivanshu Shukla count = ice_fill_valid_words(&lkups[i], &lkup_exts); 64668bb98f33SShivanshu Shukla if (!count) 6467d54699e2STony Nguyen return -EIO; 64688bb98f33SShivanshu Shukla } 64698bb98f33SShivanshu Shukla 6470bccd9bceSMarcin Szycik rid = ice_find_recp(hw, &lkup_exts, rinfo); 64718bb98f33SShivanshu Shukla /* If did not find a recipe that match the existing criteria */ 64728bb98f33SShivanshu Shukla if (rid == ICE_MAX_NUM_RECIPES) 6473d54699e2STony Nguyen return -EINVAL; 64748bb98f33SShivanshu Shukla 64758bb98f33SShivanshu Shukla rule_lock = &hw->switch_info->recp_list[rid].filt_rule_lock; 64768bb98f33SShivanshu Shukla list_elem = ice_find_adv_rule_entry(hw, lkups, lkups_cnt, rid, rinfo); 64778bb98f33SShivanshu Shukla /* the rule is already removed */ 64788bb98f33SShivanshu Shukla if (!list_elem) 64798bb98f33SShivanshu Shukla return 0; 64808bb98f33SShivanshu Shukla mutex_lock(rule_lock); 64818bb98f33SShivanshu Shukla if (list_elem->rule_info.sw_act.fltr_act != ICE_FWD_TO_VSI_LIST) { 64828bb98f33SShivanshu Shukla remove_rule = true; 64838bb98f33SShivanshu Shukla } else if (list_elem->vsi_count > 1) { 64848bb98f33SShivanshu Shukla remove_rule = false; 64858bb98f33SShivanshu Shukla vsi_handle = rinfo->sw_act.vsi_handle; 64868bb98f33SShivanshu Shukla status = ice_adv_rem_update_vsi_list(hw, vsi_handle, list_elem); 64878bb98f33SShivanshu Shukla } else { 64888bb98f33SShivanshu Shukla vsi_handle = rinfo->sw_act.vsi_handle; 64898bb98f33SShivanshu Shukla status = ice_adv_rem_update_vsi_list(hw, vsi_handle, list_elem); 64908bb98f33SShivanshu Shukla if (status) { 64918bb98f33SShivanshu Shukla mutex_unlock(rule_lock); 64928bb98f33SShivanshu Shukla return status; 64938bb98f33SShivanshu Shukla } 64948bb98f33SShivanshu Shukla if (list_elem->vsi_count == 0) 64958bb98f33SShivanshu Shukla remove_rule = true; 64968bb98f33SShivanshu Shukla } 64978bb98f33SShivanshu Shukla mutex_unlock(rule_lock); 64988bb98f33SShivanshu Shukla if (remove_rule) { 64996e1ff618SAlexander Lobakin struct ice_sw_rule_lkup_rx_tx *s_rule; 65008bb98f33SShivanshu Shukla u16 rule_buf_sz; 65018bb98f33SShivanshu Shukla 65026e1ff618SAlexander Lobakin rule_buf_sz = ICE_SW_RULE_RX_TX_NO_HDR_SIZE(s_rule); 65038bb98f33SShivanshu Shukla s_rule = kzalloc(rule_buf_sz, GFP_KERNEL); 65048bb98f33SShivanshu Shukla if (!s_rule) 6505d54699e2STony Nguyen return -ENOMEM; 65066e1ff618SAlexander Lobakin s_rule->act = 0; 65076e1ff618SAlexander Lobakin s_rule->index = cpu_to_le16(list_elem->rule_info.fltr_rule_id); 65086e1ff618SAlexander Lobakin s_rule->hdr_len = 0; 65098bb98f33SShivanshu Shukla status = ice_aq_sw_rules(hw, (struct ice_aqc_sw_rules *)s_rule, 65108bb98f33SShivanshu Shukla rule_buf_sz, 1, 65118bb98f33SShivanshu Shukla ice_aqc_opc_remove_sw_rules, NULL); 6512d54699e2STony Nguyen if (!status || status == -ENOENT) { 65138bb98f33SShivanshu Shukla struct ice_switch_info *sw = hw->switch_info; 65148bb98f33SShivanshu Shukla 65158bb98f33SShivanshu Shukla mutex_lock(rule_lock); 65168bb98f33SShivanshu Shukla list_del(&list_elem->list_entry); 65178bb98f33SShivanshu Shukla devm_kfree(ice_hw_to_dev(hw), list_elem->lkups); 65188bb98f33SShivanshu Shukla devm_kfree(ice_hw_to_dev(hw), list_elem); 65198bb98f33SShivanshu Shukla mutex_unlock(rule_lock); 65208bb98f33SShivanshu Shukla if (list_empty(&sw->recp_list[rid].filt_rules)) 65218bb98f33SShivanshu Shukla sw->recp_list[rid].adv_rule = false; 65228bb98f33SShivanshu Shukla } 65238bb98f33SShivanshu Shukla kfree(s_rule); 65248bb98f33SShivanshu Shukla } 65258bb98f33SShivanshu Shukla return status; 65268bb98f33SShivanshu Shukla } 65278bb98f33SShivanshu Shukla 65288bb98f33SShivanshu Shukla /** 65298bb98f33SShivanshu Shukla * ice_rem_adv_rule_by_id - removes existing advanced switch rule by ID 65308bb98f33SShivanshu Shukla * @hw: pointer to the hardware structure 65318bb98f33SShivanshu Shukla * @remove_entry: data struct which holds rule_id, VSI handle and recipe ID 65328bb98f33SShivanshu Shukla * 65338bb98f33SShivanshu Shukla * This function is used to remove 1 rule at a time. The removal is based on 65348bb98f33SShivanshu Shukla * the remove_entry parameter. This function will remove rule for a given 65358bb98f33SShivanshu Shukla * vsi_handle with a given rule_id which is passed as parameter in remove_entry 65368bb98f33SShivanshu Shukla */ 65375e24d598STony Nguyen int 65388bb98f33SShivanshu Shukla ice_rem_adv_rule_by_id(struct ice_hw *hw, 65398bb98f33SShivanshu Shukla struct ice_rule_query_data *remove_entry) 65408bb98f33SShivanshu Shukla { 65418bb98f33SShivanshu Shukla struct ice_adv_fltr_mgmt_list_entry *list_itr; 65428bb98f33SShivanshu Shukla struct list_head *list_head; 65438bb98f33SShivanshu Shukla struct ice_adv_rule_info rinfo; 65448bb98f33SShivanshu Shukla struct ice_switch_info *sw; 65458bb98f33SShivanshu Shukla 65468bb98f33SShivanshu Shukla sw = hw->switch_info; 65478bb98f33SShivanshu Shukla if (!sw->recp_list[remove_entry->rid].recp_created) 6548d54699e2STony Nguyen return -EINVAL; 65498bb98f33SShivanshu Shukla list_head = &sw->recp_list[remove_entry->rid].filt_rules; 65508bb98f33SShivanshu Shukla list_for_each_entry(list_itr, list_head, list_entry) { 65518bb98f33SShivanshu Shukla if (list_itr->rule_info.fltr_rule_id == 65528bb98f33SShivanshu Shukla remove_entry->rule_id) { 65538bb98f33SShivanshu Shukla rinfo = list_itr->rule_info; 65548bb98f33SShivanshu Shukla rinfo.sw_act.vsi_handle = remove_entry->vsi_handle; 65558bb98f33SShivanshu Shukla return ice_rem_adv_rule(hw, list_itr->lkups, 65568bb98f33SShivanshu Shukla list_itr->lkups_cnt, &rinfo); 65578bb98f33SShivanshu Shukla } 65588bb98f33SShivanshu Shukla } 65598bb98f33SShivanshu Shukla /* either list is empty or unable to find rule */ 6560d54699e2STony Nguyen return -ENOENT; 65618bb98f33SShivanshu Shukla } 65628bb98f33SShivanshu Shukla 65638bb98f33SShivanshu Shukla /** 6564c36a2b97SVictor Raj * ice_replay_vsi_adv_rule - Replay advanced rule for requested VSI 6565c36a2b97SVictor Raj * @hw: pointer to the hardware structure 6566c36a2b97SVictor Raj * @vsi_handle: driver VSI handle 6567c36a2b97SVictor Raj * @list_head: list for which filters need to be replayed 6568c36a2b97SVictor Raj * 6569c36a2b97SVictor Raj * Replay the advanced rule for the given VSI. 6570c36a2b97SVictor Raj */ 6571c36a2b97SVictor Raj static int 6572c36a2b97SVictor Raj ice_replay_vsi_adv_rule(struct ice_hw *hw, u16 vsi_handle, 6573c36a2b97SVictor Raj struct list_head *list_head) 6574c36a2b97SVictor Raj { 6575c36a2b97SVictor Raj struct ice_rule_query_data added_entry = { 0 }; 6576c36a2b97SVictor Raj struct ice_adv_fltr_mgmt_list_entry *adv_fltr; 6577c36a2b97SVictor Raj int status = 0; 6578c36a2b97SVictor Raj 6579c36a2b97SVictor Raj if (list_empty(list_head)) 6580c36a2b97SVictor Raj return status; 6581c36a2b97SVictor Raj list_for_each_entry(adv_fltr, list_head, list_entry) { 6582c36a2b97SVictor Raj struct ice_adv_rule_info *rinfo = &adv_fltr->rule_info; 6583c36a2b97SVictor Raj u16 lk_cnt = adv_fltr->lkups_cnt; 6584c36a2b97SVictor Raj 6585c36a2b97SVictor Raj if (vsi_handle != rinfo->sw_act.vsi_handle) 6586c36a2b97SVictor Raj continue; 6587c36a2b97SVictor Raj status = ice_add_adv_rule(hw, adv_fltr->lkups, lk_cnt, rinfo, 6588c36a2b97SVictor Raj &added_entry); 6589c36a2b97SVictor Raj if (status) 6590c36a2b97SVictor Raj break; 6591c36a2b97SVictor Raj } 6592c36a2b97SVictor Raj return status; 6593c36a2b97SVictor Raj } 6594c36a2b97SVictor Raj 6595c36a2b97SVictor Raj /** 6596334cb062SAnirudh Venkataramanan * ice_replay_vsi_all_fltr - replay all filters stored in bookkeeping lists 65970f9d5027SAnirudh Venkataramanan * @hw: pointer to the hardware structure 6598334cb062SAnirudh Venkataramanan * @vsi_handle: driver VSI handle 65990f9d5027SAnirudh Venkataramanan * 6600334cb062SAnirudh Venkataramanan * Replays filters for requested VSI via vsi_handle. 66010f9d5027SAnirudh Venkataramanan */ 66025e24d598STony Nguyen int ice_replay_vsi_all_fltr(struct ice_hw *hw, u16 vsi_handle) 66030f9d5027SAnirudh Venkataramanan { 66040f9d5027SAnirudh Venkataramanan struct ice_switch_info *sw = hw->switch_info; 6605c36a2b97SVictor Raj int status; 66060f9d5027SAnirudh Venkataramanan u8 i; 66070f9d5027SAnirudh Venkataramanan 6608c36a2b97SVictor Raj for (i = 0; i < ICE_MAX_NUM_RECIPES; i++) { 6609334cb062SAnirudh Venkataramanan struct list_head *head; 66100f9d5027SAnirudh Venkataramanan 6611334cb062SAnirudh Venkataramanan head = &sw->recp_list[i].filt_replay_rules; 6612c36a2b97SVictor Raj if (!sw->recp_list[i].adv_rule) 6613334cb062SAnirudh Venkataramanan status = ice_replay_vsi_fltr(hw, vsi_handle, i, head); 6614c36a2b97SVictor Raj else 6615c36a2b97SVictor Raj status = ice_replay_vsi_adv_rule(hw, vsi_handle, head); 66160f9d5027SAnirudh Venkataramanan if (status) 66170f9d5027SAnirudh Venkataramanan return status; 66180f9d5027SAnirudh Venkataramanan } 66190f9d5027SAnirudh Venkataramanan return status; 66200f9d5027SAnirudh Venkataramanan } 6621334cb062SAnirudh Venkataramanan 6622334cb062SAnirudh Venkataramanan /** 6623334cb062SAnirudh Venkataramanan * ice_rm_all_sw_replay_rule_info - deletes filter replay rules 6624f9867df6SAnirudh Venkataramanan * @hw: pointer to the HW struct 6625334cb062SAnirudh Venkataramanan * 6626334cb062SAnirudh Venkataramanan * Deletes the filter replay rules. 6627334cb062SAnirudh Venkataramanan */ 6628334cb062SAnirudh Venkataramanan void ice_rm_all_sw_replay_rule_info(struct ice_hw *hw) 6629334cb062SAnirudh Venkataramanan { 6630334cb062SAnirudh Venkataramanan struct ice_switch_info *sw = hw->switch_info; 6631334cb062SAnirudh Venkataramanan u8 i; 6632334cb062SAnirudh Venkataramanan 6633334cb062SAnirudh Venkataramanan if (!sw) 6634334cb062SAnirudh Venkataramanan return; 6635334cb062SAnirudh Venkataramanan 66368b8ef05bSVictor Raj for (i = 0; i < ICE_MAX_NUM_RECIPES; i++) { 6637334cb062SAnirudh Venkataramanan if (!list_empty(&sw->recp_list[i].filt_replay_rules)) { 6638334cb062SAnirudh Venkataramanan struct list_head *l_head; 6639334cb062SAnirudh Venkataramanan 6640334cb062SAnirudh Venkataramanan l_head = &sw->recp_list[i].filt_replay_rules; 66418b8ef05bSVictor Raj if (!sw->recp_list[i].adv_rule) 6642334cb062SAnirudh Venkataramanan ice_rem_sw_rule_info(hw, l_head); 66438b8ef05bSVictor Raj else 66448b8ef05bSVictor Raj ice_rem_adv_rule_info(hw, l_head); 6645334cb062SAnirudh Venkataramanan } 6646334cb062SAnirudh Venkataramanan } 6647334cb062SAnirudh Venkataramanan } 6648