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 18509daf8208SAnirudh Venkataramanan status = ice_aq_alloc_free_res(hw, 1, sw_buf, buf_len, opc, NULL); 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); 21047715ec32SGrishma Kotecha status = ice_aq_alloc_free_res(hw, 1, sw_buf, buf_len, 21057715ec32SGrishma Kotecha ice_aqc_opc_alloc_res, NULL); 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 /** 2463*ec5a6c5fSDave Ertman * ice_fill_eth_hdr - helper to copy dummy_eth_hdr into supplied buffer 2464*ec5a6c5fSDave Ertman * @eth_hdr: pointer to buffer to populate 2465*ec5a6c5fSDave Ertman */ 2466*ec5a6c5fSDave Ertman void ice_fill_eth_hdr(u8 *eth_hdr) 2467*ec5a6c5fSDave Ertman { 2468*ec5a6c5fSDave Ertman memcpy(eth_hdr, dummy_eth_header, DUMMY_ETH_HDR_LEN); 2469*ec5a6c5fSDave Ertman } 2470*ec5a6c5fSDave Ertman 2471*ec5a6c5fSDave 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_mac_fltr_exist - does this MAC filter exist for given VSI 34139fea7498SKiran Patil * @hw: pointer to the hardware structure 34149fea7498SKiran Patil * @mac: MAC address to be checked (for MAC filter) 34159fea7498SKiran Patil * @vsi_handle: check MAC filter for this VSI 34169fea7498SKiran Patil */ 34179fea7498SKiran Patil bool ice_mac_fltr_exist(struct ice_hw *hw, u8 *mac, 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 (!ice_is_vsi_valid(hw, vsi_handle)) 34269fea7498SKiran Patil return false; 34279fea7498SKiran Patil 34289fea7498SKiran Patil hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle); 34299fea7498SKiran Patil sw = hw->switch_info; 34309fea7498SKiran Patil rule_head = &sw->recp_list[ICE_SW_LKUP_MAC].filt_rules; 34319fea7498SKiran Patil if (!rule_head) 34329fea7498SKiran Patil return false; 34339fea7498SKiran Patil 34349fea7498SKiran Patil rule_lock = &sw->recp_list[ICE_SW_LKUP_MAC].filt_rule_lock; 34359fea7498SKiran Patil mutex_lock(rule_lock); 34369fea7498SKiran Patil list_for_each_entry(entry, rule_head, list_entry) { 34379fea7498SKiran Patil struct ice_fltr_info *f_info = &entry->fltr_info; 34389fea7498SKiran Patil u8 *mac_addr = &f_info->l_data.mac.mac_addr[0]; 34399fea7498SKiran Patil 34409fea7498SKiran Patil if (is_zero_ether_addr(mac_addr)) 34419fea7498SKiran Patil continue; 34429fea7498SKiran Patil 34439fea7498SKiran Patil if (f_info->flag != ICE_FLTR_TX || 34449fea7498SKiran Patil f_info->src_id != ICE_SRC_ID_VSI || 34459fea7498SKiran Patil f_info->lkup_type != ICE_SW_LKUP_MAC || 34469fea7498SKiran Patil f_info->fltr_act != ICE_FWD_TO_VSI || 34479fea7498SKiran Patil hw_vsi_id != f_info->fwd_id.hw_vsi_id) 34489fea7498SKiran Patil continue; 34499fea7498SKiran Patil 34509fea7498SKiran Patil if (ether_addr_equal(mac, mac_addr)) { 34519fea7498SKiran Patil mutex_unlock(rule_lock); 34529fea7498SKiran Patil return true; 34539fea7498SKiran Patil } 34549fea7498SKiran Patil } 34559fea7498SKiran Patil mutex_unlock(rule_lock); 34569fea7498SKiran Patil return false; 34579fea7498SKiran Patil } 34589fea7498SKiran Patil 34599fea7498SKiran Patil /** 34609fea7498SKiran Patil * ice_vlan_fltr_exist - does this VLAN filter exist for given VSI 34619fea7498SKiran Patil * @hw: pointer to the hardware structure 34629fea7498SKiran Patil * @vlan_id: VLAN ID 34639fea7498SKiran Patil * @vsi_handle: check MAC filter for this VSI 34649fea7498SKiran Patil */ 34659fea7498SKiran Patil bool ice_vlan_fltr_exist(struct ice_hw *hw, u16 vlan_id, u16 vsi_handle) 34669fea7498SKiran Patil { 34679fea7498SKiran Patil struct ice_fltr_mgmt_list_entry *entry; 34689fea7498SKiran Patil struct list_head *rule_head; 34699fea7498SKiran Patil struct ice_switch_info *sw; 34709fea7498SKiran Patil struct mutex *rule_lock; /* Lock to protect filter rule list */ 34719fea7498SKiran Patil u16 hw_vsi_id; 34729fea7498SKiran Patil 34739fea7498SKiran Patil if (vlan_id > ICE_MAX_VLAN_ID) 34749fea7498SKiran Patil return false; 34759fea7498SKiran Patil 34769fea7498SKiran Patil if (!ice_is_vsi_valid(hw, vsi_handle)) 34779fea7498SKiran Patil return false; 34789fea7498SKiran Patil 34799fea7498SKiran Patil hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle); 34809fea7498SKiran Patil sw = hw->switch_info; 34819fea7498SKiran Patil rule_head = &sw->recp_list[ICE_SW_LKUP_VLAN].filt_rules; 34829fea7498SKiran Patil if (!rule_head) 34839fea7498SKiran Patil return false; 34849fea7498SKiran Patil 34859fea7498SKiran Patil rule_lock = &sw->recp_list[ICE_SW_LKUP_VLAN].filt_rule_lock; 34869fea7498SKiran Patil mutex_lock(rule_lock); 34879fea7498SKiran Patil list_for_each_entry(entry, rule_head, list_entry) { 34889fea7498SKiran Patil struct ice_fltr_info *f_info = &entry->fltr_info; 34899fea7498SKiran Patil u16 entry_vlan_id = f_info->l_data.vlan.vlan_id; 34909fea7498SKiran Patil struct ice_vsi_list_map_info *map_info; 34919fea7498SKiran Patil 34929fea7498SKiran Patil if (entry_vlan_id > ICE_MAX_VLAN_ID) 34939fea7498SKiran Patil continue; 34949fea7498SKiran Patil 34959fea7498SKiran Patil if (f_info->flag != ICE_FLTR_TX || 34969fea7498SKiran Patil f_info->src_id != ICE_SRC_ID_VSI || 34979fea7498SKiran Patil f_info->lkup_type != ICE_SW_LKUP_VLAN) 34989fea7498SKiran Patil continue; 34999fea7498SKiran Patil 35009fea7498SKiran Patil /* Only allowed filter action are FWD_TO_VSI/_VSI_LIST */ 35019fea7498SKiran Patil if (f_info->fltr_act != ICE_FWD_TO_VSI && 35029fea7498SKiran Patil f_info->fltr_act != ICE_FWD_TO_VSI_LIST) 35039fea7498SKiran Patil continue; 35049fea7498SKiran Patil 35059fea7498SKiran Patil if (f_info->fltr_act == ICE_FWD_TO_VSI) { 35069fea7498SKiran Patil if (hw_vsi_id != f_info->fwd_id.hw_vsi_id) 35079fea7498SKiran Patil continue; 35089fea7498SKiran Patil } else if (f_info->fltr_act == ICE_FWD_TO_VSI_LIST) { 35099fea7498SKiran Patil /* If filter_action is FWD_TO_VSI_LIST, make sure 35109fea7498SKiran Patil * that VSI being checked is part of VSI list 35119fea7498SKiran Patil */ 35129fea7498SKiran Patil if (entry->vsi_count == 1 && 35139fea7498SKiran Patil entry->vsi_list_info) { 35149fea7498SKiran Patil map_info = entry->vsi_list_info; 35159fea7498SKiran Patil if (!test_bit(vsi_handle, map_info->vsi_map)) 35169fea7498SKiran Patil continue; 35179fea7498SKiran Patil } 35189fea7498SKiran Patil } 35199fea7498SKiran Patil 35209fea7498SKiran Patil if (vlan_id == entry_vlan_id) { 35219fea7498SKiran Patil mutex_unlock(rule_lock); 35229fea7498SKiran Patil return true; 35239fea7498SKiran Patil } 35249fea7498SKiran Patil } 35259fea7498SKiran Patil mutex_unlock(rule_lock); 35269fea7498SKiran Patil 35279fea7498SKiran Patil return false; 35289fea7498SKiran Patil } 35299fea7498SKiran Patil 35309fea7498SKiran Patil /** 35319daf8208SAnirudh Venkataramanan * ice_add_mac - Add a MAC address based filter rule 35329daf8208SAnirudh Venkataramanan * @hw: pointer to the hardware structure 35339daf8208SAnirudh Venkataramanan * @m_list: list of MAC addresses and forwarding information 35349daf8208SAnirudh Venkataramanan */ 35355e24d598STony Nguyen int ice_add_mac(struct ice_hw *hw, struct list_head *m_list) 35369daf8208SAnirudh Venkataramanan { 35379daf8208SAnirudh Venkataramanan struct ice_fltr_list_entry *m_list_itr; 35385518ac2aSTony Nguyen int status = 0; 35399daf8208SAnirudh Venkataramanan 35409daf8208SAnirudh Venkataramanan if (!m_list || !hw) 3541d54699e2STony Nguyen return -EINVAL; 35429daf8208SAnirudh Venkataramanan 35439daf8208SAnirudh Venkataramanan list_for_each_entry(m_list_itr, m_list, list_entry) { 35449daf8208SAnirudh Venkataramanan u8 *add = &m_list_itr->fltr_info.l_data.mac.mac_addr[0]; 35455726ca0eSAnirudh Venkataramanan u16 vsi_handle; 35465726ca0eSAnirudh Venkataramanan u16 hw_vsi_id; 35479daf8208SAnirudh Venkataramanan 354880d144c9SAnirudh Venkataramanan m_list_itr->fltr_info.flag = ICE_FLTR_TX; 35495726ca0eSAnirudh Venkataramanan vsi_handle = m_list_itr->fltr_info.vsi_handle; 35505726ca0eSAnirudh Venkataramanan if (!ice_is_vsi_valid(hw, vsi_handle)) 3551d54699e2STony Nguyen return -EINVAL; 35525726ca0eSAnirudh Venkataramanan hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle); 35535726ca0eSAnirudh Venkataramanan m_list_itr->fltr_info.fwd_id.hw_vsi_id = hw_vsi_id; 3554f9867df6SAnirudh Venkataramanan /* update the src in case it is VSI num */ 35555726ca0eSAnirudh Venkataramanan if (m_list_itr->fltr_info.src_id != ICE_SRC_ID_VSI) 3556d54699e2STony Nguyen return -EINVAL; 35575726ca0eSAnirudh Venkataramanan m_list_itr->fltr_info.src = hw_vsi_id; 355880d144c9SAnirudh Venkataramanan if (m_list_itr->fltr_info.lkup_type != ICE_SW_LKUP_MAC || 355980d144c9SAnirudh Venkataramanan is_zero_ether_addr(add)) 3560d54699e2STony Nguyen return -EINVAL; 3561e1e9db57SSylwester Dziedziuch 3562e1e9db57SSylwester Dziedziuch m_list_itr->status = ice_add_rule_internal(hw, ICE_SW_LKUP_MAC, 356380d144c9SAnirudh Venkataramanan m_list_itr); 356480d144c9SAnirudh Venkataramanan if (m_list_itr->status) 356580d144c9SAnirudh Venkataramanan return m_list_itr->status; 35669daf8208SAnirudh Venkataramanan } 35679daf8208SAnirudh Venkataramanan 35689daf8208SAnirudh Venkataramanan return status; 35699daf8208SAnirudh Venkataramanan } 35709daf8208SAnirudh Venkataramanan 35719daf8208SAnirudh Venkataramanan /** 3572d76a60baSAnirudh Venkataramanan * ice_add_vlan_internal - Add one VLAN based filter rule 3573d76a60baSAnirudh Venkataramanan * @hw: pointer to the hardware structure 3574d76a60baSAnirudh Venkataramanan * @f_entry: filter entry containing one VLAN information 3575d76a60baSAnirudh Venkataramanan */ 35765e24d598STony Nguyen static int 3577d76a60baSAnirudh Venkataramanan ice_add_vlan_internal(struct ice_hw *hw, struct ice_fltr_list_entry *f_entry) 3578d76a60baSAnirudh Venkataramanan { 357980d144c9SAnirudh Venkataramanan struct ice_switch_info *sw = hw->switch_info; 3580d76a60baSAnirudh Venkataramanan struct ice_fltr_mgmt_list_entry *v_list_itr; 35815726ca0eSAnirudh Venkataramanan struct ice_fltr_info *new_fltr, *cur_fltr; 35825726ca0eSAnirudh Venkataramanan enum ice_sw_lkup_type lkup_type; 35835726ca0eSAnirudh Venkataramanan u16 vsi_list_id = 0, vsi_handle; 358480d144c9SAnirudh Venkataramanan struct mutex *rule_lock; /* Lock to protect filter rule list */ 35855e24d598STony Nguyen int status = 0; 3586d76a60baSAnirudh Venkataramanan 35875726ca0eSAnirudh Venkataramanan if (!ice_is_vsi_valid(hw, f_entry->fltr_info.vsi_handle)) 3588d54699e2STony Nguyen return -EINVAL; 35895726ca0eSAnirudh Venkataramanan 35905726ca0eSAnirudh Venkataramanan f_entry->fltr_info.fwd_id.hw_vsi_id = 35915726ca0eSAnirudh Venkataramanan ice_get_hw_vsi_num(hw, f_entry->fltr_info.vsi_handle); 3592d76a60baSAnirudh Venkataramanan new_fltr = &f_entry->fltr_info; 35935726ca0eSAnirudh Venkataramanan 3594f9867df6SAnirudh Venkataramanan /* VLAN ID should only be 12 bits */ 3595d76a60baSAnirudh Venkataramanan if (new_fltr->l_data.vlan.vlan_id > ICE_MAX_VLAN_ID) 3596d54699e2STony Nguyen return -EINVAL; 3597d76a60baSAnirudh Venkataramanan 35985726ca0eSAnirudh Venkataramanan if (new_fltr->src_id != ICE_SRC_ID_VSI) 3599d54699e2STony Nguyen return -EINVAL; 36005726ca0eSAnirudh Venkataramanan 36015726ca0eSAnirudh Venkataramanan new_fltr->src = new_fltr->fwd_id.hw_vsi_id; 36025726ca0eSAnirudh Venkataramanan lkup_type = new_fltr->lkup_type; 36035726ca0eSAnirudh Venkataramanan vsi_handle = new_fltr->vsi_handle; 360480d144c9SAnirudh Venkataramanan rule_lock = &sw->recp_list[ICE_SW_LKUP_VLAN].filt_rule_lock; 360580d144c9SAnirudh Venkataramanan mutex_lock(rule_lock); 360680d144c9SAnirudh Venkataramanan v_list_itr = ice_find_rule_entry(hw, ICE_SW_LKUP_VLAN, new_fltr); 3607d76a60baSAnirudh Venkataramanan if (!v_list_itr) { 36085726ca0eSAnirudh Venkataramanan struct ice_vsi_list_map_info *map_info = NULL; 3609d76a60baSAnirudh Venkataramanan 3610d76a60baSAnirudh Venkataramanan if (new_fltr->fltr_act == ICE_FWD_TO_VSI) { 36115726ca0eSAnirudh Venkataramanan /* All VLAN pruning rules use a VSI list. Check if 36125726ca0eSAnirudh Venkataramanan * there is already a VSI list containing VSI that we 36135726ca0eSAnirudh Venkataramanan * want to add. If found, use the same vsi_list_id for 36145726ca0eSAnirudh Venkataramanan * this new VLAN rule or else create a new list. 3615d76a60baSAnirudh Venkataramanan */ 36165726ca0eSAnirudh Venkataramanan map_info = ice_find_vsi_list_entry(hw, ICE_SW_LKUP_VLAN, 36175726ca0eSAnirudh Venkataramanan vsi_handle, 36185726ca0eSAnirudh Venkataramanan &vsi_list_id); 36195726ca0eSAnirudh Venkataramanan if (!map_info) { 36205726ca0eSAnirudh Venkataramanan status = ice_create_vsi_list_rule(hw, 36215726ca0eSAnirudh Venkataramanan &vsi_handle, 36225726ca0eSAnirudh Venkataramanan 1, 3623d76a60baSAnirudh Venkataramanan &vsi_list_id, 3624d76a60baSAnirudh Venkataramanan lkup_type); 3625d76a60baSAnirudh Venkataramanan if (status) 362680d144c9SAnirudh Venkataramanan goto exit; 36275726ca0eSAnirudh Venkataramanan } 36285726ca0eSAnirudh Venkataramanan /* Convert the action to forwarding to a VSI list. */ 3629d76a60baSAnirudh Venkataramanan new_fltr->fltr_act = ICE_FWD_TO_VSI_LIST; 3630d76a60baSAnirudh Venkataramanan new_fltr->fwd_id.vsi_list_id = vsi_list_id; 3631d76a60baSAnirudh Venkataramanan } 3632d76a60baSAnirudh Venkataramanan 3633d76a60baSAnirudh Venkataramanan status = ice_create_pkt_fwd_rule(hw, f_entry); 36345726ca0eSAnirudh Venkataramanan if (!status) { 363580d144c9SAnirudh Venkataramanan v_list_itr = ice_find_rule_entry(hw, ICE_SW_LKUP_VLAN, 363680d144c9SAnirudh Venkataramanan new_fltr); 363780d144c9SAnirudh Venkataramanan if (!v_list_itr) { 3638d54699e2STony Nguyen status = -ENOENT; 363980d144c9SAnirudh Venkataramanan goto exit; 364080d144c9SAnirudh Venkataramanan } 36415726ca0eSAnirudh Venkataramanan /* reuse VSI list for new rule and increment ref_cnt */ 36425726ca0eSAnirudh Venkataramanan if (map_info) { 36435726ca0eSAnirudh Venkataramanan v_list_itr->vsi_list_info = map_info; 36445726ca0eSAnirudh Venkataramanan map_info->ref_cnt++; 36455726ca0eSAnirudh Venkataramanan } else { 3646d76a60baSAnirudh Venkataramanan v_list_itr->vsi_list_info = 36475726ca0eSAnirudh Venkataramanan ice_create_vsi_list_map(hw, &vsi_handle, 36485726ca0eSAnirudh Venkataramanan 1, vsi_list_id); 3649d76a60baSAnirudh Venkataramanan } 36505726ca0eSAnirudh Venkataramanan } 36515726ca0eSAnirudh Venkataramanan } else if (v_list_itr->vsi_list_info->ref_cnt == 1) { 3652f9867df6SAnirudh Venkataramanan /* Update existing VSI list to add new VSI ID only if it used 36535726ca0eSAnirudh Venkataramanan * by one VLAN rule. 36545726ca0eSAnirudh Venkataramanan */ 36555726ca0eSAnirudh Venkataramanan cur_fltr = &v_list_itr->fltr_info; 36565726ca0eSAnirudh Venkataramanan status = ice_add_update_vsi_list(hw, v_list_itr, cur_fltr, 36575726ca0eSAnirudh Venkataramanan new_fltr); 36585726ca0eSAnirudh Venkataramanan } else { 36595726ca0eSAnirudh Venkataramanan /* If VLAN rule exists and VSI list being used by this rule is 36605726ca0eSAnirudh Venkataramanan * referenced by more than 1 VLAN rule. Then create a new VSI 36615726ca0eSAnirudh Venkataramanan * list appending previous VSI with new VSI and update existing 3662f9867df6SAnirudh Venkataramanan * VLAN rule to point to new VSI list ID 36635726ca0eSAnirudh Venkataramanan */ 36645726ca0eSAnirudh Venkataramanan struct ice_fltr_info tmp_fltr; 36655726ca0eSAnirudh Venkataramanan u16 vsi_handle_arr[2]; 36665726ca0eSAnirudh Venkataramanan u16 cur_handle; 3667d76a60baSAnirudh Venkataramanan 36685726ca0eSAnirudh Venkataramanan /* Current implementation only supports reusing VSI list with 36695726ca0eSAnirudh Venkataramanan * one VSI count. We should never hit below condition 36705726ca0eSAnirudh Venkataramanan */ 36715726ca0eSAnirudh Venkataramanan if (v_list_itr->vsi_count > 1 && 36725726ca0eSAnirudh Venkataramanan v_list_itr->vsi_list_info->ref_cnt > 1) { 36739228d8b2SJacob 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"); 3674d54699e2STony Nguyen status = -EIO; 367580d144c9SAnirudh Venkataramanan goto exit; 3676d76a60baSAnirudh Venkataramanan } 3677d76a60baSAnirudh Venkataramanan 36785726ca0eSAnirudh Venkataramanan cur_handle = 36795726ca0eSAnirudh Venkataramanan find_first_bit(v_list_itr->vsi_list_info->vsi_map, 36805726ca0eSAnirudh Venkataramanan ICE_MAX_VSI); 36815726ca0eSAnirudh Venkataramanan 36825726ca0eSAnirudh Venkataramanan /* A rule already exists with the new VSI being added */ 36835726ca0eSAnirudh Venkataramanan if (cur_handle == vsi_handle) { 3684d54699e2STony Nguyen status = -EEXIST; 36855726ca0eSAnirudh Venkataramanan goto exit; 36865726ca0eSAnirudh Venkataramanan } 36875726ca0eSAnirudh Venkataramanan 36885726ca0eSAnirudh Venkataramanan vsi_handle_arr[0] = cur_handle; 36895726ca0eSAnirudh Venkataramanan vsi_handle_arr[1] = vsi_handle; 36905726ca0eSAnirudh Venkataramanan status = ice_create_vsi_list_rule(hw, &vsi_handle_arr[0], 2, 36915726ca0eSAnirudh Venkataramanan &vsi_list_id, lkup_type); 36925726ca0eSAnirudh Venkataramanan if (status) 36935726ca0eSAnirudh Venkataramanan goto exit; 36945726ca0eSAnirudh Venkataramanan 36955726ca0eSAnirudh Venkataramanan tmp_fltr = v_list_itr->fltr_info; 36965726ca0eSAnirudh Venkataramanan tmp_fltr.fltr_rule_id = v_list_itr->fltr_info.fltr_rule_id; 36975726ca0eSAnirudh Venkataramanan tmp_fltr.fwd_id.vsi_list_id = vsi_list_id; 36985726ca0eSAnirudh Venkataramanan tmp_fltr.fltr_act = ICE_FWD_TO_VSI_LIST; 36995726ca0eSAnirudh Venkataramanan /* Update the previous switch rule to a new VSI list which 3700df17b7e0SAnirudh Venkataramanan * includes current VSI that is requested 37015726ca0eSAnirudh Venkataramanan */ 37025726ca0eSAnirudh Venkataramanan status = ice_update_pkt_fwd_rule(hw, &tmp_fltr); 37035726ca0eSAnirudh Venkataramanan if (status) 37045726ca0eSAnirudh Venkataramanan goto exit; 37055726ca0eSAnirudh Venkataramanan 37065726ca0eSAnirudh Venkataramanan /* before overriding VSI list map info. decrement ref_cnt of 37075726ca0eSAnirudh Venkataramanan * previous VSI list 37085726ca0eSAnirudh Venkataramanan */ 37095726ca0eSAnirudh Venkataramanan v_list_itr->vsi_list_info->ref_cnt--; 37105726ca0eSAnirudh Venkataramanan 37115726ca0eSAnirudh Venkataramanan /* now update to newly created list */ 37125726ca0eSAnirudh Venkataramanan v_list_itr->fltr_info.fwd_id.vsi_list_id = vsi_list_id; 37135726ca0eSAnirudh Venkataramanan v_list_itr->vsi_list_info = 37145726ca0eSAnirudh Venkataramanan ice_create_vsi_list_map(hw, &vsi_handle_arr[0], 2, 37155726ca0eSAnirudh Venkataramanan vsi_list_id); 37165726ca0eSAnirudh Venkataramanan v_list_itr->vsi_count++; 37175726ca0eSAnirudh Venkataramanan } 371880d144c9SAnirudh Venkataramanan 371980d144c9SAnirudh Venkataramanan exit: 372080d144c9SAnirudh Venkataramanan mutex_unlock(rule_lock); 372180d144c9SAnirudh Venkataramanan return status; 3722d76a60baSAnirudh Venkataramanan } 3723d76a60baSAnirudh Venkataramanan 3724d76a60baSAnirudh Venkataramanan /** 3725d76a60baSAnirudh Venkataramanan * ice_add_vlan - Add VLAN based filter rule 3726d76a60baSAnirudh Venkataramanan * @hw: pointer to the hardware structure 3727d76a60baSAnirudh Venkataramanan * @v_list: list of VLAN entries and forwarding information 3728d76a60baSAnirudh Venkataramanan */ 37295e24d598STony Nguyen int ice_add_vlan(struct ice_hw *hw, struct list_head *v_list) 3730d76a60baSAnirudh Venkataramanan { 3731d76a60baSAnirudh Venkataramanan struct ice_fltr_list_entry *v_list_itr; 3732d76a60baSAnirudh Venkataramanan 3733d76a60baSAnirudh Venkataramanan if (!v_list || !hw) 3734d54699e2STony Nguyen return -EINVAL; 3735d76a60baSAnirudh Venkataramanan 3736d76a60baSAnirudh Venkataramanan list_for_each_entry(v_list_itr, v_list, list_entry) { 3737d76a60baSAnirudh Venkataramanan if (v_list_itr->fltr_info.lkup_type != ICE_SW_LKUP_VLAN) 3738d54699e2STony Nguyen return -EINVAL; 373980d144c9SAnirudh Venkataramanan v_list_itr->fltr_info.flag = ICE_FLTR_TX; 374080d144c9SAnirudh Venkataramanan v_list_itr->status = ice_add_vlan_internal(hw, v_list_itr); 374180d144c9SAnirudh Venkataramanan if (v_list_itr->status) 374280d144c9SAnirudh Venkataramanan return v_list_itr->status; 3743d76a60baSAnirudh Venkataramanan } 3744d76a60baSAnirudh Venkataramanan return 0; 3745d76a60baSAnirudh Venkataramanan } 3746d76a60baSAnirudh Venkataramanan 3747d76a60baSAnirudh Venkataramanan /** 3748d95276ceSAkeem G Abodunrin * ice_add_eth_mac - Add ethertype and MAC based filter rule 3749d95276ceSAkeem G Abodunrin * @hw: pointer to the hardware structure 3750d95276ceSAkeem G Abodunrin * @em_list: list of ether type MAC filter, MAC is optional 37512e0e6228SDave Ertman * 37522e0e6228SDave Ertman * This function requires the caller to populate the entries in 37532e0e6228SDave Ertman * the filter list with the necessary fields (including flags to 37542e0e6228SDave Ertman * indicate Tx or Rx rules). 3755d95276ceSAkeem G Abodunrin */ 37565518ac2aSTony Nguyen int ice_add_eth_mac(struct ice_hw *hw, struct list_head *em_list) 3757d95276ceSAkeem G Abodunrin { 3758d95276ceSAkeem G Abodunrin struct ice_fltr_list_entry *em_list_itr; 3759d95276ceSAkeem G Abodunrin 3760d95276ceSAkeem G Abodunrin if (!em_list || !hw) 3761d54699e2STony Nguyen return -EINVAL; 3762d95276ceSAkeem G Abodunrin 3763d95276ceSAkeem G Abodunrin list_for_each_entry(em_list_itr, em_list, list_entry) { 3764d95276ceSAkeem G Abodunrin enum ice_sw_lkup_type l_type = 3765d95276ceSAkeem G Abodunrin em_list_itr->fltr_info.lkup_type; 3766d95276ceSAkeem G Abodunrin 3767d95276ceSAkeem G Abodunrin if (l_type != ICE_SW_LKUP_ETHERTYPE_MAC && 3768d95276ceSAkeem G Abodunrin l_type != ICE_SW_LKUP_ETHERTYPE) 3769d54699e2STony Nguyen return -EINVAL; 3770d95276ceSAkeem G Abodunrin 3771d95276ceSAkeem G Abodunrin em_list_itr->status = ice_add_rule_internal(hw, l_type, 3772d95276ceSAkeem G Abodunrin em_list_itr); 3773d95276ceSAkeem G Abodunrin if (em_list_itr->status) 3774d95276ceSAkeem G Abodunrin return em_list_itr->status; 3775d95276ceSAkeem G Abodunrin } 3776d95276ceSAkeem G Abodunrin return 0; 3777d95276ceSAkeem G Abodunrin } 3778d95276ceSAkeem G Abodunrin 3779d95276ceSAkeem G Abodunrin /** 3780d95276ceSAkeem G Abodunrin * ice_remove_eth_mac - Remove an ethertype (or MAC) based filter rule 3781d95276ceSAkeem G Abodunrin * @hw: pointer to the hardware structure 3782d95276ceSAkeem G Abodunrin * @em_list: list of ethertype or ethertype MAC entries 3783d95276ceSAkeem G Abodunrin */ 37845518ac2aSTony Nguyen int ice_remove_eth_mac(struct ice_hw *hw, struct list_head *em_list) 3785d95276ceSAkeem G Abodunrin { 3786d95276ceSAkeem G Abodunrin struct ice_fltr_list_entry *em_list_itr, *tmp; 3787d95276ceSAkeem G Abodunrin 3788d95276ceSAkeem G Abodunrin if (!em_list || !hw) 3789d54699e2STony Nguyen return -EINVAL; 3790d95276ceSAkeem G Abodunrin 3791d95276ceSAkeem G Abodunrin list_for_each_entry_safe(em_list_itr, tmp, em_list, list_entry) { 3792d95276ceSAkeem G Abodunrin enum ice_sw_lkup_type l_type = 3793d95276ceSAkeem G Abodunrin em_list_itr->fltr_info.lkup_type; 3794d95276ceSAkeem G Abodunrin 3795d95276ceSAkeem G Abodunrin if (l_type != ICE_SW_LKUP_ETHERTYPE_MAC && 3796d95276ceSAkeem G Abodunrin l_type != ICE_SW_LKUP_ETHERTYPE) 3797d54699e2STony Nguyen return -EINVAL; 3798d95276ceSAkeem G Abodunrin 3799d95276ceSAkeem G Abodunrin em_list_itr->status = ice_remove_rule_internal(hw, l_type, 3800d95276ceSAkeem G Abodunrin em_list_itr); 3801d95276ceSAkeem G Abodunrin if (em_list_itr->status) 3802d95276ceSAkeem G Abodunrin return em_list_itr->status; 3803d95276ceSAkeem G Abodunrin } 3804d95276ceSAkeem G Abodunrin return 0; 3805d95276ceSAkeem G Abodunrin } 3806d95276ceSAkeem G Abodunrin 3807d95276ceSAkeem G Abodunrin /** 38080f9d5027SAnirudh Venkataramanan * ice_rem_sw_rule_info 38090f9d5027SAnirudh Venkataramanan * @hw: pointer to the hardware structure 38100f9d5027SAnirudh Venkataramanan * @rule_head: pointer to the switch list structure that we want to delete 38110f9d5027SAnirudh Venkataramanan */ 38120f9d5027SAnirudh Venkataramanan static void 38130f9d5027SAnirudh Venkataramanan ice_rem_sw_rule_info(struct ice_hw *hw, struct list_head *rule_head) 38140f9d5027SAnirudh Venkataramanan { 38150f9d5027SAnirudh Venkataramanan if (!list_empty(rule_head)) { 38160f9d5027SAnirudh Venkataramanan struct ice_fltr_mgmt_list_entry *entry; 38170f9d5027SAnirudh Venkataramanan struct ice_fltr_mgmt_list_entry *tmp; 38180f9d5027SAnirudh Venkataramanan 38190f9d5027SAnirudh Venkataramanan list_for_each_entry_safe(entry, tmp, rule_head, list_entry) { 38200f9d5027SAnirudh Venkataramanan list_del(&entry->list_entry); 38210f9d5027SAnirudh Venkataramanan devm_kfree(ice_hw_to_dev(hw), entry); 38220f9d5027SAnirudh Venkataramanan } 38230f9d5027SAnirudh Venkataramanan } 38240f9d5027SAnirudh Venkataramanan } 38250f9d5027SAnirudh Venkataramanan 38260f9d5027SAnirudh Venkataramanan /** 38278b8ef05bSVictor Raj * ice_rem_adv_rule_info 38288b8ef05bSVictor Raj * @hw: pointer to the hardware structure 38298b8ef05bSVictor Raj * @rule_head: pointer to the switch list structure that we want to delete 38308b8ef05bSVictor Raj */ 38318b8ef05bSVictor Raj static void 38328b8ef05bSVictor Raj ice_rem_adv_rule_info(struct ice_hw *hw, struct list_head *rule_head) 38338b8ef05bSVictor Raj { 38348b8ef05bSVictor Raj struct ice_adv_fltr_mgmt_list_entry *tmp_entry; 38358b8ef05bSVictor Raj struct ice_adv_fltr_mgmt_list_entry *lst_itr; 38368b8ef05bSVictor Raj 38378b8ef05bSVictor Raj if (list_empty(rule_head)) 38388b8ef05bSVictor Raj return; 38398b8ef05bSVictor Raj 38408b8ef05bSVictor Raj list_for_each_entry_safe(lst_itr, tmp_entry, rule_head, list_entry) { 38418b8ef05bSVictor Raj list_del(&lst_itr->list_entry); 38428b8ef05bSVictor Raj devm_kfree(ice_hw_to_dev(hw), lst_itr->lkups); 38438b8ef05bSVictor Raj devm_kfree(ice_hw_to_dev(hw), lst_itr); 38448b8ef05bSVictor Raj } 38458b8ef05bSVictor Raj } 38468b8ef05bSVictor Raj 38478b8ef05bSVictor Raj /** 384880d144c9SAnirudh Venkataramanan * ice_cfg_dflt_vsi - change state of VSI to set/clear default 3849d7393425SMichal Wilczynski * @pi: pointer to the port_info structure 38505726ca0eSAnirudh Venkataramanan * @vsi_handle: VSI handle to set as default 3851e94d4478SAnirudh Venkataramanan * @set: true to add the above mentioned switch rule, false to remove it 3852e94d4478SAnirudh Venkataramanan * @direction: ICE_FLTR_RX or ICE_FLTR_TX 385380d144c9SAnirudh Venkataramanan * 385480d144c9SAnirudh Venkataramanan * add filter rule to set/unset given VSI as default VSI for the switch 385580d144c9SAnirudh Venkataramanan * (represented by swid) 3856e94d4478SAnirudh Venkataramanan */ 3857d7393425SMichal Wilczynski int 3858d7393425SMichal Wilczynski ice_cfg_dflt_vsi(struct ice_port_info *pi, u16 vsi_handle, bool set, 3859d7393425SMichal Wilczynski u8 direction) 3860e94d4478SAnirudh Venkataramanan { 3861d7393425SMichal Wilczynski struct ice_fltr_list_entry f_list_entry; 3862e94d4478SAnirudh Venkataramanan struct ice_fltr_info f_info; 3863d7393425SMichal Wilczynski struct ice_hw *hw = pi->hw; 38645726ca0eSAnirudh Venkataramanan u16 hw_vsi_id; 38655518ac2aSTony Nguyen int status; 38665726ca0eSAnirudh Venkataramanan 38675726ca0eSAnirudh Venkataramanan if (!ice_is_vsi_valid(hw, vsi_handle)) 3868d54699e2STony Nguyen return -EINVAL; 3869d7393425SMichal Wilczynski 38705726ca0eSAnirudh Venkataramanan hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle); 3871e94d4478SAnirudh Venkataramanan 3872e94d4478SAnirudh Venkataramanan memset(&f_info, 0, sizeof(f_info)); 3873e94d4478SAnirudh Venkataramanan 3874e94d4478SAnirudh Venkataramanan f_info.lkup_type = ICE_SW_LKUP_DFLT; 3875e94d4478SAnirudh Venkataramanan f_info.flag = direction; 3876e94d4478SAnirudh Venkataramanan f_info.fltr_act = ICE_FWD_TO_VSI; 38775726ca0eSAnirudh Venkataramanan f_info.fwd_id.hw_vsi_id = hw_vsi_id; 3878d7393425SMichal Wilczynski f_info.vsi_handle = vsi_handle; 3879e94d4478SAnirudh Venkataramanan 3880e94d4478SAnirudh Venkataramanan if (f_info.flag & ICE_FLTR_RX) { 3881e94d4478SAnirudh Venkataramanan f_info.src = hw->port_info->lport; 38825726ca0eSAnirudh Venkataramanan f_info.src_id = ICE_SRC_ID_LPORT; 3883e94d4478SAnirudh Venkataramanan } else if (f_info.flag & ICE_FLTR_TX) { 38845726ca0eSAnirudh Venkataramanan f_info.src_id = ICE_SRC_ID_VSI; 38855726ca0eSAnirudh Venkataramanan f_info.src = hw_vsi_id; 3886e94d4478SAnirudh Venkataramanan } 3887d7393425SMichal Wilczynski f_list_entry.fltr_info = f_info; 3888e94d4478SAnirudh Venkataramanan 3889e94d4478SAnirudh Venkataramanan if (set) 3890d7393425SMichal Wilczynski status = ice_add_rule_internal(hw, ICE_SW_LKUP_DFLT, 3891d7393425SMichal Wilczynski &f_list_entry); 3892e94d4478SAnirudh Venkataramanan else 3893d7393425SMichal Wilczynski status = ice_remove_rule_internal(hw, ICE_SW_LKUP_DFLT, 3894d7393425SMichal Wilczynski &f_list_entry); 3895e94d4478SAnirudh Venkataramanan 3896e94d4478SAnirudh Venkataramanan return status; 3897e94d4478SAnirudh Venkataramanan } 3898e94d4478SAnirudh Venkataramanan 3899e94d4478SAnirudh Venkataramanan /** 3900d7393425SMichal Wilczynski * ice_vsi_uses_fltr - Determine if given VSI uses specified filter 3901d7393425SMichal Wilczynski * @fm_entry: filter entry to inspect 3902d7393425SMichal Wilczynski * @vsi_handle: VSI handle to compare with filter info 3903d7393425SMichal Wilczynski */ 3904d7393425SMichal Wilczynski static bool 3905d7393425SMichal Wilczynski ice_vsi_uses_fltr(struct ice_fltr_mgmt_list_entry *fm_entry, u16 vsi_handle) 3906d7393425SMichal Wilczynski { 3907d7393425SMichal Wilczynski return ((fm_entry->fltr_info.fltr_act == ICE_FWD_TO_VSI && 3908d7393425SMichal Wilczynski fm_entry->fltr_info.vsi_handle == vsi_handle) || 3909d7393425SMichal Wilczynski (fm_entry->fltr_info.fltr_act == ICE_FWD_TO_VSI_LIST && 3910d7393425SMichal Wilczynski fm_entry->vsi_list_info && 3911d7393425SMichal Wilczynski (test_bit(vsi_handle, fm_entry->vsi_list_info->vsi_map)))); 3912d7393425SMichal Wilczynski } 3913d7393425SMichal Wilczynski 3914d7393425SMichal Wilczynski /** 3915d7393425SMichal Wilczynski * ice_check_if_dflt_vsi - check if VSI is default VSI 3916d7393425SMichal Wilczynski * @pi: pointer to the port_info structure 3917d7393425SMichal Wilczynski * @vsi_handle: vsi handle to check for in filter list 3918d7393425SMichal Wilczynski * @rule_exists: indicates if there are any VSI's in the rule list 3919d7393425SMichal Wilczynski * 3920d7393425SMichal Wilczynski * checks if the VSI is in a default VSI list, and also indicates 3921d7393425SMichal Wilczynski * if the default VSI list is empty 3922d7393425SMichal Wilczynski */ 3923d7393425SMichal Wilczynski bool 3924d7393425SMichal Wilczynski ice_check_if_dflt_vsi(struct ice_port_info *pi, u16 vsi_handle, 3925d7393425SMichal Wilczynski bool *rule_exists) 3926d7393425SMichal Wilczynski { 3927d7393425SMichal Wilczynski struct ice_fltr_mgmt_list_entry *fm_entry; 3928d7393425SMichal Wilczynski struct ice_sw_recipe *recp_list; 3929d7393425SMichal Wilczynski struct list_head *rule_head; 3930d7393425SMichal Wilczynski struct mutex *rule_lock; /* Lock to protect filter rule list */ 3931d7393425SMichal Wilczynski bool ret = false; 3932d7393425SMichal Wilczynski 3933d7393425SMichal Wilczynski recp_list = &pi->hw->switch_info->recp_list[ICE_SW_LKUP_DFLT]; 3934d7393425SMichal Wilczynski rule_lock = &recp_list->filt_rule_lock; 3935d7393425SMichal Wilczynski rule_head = &recp_list->filt_rules; 3936d7393425SMichal Wilczynski 3937d7393425SMichal Wilczynski mutex_lock(rule_lock); 3938d7393425SMichal Wilczynski 3939d7393425SMichal Wilczynski if (rule_exists && !list_empty(rule_head)) 3940d7393425SMichal Wilczynski *rule_exists = true; 3941d7393425SMichal Wilczynski 3942d7393425SMichal Wilczynski list_for_each_entry(fm_entry, rule_head, list_entry) { 3943d7393425SMichal Wilczynski if (ice_vsi_uses_fltr(fm_entry, vsi_handle)) { 3944d7393425SMichal Wilczynski ret = true; 3945d7393425SMichal Wilczynski break; 3946d7393425SMichal Wilczynski } 3947d7393425SMichal Wilczynski } 3948d7393425SMichal Wilczynski 3949d7393425SMichal Wilczynski mutex_unlock(rule_lock); 3950d7393425SMichal Wilczynski 3951d7393425SMichal Wilczynski return ret; 3952d7393425SMichal Wilczynski } 3953d7393425SMichal Wilczynski 3954d7393425SMichal Wilczynski /** 395580d144c9SAnirudh Venkataramanan * ice_remove_mac - remove a MAC address based filter rule 3956d76a60baSAnirudh Venkataramanan * @hw: pointer to the hardware structure 395780d144c9SAnirudh Venkataramanan * @m_list: list of MAC addresses and forwarding information 395880d144c9SAnirudh Venkataramanan * 395980d144c9SAnirudh Venkataramanan * This function removes either a MAC filter rule or a specific VSI from a 396080d144c9SAnirudh Venkataramanan * VSI list for a multicast MAC address. 396180d144c9SAnirudh Venkataramanan * 39625518ac2aSTony Nguyen * Returns -ENOENT if a given entry was not added by ice_add_mac. Caller should 39635518ac2aSTony Nguyen * be aware that this call will only work if all the entries passed into m_list 39645518ac2aSTony Nguyen * were added previously. It will not attempt to do a partial remove of entries 39655518ac2aSTony Nguyen * that were found. 3966d76a60baSAnirudh Venkataramanan */ 39675e24d598STony Nguyen int ice_remove_mac(struct ice_hw *hw, struct list_head *m_list) 3968d76a60baSAnirudh Venkataramanan { 3969072f0c3dSDave Ertman struct ice_fltr_list_entry *list_itr, *tmp; 3970d76a60baSAnirudh Venkataramanan 397180d144c9SAnirudh Venkataramanan if (!m_list) 3972d54699e2STony Nguyen return -EINVAL; 3973d76a60baSAnirudh Venkataramanan 3974072f0c3dSDave Ertman list_for_each_entry_safe(list_itr, tmp, m_list, list_entry) { 397580d144c9SAnirudh Venkataramanan enum ice_sw_lkup_type l_type = list_itr->fltr_info.lkup_type; 39768b2c8582SAkeem G Abodunrin u16 vsi_handle; 397780d144c9SAnirudh Venkataramanan 397880d144c9SAnirudh Venkataramanan if (l_type != ICE_SW_LKUP_MAC) 3979d54699e2STony Nguyen return -EINVAL; 39808b2c8582SAkeem G Abodunrin 39818b2c8582SAkeem G Abodunrin vsi_handle = list_itr->fltr_info.vsi_handle; 39828b2c8582SAkeem G Abodunrin if (!ice_is_vsi_valid(hw, vsi_handle)) 3983d54699e2STony Nguyen return -EINVAL; 39848b2c8582SAkeem G Abodunrin 39858b2c8582SAkeem G Abodunrin list_itr->fltr_info.fwd_id.hw_vsi_id = 39868b2c8582SAkeem G Abodunrin ice_get_hw_vsi_num(hw, vsi_handle); 3987e1e9db57SSylwester Dziedziuch 398880d144c9SAnirudh Venkataramanan list_itr->status = ice_remove_rule_internal(hw, 398980d144c9SAnirudh Venkataramanan ICE_SW_LKUP_MAC, 399080d144c9SAnirudh Venkataramanan list_itr); 399180d144c9SAnirudh Venkataramanan if (list_itr->status) 399280d144c9SAnirudh Venkataramanan return list_itr->status; 399380d144c9SAnirudh Venkataramanan } 399480d144c9SAnirudh Venkataramanan return 0; 3995d76a60baSAnirudh Venkataramanan } 3996d76a60baSAnirudh Venkataramanan 3997d76a60baSAnirudh Venkataramanan /** 3998d76a60baSAnirudh Venkataramanan * ice_remove_vlan - Remove VLAN based filter rule 3999d76a60baSAnirudh Venkataramanan * @hw: pointer to the hardware structure 4000d76a60baSAnirudh Venkataramanan * @v_list: list of VLAN entries and forwarding information 4001d76a60baSAnirudh Venkataramanan */ 40025518ac2aSTony Nguyen int ice_remove_vlan(struct ice_hw *hw, struct list_head *v_list) 4003d76a60baSAnirudh Venkataramanan { 4004072f0c3dSDave Ertman struct ice_fltr_list_entry *v_list_itr, *tmp; 4005d76a60baSAnirudh Venkataramanan 4006d76a60baSAnirudh Venkataramanan if (!v_list || !hw) 4007d54699e2STony Nguyen return -EINVAL; 4008d76a60baSAnirudh Venkataramanan 4009072f0c3dSDave Ertman list_for_each_entry_safe(v_list_itr, tmp, v_list, list_entry) { 401080d144c9SAnirudh Venkataramanan enum ice_sw_lkup_type l_type = v_list_itr->fltr_info.lkup_type; 401180d144c9SAnirudh Venkataramanan 401280d144c9SAnirudh Venkataramanan if (l_type != ICE_SW_LKUP_VLAN) 4013d54699e2STony Nguyen return -EINVAL; 401480d144c9SAnirudh Venkataramanan v_list_itr->status = ice_remove_rule_internal(hw, 401580d144c9SAnirudh Venkataramanan ICE_SW_LKUP_VLAN, 401680d144c9SAnirudh Venkataramanan v_list_itr); 401780d144c9SAnirudh Venkataramanan if (v_list_itr->status) 401880d144c9SAnirudh Venkataramanan return v_list_itr->status; 4019d76a60baSAnirudh Venkataramanan } 402080d144c9SAnirudh Venkataramanan return 0; 4021d76a60baSAnirudh Venkataramanan } 402280d144c9SAnirudh Venkataramanan 402380d144c9SAnirudh Venkataramanan /** 402480d144c9SAnirudh Venkataramanan * ice_add_entry_to_vsi_fltr_list - Add copy of fltr_list_entry to remove list 402580d144c9SAnirudh Venkataramanan * @hw: pointer to the hardware structure 40265726ca0eSAnirudh Venkataramanan * @vsi_handle: VSI handle to remove filters from 402780d144c9SAnirudh Venkataramanan * @vsi_list_head: pointer to the list to add entry to 402880d144c9SAnirudh Venkataramanan * @fi: pointer to fltr_info of filter entry to copy & add 402980d144c9SAnirudh Venkataramanan * 403080d144c9SAnirudh Venkataramanan * Helper function, used when creating a list of filters to remove from 403180d144c9SAnirudh Venkataramanan * a specific VSI. The entry added to vsi_list_head is a COPY of the 403280d144c9SAnirudh Venkataramanan * original filter entry, with the exception of fltr_info.fltr_act and 403380d144c9SAnirudh Venkataramanan * fltr_info.fwd_id fields. These are set such that later logic can 403480d144c9SAnirudh Venkataramanan * extract which VSI to remove the fltr from, and pass on that information. 403580d144c9SAnirudh Venkataramanan */ 40365e24d598STony Nguyen static int 40375726ca0eSAnirudh Venkataramanan ice_add_entry_to_vsi_fltr_list(struct ice_hw *hw, u16 vsi_handle, 403880d144c9SAnirudh Venkataramanan struct list_head *vsi_list_head, 403980d144c9SAnirudh Venkataramanan struct ice_fltr_info *fi) 404080d144c9SAnirudh Venkataramanan { 404180d144c9SAnirudh Venkataramanan struct ice_fltr_list_entry *tmp; 404280d144c9SAnirudh Venkataramanan 404380d144c9SAnirudh Venkataramanan /* this memory is freed up in the caller function 404480d144c9SAnirudh Venkataramanan * once filters for this VSI are removed 404580d144c9SAnirudh Venkataramanan */ 404680d144c9SAnirudh Venkataramanan tmp = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*tmp), GFP_KERNEL); 404780d144c9SAnirudh Venkataramanan if (!tmp) 4048d54699e2STony Nguyen return -ENOMEM; 404980d144c9SAnirudh Venkataramanan 405080d144c9SAnirudh Venkataramanan tmp->fltr_info = *fi; 405180d144c9SAnirudh Venkataramanan 405280d144c9SAnirudh Venkataramanan /* Overwrite these fields to indicate which VSI to remove filter from, 405380d144c9SAnirudh Venkataramanan * so find and remove logic can extract the information from the 405480d144c9SAnirudh Venkataramanan * list entries. Note that original entries will still have proper 405580d144c9SAnirudh Venkataramanan * values. 405680d144c9SAnirudh Venkataramanan */ 405780d144c9SAnirudh Venkataramanan tmp->fltr_info.fltr_act = ICE_FWD_TO_VSI; 40585726ca0eSAnirudh Venkataramanan tmp->fltr_info.vsi_handle = vsi_handle; 40595726ca0eSAnirudh Venkataramanan tmp->fltr_info.fwd_id.hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle); 406080d144c9SAnirudh Venkataramanan 406180d144c9SAnirudh Venkataramanan list_add(&tmp->list_entry, vsi_list_head); 406280d144c9SAnirudh Venkataramanan 406380d144c9SAnirudh Venkataramanan return 0; 4064d76a60baSAnirudh Venkataramanan } 4065d76a60baSAnirudh Venkataramanan 4066d76a60baSAnirudh Venkataramanan /** 40679daf8208SAnirudh Venkataramanan * ice_add_to_vsi_fltr_list - Add VSI filters to the list 40689daf8208SAnirudh Venkataramanan * @hw: pointer to the hardware structure 40695726ca0eSAnirudh Venkataramanan * @vsi_handle: VSI handle to remove filters from 40709daf8208SAnirudh Venkataramanan * @lkup_list_head: pointer to the list that has certain lookup type filters 40715726ca0eSAnirudh Venkataramanan * @vsi_list_head: pointer to the list pertaining to VSI with vsi_handle 407280d144c9SAnirudh Venkataramanan * 407380d144c9SAnirudh Venkataramanan * Locates all filters in lkup_list_head that are used by the given VSI, 407480d144c9SAnirudh Venkataramanan * and adds COPIES of those entries to vsi_list_head (intended to be used 407580d144c9SAnirudh Venkataramanan * to remove the listed filters). 407680d144c9SAnirudh Venkataramanan * Note that this means all entries in vsi_list_head must be explicitly 407780d144c9SAnirudh Venkataramanan * deallocated by the caller when done with list. 40789daf8208SAnirudh Venkataramanan */ 40795e24d598STony Nguyen static int 40805726ca0eSAnirudh Venkataramanan ice_add_to_vsi_fltr_list(struct ice_hw *hw, u16 vsi_handle, 40819daf8208SAnirudh Venkataramanan struct list_head *lkup_list_head, 40829daf8208SAnirudh Venkataramanan struct list_head *vsi_list_head) 40839daf8208SAnirudh Venkataramanan { 40849daf8208SAnirudh Venkataramanan struct ice_fltr_mgmt_list_entry *fm_entry; 40855e24d598STony Nguyen int status = 0; 40869daf8208SAnirudh Venkataramanan 4087f9867df6SAnirudh Venkataramanan /* check to make sure VSI ID is valid and within boundary */ 40885726ca0eSAnirudh Venkataramanan if (!ice_is_vsi_valid(hw, vsi_handle)) 4089d54699e2STony Nguyen return -EINVAL; 40909daf8208SAnirudh Venkataramanan 40919daf8208SAnirudh Venkataramanan list_for_each_entry(fm_entry, lkup_list_head, list_entry) { 40927a91d3f0SJacek Bułatek if (!ice_vsi_uses_fltr(fm_entry, vsi_handle)) 409380d144c9SAnirudh Venkataramanan continue; 40949daf8208SAnirudh Venkataramanan 40955726ca0eSAnirudh Venkataramanan status = ice_add_entry_to_vsi_fltr_list(hw, vsi_handle, 40967a91d3f0SJacek Bułatek vsi_list_head, 40977a91d3f0SJacek Bułatek &fm_entry->fltr_info); 409880d144c9SAnirudh Venkataramanan if (status) 409980d144c9SAnirudh Venkataramanan return status; 41009daf8208SAnirudh Venkataramanan } 410180d144c9SAnirudh Venkataramanan return status; 41029daf8208SAnirudh Venkataramanan } 41039daf8208SAnirudh Venkataramanan 41049daf8208SAnirudh Venkataramanan /** 41055eda8afdSAkeem G Abodunrin * ice_determine_promisc_mask 41065eda8afdSAkeem G Abodunrin * @fi: filter info to parse 41075eda8afdSAkeem G Abodunrin * 41085eda8afdSAkeem G Abodunrin * Helper function to determine which ICE_PROMISC_ mask corresponds 41095eda8afdSAkeem G Abodunrin * to given filter into. 41105eda8afdSAkeem G Abodunrin */ 41115eda8afdSAkeem G Abodunrin static u8 ice_determine_promisc_mask(struct ice_fltr_info *fi) 41125eda8afdSAkeem G Abodunrin { 41135eda8afdSAkeem G Abodunrin u16 vid = fi->l_data.mac_vlan.vlan_id; 41145eda8afdSAkeem G Abodunrin u8 *macaddr = fi->l_data.mac.mac_addr; 41155eda8afdSAkeem G Abodunrin bool is_tx_fltr = false; 41165eda8afdSAkeem G Abodunrin u8 promisc_mask = 0; 41175eda8afdSAkeem G Abodunrin 41185eda8afdSAkeem G Abodunrin if (fi->flag == ICE_FLTR_TX) 41195eda8afdSAkeem G Abodunrin is_tx_fltr = true; 41205eda8afdSAkeem G Abodunrin 41215eda8afdSAkeem G Abodunrin if (is_broadcast_ether_addr(macaddr)) 41225eda8afdSAkeem G Abodunrin promisc_mask |= is_tx_fltr ? 41235eda8afdSAkeem G Abodunrin ICE_PROMISC_BCAST_TX : ICE_PROMISC_BCAST_RX; 41245eda8afdSAkeem G Abodunrin else if (is_multicast_ether_addr(macaddr)) 41255eda8afdSAkeem G Abodunrin promisc_mask |= is_tx_fltr ? 41265eda8afdSAkeem G Abodunrin ICE_PROMISC_MCAST_TX : ICE_PROMISC_MCAST_RX; 41275eda8afdSAkeem G Abodunrin else if (is_unicast_ether_addr(macaddr)) 41285eda8afdSAkeem G Abodunrin promisc_mask |= is_tx_fltr ? 41295eda8afdSAkeem G Abodunrin ICE_PROMISC_UCAST_TX : ICE_PROMISC_UCAST_RX; 41305eda8afdSAkeem G Abodunrin if (vid) 41315eda8afdSAkeem G Abodunrin promisc_mask |= is_tx_fltr ? 41325eda8afdSAkeem G Abodunrin ICE_PROMISC_VLAN_TX : ICE_PROMISC_VLAN_RX; 41335eda8afdSAkeem G Abodunrin 41345eda8afdSAkeem G Abodunrin return promisc_mask; 41355eda8afdSAkeem G Abodunrin } 41365eda8afdSAkeem G Abodunrin 41375eda8afdSAkeem G Abodunrin /** 41385eda8afdSAkeem G Abodunrin * ice_remove_promisc - Remove promisc based filter rules 41395eda8afdSAkeem G Abodunrin * @hw: pointer to the hardware structure 4140f9867df6SAnirudh Venkataramanan * @recp_id: recipe ID for which the rule needs to removed 41415eda8afdSAkeem G Abodunrin * @v_list: list of promisc entries 41425eda8afdSAkeem G Abodunrin */ 41435e24d598STony Nguyen static int 41445518ac2aSTony Nguyen ice_remove_promisc(struct ice_hw *hw, u8 recp_id, struct list_head *v_list) 41455eda8afdSAkeem G Abodunrin { 41465eda8afdSAkeem G Abodunrin struct ice_fltr_list_entry *v_list_itr, *tmp; 41475eda8afdSAkeem G Abodunrin 41485eda8afdSAkeem G Abodunrin list_for_each_entry_safe(v_list_itr, tmp, v_list, list_entry) { 41495eda8afdSAkeem G Abodunrin v_list_itr->status = 41505eda8afdSAkeem G Abodunrin ice_remove_rule_internal(hw, recp_id, v_list_itr); 41515eda8afdSAkeem G Abodunrin if (v_list_itr->status) 41525eda8afdSAkeem G Abodunrin return v_list_itr->status; 41535eda8afdSAkeem G Abodunrin } 41545eda8afdSAkeem G Abodunrin return 0; 41555eda8afdSAkeem G Abodunrin } 41565eda8afdSAkeem G Abodunrin 41575eda8afdSAkeem G Abodunrin /** 41585eda8afdSAkeem G Abodunrin * ice_clear_vsi_promisc - clear specified promiscuous mode(s) for given VSI 41595eda8afdSAkeem G Abodunrin * @hw: pointer to the hardware structure 41605eda8afdSAkeem G Abodunrin * @vsi_handle: VSI handle to clear mode 41615eda8afdSAkeem G Abodunrin * @promisc_mask: mask of promiscuous config bits to clear 41625eda8afdSAkeem G Abodunrin * @vid: VLAN ID to clear VLAN promiscuous 41635eda8afdSAkeem G Abodunrin */ 41645e24d598STony Nguyen int 41655eda8afdSAkeem G Abodunrin ice_clear_vsi_promisc(struct ice_hw *hw, u16 vsi_handle, u8 promisc_mask, 41665eda8afdSAkeem G Abodunrin u16 vid) 41675eda8afdSAkeem G Abodunrin { 41685eda8afdSAkeem G Abodunrin struct ice_switch_info *sw = hw->switch_info; 41695eda8afdSAkeem G Abodunrin struct ice_fltr_list_entry *fm_entry, *tmp; 41705eda8afdSAkeem G Abodunrin struct list_head remove_list_head; 41715eda8afdSAkeem G Abodunrin struct ice_fltr_mgmt_list_entry *itr; 41725eda8afdSAkeem G Abodunrin struct list_head *rule_head; 41735eda8afdSAkeem G Abodunrin struct mutex *rule_lock; /* Lock to protect filter rule list */ 41745e24d598STony Nguyen int status = 0; 41755eda8afdSAkeem G Abodunrin u8 recipe_id; 41765eda8afdSAkeem G Abodunrin 41775eda8afdSAkeem G Abodunrin if (!ice_is_vsi_valid(hw, vsi_handle)) 4178d54699e2STony Nguyen return -EINVAL; 41795eda8afdSAkeem G Abodunrin 41801bc7a4abSBrett Creeley if (promisc_mask & (ICE_PROMISC_VLAN_RX | ICE_PROMISC_VLAN_TX)) 41815eda8afdSAkeem G Abodunrin recipe_id = ICE_SW_LKUP_PROMISC_VLAN; 41825eda8afdSAkeem G Abodunrin else 41835eda8afdSAkeem G Abodunrin recipe_id = ICE_SW_LKUP_PROMISC; 41845eda8afdSAkeem G Abodunrin 41855eda8afdSAkeem G Abodunrin rule_head = &sw->recp_list[recipe_id].filt_rules; 41865eda8afdSAkeem G Abodunrin rule_lock = &sw->recp_list[recipe_id].filt_rule_lock; 41875eda8afdSAkeem G Abodunrin 41885eda8afdSAkeem G Abodunrin INIT_LIST_HEAD(&remove_list_head); 41895eda8afdSAkeem G Abodunrin 41905eda8afdSAkeem G Abodunrin mutex_lock(rule_lock); 41915eda8afdSAkeem G Abodunrin list_for_each_entry(itr, rule_head, list_entry) { 41921bc7a4abSBrett Creeley struct ice_fltr_info *fltr_info; 41935eda8afdSAkeem G Abodunrin u8 fltr_promisc_mask = 0; 41945eda8afdSAkeem G Abodunrin 41955eda8afdSAkeem G Abodunrin if (!ice_vsi_uses_fltr(itr, vsi_handle)) 41965eda8afdSAkeem G Abodunrin continue; 41971bc7a4abSBrett Creeley fltr_info = &itr->fltr_info; 41985eda8afdSAkeem G Abodunrin 41991bc7a4abSBrett Creeley if (recipe_id == ICE_SW_LKUP_PROMISC_VLAN && 42001bc7a4abSBrett Creeley vid != fltr_info->l_data.mac_vlan.vlan_id) 42011bc7a4abSBrett Creeley continue; 42021bc7a4abSBrett Creeley 42031bc7a4abSBrett Creeley fltr_promisc_mask |= ice_determine_promisc_mask(fltr_info); 42045eda8afdSAkeem G Abodunrin 42055eda8afdSAkeem G Abodunrin /* Skip if filter is not completely specified by given mask */ 42065eda8afdSAkeem G Abodunrin if (fltr_promisc_mask & ~promisc_mask) 42075eda8afdSAkeem G Abodunrin continue; 42085eda8afdSAkeem G Abodunrin 42095eda8afdSAkeem G Abodunrin status = ice_add_entry_to_vsi_fltr_list(hw, vsi_handle, 42105eda8afdSAkeem G Abodunrin &remove_list_head, 42111bc7a4abSBrett Creeley fltr_info); 42125eda8afdSAkeem G Abodunrin if (status) { 42135eda8afdSAkeem G Abodunrin mutex_unlock(rule_lock); 42145eda8afdSAkeem G Abodunrin goto free_fltr_list; 42155eda8afdSAkeem G Abodunrin } 42165eda8afdSAkeem G Abodunrin } 42175eda8afdSAkeem G Abodunrin mutex_unlock(rule_lock); 42185eda8afdSAkeem G Abodunrin 42195eda8afdSAkeem G Abodunrin status = ice_remove_promisc(hw, recipe_id, &remove_list_head); 42205eda8afdSAkeem G Abodunrin 42215eda8afdSAkeem G Abodunrin free_fltr_list: 42225eda8afdSAkeem G Abodunrin list_for_each_entry_safe(fm_entry, tmp, &remove_list_head, list_entry) { 42235eda8afdSAkeem G Abodunrin list_del(&fm_entry->list_entry); 42245eda8afdSAkeem G Abodunrin devm_kfree(ice_hw_to_dev(hw), fm_entry); 42255eda8afdSAkeem G Abodunrin } 42265eda8afdSAkeem G Abodunrin 42275eda8afdSAkeem G Abodunrin return status; 42285eda8afdSAkeem G Abodunrin } 42295eda8afdSAkeem G Abodunrin 42305eda8afdSAkeem G Abodunrin /** 42315eda8afdSAkeem G Abodunrin * ice_set_vsi_promisc - set given VSI to given promiscuous mode(s) 42325eda8afdSAkeem G Abodunrin * @hw: pointer to the hardware structure 42335eda8afdSAkeem G Abodunrin * @vsi_handle: VSI handle to configure 42345eda8afdSAkeem G Abodunrin * @promisc_mask: mask of promiscuous config bits 42355eda8afdSAkeem G Abodunrin * @vid: VLAN ID to set VLAN promiscuous 42365eda8afdSAkeem G Abodunrin */ 42375e24d598STony Nguyen int 42385eda8afdSAkeem G Abodunrin ice_set_vsi_promisc(struct ice_hw *hw, u16 vsi_handle, u8 promisc_mask, u16 vid) 42395eda8afdSAkeem G Abodunrin { 42405eda8afdSAkeem G Abodunrin enum { UCAST_FLTR = 1, MCAST_FLTR, BCAST_FLTR }; 42415eda8afdSAkeem G Abodunrin struct ice_fltr_list_entry f_list_entry; 42425eda8afdSAkeem G Abodunrin struct ice_fltr_info new_fltr; 42435eda8afdSAkeem G Abodunrin bool is_tx_fltr; 42445518ac2aSTony Nguyen int status = 0; 42455eda8afdSAkeem G Abodunrin u16 hw_vsi_id; 42465eda8afdSAkeem G Abodunrin int pkt_type; 42475eda8afdSAkeem G Abodunrin u8 recipe_id; 42485eda8afdSAkeem G Abodunrin 42495eda8afdSAkeem G Abodunrin if (!ice_is_vsi_valid(hw, vsi_handle)) 4250d54699e2STony Nguyen return -EINVAL; 42515eda8afdSAkeem G Abodunrin hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle); 42525eda8afdSAkeem G Abodunrin 42535eda8afdSAkeem G Abodunrin memset(&new_fltr, 0, sizeof(new_fltr)); 42545eda8afdSAkeem G Abodunrin 42555eda8afdSAkeem G Abodunrin if (promisc_mask & (ICE_PROMISC_VLAN_RX | ICE_PROMISC_VLAN_TX)) { 42565eda8afdSAkeem G Abodunrin new_fltr.lkup_type = ICE_SW_LKUP_PROMISC_VLAN; 42575eda8afdSAkeem G Abodunrin new_fltr.l_data.mac_vlan.vlan_id = vid; 42585eda8afdSAkeem G Abodunrin recipe_id = ICE_SW_LKUP_PROMISC_VLAN; 42595eda8afdSAkeem G Abodunrin } else { 42605eda8afdSAkeem G Abodunrin new_fltr.lkup_type = ICE_SW_LKUP_PROMISC; 42615eda8afdSAkeem G Abodunrin recipe_id = ICE_SW_LKUP_PROMISC; 42625eda8afdSAkeem G Abodunrin } 42635eda8afdSAkeem G Abodunrin 42645eda8afdSAkeem G Abodunrin /* Separate filters must be set for each direction/packet type 42655eda8afdSAkeem G Abodunrin * combination, so we will loop over the mask value, store the 42665eda8afdSAkeem G Abodunrin * individual type, and clear it out in the input mask as it 42675eda8afdSAkeem G Abodunrin * is found. 42685eda8afdSAkeem G Abodunrin */ 42695eda8afdSAkeem G Abodunrin while (promisc_mask) { 42705eda8afdSAkeem G Abodunrin u8 *mac_addr; 42715eda8afdSAkeem G Abodunrin 42725eda8afdSAkeem G Abodunrin pkt_type = 0; 42735eda8afdSAkeem G Abodunrin is_tx_fltr = false; 42745eda8afdSAkeem G Abodunrin 42755eda8afdSAkeem G Abodunrin if (promisc_mask & ICE_PROMISC_UCAST_RX) { 42765eda8afdSAkeem G Abodunrin promisc_mask &= ~ICE_PROMISC_UCAST_RX; 42775eda8afdSAkeem G Abodunrin pkt_type = UCAST_FLTR; 42785eda8afdSAkeem G Abodunrin } else if (promisc_mask & ICE_PROMISC_UCAST_TX) { 42795eda8afdSAkeem G Abodunrin promisc_mask &= ~ICE_PROMISC_UCAST_TX; 42805eda8afdSAkeem G Abodunrin pkt_type = UCAST_FLTR; 42815eda8afdSAkeem G Abodunrin is_tx_fltr = true; 42825eda8afdSAkeem G Abodunrin } else if (promisc_mask & ICE_PROMISC_MCAST_RX) { 42835eda8afdSAkeem G Abodunrin promisc_mask &= ~ICE_PROMISC_MCAST_RX; 42845eda8afdSAkeem G Abodunrin pkt_type = MCAST_FLTR; 42855eda8afdSAkeem G Abodunrin } else if (promisc_mask & ICE_PROMISC_MCAST_TX) { 42865eda8afdSAkeem G Abodunrin promisc_mask &= ~ICE_PROMISC_MCAST_TX; 42875eda8afdSAkeem G Abodunrin pkt_type = MCAST_FLTR; 42885eda8afdSAkeem G Abodunrin is_tx_fltr = true; 42895eda8afdSAkeem G Abodunrin } else if (promisc_mask & ICE_PROMISC_BCAST_RX) { 42905eda8afdSAkeem G Abodunrin promisc_mask &= ~ICE_PROMISC_BCAST_RX; 42915eda8afdSAkeem G Abodunrin pkt_type = BCAST_FLTR; 42925eda8afdSAkeem G Abodunrin } else if (promisc_mask & ICE_PROMISC_BCAST_TX) { 42935eda8afdSAkeem G Abodunrin promisc_mask &= ~ICE_PROMISC_BCAST_TX; 42945eda8afdSAkeem G Abodunrin pkt_type = BCAST_FLTR; 42955eda8afdSAkeem G Abodunrin is_tx_fltr = true; 42965eda8afdSAkeem G Abodunrin } 42975eda8afdSAkeem G Abodunrin 42985eda8afdSAkeem G Abodunrin /* Check for VLAN promiscuous flag */ 42995eda8afdSAkeem G Abodunrin if (promisc_mask & ICE_PROMISC_VLAN_RX) { 43005eda8afdSAkeem G Abodunrin promisc_mask &= ~ICE_PROMISC_VLAN_RX; 43015eda8afdSAkeem G Abodunrin } else if (promisc_mask & ICE_PROMISC_VLAN_TX) { 43025eda8afdSAkeem G Abodunrin promisc_mask &= ~ICE_PROMISC_VLAN_TX; 43035eda8afdSAkeem G Abodunrin is_tx_fltr = true; 43045eda8afdSAkeem G Abodunrin } 43055eda8afdSAkeem G Abodunrin 43065eda8afdSAkeem G Abodunrin /* Set filter DA based on packet type */ 43075eda8afdSAkeem G Abodunrin mac_addr = new_fltr.l_data.mac.mac_addr; 43085eda8afdSAkeem G Abodunrin if (pkt_type == BCAST_FLTR) { 43095eda8afdSAkeem G Abodunrin eth_broadcast_addr(mac_addr); 43105eda8afdSAkeem G Abodunrin } else if (pkt_type == MCAST_FLTR || 43115eda8afdSAkeem G Abodunrin pkt_type == UCAST_FLTR) { 43125eda8afdSAkeem G Abodunrin /* Use the dummy ether header DA */ 43135eda8afdSAkeem G Abodunrin ether_addr_copy(mac_addr, dummy_eth_header); 43145eda8afdSAkeem G Abodunrin if (pkt_type == MCAST_FLTR) 43155eda8afdSAkeem G Abodunrin mac_addr[0] |= 0x1; /* Set multicast bit */ 43165eda8afdSAkeem G Abodunrin } 43175eda8afdSAkeem G Abodunrin 43185eda8afdSAkeem G Abodunrin /* Need to reset this to zero for all iterations */ 43195eda8afdSAkeem G Abodunrin new_fltr.flag = 0; 43205eda8afdSAkeem G Abodunrin if (is_tx_fltr) { 43215eda8afdSAkeem G Abodunrin new_fltr.flag |= ICE_FLTR_TX; 43225eda8afdSAkeem G Abodunrin new_fltr.src = hw_vsi_id; 43235eda8afdSAkeem G Abodunrin } else { 43245eda8afdSAkeem G Abodunrin new_fltr.flag |= ICE_FLTR_RX; 43255eda8afdSAkeem G Abodunrin new_fltr.src = hw->port_info->lport; 43265eda8afdSAkeem G Abodunrin } 43275eda8afdSAkeem G Abodunrin 43285eda8afdSAkeem G Abodunrin new_fltr.fltr_act = ICE_FWD_TO_VSI; 43295eda8afdSAkeem G Abodunrin new_fltr.vsi_handle = vsi_handle; 43305eda8afdSAkeem G Abodunrin new_fltr.fwd_id.hw_vsi_id = hw_vsi_id; 43315eda8afdSAkeem G Abodunrin f_list_entry.fltr_info = new_fltr; 43325eda8afdSAkeem G Abodunrin 43335eda8afdSAkeem G Abodunrin status = ice_add_rule_internal(hw, recipe_id, &f_list_entry); 43345eda8afdSAkeem G Abodunrin if (status) 43355eda8afdSAkeem G Abodunrin goto set_promisc_exit; 43365eda8afdSAkeem G Abodunrin } 43375eda8afdSAkeem G Abodunrin 43385eda8afdSAkeem G Abodunrin set_promisc_exit: 43395eda8afdSAkeem G Abodunrin return status; 43405eda8afdSAkeem G Abodunrin } 43415eda8afdSAkeem G Abodunrin 43425eda8afdSAkeem G Abodunrin /** 43435eda8afdSAkeem G Abodunrin * ice_set_vlan_vsi_promisc 43445eda8afdSAkeem G Abodunrin * @hw: pointer to the hardware structure 43455eda8afdSAkeem G Abodunrin * @vsi_handle: VSI handle to configure 43465eda8afdSAkeem G Abodunrin * @promisc_mask: mask of promiscuous config bits 43475eda8afdSAkeem G Abodunrin * @rm_vlan_promisc: Clear VLANs VSI promisc mode 43485eda8afdSAkeem G Abodunrin * 43495eda8afdSAkeem G Abodunrin * Configure VSI with all associated VLANs to given promiscuous mode(s) 43505eda8afdSAkeem G Abodunrin */ 43515e24d598STony Nguyen int 43525eda8afdSAkeem G Abodunrin ice_set_vlan_vsi_promisc(struct ice_hw *hw, u16 vsi_handle, u8 promisc_mask, 43535eda8afdSAkeem G Abodunrin bool rm_vlan_promisc) 43545eda8afdSAkeem G Abodunrin { 43555eda8afdSAkeem G Abodunrin struct ice_switch_info *sw = hw->switch_info; 43565eda8afdSAkeem G Abodunrin struct ice_fltr_list_entry *list_itr, *tmp; 43575eda8afdSAkeem G Abodunrin struct list_head vsi_list_head; 43585eda8afdSAkeem G Abodunrin struct list_head *vlan_head; 43595eda8afdSAkeem G Abodunrin struct mutex *vlan_lock; /* Lock to protect filter rule list */ 43605eda8afdSAkeem G Abodunrin u16 vlan_id; 43615518ac2aSTony Nguyen int status; 43625eda8afdSAkeem G Abodunrin 43635eda8afdSAkeem G Abodunrin INIT_LIST_HEAD(&vsi_list_head); 43645eda8afdSAkeem G Abodunrin vlan_lock = &sw->recp_list[ICE_SW_LKUP_VLAN].filt_rule_lock; 43655eda8afdSAkeem G Abodunrin vlan_head = &sw->recp_list[ICE_SW_LKUP_VLAN].filt_rules; 43665eda8afdSAkeem G Abodunrin mutex_lock(vlan_lock); 43675eda8afdSAkeem G Abodunrin status = ice_add_to_vsi_fltr_list(hw, vsi_handle, vlan_head, 43685eda8afdSAkeem G Abodunrin &vsi_list_head); 43695eda8afdSAkeem G Abodunrin mutex_unlock(vlan_lock); 43705eda8afdSAkeem G Abodunrin if (status) 43715eda8afdSAkeem G Abodunrin goto free_fltr_list; 43725eda8afdSAkeem G Abodunrin 43735eda8afdSAkeem G Abodunrin list_for_each_entry(list_itr, &vsi_list_head, list_entry) { 4374ffa9ed86SGrzegorz Siwik /* Avoid enabling or disabling VLAN zero twice when in double 4375ffa9ed86SGrzegorz Siwik * VLAN mode 4376ffa9ed86SGrzegorz Siwik */ 4377ffa9ed86SGrzegorz Siwik if (ice_is_dvm_ena(hw) && 4378ffa9ed86SGrzegorz Siwik list_itr->fltr_info.l_data.vlan.tpid == 0) 4379ffa9ed86SGrzegorz Siwik continue; 4380ffa9ed86SGrzegorz Siwik 43815eda8afdSAkeem G Abodunrin vlan_id = list_itr->fltr_info.l_data.vlan.vlan_id; 43825eda8afdSAkeem G Abodunrin if (rm_vlan_promisc) 43835eda8afdSAkeem G Abodunrin status = ice_clear_vsi_promisc(hw, vsi_handle, 43845eda8afdSAkeem G Abodunrin promisc_mask, vlan_id); 43855eda8afdSAkeem G Abodunrin else 43865eda8afdSAkeem G Abodunrin status = ice_set_vsi_promisc(hw, vsi_handle, 43875eda8afdSAkeem G Abodunrin promisc_mask, vlan_id); 438811e551a2SGrzegorz Siwik if (status && status != -EEXIST) 43895eda8afdSAkeem G Abodunrin break; 43905eda8afdSAkeem G Abodunrin } 43915eda8afdSAkeem G Abodunrin 43925eda8afdSAkeem G Abodunrin free_fltr_list: 43935eda8afdSAkeem G Abodunrin list_for_each_entry_safe(list_itr, tmp, &vsi_list_head, list_entry) { 43945eda8afdSAkeem G Abodunrin list_del(&list_itr->list_entry); 43955eda8afdSAkeem G Abodunrin devm_kfree(ice_hw_to_dev(hw), list_itr); 43965eda8afdSAkeem G Abodunrin } 43975eda8afdSAkeem G Abodunrin return status; 43985eda8afdSAkeem G Abodunrin } 43995eda8afdSAkeem G Abodunrin 44005eda8afdSAkeem G Abodunrin /** 44019daf8208SAnirudh Venkataramanan * ice_remove_vsi_lkup_fltr - Remove lookup type filters for a VSI 44029daf8208SAnirudh Venkataramanan * @hw: pointer to the hardware structure 44035726ca0eSAnirudh Venkataramanan * @vsi_handle: VSI handle to remove filters from 44049daf8208SAnirudh Venkataramanan * @lkup: switch rule filter lookup type 44059daf8208SAnirudh Venkataramanan */ 44069daf8208SAnirudh Venkataramanan static void 44075726ca0eSAnirudh Venkataramanan ice_remove_vsi_lkup_fltr(struct ice_hw *hw, u16 vsi_handle, 44089daf8208SAnirudh Venkataramanan enum ice_sw_lkup_type lkup) 44099daf8208SAnirudh Venkataramanan { 44109daf8208SAnirudh Venkataramanan struct ice_switch_info *sw = hw->switch_info; 44119daf8208SAnirudh Venkataramanan struct ice_fltr_list_entry *fm_entry; 44129daf8208SAnirudh Venkataramanan struct list_head remove_list_head; 441380d144c9SAnirudh Venkataramanan struct list_head *rule_head; 44149daf8208SAnirudh Venkataramanan struct ice_fltr_list_entry *tmp; 441580d144c9SAnirudh Venkataramanan struct mutex *rule_lock; /* Lock to protect filter rule list */ 44165e24d598STony Nguyen int status; 44179daf8208SAnirudh Venkataramanan 44189daf8208SAnirudh Venkataramanan INIT_LIST_HEAD(&remove_list_head); 441980d144c9SAnirudh Venkataramanan rule_lock = &sw->recp_list[lkup].filt_rule_lock; 442080d144c9SAnirudh Venkataramanan rule_head = &sw->recp_list[lkup].filt_rules; 442180d144c9SAnirudh Venkataramanan mutex_lock(rule_lock); 44225726ca0eSAnirudh Venkataramanan status = ice_add_to_vsi_fltr_list(hw, vsi_handle, rule_head, 442380d144c9SAnirudh Venkataramanan &remove_list_head); 442480d144c9SAnirudh Venkataramanan mutex_unlock(rule_lock); 442580d144c9SAnirudh Venkataramanan if (status) 4426b7eeb527SRobert Malz goto free_fltr_list; 442780d144c9SAnirudh Venkataramanan 44289daf8208SAnirudh Venkataramanan switch (lkup) { 44299daf8208SAnirudh Venkataramanan case ICE_SW_LKUP_MAC: 44309daf8208SAnirudh Venkataramanan ice_remove_mac(hw, &remove_list_head); 44319daf8208SAnirudh Venkataramanan break; 44329daf8208SAnirudh Venkataramanan case ICE_SW_LKUP_VLAN: 4433d76a60baSAnirudh Venkataramanan ice_remove_vlan(hw, &remove_list_head); 4434d76a60baSAnirudh Venkataramanan break; 44355eda8afdSAkeem G Abodunrin case ICE_SW_LKUP_PROMISC: 44365eda8afdSAkeem G Abodunrin case ICE_SW_LKUP_PROMISC_VLAN: 44375eda8afdSAkeem G Abodunrin ice_remove_promisc(hw, lkup, &remove_list_head); 44385eda8afdSAkeem G Abodunrin break; 44399daf8208SAnirudh Venkataramanan case ICE_SW_LKUP_MAC_VLAN: 44409daf8208SAnirudh Venkataramanan case ICE_SW_LKUP_ETHERTYPE: 44419daf8208SAnirudh Venkataramanan case ICE_SW_LKUP_ETHERTYPE_MAC: 44429daf8208SAnirudh Venkataramanan case ICE_SW_LKUP_DFLT: 444380d144c9SAnirudh Venkataramanan case ICE_SW_LKUP_LAST: 444480d144c9SAnirudh Venkataramanan default: 444580d144c9SAnirudh Venkataramanan ice_debug(hw, ICE_DBG_SW, "Unsupported lookup type %d\n", lkup); 44469daf8208SAnirudh Venkataramanan break; 44479daf8208SAnirudh Venkataramanan } 44489daf8208SAnirudh Venkataramanan 4449b7eeb527SRobert Malz free_fltr_list: 44509daf8208SAnirudh Venkataramanan list_for_each_entry_safe(fm_entry, tmp, &remove_list_head, list_entry) { 44519daf8208SAnirudh Venkataramanan list_del(&fm_entry->list_entry); 44529daf8208SAnirudh Venkataramanan devm_kfree(ice_hw_to_dev(hw), fm_entry); 44539daf8208SAnirudh Venkataramanan } 44549daf8208SAnirudh Venkataramanan } 44559daf8208SAnirudh Venkataramanan 44569daf8208SAnirudh Venkataramanan /** 44579daf8208SAnirudh Venkataramanan * ice_remove_vsi_fltr - Remove all filters for a VSI 44589daf8208SAnirudh Venkataramanan * @hw: pointer to the hardware structure 44595726ca0eSAnirudh Venkataramanan * @vsi_handle: VSI handle to remove filters from 44609daf8208SAnirudh Venkataramanan */ 44615726ca0eSAnirudh Venkataramanan void ice_remove_vsi_fltr(struct ice_hw *hw, u16 vsi_handle) 44629daf8208SAnirudh Venkataramanan { 44635726ca0eSAnirudh Venkataramanan ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_MAC); 44645726ca0eSAnirudh Venkataramanan ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_MAC_VLAN); 44655726ca0eSAnirudh Venkataramanan ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_PROMISC); 44665726ca0eSAnirudh Venkataramanan ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_VLAN); 44675726ca0eSAnirudh Venkataramanan ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_DFLT); 44685726ca0eSAnirudh Venkataramanan ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_ETHERTYPE); 44695726ca0eSAnirudh Venkataramanan ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_ETHERTYPE_MAC); 44705726ca0eSAnirudh Venkataramanan ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_PROMISC_VLAN); 44719daf8208SAnirudh Venkataramanan } 44720f9d5027SAnirudh Venkataramanan 44730f9d5027SAnirudh Venkataramanan /** 4474148beb61SHenry Tieman * ice_alloc_res_cntr - allocating resource counter 4475148beb61SHenry Tieman * @hw: pointer to the hardware structure 4476148beb61SHenry Tieman * @type: type of resource 4477148beb61SHenry Tieman * @alloc_shared: if set it is shared else dedicated 4478148beb61SHenry Tieman * @num_items: number of entries requested for FD resource type 4479148beb61SHenry Tieman * @counter_id: counter index returned by AQ call 4480148beb61SHenry Tieman */ 44815e24d598STony Nguyen int 4482148beb61SHenry Tieman ice_alloc_res_cntr(struct ice_hw *hw, u8 type, u8 alloc_shared, u16 num_items, 4483148beb61SHenry Tieman u16 *counter_id) 4484148beb61SHenry Tieman { 4485148beb61SHenry Tieman struct ice_aqc_alloc_free_res_elem *buf; 4486148beb61SHenry Tieman u16 buf_len; 44875518ac2aSTony Nguyen int status; 4488148beb61SHenry Tieman 4489148beb61SHenry Tieman /* Allocate resource */ 449066486d89SBruce Allan buf_len = struct_size(buf, elem, 1); 4491148beb61SHenry Tieman buf = kzalloc(buf_len, GFP_KERNEL); 4492148beb61SHenry Tieman if (!buf) 4493d54699e2STony Nguyen return -ENOMEM; 4494148beb61SHenry Tieman 4495148beb61SHenry Tieman buf->num_elems = cpu_to_le16(num_items); 4496148beb61SHenry Tieman buf->res_type = cpu_to_le16(((type << ICE_AQC_RES_TYPE_S) & 4497148beb61SHenry Tieman ICE_AQC_RES_TYPE_M) | alloc_shared); 4498148beb61SHenry Tieman 4499148beb61SHenry Tieman status = ice_aq_alloc_free_res(hw, 1, buf, buf_len, 4500148beb61SHenry Tieman ice_aqc_opc_alloc_res, NULL); 4501148beb61SHenry Tieman if (status) 4502148beb61SHenry Tieman goto exit; 4503148beb61SHenry Tieman 4504148beb61SHenry Tieman *counter_id = le16_to_cpu(buf->elem[0].e.sw_resp); 4505148beb61SHenry Tieman 4506148beb61SHenry Tieman exit: 4507148beb61SHenry Tieman kfree(buf); 4508148beb61SHenry Tieman return status; 4509148beb61SHenry Tieman } 4510148beb61SHenry Tieman 4511148beb61SHenry Tieman /** 4512148beb61SHenry Tieman * ice_free_res_cntr - free resource counter 4513148beb61SHenry Tieman * @hw: pointer to the hardware structure 4514148beb61SHenry Tieman * @type: type of resource 4515148beb61SHenry Tieman * @alloc_shared: if set it is shared else dedicated 4516148beb61SHenry Tieman * @num_items: number of entries to be freed for FD resource type 4517148beb61SHenry Tieman * @counter_id: counter ID resource which needs to be freed 4518148beb61SHenry Tieman */ 45195e24d598STony Nguyen int 4520148beb61SHenry Tieman ice_free_res_cntr(struct ice_hw *hw, u8 type, u8 alloc_shared, u16 num_items, 4521148beb61SHenry Tieman u16 counter_id) 4522148beb61SHenry Tieman { 4523148beb61SHenry Tieman struct ice_aqc_alloc_free_res_elem *buf; 4524148beb61SHenry Tieman u16 buf_len; 45255518ac2aSTony Nguyen int status; 4526148beb61SHenry Tieman 4527148beb61SHenry Tieman /* Free resource */ 452866486d89SBruce Allan buf_len = struct_size(buf, elem, 1); 4529148beb61SHenry Tieman buf = kzalloc(buf_len, GFP_KERNEL); 4530148beb61SHenry Tieman if (!buf) 4531d54699e2STony Nguyen return -ENOMEM; 4532148beb61SHenry Tieman 4533148beb61SHenry Tieman buf->num_elems = cpu_to_le16(num_items); 4534148beb61SHenry Tieman buf->res_type = cpu_to_le16(((type << ICE_AQC_RES_TYPE_S) & 4535148beb61SHenry Tieman ICE_AQC_RES_TYPE_M) | alloc_shared); 4536148beb61SHenry Tieman buf->elem[0].e.sw_resp = cpu_to_le16(counter_id); 4537148beb61SHenry Tieman 4538148beb61SHenry Tieman status = ice_aq_alloc_free_res(hw, 1, buf, buf_len, 4539148beb61SHenry Tieman ice_aqc_opc_free_res, NULL); 4540148beb61SHenry Tieman if (status) 45419228d8b2SJacob Keller ice_debug(hw, ICE_DBG_SW, "counter resource could not be freed\n"); 4542148beb61SHenry Tieman 4543148beb61SHenry Tieman kfree(buf); 4544148beb61SHenry Tieman return status; 4545148beb61SHenry Tieman } 4546148beb61SHenry Tieman 454717c6d835SMichal Swiatkowski #define ICE_PROTOCOL_ENTRY(id, ...) { \ 454817c6d835SMichal Swiatkowski .prot_type = id, \ 454917c6d835SMichal Swiatkowski .offs = {__VA_ARGS__}, \ 455017c6d835SMichal Swiatkowski } 455117c6d835SMichal Swiatkowski 455223ccae5cSDave Ertman /** 455323ccae5cSDave Ertman * ice_share_res - set a resource as shared or dedicated 455423ccae5cSDave Ertman * @hw: hw struct of original owner of resource 455523ccae5cSDave Ertman * @type: resource type 455623ccae5cSDave Ertman * @shared: is the resource being set to shared 455723ccae5cSDave Ertman * @res_id: resource id (descriptor) 455823ccae5cSDave Ertman */ 455923ccae5cSDave Ertman int ice_share_res(struct ice_hw *hw, u16 type, u8 shared, u16 res_id) 456023ccae5cSDave Ertman { 456123ccae5cSDave Ertman struct ice_aqc_alloc_free_res_elem *buf; 456223ccae5cSDave Ertman u16 buf_len; 456323ccae5cSDave Ertman int status; 456423ccae5cSDave Ertman 456523ccae5cSDave Ertman buf_len = struct_size(buf, elem, 1); 456623ccae5cSDave Ertman buf = kzalloc(buf_len, GFP_KERNEL); 456723ccae5cSDave Ertman if (!buf) 456823ccae5cSDave Ertman return -ENOMEM; 456923ccae5cSDave Ertman 457023ccae5cSDave Ertman buf->num_elems = cpu_to_le16(1); 457123ccae5cSDave Ertman if (shared) 457223ccae5cSDave Ertman buf->res_type = cpu_to_le16(((type << ICE_AQC_RES_TYPE_S) & 457323ccae5cSDave Ertman ICE_AQC_RES_TYPE_M) | 457423ccae5cSDave Ertman ICE_AQC_RES_TYPE_FLAG_SHARED); 457523ccae5cSDave Ertman else 457623ccae5cSDave Ertman buf->res_type = cpu_to_le16(((type << ICE_AQC_RES_TYPE_S) & 457723ccae5cSDave Ertman ICE_AQC_RES_TYPE_M) & 457823ccae5cSDave Ertman ~ICE_AQC_RES_TYPE_FLAG_SHARED); 457923ccae5cSDave Ertman 458023ccae5cSDave Ertman buf->elem[0].e.sw_resp = cpu_to_le16(res_id); 458123ccae5cSDave Ertman status = ice_aq_alloc_free_res(hw, 1, buf, buf_len, 458223ccae5cSDave Ertman ice_aqc_opc_share_res, NULL); 458323ccae5cSDave Ertman if (status) 458423ccae5cSDave Ertman ice_debug(hw, ICE_DBG_SW, "Could not set resource type %u id %u to %s\n", 458523ccae5cSDave Ertman type, res_id, shared ? "SHARED" : "DEDICATED"); 458623ccae5cSDave Ertman 458723ccae5cSDave Ertman kfree(buf); 458823ccae5cSDave Ertman return status; 458923ccae5cSDave Ertman } 459023ccae5cSDave Ertman 4591fd2a6b71SDan Nowlin /* This is mapping table entry that maps every word within a given protocol 4592fd2a6b71SDan Nowlin * structure to the real byte offset as per the specification of that 4593fd2a6b71SDan Nowlin * protocol header. 4594fd2a6b71SDan Nowlin * for example dst address is 3 words in ethertype header and corresponding 4595fd2a6b71SDan Nowlin * bytes are 0, 2, 3 in the actual packet header and src address is at 4, 6, 8 4596fd2a6b71SDan Nowlin * IMPORTANT: Every structure part of "ice_prot_hdr" union should have a 4597fd2a6b71SDan Nowlin * matching entry describing its field. This needs to be updated if new 4598fd2a6b71SDan Nowlin * structure is added to that union. 4599fd2a6b71SDan Nowlin */ 4600fd2a6b71SDan Nowlin static const struct ice_prot_ext_tbl_entry ice_prot_ext[ICE_PROTOCOL_LAST] = { 460117c6d835SMichal Swiatkowski ICE_PROTOCOL_ENTRY(ICE_MAC_OFOS, 0, 2, 4, 6, 8, 10, 12), 460217c6d835SMichal Swiatkowski ICE_PROTOCOL_ENTRY(ICE_MAC_IL, 0, 2, 4, 6, 8, 10, 12), 460317c6d835SMichal Swiatkowski ICE_PROTOCOL_ENTRY(ICE_ETYPE_OL, 0), 460417c6d835SMichal Swiatkowski ICE_PROTOCOL_ENTRY(ICE_ETYPE_IL, 0), 460517c6d835SMichal Swiatkowski ICE_PROTOCOL_ENTRY(ICE_VLAN_OFOS, 2, 0), 460617c6d835SMichal Swiatkowski ICE_PROTOCOL_ENTRY(ICE_IPV4_OFOS, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18), 460717c6d835SMichal Swiatkowski ICE_PROTOCOL_ENTRY(ICE_IPV4_IL, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18), 460817c6d835SMichal Swiatkowski ICE_PROTOCOL_ENTRY(ICE_IPV6_OFOS, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 460917c6d835SMichal Swiatkowski 20, 22, 24, 26, 28, 30, 32, 34, 36, 38), 461017c6d835SMichal Swiatkowski ICE_PROTOCOL_ENTRY(ICE_IPV6_IL, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 461117c6d835SMichal Swiatkowski 22, 24, 26, 28, 30, 32, 34, 36, 38), 461217c6d835SMichal Swiatkowski ICE_PROTOCOL_ENTRY(ICE_TCP_IL, 0, 2), 461317c6d835SMichal Swiatkowski ICE_PROTOCOL_ENTRY(ICE_UDP_OF, 0, 2), 461417c6d835SMichal Swiatkowski ICE_PROTOCOL_ENTRY(ICE_UDP_ILOS, 0, 2), 461517c6d835SMichal Swiatkowski ICE_PROTOCOL_ENTRY(ICE_VXLAN, 8, 10, 12, 14), 461617c6d835SMichal Swiatkowski ICE_PROTOCOL_ENTRY(ICE_GENEVE, 8, 10, 12, 14), 461717c6d835SMichal Swiatkowski ICE_PROTOCOL_ENTRY(ICE_NVGRE, 0, 2, 4, 6), 461817c6d835SMichal Swiatkowski ICE_PROTOCOL_ENTRY(ICE_GTP, 8, 10, 12, 14, 16, 18, 20, 22), 461917c6d835SMichal Swiatkowski ICE_PROTOCOL_ENTRY(ICE_GTP_NO_PAY, 8, 10, 12, 14), 462017c6d835SMichal Swiatkowski ICE_PROTOCOL_ENTRY(ICE_PPPOE, 0, 2, 4, 6), 462117c6d835SMichal Swiatkowski ICE_PROTOCOL_ENTRY(ICE_L2TPV3, 0, 2, 4, 6, 8, 10), 462217c6d835SMichal Swiatkowski ICE_PROTOCOL_ENTRY(ICE_VLAN_EX, 2, 0), 462317c6d835SMichal Swiatkowski ICE_PROTOCOL_ENTRY(ICE_VLAN_IN, 2, 0), 462403592a14SMichal Swiatkowski ICE_PROTOCOL_ENTRY(ICE_HW_METADATA, 462503592a14SMichal Swiatkowski ICE_SOURCE_PORT_MDID_OFFSET, 462603592a14SMichal Swiatkowski ICE_PTYPE_MDID_OFFSET, 462703592a14SMichal Swiatkowski ICE_PACKET_LENGTH_MDID_OFFSET, 462803592a14SMichal Swiatkowski ICE_SOURCE_VSI_MDID_OFFSET, 462903592a14SMichal Swiatkowski ICE_PKT_VLAN_MDID_OFFSET, 463003592a14SMichal Swiatkowski ICE_PKT_TUNNEL_MDID_OFFSET, 463103592a14SMichal Swiatkowski ICE_PKT_TCP_MDID_OFFSET, 463203592a14SMichal Swiatkowski ICE_PKT_ERROR_MDID_OFFSET), 4633fd2a6b71SDan Nowlin }; 4634fd2a6b71SDan Nowlin 4635fd2a6b71SDan Nowlin static struct ice_protocol_entry ice_prot_id_tbl[ICE_PROTOCOL_LAST] = { 4636fd2a6b71SDan Nowlin { ICE_MAC_OFOS, ICE_MAC_OFOS_HW }, 4637fd2a6b71SDan Nowlin { ICE_MAC_IL, ICE_MAC_IL_HW }, 4638fd2a6b71SDan Nowlin { ICE_ETYPE_OL, ICE_ETYPE_OL_HW }, 463934a89775SMartyna Szapar-Mudlaw { ICE_ETYPE_IL, ICE_ETYPE_IL_HW }, 4640fd2a6b71SDan Nowlin { ICE_VLAN_OFOS, ICE_VLAN_OL_HW }, 4641fd2a6b71SDan Nowlin { ICE_IPV4_OFOS, ICE_IPV4_OFOS_HW }, 4642fd2a6b71SDan Nowlin { ICE_IPV4_IL, ICE_IPV4_IL_HW }, 4643fd2a6b71SDan Nowlin { ICE_IPV6_OFOS, ICE_IPV6_OFOS_HW }, 4644fd2a6b71SDan Nowlin { ICE_IPV6_IL, ICE_IPV6_IL_HW }, 4645fd2a6b71SDan Nowlin { ICE_TCP_IL, ICE_TCP_IL_HW }, 4646fd2a6b71SDan Nowlin { ICE_UDP_OF, ICE_UDP_OF_HW }, 4647fd2a6b71SDan Nowlin { ICE_UDP_ILOS, ICE_UDP_ILOS_HW }, 46488b032a55SMichal Swiatkowski { ICE_VXLAN, ICE_UDP_OF_HW }, 46498b032a55SMichal Swiatkowski { ICE_GENEVE, ICE_UDP_OF_HW }, 4650f0a35040SMichal Swiatkowski { ICE_NVGRE, ICE_GRE_OF_HW }, 46519a225f81SMarcin Szycik { ICE_GTP, ICE_UDP_OF_HW }, 46529a225f81SMarcin Szycik { ICE_GTP_NO_PAY, ICE_UDP_ILOS_HW }, 4653cd8efeeeSMarcin Szycik { ICE_PPPOE, ICE_PPPOE_HW }, 4654cd634549SMarcin Szycik { ICE_L2TPV3, ICE_L2TPV3_HW }, 465506bca7c2SMartyna Szapar-Mudlaw { ICE_VLAN_EX, ICE_VLAN_OF_HW }, 465606bca7c2SMartyna Szapar-Mudlaw { ICE_VLAN_IN, ICE_VLAN_OL_HW }, 465703592a14SMichal Swiatkowski { ICE_HW_METADATA, ICE_META_DATA_ID_HW }, 4658fd2a6b71SDan Nowlin }; 4659fd2a6b71SDan Nowlin 4660fd2a6b71SDan Nowlin /** 4661fd2a6b71SDan Nowlin * ice_find_recp - find a recipe 4662fd2a6b71SDan Nowlin * @hw: pointer to the hardware structure 4663fd2a6b71SDan Nowlin * @lkup_exts: extension sequence to match 4664bccd9bceSMarcin Szycik * @rinfo: information regarding the rule e.g. priority and action info 4665fd2a6b71SDan Nowlin * 4666fd2a6b71SDan Nowlin * Returns index of matching recipe, or ICE_MAX_NUM_RECIPES if not found. 4667fd2a6b71SDan Nowlin */ 4668de6acd1cSMichal Swiatkowski static u16 4669de6acd1cSMichal Swiatkowski ice_find_recp(struct ice_hw *hw, struct ice_prot_lkup_ext *lkup_exts, 4670bccd9bceSMarcin Szycik const struct ice_adv_rule_info *rinfo) 4671fd2a6b71SDan Nowlin { 4672fd2a6b71SDan Nowlin bool refresh_required = true; 4673fd2a6b71SDan Nowlin struct ice_sw_recipe *recp; 4674fd2a6b71SDan Nowlin u8 i; 4675fd2a6b71SDan Nowlin 4676fd2a6b71SDan Nowlin /* Walk through existing recipes to find a match */ 4677fd2a6b71SDan Nowlin recp = hw->switch_info->recp_list; 4678fd2a6b71SDan Nowlin for (i = 0; i < ICE_MAX_NUM_RECIPES; i++) { 4679fd2a6b71SDan Nowlin /* If recipe was not created for this ID, in SW bookkeeping, 4680fd2a6b71SDan Nowlin * check if FW has an entry for this recipe. If the FW has an 4681fd2a6b71SDan Nowlin * entry update it in our SW bookkeeping and continue with the 4682fd2a6b71SDan Nowlin * matching. 4683fd2a6b71SDan Nowlin */ 4684fd2a6b71SDan Nowlin if (!recp[i].recp_created) 4685fd2a6b71SDan Nowlin if (ice_get_recp_frm_fw(hw, 4686fd2a6b71SDan Nowlin hw->switch_info->recp_list, i, 4687fd2a6b71SDan Nowlin &refresh_required)) 4688fd2a6b71SDan Nowlin continue; 4689fd2a6b71SDan Nowlin 4690fd2a6b71SDan Nowlin /* Skip inverse action recipes */ 4691fd2a6b71SDan Nowlin if (recp[i].root_buf && recp[i].root_buf->content.act_ctrl & 4692fd2a6b71SDan Nowlin ICE_AQ_RECIPE_ACT_INV_ACT) 4693fd2a6b71SDan Nowlin continue; 4694fd2a6b71SDan Nowlin 4695fd2a6b71SDan Nowlin /* if number of words we are looking for match */ 4696fd2a6b71SDan Nowlin if (lkup_exts->n_val_words == recp[i].lkup_exts.n_val_words) { 4697fd2a6b71SDan Nowlin struct ice_fv_word *ar = recp[i].lkup_exts.fv_words; 4698fd2a6b71SDan Nowlin struct ice_fv_word *be = lkup_exts->fv_words; 4699fd2a6b71SDan Nowlin u16 *cr = recp[i].lkup_exts.field_mask; 4700fd2a6b71SDan Nowlin u16 *de = lkup_exts->field_mask; 4701fd2a6b71SDan Nowlin bool found = true; 4702fd2a6b71SDan Nowlin u8 pe, qr; 4703fd2a6b71SDan Nowlin 4704fd2a6b71SDan Nowlin /* ar, cr, and qr are related to the recipe words, while 4705fd2a6b71SDan Nowlin * be, de, and pe are related to the lookup words 4706fd2a6b71SDan Nowlin */ 4707fd2a6b71SDan Nowlin for (pe = 0; pe < lkup_exts->n_val_words; pe++) { 4708fd2a6b71SDan Nowlin for (qr = 0; qr < recp[i].lkup_exts.n_val_words; 4709fd2a6b71SDan Nowlin qr++) { 4710fd2a6b71SDan Nowlin if (ar[qr].off == be[pe].off && 4711fd2a6b71SDan Nowlin ar[qr].prot_id == be[pe].prot_id && 4712fd2a6b71SDan Nowlin cr[qr] == de[pe]) 4713fd2a6b71SDan Nowlin /* Found the "pe"th word in the 4714fd2a6b71SDan Nowlin * given recipe 4715fd2a6b71SDan Nowlin */ 4716fd2a6b71SDan Nowlin break; 4717fd2a6b71SDan Nowlin } 4718fd2a6b71SDan Nowlin /* After walking through all the words in the 4719fd2a6b71SDan Nowlin * "i"th recipe if "p"th word was not found then 4720fd2a6b71SDan Nowlin * this recipe is not what we are looking for. 4721fd2a6b71SDan Nowlin * So break out from this loop and try the next 4722fd2a6b71SDan Nowlin * recipe 4723fd2a6b71SDan Nowlin */ 4724fd2a6b71SDan Nowlin if (qr >= recp[i].lkup_exts.n_val_words) { 4725fd2a6b71SDan Nowlin found = false; 4726fd2a6b71SDan Nowlin break; 4727fd2a6b71SDan Nowlin } 4728fd2a6b71SDan Nowlin } 4729fd2a6b71SDan Nowlin /* If for "i"th recipe the found was never set to false 4730fd2a6b71SDan Nowlin * then it means we found our match 4731bccd9bceSMarcin Szycik * Also tun type and *_pass_l2 of recipe needs to be 4732bccd9bceSMarcin Szycik * checked 4733fd2a6b71SDan Nowlin */ 4734bccd9bceSMarcin Szycik if (found && recp[i].tun_type == rinfo->tun_type && 4735bccd9bceSMarcin Szycik recp[i].need_pass_l2 == rinfo->need_pass_l2 && 4736bccd9bceSMarcin Szycik recp[i].allow_pass_l2 == rinfo->allow_pass_l2) 4737fd2a6b71SDan Nowlin return i; /* Return the recipe ID */ 4738fd2a6b71SDan Nowlin } 4739fd2a6b71SDan Nowlin } 4740fd2a6b71SDan Nowlin return ICE_MAX_NUM_RECIPES; 4741fd2a6b71SDan Nowlin } 4742fd2a6b71SDan Nowlin 4743fd2a6b71SDan Nowlin /** 4744a1ffafb0SBrett Creeley * ice_change_proto_id_to_dvm - change proto id in prot_id_tbl 4745a1ffafb0SBrett Creeley * 4746a1ffafb0SBrett Creeley * As protocol id for outer vlan is different in dvm and svm, if dvm is 4747a1ffafb0SBrett Creeley * supported protocol array record for outer vlan has to be modified to 4748a1ffafb0SBrett Creeley * reflect the value proper for DVM. 4749a1ffafb0SBrett Creeley */ 4750a1ffafb0SBrett Creeley void ice_change_proto_id_to_dvm(void) 4751a1ffafb0SBrett Creeley { 4752a1ffafb0SBrett Creeley u8 i; 4753a1ffafb0SBrett Creeley 4754a1ffafb0SBrett Creeley for (i = 0; i < ARRAY_SIZE(ice_prot_id_tbl); i++) 4755a1ffafb0SBrett Creeley if (ice_prot_id_tbl[i].type == ICE_VLAN_OFOS && 4756a1ffafb0SBrett Creeley ice_prot_id_tbl[i].protocol_id != ICE_VLAN_OF_HW) 4757a1ffafb0SBrett Creeley ice_prot_id_tbl[i].protocol_id = ICE_VLAN_OF_HW; 4758a1ffafb0SBrett Creeley } 4759a1ffafb0SBrett Creeley 4760a1ffafb0SBrett Creeley /** 4761fd2a6b71SDan Nowlin * ice_prot_type_to_id - get protocol ID from protocol type 4762fd2a6b71SDan Nowlin * @type: protocol type 4763fd2a6b71SDan Nowlin * @id: pointer to variable that will receive the ID 4764fd2a6b71SDan Nowlin * 4765fd2a6b71SDan Nowlin * Returns true if found, false otherwise 4766fd2a6b71SDan Nowlin */ 4767fd2a6b71SDan Nowlin static bool ice_prot_type_to_id(enum ice_protocol_type type, u8 *id) 4768fd2a6b71SDan Nowlin { 4769fd2a6b71SDan Nowlin u8 i; 4770fd2a6b71SDan Nowlin 4771fd2a6b71SDan Nowlin for (i = 0; i < ARRAY_SIZE(ice_prot_id_tbl); i++) 4772fd2a6b71SDan Nowlin if (ice_prot_id_tbl[i].type == type) { 4773fd2a6b71SDan Nowlin *id = ice_prot_id_tbl[i].protocol_id; 4774fd2a6b71SDan Nowlin return true; 4775fd2a6b71SDan Nowlin } 4776fd2a6b71SDan Nowlin return false; 4777fd2a6b71SDan Nowlin } 4778fd2a6b71SDan Nowlin 4779fd2a6b71SDan Nowlin /** 4780fd2a6b71SDan Nowlin * ice_fill_valid_words - count valid words 4781fd2a6b71SDan Nowlin * @rule: advanced rule with lookup information 4782fd2a6b71SDan Nowlin * @lkup_exts: byte offset extractions of the words that are valid 4783fd2a6b71SDan Nowlin * 4784fd2a6b71SDan Nowlin * calculate valid words in a lookup rule using mask value 4785fd2a6b71SDan Nowlin */ 4786fd2a6b71SDan Nowlin static u8 4787fd2a6b71SDan Nowlin ice_fill_valid_words(struct ice_adv_lkup_elem *rule, 4788fd2a6b71SDan Nowlin struct ice_prot_lkup_ext *lkup_exts) 4789fd2a6b71SDan Nowlin { 4790fd2a6b71SDan Nowlin u8 j, word, prot_id, ret_val; 4791fd2a6b71SDan Nowlin 4792fd2a6b71SDan Nowlin if (!ice_prot_type_to_id(rule->type, &prot_id)) 4793fd2a6b71SDan Nowlin return 0; 4794fd2a6b71SDan Nowlin 4795fd2a6b71SDan Nowlin word = lkup_exts->n_val_words; 4796fd2a6b71SDan Nowlin 4797fd2a6b71SDan Nowlin for (j = 0; j < sizeof(rule->m_u) / sizeof(u16); j++) 4798fd2a6b71SDan Nowlin if (((u16 *)&rule->m_u)[j] && 4799fd2a6b71SDan Nowlin rule->type < ARRAY_SIZE(ice_prot_ext)) { 4800fd2a6b71SDan Nowlin /* No more space to accommodate */ 4801fd2a6b71SDan Nowlin if (word >= ICE_MAX_CHAIN_WORDS) 4802fd2a6b71SDan Nowlin return 0; 4803fd2a6b71SDan Nowlin lkup_exts->fv_words[word].off = 4804fd2a6b71SDan Nowlin ice_prot_ext[rule->type].offs[j]; 4805fd2a6b71SDan Nowlin lkup_exts->fv_words[word].prot_id = 4806fd2a6b71SDan Nowlin ice_prot_id_tbl[rule->type].protocol_id; 4807fd2a6b71SDan Nowlin lkup_exts->field_mask[word] = 4808fd2a6b71SDan Nowlin be16_to_cpu(((__force __be16 *)&rule->m_u)[j]); 4809fd2a6b71SDan Nowlin word++; 4810fd2a6b71SDan Nowlin } 4811fd2a6b71SDan Nowlin 4812fd2a6b71SDan Nowlin ret_val = word - lkup_exts->n_val_words; 4813fd2a6b71SDan Nowlin lkup_exts->n_val_words = word; 4814fd2a6b71SDan Nowlin 4815fd2a6b71SDan Nowlin return ret_val; 4816fd2a6b71SDan Nowlin } 4817fd2a6b71SDan Nowlin 4818fd2a6b71SDan Nowlin /** 4819fd2a6b71SDan Nowlin * ice_create_first_fit_recp_def - Create a recipe grouping 4820fd2a6b71SDan Nowlin * @hw: pointer to the hardware structure 4821fd2a6b71SDan Nowlin * @lkup_exts: an array of protocol header extractions 4822fd2a6b71SDan Nowlin * @rg_list: pointer to a list that stores new recipe groups 4823fd2a6b71SDan Nowlin * @recp_cnt: pointer to a variable that stores returned number of recipe groups 4824fd2a6b71SDan Nowlin * 4825fd2a6b71SDan Nowlin * Using first fit algorithm, take all the words that are still not done 4826fd2a6b71SDan Nowlin * and start grouping them in 4-word groups. Each group makes up one 4827fd2a6b71SDan Nowlin * recipe. 4828fd2a6b71SDan Nowlin */ 48295e24d598STony Nguyen static int 4830fd2a6b71SDan Nowlin ice_create_first_fit_recp_def(struct ice_hw *hw, 4831fd2a6b71SDan Nowlin struct ice_prot_lkup_ext *lkup_exts, 4832fd2a6b71SDan Nowlin struct list_head *rg_list, 4833fd2a6b71SDan Nowlin u8 *recp_cnt) 4834fd2a6b71SDan Nowlin { 4835fd2a6b71SDan Nowlin struct ice_pref_recipe_group *grp = NULL; 4836fd2a6b71SDan Nowlin u8 j; 4837fd2a6b71SDan Nowlin 4838fd2a6b71SDan Nowlin *recp_cnt = 0; 4839fd2a6b71SDan Nowlin 4840fd2a6b71SDan Nowlin /* Walk through every word in the rule to check if it is not done. If so 4841fd2a6b71SDan Nowlin * then this word needs to be part of a new recipe. 4842fd2a6b71SDan Nowlin */ 4843fd2a6b71SDan Nowlin for (j = 0; j < lkup_exts->n_val_words; j++) 4844fd2a6b71SDan Nowlin if (!test_bit(j, lkup_exts->done)) { 4845fd2a6b71SDan Nowlin if (!grp || 4846fd2a6b71SDan Nowlin grp->n_val_pairs == ICE_NUM_WORDS_RECIPE) { 4847fd2a6b71SDan Nowlin struct ice_recp_grp_entry *entry; 4848fd2a6b71SDan Nowlin 4849fd2a6b71SDan Nowlin entry = devm_kzalloc(ice_hw_to_dev(hw), 4850fd2a6b71SDan Nowlin sizeof(*entry), 4851fd2a6b71SDan Nowlin GFP_KERNEL); 4852fd2a6b71SDan Nowlin if (!entry) 4853d54699e2STony Nguyen return -ENOMEM; 4854fd2a6b71SDan Nowlin list_add(&entry->l_entry, rg_list); 4855fd2a6b71SDan Nowlin grp = &entry->r_group; 4856fd2a6b71SDan Nowlin (*recp_cnt)++; 4857fd2a6b71SDan Nowlin } 4858fd2a6b71SDan Nowlin 4859fd2a6b71SDan Nowlin grp->pairs[grp->n_val_pairs].prot_id = 4860fd2a6b71SDan Nowlin lkup_exts->fv_words[j].prot_id; 4861fd2a6b71SDan Nowlin grp->pairs[grp->n_val_pairs].off = 4862fd2a6b71SDan Nowlin lkup_exts->fv_words[j].off; 4863fd2a6b71SDan Nowlin grp->mask[grp->n_val_pairs] = lkup_exts->field_mask[j]; 4864fd2a6b71SDan Nowlin grp->n_val_pairs++; 4865fd2a6b71SDan Nowlin } 4866fd2a6b71SDan Nowlin 4867fd2a6b71SDan Nowlin return 0; 4868fd2a6b71SDan Nowlin } 4869fd2a6b71SDan Nowlin 4870fd2a6b71SDan Nowlin /** 4871fd2a6b71SDan Nowlin * ice_fill_fv_word_index - fill in the field vector indices for a recipe group 4872fd2a6b71SDan Nowlin * @hw: pointer to the hardware structure 4873fd2a6b71SDan Nowlin * @fv_list: field vector with the extraction sequence information 4874fd2a6b71SDan Nowlin * @rg_list: recipe groupings with protocol-offset pairs 4875fd2a6b71SDan Nowlin * 4876fd2a6b71SDan Nowlin * Helper function to fill in the field vector indices for protocol-offset 4877fd2a6b71SDan Nowlin * pairs. These indexes are then ultimately programmed into a recipe. 4878fd2a6b71SDan Nowlin */ 48795e24d598STony Nguyen static int 4880fd2a6b71SDan Nowlin ice_fill_fv_word_index(struct ice_hw *hw, struct list_head *fv_list, 4881fd2a6b71SDan Nowlin struct list_head *rg_list) 4882fd2a6b71SDan Nowlin { 4883fd2a6b71SDan Nowlin struct ice_sw_fv_list_entry *fv; 4884fd2a6b71SDan Nowlin struct ice_recp_grp_entry *rg; 4885fd2a6b71SDan Nowlin struct ice_fv_word *fv_ext; 4886fd2a6b71SDan Nowlin 4887fd2a6b71SDan Nowlin if (list_empty(fv_list)) 4888fd2a6b71SDan Nowlin return 0; 4889fd2a6b71SDan Nowlin 4890fd2a6b71SDan Nowlin fv = list_first_entry(fv_list, struct ice_sw_fv_list_entry, 4891fd2a6b71SDan Nowlin list_entry); 4892fd2a6b71SDan Nowlin fv_ext = fv->fv_ptr->ew; 4893fd2a6b71SDan Nowlin 4894fd2a6b71SDan Nowlin list_for_each_entry(rg, rg_list, l_entry) { 4895fd2a6b71SDan Nowlin u8 i; 4896fd2a6b71SDan Nowlin 4897fd2a6b71SDan Nowlin for (i = 0; i < rg->r_group.n_val_pairs; i++) { 4898fd2a6b71SDan Nowlin struct ice_fv_word *pr; 4899fd2a6b71SDan Nowlin bool found = false; 4900fd2a6b71SDan Nowlin u16 mask; 4901fd2a6b71SDan Nowlin u8 j; 4902fd2a6b71SDan Nowlin 4903fd2a6b71SDan Nowlin pr = &rg->r_group.pairs[i]; 4904fd2a6b71SDan Nowlin mask = rg->r_group.mask[i]; 4905fd2a6b71SDan Nowlin 4906fd2a6b71SDan Nowlin for (j = 0; j < hw->blk[ICE_BLK_SW].es.fvw; j++) 4907fd2a6b71SDan Nowlin if (fv_ext[j].prot_id == pr->prot_id && 4908fd2a6b71SDan Nowlin fv_ext[j].off == pr->off) { 4909fd2a6b71SDan Nowlin found = true; 4910fd2a6b71SDan Nowlin 4911fd2a6b71SDan Nowlin /* Store index of field vector */ 4912fd2a6b71SDan Nowlin rg->fv_idx[i] = j; 4913fd2a6b71SDan Nowlin rg->fv_mask[i] = mask; 4914fd2a6b71SDan Nowlin break; 4915fd2a6b71SDan Nowlin } 4916fd2a6b71SDan Nowlin 4917fd2a6b71SDan Nowlin /* Protocol/offset could not be found, caller gave an 4918fd2a6b71SDan Nowlin * invalid pair 4919fd2a6b71SDan Nowlin */ 4920fd2a6b71SDan Nowlin if (!found) 4921d54699e2STony Nguyen return -EINVAL; 4922fd2a6b71SDan Nowlin } 4923fd2a6b71SDan Nowlin } 4924fd2a6b71SDan Nowlin 4925fd2a6b71SDan Nowlin return 0; 4926fd2a6b71SDan Nowlin } 4927fd2a6b71SDan Nowlin 4928fd2a6b71SDan Nowlin /** 4929fd2a6b71SDan Nowlin * ice_find_free_recp_res_idx - find free result indexes for recipe 4930fd2a6b71SDan Nowlin * @hw: pointer to hardware structure 4931fd2a6b71SDan Nowlin * @profiles: bitmap of profiles that will be associated with the new recipe 4932fd2a6b71SDan Nowlin * @free_idx: pointer to variable to receive the free index bitmap 4933fd2a6b71SDan Nowlin * 4934fd2a6b71SDan Nowlin * The algorithm used here is: 4935fd2a6b71SDan Nowlin * 1. When creating a new recipe, create a set P which contains all 4936fd2a6b71SDan Nowlin * Profiles that will be associated with our new recipe 4937fd2a6b71SDan Nowlin * 4938fd2a6b71SDan Nowlin * 2. For each Profile p in set P: 4939fd2a6b71SDan Nowlin * a. Add all recipes associated with Profile p into set R 4940fd2a6b71SDan Nowlin * b. Optional : PossibleIndexes &= profile[p].possibleIndexes 4941fd2a6b71SDan Nowlin * [initially PossibleIndexes should be 0xFFFFFFFFFFFFFFFF] 4942fd2a6b71SDan Nowlin * i. Or just assume they all have the same possible indexes: 4943fd2a6b71SDan Nowlin * 44, 45, 46, 47 4944fd2a6b71SDan Nowlin * i.e., PossibleIndexes = 0x0000F00000000000 4945fd2a6b71SDan Nowlin * 4946fd2a6b71SDan Nowlin * 3. For each Recipe r in set R: 4947fd2a6b71SDan Nowlin * a. UsedIndexes |= (bitwise or ) recipe[r].res_indexes 4948fd2a6b71SDan Nowlin * b. FreeIndexes = UsedIndexes ^ PossibleIndexes 4949fd2a6b71SDan Nowlin * 4950fd2a6b71SDan Nowlin * FreeIndexes will contain the bits indicating the indexes free for use, 4951fd2a6b71SDan Nowlin * then the code needs to update the recipe[r].used_result_idx_bits to 4952fd2a6b71SDan Nowlin * indicate which indexes were selected for use by this recipe. 4953fd2a6b71SDan Nowlin */ 4954fd2a6b71SDan Nowlin static u16 4955fd2a6b71SDan Nowlin ice_find_free_recp_res_idx(struct ice_hw *hw, const unsigned long *profiles, 4956fd2a6b71SDan Nowlin unsigned long *free_idx) 4957fd2a6b71SDan Nowlin { 4958fd2a6b71SDan Nowlin DECLARE_BITMAP(possible_idx, ICE_MAX_FV_WORDS); 4959fd2a6b71SDan Nowlin DECLARE_BITMAP(recipes, ICE_MAX_NUM_RECIPES); 4960fd2a6b71SDan Nowlin DECLARE_BITMAP(used_idx, ICE_MAX_FV_WORDS); 4961fd2a6b71SDan Nowlin u16 bit; 4962fd2a6b71SDan Nowlin 4963fd2a6b71SDan Nowlin bitmap_zero(recipes, ICE_MAX_NUM_RECIPES); 4964fd2a6b71SDan Nowlin bitmap_zero(used_idx, ICE_MAX_FV_WORDS); 4965fd2a6b71SDan Nowlin 49662f7ee2a7SAlexander Lobakin bitmap_fill(possible_idx, ICE_MAX_FV_WORDS); 4967fd2a6b71SDan Nowlin 4968fd2a6b71SDan Nowlin /* For each profile we are going to associate the recipe with, add the 4969fd2a6b71SDan Nowlin * recipes that are associated with that profile. This will give us 4970fd2a6b71SDan Nowlin * the set of recipes that our recipe may collide with. Also, determine 4971fd2a6b71SDan Nowlin * what possible result indexes are usable given this set of profiles. 4972fd2a6b71SDan Nowlin */ 4973fd2a6b71SDan Nowlin for_each_set_bit(bit, profiles, ICE_MAX_NUM_PROFILES) { 4974fd2a6b71SDan Nowlin bitmap_or(recipes, recipes, profile_to_recipe[bit], 4975fd2a6b71SDan Nowlin ICE_MAX_NUM_RECIPES); 4976fd2a6b71SDan Nowlin bitmap_and(possible_idx, possible_idx, 4977fd2a6b71SDan Nowlin hw->switch_info->prof_res_bm[bit], 4978fd2a6b71SDan Nowlin ICE_MAX_FV_WORDS); 4979fd2a6b71SDan Nowlin } 4980fd2a6b71SDan Nowlin 4981fd2a6b71SDan Nowlin /* For each recipe that our new recipe may collide with, determine 4982fd2a6b71SDan Nowlin * which indexes have been used. 4983fd2a6b71SDan Nowlin */ 4984fd2a6b71SDan Nowlin for_each_set_bit(bit, recipes, ICE_MAX_NUM_RECIPES) 4985fd2a6b71SDan Nowlin bitmap_or(used_idx, used_idx, 4986fd2a6b71SDan Nowlin hw->switch_info->recp_list[bit].res_idxs, 4987fd2a6b71SDan Nowlin ICE_MAX_FV_WORDS); 4988fd2a6b71SDan Nowlin 4989fd2a6b71SDan Nowlin bitmap_xor(free_idx, used_idx, possible_idx, ICE_MAX_FV_WORDS); 4990fd2a6b71SDan Nowlin 4991fd2a6b71SDan Nowlin /* return number of free indexes */ 4992fd2a6b71SDan Nowlin return (u16)bitmap_weight(free_idx, ICE_MAX_FV_WORDS); 4993fd2a6b71SDan Nowlin } 4994fd2a6b71SDan Nowlin 4995fd2a6b71SDan Nowlin /** 4996fd2a6b71SDan Nowlin * ice_add_sw_recipe - function to call AQ calls to create switch recipe 4997fd2a6b71SDan Nowlin * @hw: pointer to hardware structure 4998fd2a6b71SDan Nowlin * @rm: recipe management list entry 4999fd2a6b71SDan Nowlin * @profiles: bitmap of profiles that will be associated. 5000fd2a6b71SDan Nowlin */ 50015e24d598STony Nguyen static int 5002fd2a6b71SDan Nowlin ice_add_sw_recipe(struct ice_hw *hw, struct ice_sw_recipe *rm, 50038b032a55SMichal Swiatkowski unsigned long *profiles) 5004fd2a6b71SDan Nowlin { 5005fd2a6b71SDan Nowlin DECLARE_BITMAP(result_idx_bm, ICE_MAX_FV_WORDS); 5006bccd9bceSMarcin Szycik struct ice_aqc_recipe_content *content; 5007fd2a6b71SDan Nowlin struct ice_aqc_recipe_data_elem *tmp; 5008fd2a6b71SDan Nowlin struct ice_aqc_recipe_data_elem *buf; 5009fd2a6b71SDan Nowlin struct ice_recp_grp_entry *entry; 5010fd2a6b71SDan Nowlin u16 free_res_idx; 5011fd2a6b71SDan Nowlin u16 recipe_count; 5012fd2a6b71SDan Nowlin u8 chain_idx; 5013fd2a6b71SDan Nowlin u8 recps = 0; 50145518ac2aSTony Nguyen int status; 5015fd2a6b71SDan Nowlin 5016fd2a6b71SDan Nowlin /* When more than one recipe are required, another recipe is needed to 5017fd2a6b71SDan Nowlin * chain them together. Matching a tunnel metadata ID takes up one of 5018fd2a6b71SDan Nowlin * the match fields in the chaining recipe reducing the number of 5019fd2a6b71SDan Nowlin * chained recipes by one. 5020fd2a6b71SDan Nowlin */ 5021fd2a6b71SDan Nowlin /* check number of free result indices */ 5022fd2a6b71SDan Nowlin bitmap_zero(result_idx_bm, ICE_MAX_FV_WORDS); 5023fd2a6b71SDan Nowlin free_res_idx = ice_find_free_recp_res_idx(hw, profiles, result_idx_bm); 5024fd2a6b71SDan Nowlin 5025fd2a6b71SDan Nowlin ice_debug(hw, ICE_DBG_SW, "Result idx slots: %d, need %d\n", 5026fd2a6b71SDan Nowlin free_res_idx, rm->n_grp_count); 5027fd2a6b71SDan Nowlin 5028fd2a6b71SDan Nowlin if (rm->n_grp_count > 1) { 5029fd2a6b71SDan Nowlin if (rm->n_grp_count > free_res_idx) 5030d54699e2STony Nguyen return -ENOSPC; 5031fd2a6b71SDan Nowlin 5032fd2a6b71SDan Nowlin rm->n_grp_count++; 5033fd2a6b71SDan Nowlin } 5034fd2a6b71SDan Nowlin 5035fd2a6b71SDan Nowlin if (rm->n_grp_count > ICE_MAX_CHAIN_RECIPE) 5036d54699e2STony Nguyen return -ENOSPC; 5037fd2a6b71SDan Nowlin 5038fd2a6b71SDan Nowlin tmp = kcalloc(ICE_MAX_NUM_RECIPES, sizeof(*tmp), GFP_KERNEL); 5039fd2a6b71SDan Nowlin if (!tmp) 5040d54699e2STony Nguyen return -ENOMEM; 5041fd2a6b71SDan Nowlin 5042fd2a6b71SDan Nowlin buf = devm_kcalloc(ice_hw_to_dev(hw), rm->n_grp_count, sizeof(*buf), 5043fd2a6b71SDan Nowlin GFP_KERNEL); 5044fd2a6b71SDan Nowlin if (!buf) { 5045d54699e2STony Nguyen status = -ENOMEM; 5046fd2a6b71SDan Nowlin goto err_mem; 5047fd2a6b71SDan Nowlin } 5048fd2a6b71SDan Nowlin 5049fd2a6b71SDan Nowlin bitmap_zero(rm->r_bitmap, ICE_MAX_NUM_RECIPES); 5050fd2a6b71SDan Nowlin recipe_count = ICE_MAX_NUM_RECIPES; 5051fd2a6b71SDan Nowlin status = ice_aq_get_recipe(hw, tmp, &recipe_count, ICE_SW_LKUP_MAC, 5052fd2a6b71SDan Nowlin NULL); 5053fd2a6b71SDan Nowlin if (status || recipe_count == 0) 5054fd2a6b71SDan Nowlin goto err_unroll; 5055fd2a6b71SDan Nowlin 5056fd2a6b71SDan Nowlin /* Allocate the recipe resources, and configure them according to the 5057fd2a6b71SDan Nowlin * match fields from protocol headers and extracted field vectors. 5058fd2a6b71SDan Nowlin */ 5059fd2a6b71SDan Nowlin chain_idx = find_first_bit(result_idx_bm, ICE_MAX_FV_WORDS); 5060fd2a6b71SDan Nowlin list_for_each_entry(entry, &rm->rg_list, l_entry) { 5061fd2a6b71SDan Nowlin u8 i; 5062fd2a6b71SDan Nowlin 5063fd2a6b71SDan Nowlin status = ice_alloc_recipe(hw, &entry->rid); 5064fd2a6b71SDan Nowlin if (status) 5065fd2a6b71SDan Nowlin goto err_unroll; 5066fd2a6b71SDan Nowlin 5067bccd9bceSMarcin Szycik content = &buf[recps].content; 5068bccd9bceSMarcin Szycik 5069fd2a6b71SDan Nowlin /* Clear the result index of the located recipe, as this will be 5070fd2a6b71SDan Nowlin * updated, if needed, later in the recipe creation process. 5071fd2a6b71SDan Nowlin */ 5072fd2a6b71SDan Nowlin tmp[0].content.result_indx = 0; 5073fd2a6b71SDan Nowlin 5074fd2a6b71SDan Nowlin buf[recps] = tmp[0]; 5075fd2a6b71SDan Nowlin buf[recps].recipe_indx = (u8)entry->rid; 5076fd2a6b71SDan Nowlin /* if the recipe is a non-root recipe RID should be programmed 5077fd2a6b71SDan Nowlin * as 0 for the rules to be applied correctly. 5078fd2a6b71SDan Nowlin */ 5079bccd9bceSMarcin Szycik content->rid = 0; 5080bccd9bceSMarcin Szycik memset(&content->lkup_indx, 0, 5081bccd9bceSMarcin Szycik sizeof(content->lkup_indx)); 5082fd2a6b71SDan Nowlin 5083fd2a6b71SDan Nowlin /* All recipes use look-up index 0 to match switch ID. */ 5084bccd9bceSMarcin Szycik content->lkup_indx[0] = ICE_AQ_SW_ID_LKUP_IDX; 5085bccd9bceSMarcin Szycik content->mask[0] = cpu_to_le16(ICE_AQ_SW_ID_LKUP_MASK); 5086fd2a6b71SDan Nowlin /* Setup lkup_indx 1..4 to INVALID/ignore and set the mask 5087fd2a6b71SDan Nowlin * to be 0 5088fd2a6b71SDan Nowlin */ 5089fd2a6b71SDan Nowlin for (i = 1; i <= ICE_NUM_WORDS_RECIPE; i++) { 5090bccd9bceSMarcin Szycik content->lkup_indx[i] = 0x80; 5091bccd9bceSMarcin Szycik content->mask[i] = 0; 5092fd2a6b71SDan Nowlin } 5093fd2a6b71SDan Nowlin 5094fd2a6b71SDan Nowlin for (i = 0; i < entry->r_group.n_val_pairs; i++) { 5095bccd9bceSMarcin Szycik content->lkup_indx[i + 1] = entry->fv_idx[i]; 5096bccd9bceSMarcin Szycik content->mask[i + 1] = cpu_to_le16(entry->fv_mask[i]); 5097fd2a6b71SDan Nowlin } 5098fd2a6b71SDan Nowlin 5099fd2a6b71SDan Nowlin if (rm->n_grp_count > 1) { 5100fd2a6b71SDan Nowlin /* Checks to see if there really is a valid result index 5101fd2a6b71SDan Nowlin * that can be used. 5102fd2a6b71SDan Nowlin */ 5103fd2a6b71SDan Nowlin if (chain_idx >= ICE_MAX_FV_WORDS) { 5104fd2a6b71SDan Nowlin ice_debug(hw, ICE_DBG_SW, "No chain index available\n"); 5105d54699e2STony Nguyen status = -ENOSPC; 5106fd2a6b71SDan Nowlin goto err_unroll; 5107fd2a6b71SDan Nowlin } 5108fd2a6b71SDan Nowlin 5109fd2a6b71SDan Nowlin entry->chain_idx = chain_idx; 5110bccd9bceSMarcin Szycik content->result_indx = 5111fd2a6b71SDan Nowlin ICE_AQ_RECIPE_RESULT_EN | 5112fd2a6b71SDan Nowlin ((chain_idx << ICE_AQ_RECIPE_RESULT_DATA_S) & 5113fd2a6b71SDan Nowlin ICE_AQ_RECIPE_RESULT_DATA_M); 5114fd2a6b71SDan Nowlin clear_bit(chain_idx, result_idx_bm); 5115fd2a6b71SDan Nowlin chain_idx = find_first_bit(result_idx_bm, 5116fd2a6b71SDan Nowlin ICE_MAX_FV_WORDS); 5117fd2a6b71SDan Nowlin } 5118fd2a6b71SDan Nowlin 5119fd2a6b71SDan Nowlin /* fill recipe dependencies */ 5120fd2a6b71SDan Nowlin bitmap_zero((unsigned long *)buf[recps].recipe_bitmap, 5121fd2a6b71SDan Nowlin ICE_MAX_NUM_RECIPES); 5122fd2a6b71SDan Nowlin set_bit(buf[recps].recipe_indx, 5123fd2a6b71SDan Nowlin (unsigned long *)buf[recps].recipe_bitmap); 5124bccd9bceSMarcin Szycik content->act_ctrl_fwd_priority = rm->priority; 5125bccd9bceSMarcin Szycik 5126bccd9bceSMarcin Szycik if (rm->need_pass_l2) 5127bccd9bceSMarcin Szycik content->act_ctrl |= ICE_AQ_RECIPE_ACT_NEED_PASS_L2; 5128bccd9bceSMarcin Szycik 5129bccd9bceSMarcin Szycik if (rm->allow_pass_l2) 5130bccd9bceSMarcin Szycik content->act_ctrl |= ICE_AQ_RECIPE_ACT_ALLOW_PASS_L2; 5131fd2a6b71SDan Nowlin recps++; 5132fd2a6b71SDan Nowlin } 5133fd2a6b71SDan Nowlin 5134fd2a6b71SDan Nowlin if (rm->n_grp_count == 1) { 5135fd2a6b71SDan Nowlin rm->root_rid = buf[0].recipe_indx; 5136fd2a6b71SDan Nowlin set_bit(buf[0].recipe_indx, rm->r_bitmap); 5137fd2a6b71SDan Nowlin buf[0].content.rid = rm->root_rid | ICE_AQ_RECIPE_ID_IS_ROOT; 5138fd2a6b71SDan Nowlin if (sizeof(buf[0].recipe_bitmap) >= sizeof(rm->r_bitmap)) { 5139fd2a6b71SDan Nowlin memcpy(buf[0].recipe_bitmap, rm->r_bitmap, 5140fd2a6b71SDan Nowlin sizeof(buf[0].recipe_bitmap)); 5141fd2a6b71SDan Nowlin } else { 5142d54699e2STony Nguyen status = -EINVAL; 5143fd2a6b71SDan Nowlin goto err_unroll; 5144fd2a6b71SDan Nowlin } 5145fd2a6b71SDan Nowlin /* Applicable only for ROOT_RECIPE, set the fwd_priority for 5146fd2a6b71SDan Nowlin * the recipe which is getting created if specified 5147fd2a6b71SDan Nowlin * by user. Usually any advanced switch filter, which results 5148fd2a6b71SDan Nowlin * into new extraction sequence, ended up creating a new recipe 5149fd2a6b71SDan Nowlin * of type ROOT and usually recipes are associated with profiles 5150fd2a6b71SDan Nowlin * Switch rule referreing newly created recipe, needs to have 5151fd2a6b71SDan Nowlin * either/or 'fwd' or 'join' priority, otherwise switch rule 5152fd2a6b71SDan Nowlin * evaluation will not happen correctly. In other words, if 5153fd2a6b71SDan Nowlin * switch rule to be evaluated on priority basis, then recipe 5154fd2a6b71SDan Nowlin * needs to have priority, otherwise it will be evaluated last. 5155fd2a6b71SDan Nowlin */ 5156fd2a6b71SDan Nowlin buf[0].content.act_ctrl_fwd_priority = rm->priority; 5157fd2a6b71SDan Nowlin } else { 5158fd2a6b71SDan Nowlin struct ice_recp_grp_entry *last_chain_entry; 5159fd2a6b71SDan Nowlin u16 rid, i; 5160fd2a6b71SDan Nowlin 5161fd2a6b71SDan Nowlin /* Allocate the last recipe that will chain the outcomes of the 5162fd2a6b71SDan Nowlin * other recipes together 5163fd2a6b71SDan Nowlin */ 5164fd2a6b71SDan Nowlin status = ice_alloc_recipe(hw, &rid); 5165fd2a6b71SDan Nowlin if (status) 5166fd2a6b71SDan Nowlin goto err_unroll; 5167fd2a6b71SDan Nowlin 5168bccd9bceSMarcin Szycik content = &buf[recps].content; 5169bccd9bceSMarcin Szycik 5170fd2a6b71SDan Nowlin buf[recps].recipe_indx = (u8)rid; 5171bccd9bceSMarcin Szycik content->rid = (u8)rid; 5172bccd9bceSMarcin Szycik content->rid |= ICE_AQ_RECIPE_ID_IS_ROOT; 5173fd2a6b71SDan Nowlin /* the new entry created should also be part of rg_list to 5174fd2a6b71SDan Nowlin * make sure we have complete recipe 5175fd2a6b71SDan Nowlin */ 5176fd2a6b71SDan Nowlin last_chain_entry = devm_kzalloc(ice_hw_to_dev(hw), 5177fd2a6b71SDan Nowlin sizeof(*last_chain_entry), 5178fd2a6b71SDan Nowlin GFP_KERNEL); 5179fd2a6b71SDan Nowlin if (!last_chain_entry) { 5180d54699e2STony Nguyen status = -ENOMEM; 5181fd2a6b71SDan Nowlin goto err_unroll; 5182fd2a6b71SDan Nowlin } 5183fd2a6b71SDan Nowlin last_chain_entry->rid = rid; 5184bccd9bceSMarcin Szycik memset(&content->lkup_indx, 0, sizeof(content->lkup_indx)); 5185fd2a6b71SDan Nowlin /* All recipes use look-up index 0 to match switch ID. */ 5186bccd9bceSMarcin Szycik content->lkup_indx[0] = ICE_AQ_SW_ID_LKUP_IDX; 5187bccd9bceSMarcin Szycik content->mask[0] = cpu_to_le16(ICE_AQ_SW_ID_LKUP_MASK); 5188fd2a6b71SDan Nowlin for (i = 1; i <= ICE_NUM_WORDS_RECIPE; i++) { 5189bccd9bceSMarcin Szycik content->lkup_indx[i] = ICE_AQ_RECIPE_LKUP_IGNORE; 5190bccd9bceSMarcin Szycik content->mask[i] = 0; 5191fd2a6b71SDan Nowlin } 5192fd2a6b71SDan Nowlin 5193fd2a6b71SDan Nowlin i = 1; 5194fd2a6b71SDan Nowlin /* update r_bitmap with the recp that is used for chaining */ 5195fd2a6b71SDan Nowlin set_bit(rid, rm->r_bitmap); 5196fd2a6b71SDan Nowlin /* this is the recipe that chains all the other recipes so it 5197fd2a6b71SDan Nowlin * should not have a chaining ID to indicate the same 5198fd2a6b71SDan Nowlin */ 5199fd2a6b71SDan Nowlin last_chain_entry->chain_idx = ICE_INVAL_CHAIN_IND; 5200fd2a6b71SDan Nowlin list_for_each_entry(entry, &rm->rg_list, l_entry) { 5201fd2a6b71SDan Nowlin last_chain_entry->fv_idx[i] = entry->chain_idx; 5202bccd9bceSMarcin Szycik content->lkup_indx[i] = entry->chain_idx; 5203bccd9bceSMarcin Szycik content->mask[i++] = cpu_to_le16(0xFFFF); 5204fd2a6b71SDan Nowlin set_bit(entry->rid, rm->r_bitmap); 5205fd2a6b71SDan Nowlin } 5206fd2a6b71SDan Nowlin list_add(&last_chain_entry->l_entry, &rm->rg_list); 5207fd2a6b71SDan Nowlin if (sizeof(buf[recps].recipe_bitmap) >= 5208fd2a6b71SDan Nowlin sizeof(rm->r_bitmap)) { 5209fd2a6b71SDan Nowlin memcpy(buf[recps].recipe_bitmap, rm->r_bitmap, 5210fd2a6b71SDan Nowlin sizeof(buf[recps].recipe_bitmap)); 5211fd2a6b71SDan Nowlin } else { 5212d54699e2STony Nguyen status = -EINVAL; 5213fd2a6b71SDan Nowlin goto err_unroll; 5214fd2a6b71SDan Nowlin } 5215bccd9bceSMarcin Szycik content->act_ctrl_fwd_priority = rm->priority; 5216fd2a6b71SDan Nowlin 5217fd2a6b71SDan Nowlin recps++; 5218fd2a6b71SDan Nowlin rm->root_rid = (u8)rid; 5219fd2a6b71SDan Nowlin } 5220fd2a6b71SDan Nowlin status = ice_acquire_change_lock(hw, ICE_RES_WRITE); 5221fd2a6b71SDan Nowlin if (status) 5222fd2a6b71SDan Nowlin goto err_unroll; 5223fd2a6b71SDan Nowlin 5224fd2a6b71SDan Nowlin status = ice_aq_add_recipe(hw, buf, rm->n_grp_count, NULL); 5225fd2a6b71SDan Nowlin ice_release_change_lock(hw); 5226fd2a6b71SDan Nowlin if (status) 5227fd2a6b71SDan Nowlin goto err_unroll; 5228fd2a6b71SDan Nowlin 5229fd2a6b71SDan Nowlin /* Every recipe that just got created add it to the recipe 5230fd2a6b71SDan Nowlin * book keeping list 5231fd2a6b71SDan Nowlin */ 5232fd2a6b71SDan Nowlin list_for_each_entry(entry, &rm->rg_list, l_entry) { 5233fd2a6b71SDan Nowlin struct ice_switch_info *sw = hw->switch_info; 5234fd2a6b71SDan Nowlin bool is_root, idx_found = false; 5235fd2a6b71SDan Nowlin struct ice_sw_recipe *recp; 5236fd2a6b71SDan Nowlin u16 idx, buf_idx = 0; 5237fd2a6b71SDan Nowlin 5238fd2a6b71SDan Nowlin /* find buffer index for copying some data */ 5239fd2a6b71SDan Nowlin for (idx = 0; idx < rm->n_grp_count; idx++) 5240fd2a6b71SDan Nowlin if (buf[idx].recipe_indx == entry->rid) { 5241fd2a6b71SDan Nowlin buf_idx = idx; 5242fd2a6b71SDan Nowlin idx_found = true; 5243fd2a6b71SDan Nowlin } 5244fd2a6b71SDan Nowlin 5245fd2a6b71SDan Nowlin if (!idx_found) { 5246d54699e2STony Nguyen status = -EIO; 5247fd2a6b71SDan Nowlin goto err_unroll; 5248fd2a6b71SDan Nowlin } 5249fd2a6b71SDan Nowlin 5250fd2a6b71SDan Nowlin recp = &sw->recp_list[entry->rid]; 5251fd2a6b71SDan Nowlin is_root = (rm->root_rid == entry->rid); 5252fd2a6b71SDan Nowlin recp->is_root = is_root; 5253fd2a6b71SDan Nowlin 5254fd2a6b71SDan Nowlin recp->root_rid = entry->rid; 5255fd2a6b71SDan Nowlin recp->big_recp = (is_root && rm->n_grp_count > 1); 5256fd2a6b71SDan Nowlin 5257fd2a6b71SDan Nowlin memcpy(&recp->ext_words, entry->r_group.pairs, 5258fd2a6b71SDan Nowlin entry->r_group.n_val_pairs * sizeof(struct ice_fv_word)); 5259fd2a6b71SDan Nowlin 5260fd2a6b71SDan Nowlin memcpy(recp->r_bitmap, buf[buf_idx].recipe_bitmap, 5261fd2a6b71SDan Nowlin sizeof(recp->r_bitmap)); 5262fd2a6b71SDan Nowlin 5263fd2a6b71SDan Nowlin /* Copy non-result fv index values and masks to recipe. This 5264fd2a6b71SDan Nowlin * call will also update the result recipe bitmask. 5265fd2a6b71SDan Nowlin */ 5266fd2a6b71SDan Nowlin ice_collect_result_idx(&buf[buf_idx], recp); 5267fd2a6b71SDan Nowlin 5268fd2a6b71SDan Nowlin /* for non-root recipes, also copy to the root, this allows 5269fd2a6b71SDan Nowlin * easier matching of a complete chained recipe 5270fd2a6b71SDan Nowlin */ 5271fd2a6b71SDan Nowlin if (!is_root) 5272fd2a6b71SDan Nowlin ice_collect_result_idx(&buf[buf_idx], 5273fd2a6b71SDan Nowlin &sw->recp_list[rm->root_rid]); 5274fd2a6b71SDan Nowlin 5275fd2a6b71SDan Nowlin recp->n_ext_words = entry->r_group.n_val_pairs; 5276fd2a6b71SDan Nowlin recp->chain_idx = entry->chain_idx; 5277fd2a6b71SDan Nowlin recp->priority = buf[buf_idx].content.act_ctrl_fwd_priority; 5278fd2a6b71SDan Nowlin recp->n_grp_count = rm->n_grp_count; 52798b032a55SMichal Swiatkowski recp->tun_type = rm->tun_type; 5280bccd9bceSMarcin Szycik recp->need_pass_l2 = rm->need_pass_l2; 5281bccd9bceSMarcin Szycik recp->allow_pass_l2 = rm->allow_pass_l2; 5282fd2a6b71SDan Nowlin recp->recp_created = true; 5283fd2a6b71SDan Nowlin } 5284fd2a6b71SDan Nowlin rm->root_buf = buf; 5285fd2a6b71SDan Nowlin kfree(tmp); 5286fd2a6b71SDan Nowlin return status; 5287fd2a6b71SDan Nowlin 5288fd2a6b71SDan Nowlin err_unroll: 5289fd2a6b71SDan Nowlin err_mem: 5290fd2a6b71SDan Nowlin kfree(tmp); 5291fd2a6b71SDan Nowlin devm_kfree(ice_hw_to_dev(hw), buf); 5292fd2a6b71SDan Nowlin return status; 5293fd2a6b71SDan Nowlin } 5294fd2a6b71SDan Nowlin 5295fd2a6b71SDan Nowlin /** 5296fd2a6b71SDan Nowlin * ice_create_recipe_group - creates recipe group 5297fd2a6b71SDan Nowlin * @hw: pointer to hardware structure 5298fd2a6b71SDan Nowlin * @rm: recipe management list entry 5299fd2a6b71SDan Nowlin * @lkup_exts: lookup elements 5300fd2a6b71SDan Nowlin */ 53015e24d598STony Nguyen static int 5302fd2a6b71SDan Nowlin ice_create_recipe_group(struct ice_hw *hw, struct ice_sw_recipe *rm, 5303fd2a6b71SDan Nowlin struct ice_prot_lkup_ext *lkup_exts) 5304fd2a6b71SDan Nowlin { 5305fd2a6b71SDan Nowlin u8 recp_count = 0; 53065518ac2aSTony Nguyen int status; 5307fd2a6b71SDan Nowlin 5308fd2a6b71SDan Nowlin rm->n_grp_count = 0; 5309fd2a6b71SDan Nowlin 5310fd2a6b71SDan Nowlin /* Create recipes for words that are marked not done by packing them 5311fd2a6b71SDan Nowlin * as best fit. 5312fd2a6b71SDan Nowlin */ 5313fd2a6b71SDan Nowlin status = ice_create_first_fit_recp_def(hw, lkup_exts, 5314fd2a6b71SDan Nowlin &rm->rg_list, &recp_count); 5315fd2a6b71SDan Nowlin if (!status) { 5316fd2a6b71SDan Nowlin rm->n_grp_count += recp_count; 5317fd2a6b71SDan Nowlin rm->n_ext_words = lkup_exts->n_val_words; 5318fd2a6b71SDan Nowlin memcpy(&rm->ext_words, lkup_exts->fv_words, 5319fd2a6b71SDan Nowlin sizeof(rm->ext_words)); 5320fd2a6b71SDan Nowlin memcpy(rm->word_masks, lkup_exts->field_mask, 5321fd2a6b71SDan Nowlin sizeof(rm->word_masks)); 5322fd2a6b71SDan Nowlin } 5323fd2a6b71SDan Nowlin 5324fd2a6b71SDan Nowlin return status; 5325fd2a6b71SDan Nowlin } 5326fd2a6b71SDan Nowlin 5327fd2a6b71SDan Nowlin /* ice_get_compat_fv_bitmap - Get compatible field vector bitmap for rule 5328fd2a6b71SDan Nowlin * @hw: pointer to hardware structure 5329fd2a6b71SDan Nowlin * @rinfo: other information regarding the rule e.g. priority and action info 5330fd2a6b71SDan Nowlin * @bm: pointer to memory for returning the bitmap of field vectors 5331fd2a6b71SDan Nowlin */ 5332fd2a6b71SDan Nowlin static void 5333fd2a6b71SDan Nowlin ice_get_compat_fv_bitmap(struct ice_hw *hw, struct ice_adv_rule_info *rinfo, 5334fd2a6b71SDan Nowlin unsigned long *bm) 5335fd2a6b71SDan Nowlin { 53368b032a55SMichal Swiatkowski enum ice_prof_type prof_type; 53378b032a55SMichal Swiatkowski 5338fd2a6b71SDan Nowlin bitmap_zero(bm, ICE_MAX_NUM_PROFILES); 5339fd2a6b71SDan Nowlin 53408b032a55SMichal Swiatkowski switch (rinfo->tun_type) { 53418b032a55SMichal Swiatkowski case ICE_NON_TUN: 53428b032a55SMichal Swiatkowski prof_type = ICE_PROF_NON_TUN; 53438b032a55SMichal Swiatkowski break; 53448b032a55SMichal Swiatkowski case ICE_ALL_TUNNELS: 53458b032a55SMichal Swiatkowski prof_type = ICE_PROF_TUN_ALL; 53468b032a55SMichal Swiatkowski break; 53478b032a55SMichal Swiatkowski case ICE_SW_TUN_GENEVE: 53488b032a55SMichal Swiatkowski case ICE_SW_TUN_VXLAN: 53498b032a55SMichal Swiatkowski prof_type = ICE_PROF_TUN_UDP; 53508b032a55SMichal Swiatkowski break; 5351f0a35040SMichal Swiatkowski case ICE_SW_TUN_NVGRE: 5352f0a35040SMichal Swiatkowski prof_type = ICE_PROF_TUN_GRE; 5353f0a35040SMichal Swiatkowski break; 53549a225f81SMarcin Szycik case ICE_SW_TUN_GTPU: 53559a225f81SMarcin Szycik prof_type = ICE_PROF_TUN_GTPU; 53569a225f81SMarcin Szycik break; 53579a225f81SMarcin Szycik case ICE_SW_TUN_GTPC: 53589a225f81SMarcin Szycik prof_type = ICE_PROF_TUN_GTPC; 53599a225f81SMarcin Szycik break; 5360b70bc066SWojciech Drewek case ICE_SW_TUN_AND_NON_TUN: 53618b032a55SMichal Swiatkowski default: 53628b032a55SMichal Swiatkowski prof_type = ICE_PROF_ALL; 53638b032a55SMichal Swiatkowski break; 53648b032a55SMichal Swiatkowski } 53658b032a55SMichal Swiatkowski 53668b032a55SMichal Swiatkowski ice_get_sw_fv_bitmap(hw, prof_type, bm); 5367fd2a6b71SDan Nowlin } 5368fd2a6b71SDan Nowlin 5369fd2a6b71SDan Nowlin /** 5370fd2a6b71SDan Nowlin * ice_add_adv_recipe - Add an advanced recipe that is not part of the default 5371fd2a6b71SDan Nowlin * @hw: pointer to hardware structure 5372fd2a6b71SDan Nowlin * @lkups: lookup elements or match criteria for the advanced recipe, one 5373fd2a6b71SDan Nowlin * structure per protocol header 5374fd2a6b71SDan Nowlin * @lkups_cnt: number of protocols 5375fd2a6b71SDan Nowlin * @rinfo: other information regarding the rule e.g. priority and action info 5376fd2a6b71SDan Nowlin * @rid: return the recipe ID of the recipe created 5377fd2a6b71SDan Nowlin */ 53785e24d598STony Nguyen static int 5379fd2a6b71SDan Nowlin ice_add_adv_recipe(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups, 5380fd2a6b71SDan Nowlin u16 lkups_cnt, struct ice_adv_rule_info *rinfo, u16 *rid) 5381fd2a6b71SDan Nowlin { 5382fd2a6b71SDan Nowlin DECLARE_BITMAP(fv_bitmap, ICE_MAX_NUM_PROFILES); 5383fd2a6b71SDan Nowlin DECLARE_BITMAP(profiles, ICE_MAX_NUM_PROFILES); 5384fd2a6b71SDan Nowlin struct ice_prot_lkup_ext *lkup_exts; 5385fd2a6b71SDan Nowlin struct ice_recp_grp_entry *r_entry; 5386fd2a6b71SDan Nowlin struct ice_sw_fv_list_entry *fvit; 5387fd2a6b71SDan Nowlin struct ice_recp_grp_entry *r_tmp; 5388fd2a6b71SDan Nowlin struct ice_sw_fv_list_entry *tmp; 5389fd2a6b71SDan Nowlin struct ice_sw_recipe *rm; 53905518ac2aSTony Nguyen int status = 0; 5391fd2a6b71SDan Nowlin u8 i; 5392fd2a6b71SDan Nowlin 5393fd2a6b71SDan Nowlin if (!lkups_cnt) 5394d54699e2STony Nguyen return -EINVAL; 5395fd2a6b71SDan Nowlin 5396fd2a6b71SDan Nowlin lkup_exts = kzalloc(sizeof(*lkup_exts), GFP_KERNEL); 5397fd2a6b71SDan Nowlin if (!lkup_exts) 5398d54699e2STony Nguyen return -ENOMEM; 5399fd2a6b71SDan Nowlin 5400fd2a6b71SDan Nowlin /* Determine the number of words to be matched and if it exceeds a 5401fd2a6b71SDan Nowlin * recipe's restrictions 5402fd2a6b71SDan Nowlin */ 5403fd2a6b71SDan Nowlin for (i = 0; i < lkups_cnt; i++) { 5404fd2a6b71SDan Nowlin u16 count; 5405fd2a6b71SDan Nowlin 5406fd2a6b71SDan Nowlin if (lkups[i].type >= ICE_PROTOCOL_LAST) { 5407d54699e2STony Nguyen status = -EIO; 5408fd2a6b71SDan Nowlin goto err_free_lkup_exts; 5409fd2a6b71SDan Nowlin } 5410fd2a6b71SDan Nowlin 5411fd2a6b71SDan Nowlin count = ice_fill_valid_words(&lkups[i], lkup_exts); 5412fd2a6b71SDan Nowlin if (!count) { 5413d54699e2STony Nguyen status = -EIO; 5414fd2a6b71SDan Nowlin goto err_free_lkup_exts; 5415fd2a6b71SDan Nowlin } 5416fd2a6b71SDan Nowlin } 5417fd2a6b71SDan Nowlin 5418fd2a6b71SDan Nowlin rm = kzalloc(sizeof(*rm), GFP_KERNEL); 5419fd2a6b71SDan Nowlin if (!rm) { 5420d54699e2STony Nguyen status = -ENOMEM; 5421fd2a6b71SDan Nowlin goto err_free_lkup_exts; 5422fd2a6b71SDan Nowlin } 5423fd2a6b71SDan Nowlin 5424fd2a6b71SDan Nowlin /* Get field vectors that contain fields extracted from all the protocol 5425fd2a6b71SDan Nowlin * headers being programmed. 5426fd2a6b71SDan Nowlin */ 5427fd2a6b71SDan Nowlin INIT_LIST_HEAD(&rm->fv_list); 5428fd2a6b71SDan Nowlin INIT_LIST_HEAD(&rm->rg_list); 5429fd2a6b71SDan Nowlin 5430fd2a6b71SDan Nowlin /* Get bitmap of field vectors (profiles) that are compatible with the 5431fd2a6b71SDan Nowlin * rule request; only these will be searched in the subsequent call to 5432e5dd661bSMichal Swiatkowski * ice_get_sw_fv_list. 5433fd2a6b71SDan Nowlin */ 5434fd2a6b71SDan Nowlin ice_get_compat_fv_bitmap(hw, rinfo, fv_bitmap); 5435fd2a6b71SDan Nowlin 5436e5dd661bSMichal Swiatkowski status = ice_get_sw_fv_list(hw, lkup_exts, fv_bitmap, &rm->fv_list); 5437fd2a6b71SDan Nowlin if (status) 5438fd2a6b71SDan Nowlin goto err_unroll; 5439fd2a6b71SDan Nowlin 5440fd2a6b71SDan Nowlin /* Group match words into recipes using preferred recipe grouping 5441fd2a6b71SDan Nowlin * criteria. 5442fd2a6b71SDan Nowlin */ 5443fd2a6b71SDan Nowlin status = ice_create_recipe_group(hw, rm, lkup_exts); 5444fd2a6b71SDan Nowlin if (status) 5445fd2a6b71SDan Nowlin goto err_unroll; 5446fd2a6b71SDan Nowlin 5447fd2a6b71SDan Nowlin /* set the recipe priority if specified */ 5448fd2a6b71SDan Nowlin rm->priority = (u8)rinfo->priority; 5449fd2a6b71SDan Nowlin 5450bccd9bceSMarcin Szycik rm->need_pass_l2 = rinfo->need_pass_l2; 5451bccd9bceSMarcin Szycik rm->allow_pass_l2 = rinfo->allow_pass_l2; 5452bccd9bceSMarcin Szycik 5453fd2a6b71SDan Nowlin /* Find offsets from the field vector. Pick the first one for all the 5454fd2a6b71SDan Nowlin * recipes. 5455fd2a6b71SDan Nowlin */ 5456fd2a6b71SDan Nowlin status = ice_fill_fv_word_index(hw, &rm->fv_list, &rm->rg_list); 5457fd2a6b71SDan Nowlin if (status) 5458fd2a6b71SDan Nowlin goto err_unroll; 5459fd2a6b71SDan Nowlin 5460fd2a6b71SDan Nowlin /* get bitmap of all profiles the recipe will be associated with */ 5461fd2a6b71SDan Nowlin bitmap_zero(profiles, ICE_MAX_NUM_PROFILES); 5462fd2a6b71SDan Nowlin list_for_each_entry(fvit, &rm->fv_list, list_entry) { 5463fd2a6b71SDan Nowlin ice_debug(hw, ICE_DBG_SW, "profile: %d\n", fvit->profile_id); 5464fd2a6b71SDan Nowlin set_bit((u16)fvit->profile_id, profiles); 5465fd2a6b71SDan Nowlin } 5466fd2a6b71SDan Nowlin 5467fd2a6b71SDan Nowlin /* Look for a recipe which matches our requested fv / mask list */ 5468bccd9bceSMarcin Szycik *rid = ice_find_recp(hw, lkup_exts, rinfo); 5469fd2a6b71SDan Nowlin if (*rid < ICE_MAX_NUM_RECIPES) 5470fd2a6b71SDan Nowlin /* Success if found a recipe that match the existing criteria */ 5471fd2a6b71SDan Nowlin goto err_unroll; 5472fd2a6b71SDan Nowlin 5473de6acd1cSMichal Swiatkowski rm->tun_type = rinfo->tun_type; 5474fd2a6b71SDan Nowlin /* Recipe we need does not exist, add a recipe */ 54758b032a55SMichal Swiatkowski status = ice_add_sw_recipe(hw, rm, profiles); 5476fd2a6b71SDan Nowlin if (status) 5477fd2a6b71SDan Nowlin goto err_unroll; 5478fd2a6b71SDan Nowlin 5479fd2a6b71SDan Nowlin /* Associate all the recipes created with all the profiles in the 5480fd2a6b71SDan Nowlin * common field vector. 5481fd2a6b71SDan Nowlin */ 5482fd2a6b71SDan Nowlin list_for_each_entry(fvit, &rm->fv_list, list_entry) { 5483fd2a6b71SDan Nowlin DECLARE_BITMAP(r_bitmap, ICE_MAX_NUM_RECIPES); 5484fd2a6b71SDan Nowlin u16 j; 5485fd2a6b71SDan Nowlin 5486fd2a6b71SDan Nowlin status = ice_aq_get_recipe_to_profile(hw, fvit->profile_id, 5487fd2a6b71SDan Nowlin (u8 *)r_bitmap, NULL); 5488fd2a6b71SDan Nowlin if (status) 5489fd2a6b71SDan Nowlin goto err_unroll; 5490fd2a6b71SDan Nowlin 5491fd2a6b71SDan Nowlin bitmap_or(r_bitmap, r_bitmap, rm->r_bitmap, 5492fd2a6b71SDan Nowlin ICE_MAX_NUM_RECIPES); 5493fd2a6b71SDan Nowlin status = ice_acquire_change_lock(hw, ICE_RES_WRITE); 5494fd2a6b71SDan Nowlin if (status) 5495fd2a6b71SDan Nowlin goto err_unroll; 5496fd2a6b71SDan Nowlin 5497fd2a6b71SDan Nowlin status = ice_aq_map_recipe_to_profile(hw, fvit->profile_id, 5498fd2a6b71SDan Nowlin (u8 *)r_bitmap, 5499fd2a6b71SDan Nowlin NULL); 5500fd2a6b71SDan Nowlin ice_release_change_lock(hw); 5501fd2a6b71SDan Nowlin 5502fd2a6b71SDan Nowlin if (status) 5503fd2a6b71SDan Nowlin goto err_unroll; 5504fd2a6b71SDan Nowlin 5505fd2a6b71SDan Nowlin /* Update profile to recipe bitmap array */ 5506fd2a6b71SDan Nowlin bitmap_copy(profile_to_recipe[fvit->profile_id], r_bitmap, 5507fd2a6b71SDan Nowlin ICE_MAX_NUM_RECIPES); 5508fd2a6b71SDan Nowlin 5509fd2a6b71SDan Nowlin /* Update recipe to profile bitmap array */ 5510fd2a6b71SDan Nowlin for_each_set_bit(j, rm->r_bitmap, ICE_MAX_NUM_RECIPES) 5511fd2a6b71SDan Nowlin set_bit((u16)fvit->profile_id, recipe_to_profile[j]); 5512fd2a6b71SDan Nowlin } 5513fd2a6b71SDan Nowlin 5514fd2a6b71SDan Nowlin *rid = rm->root_rid; 5515fd2a6b71SDan Nowlin memcpy(&hw->switch_info->recp_list[*rid].lkup_exts, lkup_exts, 5516fd2a6b71SDan Nowlin sizeof(*lkup_exts)); 5517fd2a6b71SDan Nowlin err_unroll: 5518fd2a6b71SDan Nowlin list_for_each_entry_safe(r_entry, r_tmp, &rm->rg_list, l_entry) { 5519fd2a6b71SDan Nowlin list_del(&r_entry->l_entry); 5520fd2a6b71SDan Nowlin devm_kfree(ice_hw_to_dev(hw), r_entry); 5521fd2a6b71SDan Nowlin } 5522fd2a6b71SDan Nowlin 5523fd2a6b71SDan Nowlin list_for_each_entry_safe(fvit, tmp, &rm->fv_list, list_entry) { 5524fd2a6b71SDan Nowlin list_del(&fvit->list_entry); 5525fd2a6b71SDan Nowlin devm_kfree(ice_hw_to_dev(hw), fvit); 5526fd2a6b71SDan Nowlin } 5527fd2a6b71SDan Nowlin 5528fd2a6b71SDan Nowlin devm_kfree(ice_hw_to_dev(hw), rm->root_buf); 5529fd2a6b71SDan Nowlin kfree(rm); 5530fd2a6b71SDan Nowlin 5531fd2a6b71SDan Nowlin err_free_lkup_exts: 5532fd2a6b71SDan Nowlin kfree(lkup_exts); 5533fd2a6b71SDan Nowlin 5534fd2a6b71SDan Nowlin return status; 5535fd2a6b71SDan Nowlin } 5536fd2a6b71SDan Nowlin 5537148beb61SHenry Tieman /** 553826395726SMartyna Szapar-Mudlaw * ice_dummy_packet_add_vlan - insert VLAN header to dummy pkt 553926395726SMartyna Szapar-Mudlaw * 554026395726SMartyna Szapar-Mudlaw * @dummy_pkt: dummy packet profile pattern to which VLAN tag(s) will be added 554126395726SMartyna Szapar-Mudlaw * @num_vlan: number of VLAN tags 554226395726SMartyna Szapar-Mudlaw */ 554326395726SMartyna Szapar-Mudlaw static struct ice_dummy_pkt_profile * 554426395726SMartyna Szapar-Mudlaw ice_dummy_packet_add_vlan(const struct ice_dummy_pkt_profile *dummy_pkt, 554526395726SMartyna Szapar-Mudlaw u32 num_vlan) 554626395726SMartyna Szapar-Mudlaw { 554726395726SMartyna Szapar-Mudlaw struct ice_dummy_pkt_profile *profile; 554826395726SMartyna Szapar-Mudlaw struct ice_dummy_pkt_offsets *offsets; 554926395726SMartyna Szapar-Mudlaw u32 buf_len, off, etype_off, i; 555026395726SMartyna Szapar-Mudlaw u8 *pkt; 555126395726SMartyna Szapar-Mudlaw 555226395726SMartyna Szapar-Mudlaw if (num_vlan < 1 || num_vlan > 2) 555326395726SMartyna Szapar-Mudlaw return ERR_PTR(-EINVAL); 555426395726SMartyna Szapar-Mudlaw 555526395726SMartyna Szapar-Mudlaw off = num_vlan * VLAN_HLEN; 555626395726SMartyna Szapar-Mudlaw 555726395726SMartyna Szapar-Mudlaw buf_len = array_size(num_vlan, sizeof(ice_dummy_vlan_packet_offsets)) + 555826395726SMartyna Szapar-Mudlaw dummy_pkt->offsets_len; 555926395726SMartyna Szapar-Mudlaw offsets = kzalloc(buf_len, GFP_KERNEL); 556026395726SMartyna Szapar-Mudlaw if (!offsets) 556126395726SMartyna Szapar-Mudlaw return ERR_PTR(-ENOMEM); 556226395726SMartyna Szapar-Mudlaw 556326395726SMartyna Szapar-Mudlaw offsets[0] = dummy_pkt->offsets[0]; 556426395726SMartyna Szapar-Mudlaw if (num_vlan == 2) { 556526395726SMartyna Szapar-Mudlaw offsets[1] = ice_dummy_qinq_packet_offsets[0]; 556626395726SMartyna Szapar-Mudlaw offsets[2] = ice_dummy_qinq_packet_offsets[1]; 556726395726SMartyna Szapar-Mudlaw } else if (num_vlan == 1) { 556826395726SMartyna Szapar-Mudlaw offsets[1] = ice_dummy_vlan_packet_offsets[0]; 556926395726SMartyna Szapar-Mudlaw } 557026395726SMartyna Szapar-Mudlaw 557126395726SMartyna Szapar-Mudlaw for (i = 1; dummy_pkt->offsets[i].type != ICE_PROTOCOL_LAST; i++) { 557226395726SMartyna Szapar-Mudlaw offsets[i + num_vlan].type = dummy_pkt->offsets[i].type; 557326395726SMartyna Szapar-Mudlaw offsets[i + num_vlan].offset = 557426395726SMartyna Szapar-Mudlaw dummy_pkt->offsets[i].offset + off; 557526395726SMartyna Szapar-Mudlaw } 557626395726SMartyna Szapar-Mudlaw offsets[i + num_vlan] = dummy_pkt->offsets[i]; 557726395726SMartyna Szapar-Mudlaw 557826395726SMartyna Szapar-Mudlaw etype_off = dummy_pkt->offsets[1].offset; 557926395726SMartyna Szapar-Mudlaw 558026395726SMartyna Szapar-Mudlaw buf_len = array_size(num_vlan, sizeof(ice_dummy_vlan_packet)) + 558126395726SMartyna Szapar-Mudlaw dummy_pkt->pkt_len; 558226395726SMartyna Szapar-Mudlaw pkt = kzalloc(buf_len, GFP_KERNEL); 558326395726SMartyna Szapar-Mudlaw if (!pkt) { 558426395726SMartyna Szapar-Mudlaw kfree(offsets); 558526395726SMartyna Szapar-Mudlaw return ERR_PTR(-ENOMEM); 558626395726SMartyna Szapar-Mudlaw } 558726395726SMartyna Szapar-Mudlaw 558826395726SMartyna Szapar-Mudlaw memcpy(pkt, dummy_pkt->pkt, etype_off); 558926395726SMartyna Szapar-Mudlaw memcpy(pkt + etype_off, 559026395726SMartyna Szapar-Mudlaw num_vlan == 2 ? ice_dummy_qinq_packet : ice_dummy_vlan_packet, 559126395726SMartyna Szapar-Mudlaw off); 559226395726SMartyna Szapar-Mudlaw memcpy(pkt + etype_off + off, dummy_pkt->pkt + etype_off, 559326395726SMartyna Szapar-Mudlaw dummy_pkt->pkt_len - etype_off); 559426395726SMartyna Szapar-Mudlaw 559526395726SMartyna Szapar-Mudlaw profile = kzalloc(sizeof(*profile), GFP_KERNEL); 559626395726SMartyna Szapar-Mudlaw if (!profile) { 559726395726SMartyna Szapar-Mudlaw kfree(offsets); 559826395726SMartyna Szapar-Mudlaw kfree(pkt); 559926395726SMartyna Szapar-Mudlaw return ERR_PTR(-ENOMEM); 560026395726SMartyna Szapar-Mudlaw } 560126395726SMartyna Szapar-Mudlaw 560226395726SMartyna Szapar-Mudlaw profile->offsets = offsets; 560326395726SMartyna Szapar-Mudlaw profile->pkt = pkt; 560426395726SMartyna Szapar-Mudlaw profile->pkt_len = buf_len; 560526395726SMartyna Szapar-Mudlaw profile->match |= ICE_PKT_KMALLOC; 560626395726SMartyna Szapar-Mudlaw 560726395726SMartyna Szapar-Mudlaw return profile; 560826395726SMartyna Szapar-Mudlaw } 560926395726SMartyna Szapar-Mudlaw 561026395726SMartyna Szapar-Mudlaw /** 56110f94570dSGrishma Kotecha * ice_find_dummy_packet - find dummy packet 56120f94570dSGrishma Kotecha * 56130f94570dSGrishma Kotecha * @lkups: lookup elements or match criteria for the advanced recipe, one 56140f94570dSGrishma Kotecha * structure per protocol header 56150f94570dSGrishma Kotecha * @lkups_cnt: number of protocols 56168b032a55SMichal Swiatkowski * @tun_type: tunnel type 56171b699f81SAlexander Lobakin * 56181b699f81SAlexander Lobakin * Returns the &ice_dummy_pkt_profile corresponding to these lookup params. 56190f94570dSGrishma Kotecha */ 5620e33163a4SAlexander Lobakin static const struct ice_dummy_pkt_profile * 56210f94570dSGrishma Kotecha ice_find_dummy_packet(struct ice_adv_lkup_elem *lkups, u16 lkups_cnt, 56221b699f81SAlexander Lobakin enum ice_sw_tunnel_type tun_type) 56230f94570dSGrishma Kotecha { 5624e33163a4SAlexander Lobakin const struct ice_dummy_pkt_profile *ret = ice_dummy_pkt_profiles; 562526395726SMartyna Szapar-Mudlaw u32 match = 0, vlan_count = 0; 56260f94570dSGrishma Kotecha u16 i; 56270f94570dSGrishma Kotecha 5628e33163a4SAlexander Lobakin switch (tun_type) { 5629e33163a4SAlexander Lobakin case ICE_SW_TUN_GTPC: 5630e33163a4SAlexander Lobakin match |= ICE_PKT_TUN_GTPC; 5631e33163a4SAlexander Lobakin break; 5632e33163a4SAlexander Lobakin case ICE_SW_TUN_GTPU: 5633e33163a4SAlexander Lobakin match |= ICE_PKT_TUN_GTPU; 5634e33163a4SAlexander Lobakin break; 5635e33163a4SAlexander Lobakin case ICE_SW_TUN_NVGRE: 5636e33163a4SAlexander Lobakin match |= ICE_PKT_TUN_NVGRE; 5637e33163a4SAlexander Lobakin break; 5638e33163a4SAlexander Lobakin case ICE_SW_TUN_GENEVE: 5639e33163a4SAlexander Lobakin case ICE_SW_TUN_VXLAN: 5640e33163a4SAlexander Lobakin match |= ICE_PKT_TUN_UDP; 5641e33163a4SAlexander Lobakin break; 5642e33163a4SAlexander Lobakin default: 5643e33163a4SAlexander Lobakin break; 5644e33163a4SAlexander Lobakin } 5645e33163a4SAlexander Lobakin 56460f94570dSGrishma Kotecha for (i = 0; i < lkups_cnt; i++) { 56470f94570dSGrishma Kotecha if (lkups[i].type == ICE_UDP_ILOS) 5648e33163a4SAlexander Lobakin match |= ICE_PKT_INNER_UDP; 56490f94570dSGrishma Kotecha else if (lkups[i].type == ICE_TCP_IL) 5650e33163a4SAlexander Lobakin match |= ICE_PKT_INNER_TCP; 56510f94570dSGrishma Kotecha else if (lkups[i].type == ICE_IPV6_OFOS) 5652e33163a4SAlexander Lobakin match |= ICE_PKT_OUTER_IPV6; 565306bca7c2SMartyna Szapar-Mudlaw else if (lkups[i].type == ICE_VLAN_OFOS || 565406bca7c2SMartyna Szapar-Mudlaw lkups[i].type == ICE_VLAN_EX) 565526395726SMartyna Szapar-Mudlaw vlan_count++; 565606bca7c2SMartyna Szapar-Mudlaw else if (lkups[i].type == ICE_VLAN_IN) 565726395726SMartyna Szapar-Mudlaw vlan_count++; 56580f94570dSGrishma Kotecha else if (lkups[i].type == ICE_ETYPE_OL && 56590f94570dSGrishma Kotecha lkups[i].h_u.ethertype.ethtype_id == 56600f94570dSGrishma Kotecha cpu_to_be16(ICE_IPV6_ETHER_ID) && 56610f94570dSGrishma Kotecha lkups[i].m_u.ethertype.ethtype_id == 56620f94570dSGrishma Kotecha cpu_to_be16(0xFFFF)) 5663e33163a4SAlexander Lobakin match |= ICE_PKT_OUTER_IPV6; 566434a89775SMartyna Szapar-Mudlaw else if (lkups[i].type == ICE_ETYPE_IL && 566534a89775SMartyna Szapar-Mudlaw lkups[i].h_u.ethertype.ethtype_id == 566634a89775SMartyna Szapar-Mudlaw cpu_to_be16(ICE_IPV6_ETHER_ID) && 566734a89775SMartyna Szapar-Mudlaw lkups[i].m_u.ethertype.ethtype_id == 566834a89775SMartyna Szapar-Mudlaw cpu_to_be16(0xFFFF)) 5669e33163a4SAlexander Lobakin match |= ICE_PKT_INNER_IPV6; 56709a225f81SMarcin Szycik else if (lkups[i].type == ICE_IPV6_IL) 5671e33163a4SAlexander Lobakin match |= ICE_PKT_INNER_IPV6; 56729a225f81SMarcin Szycik else if (lkups[i].type == ICE_GTP_NO_PAY) 5673e33163a4SAlexander Lobakin match |= ICE_PKT_GTP_NOPAY; 5674cd8efeeeSMarcin Szycik else if (lkups[i].type == ICE_PPPOE) { 5675cd8efeeeSMarcin Szycik match |= ICE_PKT_PPPOE; 5676cd8efeeeSMarcin Szycik if (lkups[i].h_u.pppoe_hdr.ppp_prot_id == 5677cd8efeeeSMarcin Szycik htons(PPP_IPV6)) 5678cd8efeeeSMarcin Szycik match |= ICE_PKT_OUTER_IPV6; 5679cd634549SMarcin Szycik } else if (lkups[i].type == ICE_L2TPV3) 5680cd634549SMarcin Szycik match |= ICE_PKT_L2TPV3; 56819a225f81SMarcin Szycik } 56829a225f81SMarcin Szycik 5683e33163a4SAlexander Lobakin while (ret->match && (match & ret->match) != ret->match) 5684e33163a4SAlexander Lobakin ret++; 56859a225f81SMarcin Szycik 568626395726SMartyna Szapar-Mudlaw if (vlan_count != 0) 568726395726SMartyna Szapar-Mudlaw ret = ice_dummy_packet_add_vlan(ret, vlan_count); 568826395726SMartyna Szapar-Mudlaw 5689e33163a4SAlexander Lobakin return ret; 56900f94570dSGrishma Kotecha } 56910f94570dSGrishma Kotecha 56920f94570dSGrishma Kotecha /** 56930f94570dSGrishma Kotecha * ice_fill_adv_dummy_packet - fill a dummy packet with given match criteria 56940f94570dSGrishma Kotecha * 56950f94570dSGrishma Kotecha * @lkups: lookup elements or match criteria for the advanced recipe, one 56960f94570dSGrishma Kotecha * structure per protocol header 56970f94570dSGrishma Kotecha * @lkups_cnt: number of protocols 56980f94570dSGrishma Kotecha * @s_rule: stores rule information from the match criteria 56991b699f81SAlexander Lobakin * @profile: dummy packet profile (the template, its size and header offsets) 57000f94570dSGrishma Kotecha */ 57015e24d598STony Nguyen static int 57020f94570dSGrishma Kotecha ice_fill_adv_dummy_packet(struct ice_adv_lkup_elem *lkups, u16 lkups_cnt, 57036e1ff618SAlexander Lobakin struct ice_sw_rule_lkup_rx_tx *s_rule, 57041b699f81SAlexander Lobakin const struct ice_dummy_pkt_profile *profile) 57050f94570dSGrishma Kotecha { 57060f94570dSGrishma Kotecha u8 *pkt; 57070f94570dSGrishma Kotecha u16 i; 57080f94570dSGrishma Kotecha 57090f94570dSGrishma Kotecha /* Start with a packet with a pre-defined/dummy content. Then, fill 57100f94570dSGrishma Kotecha * in the header values to be looked up or matched. 57110f94570dSGrishma Kotecha */ 57126e1ff618SAlexander Lobakin pkt = s_rule->hdr_data; 57130f94570dSGrishma Kotecha 57141b699f81SAlexander Lobakin memcpy(pkt, profile->pkt, profile->pkt_len); 57150f94570dSGrishma Kotecha 57160f94570dSGrishma Kotecha for (i = 0; i < lkups_cnt; i++) { 57171b699f81SAlexander Lobakin const struct ice_dummy_pkt_offsets *offsets = profile->offsets; 57180f94570dSGrishma Kotecha enum ice_protocol_type type; 57190f94570dSGrishma Kotecha u16 offset = 0, len = 0, j; 57200f94570dSGrishma Kotecha bool found = false; 57210f94570dSGrishma Kotecha 57220f94570dSGrishma Kotecha /* find the start of this layer; it should be found since this 57230f94570dSGrishma Kotecha * was already checked when search for the dummy packet 57240f94570dSGrishma Kotecha */ 57250f94570dSGrishma Kotecha type = lkups[i].type; 572603592a14SMichal Swiatkowski /* metadata isn't present in the packet */ 572703592a14SMichal Swiatkowski if (type == ICE_HW_METADATA) 572803592a14SMichal Swiatkowski continue; 572903592a14SMichal Swiatkowski 57300f94570dSGrishma Kotecha for (j = 0; offsets[j].type != ICE_PROTOCOL_LAST; j++) { 57310f94570dSGrishma Kotecha if (type == offsets[j].type) { 57320f94570dSGrishma Kotecha offset = offsets[j].offset; 57330f94570dSGrishma Kotecha found = true; 57340f94570dSGrishma Kotecha break; 57350f94570dSGrishma Kotecha } 57360f94570dSGrishma Kotecha } 57370f94570dSGrishma Kotecha /* this should never happen in a correct calling sequence */ 57380f94570dSGrishma Kotecha if (!found) 5739d54699e2STony Nguyen return -EINVAL; 57400f94570dSGrishma Kotecha 57410f94570dSGrishma Kotecha switch (lkups[i].type) { 57420f94570dSGrishma Kotecha case ICE_MAC_OFOS: 57430f94570dSGrishma Kotecha case ICE_MAC_IL: 57440f94570dSGrishma Kotecha len = sizeof(struct ice_ether_hdr); 57450f94570dSGrishma Kotecha break; 57460f94570dSGrishma Kotecha case ICE_ETYPE_OL: 574734a89775SMartyna Szapar-Mudlaw case ICE_ETYPE_IL: 57480f94570dSGrishma Kotecha len = sizeof(struct ice_ethtype_hdr); 57490f94570dSGrishma Kotecha break; 57500f94570dSGrishma Kotecha case ICE_VLAN_OFOS: 575106bca7c2SMartyna Szapar-Mudlaw case ICE_VLAN_EX: 575206bca7c2SMartyna Szapar-Mudlaw case ICE_VLAN_IN: 57530f94570dSGrishma Kotecha len = sizeof(struct ice_vlan_hdr); 57540f94570dSGrishma Kotecha break; 57550f94570dSGrishma Kotecha case ICE_IPV4_OFOS: 57560f94570dSGrishma Kotecha case ICE_IPV4_IL: 57570f94570dSGrishma Kotecha len = sizeof(struct ice_ipv4_hdr); 57580f94570dSGrishma Kotecha break; 57590f94570dSGrishma Kotecha case ICE_IPV6_OFOS: 57600f94570dSGrishma Kotecha case ICE_IPV6_IL: 57610f94570dSGrishma Kotecha len = sizeof(struct ice_ipv6_hdr); 57620f94570dSGrishma Kotecha break; 57630f94570dSGrishma Kotecha case ICE_TCP_IL: 57640f94570dSGrishma Kotecha case ICE_UDP_OF: 57650f94570dSGrishma Kotecha case ICE_UDP_ILOS: 57660f94570dSGrishma Kotecha len = sizeof(struct ice_l4_hdr); 57670f94570dSGrishma Kotecha break; 57680f94570dSGrishma Kotecha case ICE_SCTP_IL: 57690f94570dSGrishma Kotecha len = sizeof(struct ice_sctp_hdr); 57700f94570dSGrishma Kotecha break; 5771f0a35040SMichal Swiatkowski case ICE_NVGRE: 5772f0a35040SMichal Swiatkowski len = sizeof(struct ice_nvgre_hdr); 5773f0a35040SMichal Swiatkowski break; 57748b032a55SMichal Swiatkowski case ICE_VXLAN: 57758b032a55SMichal Swiatkowski case ICE_GENEVE: 57768b032a55SMichal Swiatkowski len = sizeof(struct ice_udp_tnl_hdr); 57778b032a55SMichal Swiatkowski break; 57789a225f81SMarcin Szycik case ICE_GTP_NO_PAY: 57799a225f81SMarcin Szycik case ICE_GTP: 57809a225f81SMarcin Szycik len = sizeof(struct ice_udp_gtp_hdr); 57819a225f81SMarcin Szycik break; 5782cd8efeeeSMarcin Szycik case ICE_PPPOE: 5783cd8efeeeSMarcin Szycik len = sizeof(struct ice_pppoe_hdr); 5784cd8efeeeSMarcin Szycik break; 5785cd634549SMarcin Szycik case ICE_L2TPV3: 5786cd634549SMarcin Szycik len = sizeof(struct ice_l2tpv3_sess_hdr); 5787cd634549SMarcin Szycik break; 57880f94570dSGrishma Kotecha default: 5789d54699e2STony Nguyen return -EINVAL; 57900f94570dSGrishma Kotecha } 57910f94570dSGrishma Kotecha 57920f94570dSGrishma Kotecha /* the length should be a word multiple */ 57930f94570dSGrishma Kotecha if (len % ICE_BYTES_PER_WORD) 5794d54699e2STony Nguyen return -EIO; 57950f94570dSGrishma Kotecha 57960f94570dSGrishma Kotecha /* We have the offset to the header start, the length, the 57970f94570dSGrishma Kotecha * caller's header values and mask. Use this information to 57980f94570dSGrishma Kotecha * copy the data into the dummy packet appropriately based on 57990f94570dSGrishma Kotecha * the mask. Note that we need to only write the bits as 58000f94570dSGrishma Kotecha * indicated by the mask to make sure we don't improperly write 58010f94570dSGrishma Kotecha * over any significant packet data. 58020f94570dSGrishma Kotecha */ 580327ffa273SAlexander Lobakin for (j = 0; j < len / sizeof(u16); j++) { 580427ffa273SAlexander Lobakin u16 *ptr = (u16 *)(pkt + offset); 580527ffa273SAlexander Lobakin u16 mask = lkups[i].m_raw[j]; 580627ffa273SAlexander Lobakin 580727ffa273SAlexander Lobakin if (!mask) 580827ffa273SAlexander Lobakin continue; 580927ffa273SAlexander Lobakin 581027ffa273SAlexander Lobakin ptr[j] = (ptr[j] & ~mask) | (lkups[i].h_raw[j] & mask); 581127ffa273SAlexander Lobakin } 58120f94570dSGrishma Kotecha } 58130f94570dSGrishma Kotecha 58146e1ff618SAlexander Lobakin s_rule->hdr_len = cpu_to_le16(profile->pkt_len); 58150f94570dSGrishma Kotecha 58160f94570dSGrishma Kotecha return 0; 58170f94570dSGrishma Kotecha } 58180f94570dSGrishma Kotecha 58190f94570dSGrishma Kotecha /** 58208b032a55SMichal Swiatkowski * ice_fill_adv_packet_tun - fill dummy packet with udp tunnel port 58218b032a55SMichal Swiatkowski * @hw: pointer to the hardware structure 58228b032a55SMichal Swiatkowski * @tun_type: tunnel type 58238b032a55SMichal Swiatkowski * @pkt: dummy packet to fill in 58248b032a55SMichal Swiatkowski * @offsets: offset info for the dummy packet 58258b032a55SMichal Swiatkowski */ 5826d54699e2STony Nguyen static int 58278b032a55SMichal Swiatkowski ice_fill_adv_packet_tun(struct ice_hw *hw, enum ice_sw_tunnel_type tun_type, 58288b032a55SMichal Swiatkowski u8 *pkt, const struct ice_dummy_pkt_offsets *offsets) 58298b032a55SMichal Swiatkowski { 58308b032a55SMichal Swiatkowski u16 open_port, i; 58318b032a55SMichal Swiatkowski 58328b032a55SMichal Swiatkowski switch (tun_type) { 58338b032a55SMichal Swiatkowski case ICE_SW_TUN_VXLAN: 5834de6acd1cSMichal Swiatkowski if (!ice_get_open_tunnel_port(hw, &open_port, TNL_VXLAN)) 5835d54699e2STony Nguyen return -EIO; 58368b032a55SMichal Swiatkowski break; 5837de6acd1cSMichal Swiatkowski case ICE_SW_TUN_GENEVE: 5838de6acd1cSMichal Swiatkowski if (!ice_get_open_tunnel_port(hw, &open_port, TNL_GENEVE)) 5839d54699e2STony Nguyen return -EIO; 5840de6acd1cSMichal Swiatkowski break; 58418b032a55SMichal Swiatkowski default: 58428b032a55SMichal Swiatkowski /* Nothing needs to be done for this tunnel type */ 58438b032a55SMichal Swiatkowski return 0; 58448b032a55SMichal Swiatkowski } 58458b032a55SMichal Swiatkowski 58468b032a55SMichal Swiatkowski /* Find the outer UDP protocol header and insert the port number */ 58478b032a55SMichal Swiatkowski for (i = 0; offsets[i].type != ICE_PROTOCOL_LAST; i++) { 58488b032a55SMichal Swiatkowski if (offsets[i].type == ICE_UDP_OF) { 58498b032a55SMichal Swiatkowski struct ice_l4_hdr *hdr; 58508b032a55SMichal Swiatkowski u16 offset; 58518b032a55SMichal Swiatkowski 58528b032a55SMichal Swiatkowski offset = offsets[i].offset; 58538b032a55SMichal Swiatkowski hdr = (struct ice_l4_hdr *)&pkt[offset]; 58548b032a55SMichal Swiatkowski hdr->dst_port = cpu_to_be16(open_port); 58558b032a55SMichal Swiatkowski 58568b032a55SMichal Swiatkowski return 0; 58578b032a55SMichal Swiatkowski } 58588b032a55SMichal Swiatkowski } 58598b032a55SMichal Swiatkowski 5860d54699e2STony Nguyen return -EIO; 58618b032a55SMichal Swiatkowski } 58628b032a55SMichal Swiatkowski 58638b032a55SMichal Swiatkowski /** 5864ea71b967SMartyna Szapar-Mudlaw * ice_fill_adv_packet_vlan - fill dummy packet with VLAN tag type 586503592a14SMichal Swiatkowski * @hw: pointer to hw structure 5866ea71b967SMartyna Szapar-Mudlaw * @vlan_type: VLAN tag type 5867ea71b967SMartyna Szapar-Mudlaw * @pkt: dummy packet to fill in 5868ea71b967SMartyna Szapar-Mudlaw * @offsets: offset info for the dummy packet 5869ea71b967SMartyna Szapar-Mudlaw */ 5870ea71b967SMartyna Szapar-Mudlaw static int 587103592a14SMichal Swiatkowski ice_fill_adv_packet_vlan(struct ice_hw *hw, u16 vlan_type, u8 *pkt, 5872ea71b967SMartyna Szapar-Mudlaw const struct ice_dummy_pkt_offsets *offsets) 5873ea71b967SMartyna Szapar-Mudlaw { 5874ea71b967SMartyna Szapar-Mudlaw u16 i; 5875ea71b967SMartyna Szapar-Mudlaw 587603592a14SMichal Swiatkowski /* Check if there is something to do */ 587703592a14SMichal Swiatkowski if (!vlan_type || !ice_is_dvm_ena(hw)) 587803592a14SMichal Swiatkowski return 0; 587903592a14SMichal Swiatkowski 5880ea71b967SMartyna Szapar-Mudlaw /* Find VLAN header and insert VLAN TPID */ 5881ea71b967SMartyna Szapar-Mudlaw for (i = 0; offsets[i].type != ICE_PROTOCOL_LAST; i++) { 5882ea71b967SMartyna Szapar-Mudlaw if (offsets[i].type == ICE_VLAN_OFOS || 5883ea71b967SMartyna Szapar-Mudlaw offsets[i].type == ICE_VLAN_EX) { 5884ea71b967SMartyna Szapar-Mudlaw struct ice_vlan_hdr *hdr; 5885ea71b967SMartyna Szapar-Mudlaw u16 offset; 5886ea71b967SMartyna Szapar-Mudlaw 5887ea71b967SMartyna Szapar-Mudlaw offset = offsets[i].offset; 5888ea71b967SMartyna Szapar-Mudlaw hdr = (struct ice_vlan_hdr *)&pkt[offset]; 5889ea71b967SMartyna Szapar-Mudlaw hdr->type = cpu_to_be16(vlan_type); 5890ea71b967SMartyna Szapar-Mudlaw 5891ea71b967SMartyna Szapar-Mudlaw return 0; 5892ea71b967SMartyna Szapar-Mudlaw } 5893ea71b967SMartyna Szapar-Mudlaw } 5894ea71b967SMartyna Szapar-Mudlaw 5895ea71b967SMartyna Szapar-Mudlaw return -EIO; 5896ea71b967SMartyna Szapar-Mudlaw } 5897ea71b967SMartyna Szapar-Mudlaw 589803592a14SMichal Swiatkowski static bool ice_rules_equal(const struct ice_adv_rule_info *first, 589903592a14SMichal Swiatkowski const struct ice_adv_rule_info *second) 590003592a14SMichal Swiatkowski { 590103592a14SMichal Swiatkowski return first->sw_act.flag == second->sw_act.flag && 590203592a14SMichal Swiatkowski first->tun_type == second->tun_type && 590303592a14SMichal Swiatkowski first->vlan_type == second->vlan_type && 5904bccd9bceSMarcin Szycik first->src_vsi == second->src_vsi && 5905bccd9bceSMarcin Szycik first->need_pass_l2 == second->need_pass_l2 && 5906bccd9bceSMarcin Szycik first->allow_pass_l2 == second->allow_pass_l2; 590703592a14SMichal Swiatkowski } 590803592a14SMichal Swiatkowski 5909ea71b967SMartyna Szapar-Mudlaw /** 59100f94570dSGrishma Kotecha * ice_find_adv_rule_entry - Search a rule entry 59110f94570dSGrishma Kotecha * @hw: pointer to the hardware structure 59120f94570dSGrishma Kotecha * @lkups: lookup elements or match criteria for the advanced recipe, one 59130f94570dSGrishma Kotecha * structure per protocol header 59140f94570dSGrishma Kotecha * @lkups_cnt: number of protocols 59150f94570dSGrishma Kotecha * @recp_id: recipe ID for which we are finding the rule 59160f94570dSGrishma Kotecha * @rinfo: other information regarding the rule e.g. priority and action info 59170f94570dSGrishma Kotecha * 59180f94570dSGrishma Kotecha * Helper function to search for a given advance rule entry 59190f94570dSGrishma Kotecha * Returns pointer to entry storing the rule if found 59200f94570dSGrishma Kotecha */ 59210f94570dSGrishma Kotecha static struct ice_adv_fltr_mgmt_list_entry * 59220f94570dSGrishma Kotecha ice_find_adv_rule_entry(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups, 59230f94570dSGrishma Kotecha u16 lkups_cnt, u16 recp_id, 59240f94570dSGrishma Kotecha struct ice_adv_rule_info *rinfo) 59250f94570dSGrishma Kotecha { 59260f94570dSGrishma Kotecha struct ice_adv_fltr_mgmt_list_entry *list_itr; 59270f94570dSGrishma Kotecha struct ice_switch_info *sw = hw->switch_info; 59280f94570dSGrishma Kotecha int i; 59290f94570dSGrishma Kotecha 59300f94570dSGrishma Kotecha list_for_each_entry(list_itr, &sw->recp_list[recp_id].filt_rules, 59310f94570dSGrishma Kotecha list_entry) { 59320f94570dSGrishma Kotecha bool lkups_matched = true; 59330f94570dSGrishma Kotecha 59340f94570dSGrishma Kotecha if (lkups_cnt != list_itr->lkups_cnt) 59350f94570dSGrishma Kotecha continue; 59360f94570dSGrishma Kotecha for (i = 0; i < list_itr->lkups_cnt; i++) 59370f94570dSGrishma Kotecha if (memcmp(&list_itr->lkups[i], &lkups[i], 59380f94570dSGrishma Kotecha sizeof(*lkups))) { 59390f94570dSGrishma Kotecha lkups_matched = false; 59400f94570dSGrishma Kotecha break; 59410f94570dSGrishma Kotecha } 594203592a14SMichal Swiatkowski if (ice_rules_equal(rinfo, &list_itr->rule_info) && 59430f94570dSGrishma Kotecha lkups_matched) 59440f94570dSGrishma Kotecha return list_itr; 59450f94570dSGrishma Kotecha } 59460f94570dSGrishma Kotecha return NULL; 59470f94570dSGrishma Kotecha } 59480f94570dSGrishma Kotecha 59490f94570dSGrishma Kotecha /** 59500f94570dSGrishma Kotecha * ice_adv_add_update_vsi_list 59510f94570dSGrishma Kotecha * @hw: pointer to the hardware structure 59520f94570dSGrishma Kotecha * @m_entry: pointer to current adv filter management list entry 59530f94570dSGrishma Kotecha * @cur_fltr: filter information from the book keeping entry 59540f94570dSGrishma Kotecha * @new_fltr: filter information with the new VSI to be added 59550f94570dSGrishma Kotecha * 59560f94570dSGrishma Kotecha * Call AQ command to add or update previously created VSI list with new VSI. 59570f94570dSGrishma Kotecha * 59580f94570dSGrishma Kotecha * Helper function to do book keeping associated with adding filter information 59590f94570dSGrishma Kotecha * The algorithm to do the booking keeping is described below : 59600f94570dSGrishma Kotecha * When a VSI needs to subscribe to a given advanced filter 59610f94570dSGrishma Kotecha * if only one VSI has been added till now 59620f94570dSGrishma Kotecha * Allocate a new VSI list and add two VSIs 59630f94570dSGrishma Kotecha * to this list using switch rule command 59640f94570dSGrishma Kotecha * Update the previously created switch rule with the 59650f94570dSGrishma Kotecha * newly created VSI list ID 59660f94570dSGrishma Kotecha * if a VSI list was previously created 59670f94570dSGrishma Kotecha * Add the new VSI to the previously created VSI list set 59680f94570dSGrishma Kotecha * using the update switch rule command 59690f94570dSGrishma Kotecha */ 59705e24d598STony Nguyen static int 59710f94570dSGrishma Kotecha ice_adv_add_update_vsi_list(struct ice_hw *hw, 59720f94570dSGrishma Kotecha struct ice_adv_fltr_mgmt_list_entry *m_entry, 59730f94570dSGrishma Kotecha struct ice_adv_rule_info *cur_fltr, 59740f94570dSGrishma Kotecha struct ice_adv_rule_info *new_fltr) 59750f94570dSGrishma Kotecha { 59760f94570dSGrishma Kotecha u16 vsi_list_id = 0; 59775518ac2aSTony Nguyen int status; 59780f94570dSGrishma Kotecha 59790f94570dSGrishma Kotecha if (cur_fltr->sw_act.fltr_act == ICE_FWD_TO_Q || 59800f94570dSGrishma Kotecha cur_fltr->sw_act.fltr_act == ICE_FWD_TO_QGRP || 59810f94570dSGrishma Kotecha cur_fltr->sw_act.fltr_act == ICE_DROP_PACKET) 5982d54699e2STony Nguyen return -EOPNOTSUPP; 59830f94570dSGrishma Kotecha 59840f94570dSGrishma Kotecha if ((new_fltr->sw_act.fltr_act == ICE_FWD_TO_Q || 59850f94570dSGrishma Kotecha new_fltr->sw_act.fltr_act == ICE_FWD_TO_QGRP) && 59860f94570dSGrishma Kotecha (cur_fltr->sw_act.fltr_act == ICE_FWD_TO_VSI || 59870f94570dSGrishma Kotecha cur_fltr->sw_act.fltr_act == ICE_FWD_TO_VSI_LIST)) 5988d54699e2STony Nguyen return -EOPNOTSUPP; 59890f94570dSGrishma Kotecha 59900f94570dSGrishma Kotecha if (m_entry->vsi_count < 2 && !m_entry->vsi_list_info) { 59910f94570dSGrishma Kotecha /* Only one entry existed in the mapping and it was not already 59920f94570dSGrishma Kotecha * a part of a VSI list. So, create a VSI list with the old and 59930f94570dSGrishma Kotecha * new VSIs. 59940f94570dSGrishma Kotecha */ 59950f94570dSGrishma Kotecha struct ice_fltr_info tmp_fltr; 59960f94570dSGrishma Kotecha u16 vsi_handle_arr[2]; 59970f94570dSGrishma Kotecha 59980f94570dSGrishma Kotecha /* A rule already exists with the new VSI being added */ 59990f94570dSGrishma Kotecha if (cur_fltr->sw_act.fwd_id.hw_vsi_id == 60000f94570dSGrishma Kotecha new_fltr->sw_act.fwd_id.hw_vsi_id) 6001d54699e2STony Nguyen return -EEXIST; 60020f94570dSGrishma Kotecha 60030f94570dSGrishma Kotecha vsi_handle_arr[0] = cur_fltr->sw_act.vsi_handle; 60040f94570dSGrishma Kotecha vsi_handle_arr[1] = new_fltr->sw_act.vsi_handle; 60050f94570dSGrishma Kotecha status = ice_create_vsi_list_rule(hw, &vsi_handle_arr[0], 2, 60060f94570dSGrishma Kotecha &vsi_list_id, 60070f94570dSGrishma Kotecha ICE_SW_LKUP_LAST); 60080f94570dSGrishma Kotecha if (status) 60090f94570dSGrishma Kotecha return status; 60100f94570dSGrishma Kotecha 60110f94570dSGrishma Kotecha memset(&tmp_fltr, 0, sizeof(tmp_fltr)); 60120f94570dSGrishma Kotecha tmp_fltr.flag = m_entry->rule_info.sw_act.flag; 60130f94570dSGrishma Kotecha tmp_fltr.fltr_rule_id = cur_fltr->fltr_rule_id; 60140f94570dSGrishma Kotecha tmp_fltr.fltr_act = ICE_FWD_TO_VSI_LIST; 60150f94570dSGrishma Kotecha tmp_fltr.fwd_id.vsi_list_id = vsi_list_id; 60160f94570dSGrishma Kotecha tmp_fltr.lkup_type = ICE_SW_LKUP_LAST; 60170f94570dSGrishma Kotecha 60180f94570dSGrishma Kotecha /* Update the previous switch rule of "forward to VSI" to 60190f94570dSGrishma Kotecha * "fwd to VSI list" 60200f94570dSGrishma Kotecha */ 60210f94570dSGrishma Kotecha status = ice_update_pkt_fwd_rule(hw, &tmp_fltr); 60220f94570dSGrishma Kotecha if (status) 60230f94570dSGrishma Kotecha return status; 60240f94570dSGrishma Kotecha 60250f94570dSGrishma Kotecha cur_fltr->sw_act.fwd_id.vsi_list_id = vsi_list_id; 60260f94570dSGrishma Kotecha cur_fltr->sw_act.fltr_act = ICE_FWD_TO_VSI_LIST; 60270f94570dSGrishma Kotecha m_entry->vsi_list_info = 60280f94570dSGrishma Kotecha ice_create_vsi_list_map(hw, &vsi_handle_arr[0], 2, 60290f94570dSGrishma Kotecha vsi_list_id); 60300f94570dSGrishma Kotecha } else { 60310f94570dSGrishma Kotecha u16 vsi_handle = new_fltr->sw_act.vsi_handle; 60320f94570dSGrishma Kotecha 60330f94570dSGrishma Kotecha if (!m_entry->vsi_list_info) 6034d54699e2STony Nguyen return -EIO; 60350f94570dSGrishma Kotecha 60360f94570dSGrishma Kotecha /* A rule already exists with the new VSI being added */ 60370f94570dSGrishma Kotecha if (test_bit(vsi_handle, m_entry->vsi_list_info->vsi_map)) 60380f94570dSGrishma Kotecha return 0; 60390f94570dSGrishma Kotecha 60400f94570dSGrishma Kotecha /* Update the previously created VSI list set with 60410f94570dSGrishma Kotecha * the new VSI ID passed in 60420f94570dSGrishma Kotecha */ 60430f94570dSGrishma Kotecha vsi_list_id = cur_fltr->sw_act.fwd_id.vsi_list_id; 60440f94570dSGrishma Kotecha 60450f94570dSGrishma Kotecha status = ice_update_vsi_list_rule(hw, &vsi_handle, 1, 60460f94570dSGrishma Kotecha vsi_list_id, false, 60470f94570dSGrishma Kotecha ice_aqc_opc_update_sw_rules, 60480f94570dSGrishma Kotecha ICE_SW_LKUP_LAST); 60490f94570dSGrishma Kotecha /* update VSI list mapping info with new VSI ID */ 60500f94570dSGrishma Kotecha if (!status) 60510f94570dSGrishma Kotecha set_bit(vsi_handle, m_entry->vsi_list_info->vsi_map); 60520f94570dSGrishma Kotecha } 60530f94570dSGrishma Kotecha if (!status) 60540f94570dSGrishma Kotecha m_entry->vsi_count++; 60550f94570dSGrishma Kotecha return status; 60560f94570dSGrishma Kotecha } 60570f94570dSGrishma Kotecha 605803592a14SMichal Swiatkowski void ice_rule_add_tunnel_metadata(struct ice_adv_lkup_elem *lkup) 605903592a14SMichal Swiatkowski { 606003592a14SMichal Swiatkowski lkup->type = ICE_HW_METADATA; 606103592a14SMichal Swiatkowski lkup->m_u.metadata.flags[ICE_PKT_FLAGS_TUNNEL] = 606203592a14SMichal Swiatkowski cpu_to_be16(ICE_PKT_TUNNEL_MASK); 606303592a14SMichal Swiatkowski } 606403592a14SMichal Swiatkowski 606503592a14SMichal Swiatkowski void ice_rule_add_vlan_metadata(struct ice_adv_lkup_elem *lkup) 606603592a14SMichal Swiatkowski { 606703592a14SMichal Swiatkowski lkup->type = ICE_HW_METADATA; 606803592a14SMichal Swiatkowski lkup->m_u.metadata.flags[ICE_PKT_FLAGS_VLAN] = 606903592a14SMichal Swiatkowski cpu_to_be16(ICE_PKT_VLAN_MASK); 607003592a14SMichal Swiatkowski } 607103592a14SMichal Swiatkowski 60720ef4479dSMichal Swiatkowski void ice_rule_add_src_vsi_metadata(struct ice_adv_lkup_elem *lkup) 60730ef4479dSMichal Swiatkowski { 60740ef4479dSMichal Swiatkowski lkup->type = ICE_HW_METADATA; 60750ef4479dSMichal Swiatkowski lkup->m_u.metadata.source_vsi = cpu_to_be16(ICE_MDID_SOURCE_VSI_MASK); 60760ef4479dSMichal Swiatkowski } 60770ef4479dSMichal Swiatkowski 60780f94570dSGrishma Kotecha /** 60790f94570dSGrishma Kotecha * ice_add_adv_rule - helper function to create an advanced switch rule 60800f94570dSGrishma Kotecha * @hw: pointer to the hardware structure 60810f94570dSGrishma Kotecha * @lkups: information on the words that needs to be looked up. All words 60820f94570dSGrishma Kotecha * together makes one recipe 60830f94570dSGrishma Kotecha * @lkups_cnt: num of entries in the lkups array 60840f94570dSGrishma Kotecha * @rinfo: other information related to the rule that needs to be programmed 60850f94570dSGrishma Kotecha * @added_entry: this will return recipe_id, rule_id and vsi_handle. should be 60860f94570dSGrishma Kotecha * ignored is case of error. 60870f94570dSGrishma Kotecha * 60880f94570dSGrishma Kotecha * This function can program only 1 rule at a time. The lkups is used to 60890f94570dSGrishma Kotecha * describe the all the words that forms the "lookup" portion of the recipe. 60900f94570dSGrishma Kotecha * These words can span multiple protocols. Callers to this function need to 60910f94570dSGrishma Kotecha * pass in a list of protocol headers with lookup information along and mask 60920f94570dSGrishma Kotecha * that determines which words are valid from the given protocol header. 60930f94570dSGrishma Kotecha * rinfo describes other information related to this rule such as forwarding 60940f94570dSGrishma Kotecha * IDs, priority of this rule, etc. 60950f94570dSGrishma Kotecha */ 60965e24d598STony Nguyen int 60970f94570dSGrishma Kotecha ice_add_adv_rule(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups, 60980f94570dSGrishma Kotecha u16 lkups_cnt, struct ice_adv_rule_info *rinfo, 60990f94570dSGrishma Kotecha struct ice_rule_query_data *added_entry) 61000f94570dSGrishma Kotecha { 61010f94570dSGrishma Kotecha struct ice_adv_fltr_mgmt_list_entry *m_entry, *adv_fltr = NULL; 61026e1ff618SAlexander Lobakin struct ice_sw_rule_lkup_rx_tx *s_rule = NULL; 6103e33163a4SAlexander Lobakin const struct ice_dummy_pkt_profile *profile; 61041b699f81SAlexander Lobakin u16 rid = 0, i, rule_buf_sz, vsi_handle; 61050f94570dSGrishma Kotecha struct list_head *rule_head; 61060f94570dSGrishma Kotecha struct ice_switch_info *sw; 61070f94570dSGrishma Kotecha u16 word_cnt; 61080f94570dSGrishma Kotecha u32 act = 0; 61095518ac2aSTony Nguyen int status; 61100f94570dSGrishma Kotecha u8 q_rgn; 61110f94570dSGrishma Kotecha 61120f94570dSGrishma Kotecha /* Initialize profile to result index bitmap */ 61130f94570dSGrishma Kotecha if (!hw->switch_info->prof_res_bm_init) { 61140f94570dSGrishma Kotecha hw->switch_info->prof_res_bm_init = 1; 61150f94570dSGrishma Kotecha ice_init_prof_result_bm(hw); 61160f94570dSGrishma Kotecha } 61170f94570dSGrishma Kotecha 61180f94570dSGrishma Kotecha if (!lkups_cnt) 6119d54699e2STony Nguyen return -EINVAL; 61200f94570dSGrishma Kotecha 61210f94570dSGrishma Kotecha /* get # of words we need to match */ 61220f94570dSGrishma Kotecha word_cnt = 0; 61230f94570dSGrishma Kotecha for (i = 0; i < lkups_cnt; i++) { 6124135a161aSAlexander Lobakin u16 j; 61250f94570dSGrishma Kotecha 6126135a161aSAlexander Lobakin for (j = 0; j < ARRAY_SIZE(lkups->m_raw); j++) 6127135a161aSAlexander Lobakin if (lkups[i].m_raw[j]) 61280f94570dSGrishma Kotecha word_cnt++; 61290f94570dSGrishma Kotecha } 61300f94570dSGrishma Kotecha 6131bd1ffe8eSWojciech Drewek if (!word_cnt) 6132d54699e2STony Nguyen return -EINVAL; 61330f94570dSGrishma Kotecha 6134bd1ffe8eSWojciech Drewek if (word_cnt > ICE_MAX_CHAIN_WORDS) 6135bd1ffe8eSWojciech Drewek return -ENOSPC; 6136bd1ffe8eSWojciech Drewek 61371b699f81SAlexander Lobakin /* locate a dummy packet */ 61381b699f81SAlexander Lobakin profile = ice_find_dummy_packet(lkups, lkups_cnt, rinfo->tun_type); 613926395726SMartyna Szapar-Mudlaw if (IS_ERR(profile)) 614026395726SMartyna Szapar-Mudlaw return PTR_ERR(profile); 61410f94570dSGrishma Kotecha 61420f94570dSGrishma Kotecha if (!(rinfo->sw_act.fltr_act == ICE_FWD_TO_VSI || 61430f94570dSGrishma Kotecha rinfo->sw_act.fltr_act == ICE_FWD_TO_Q || 61440f94570dSGrishma Kotecha rinfo->sw_act.fltr_act == ICE_FWD_TO_QGRP || 6145bccd9bceSMarcin Szycik rinfo->sw_act.fltr_act == ICE_DROP_PACKET || 6146bccd9bceSMarcin Szycik rinfo->sw_act.fltr_act == ICE_NOP)) { 614726395726SMartyna Szapar-Mudlaw status = -EIO; 614826395726SMartyna Szapar-Mudlaw goto free_pkt_profile; 614926395726SMartyna Szapar-Mudlaw } 61500f94570dSGrishma Kotecha 61510f94570dSGrishma Kotecha vsi_handle = rinfo->sw_act.vsi_handle; 615226395726SMartyna Szapar-Mudlaw if (!ice_is_vsi_valid(hw, vsi_handle)) { 615326395726SMartyna Szapar-Mudlaw status = -EINVAL; 615426395726SMartyna Szapar-Mudlaw goto free_pkt_profile; 615526395726SMartyna Szapar-Mudlaw } 61560f94570dSGrishma Kotecha 6157bccd9bceSMarcin Szycik if (rinfo->sw_act.fltr_act == ICE_FWD_TO_VSI || 6158bccd9bceSMarcin Szycik rinfo->sw_act.fltr_act == ICE_NOP) 61590f94570dSGrishma Kotecha rinfo->sw_act.fwd_id.hw_vsi_id = 61600f94570dSGrishma Kotecha ice_get_hw_vsi_num(hw, vsi_handle); 616103592a14SMichal Swiatkowski 616203592a14SMichal Swiatkowski if (rinfo->src_vsi) 616303592a14SMichal Swiatkowski rinfo->sw_act.src = ice_get_hw_vsi_num(hw, rinfo->src_vsi); 616403592a14SMichal Swiatkowski else 61650f94570dSGrishma Kotecha rinfo->sw_act.src = ice_get_hw_vsi_num(hw, vsi_handle); 61660f94570dSGrishma Kotecha 61670f94570dSGrishma Kotecha status = ice_add_adv_recipe(hw, lkups, lkups_cnt, rinfo, &rid); 61680f94570dSGrishma Kotecha if (status) 616926395726SMartyna Szapar-Mudlaw goto free_pkt_profile; 61700f94570dSGrishma Kotecha m_entry = ice_find_adv_rule_entry(hw, lkups, lkups_cnt, rid, rinfo); 61710f94570dSGrishma Kotecha if (m_entry) { 61720f94570dSGrishma Kotecha /* we have to add VSI to VSI_LIST and increment vsi_count. 61730f94570dSGrishma Kotecha * Also Update VSI list so that we can change forwarding rule 61740f94570dSGrishma Kotecha * if the rule already exists, we will check if it exists with 61750f94570dSGrishma Kotecha * same vsi_id, if not then add it to the VSI list if it already 61760f94570dSGrishma Kotecha * exists if not then create a VSI list and add the existing VSI 61770f94570dSGrishma Kotecha * ID and the new VSI ID to the list 61780f94570dSGrishma Kotecha * We will add that VSI to the list 61790f94570dSGrishma Kotecha */ 61800f94570dSGrishma Kotecha status = ice_adv_add_update_vsi_list(hw, m_entry, 61810f94570dSGrishma Kotecha &m_entry->rule_info, 61820f94570dSGrishma Kotecha rinfo); 61830f94570dSGrishma Kotecha if (added_entry) { 61840f94570dSGrishma Kotecha added_entry->rid = rid; 61850f94570dSGrishma Kotecha added_entry->rule_id = m_entry->rule_info.fltr_rule_id; 61860f94570dSGrishma Kotecha added_entry->vsi_handle = rinfo->sw_act.vsi_handle; 61870f94570dSGrishma Kotecha } 618826395726SMartyna Szapar-Mudlaw goto free_pkt_profile; 61890f94570dSGrishma Kotecha } 61906e1ff618SAlexander Lobakin rule_buf_sz = ICE_SW_RULE_RX_TX_HDR_SIZE(s_rule, profile->pkt_len); 61910f94570dSGrishma Kotecha s_rule = kzalloc(rule_buf_sz, GFP_KERNEL); 619226395726SMartyna Szapar-Mudlaw if (!s_rule) { 619326395726SMartyna Szapar-Mudlaw status = -ENOMEM; 619426395726SMartyna Szapar-Mudlaw goto free_pkt_profile; 619526395726SMartyna Szapar-Mudlaw } 619673b483b7SWojciech Drewek if (!rinfo->flags_info.act_valid) { 619773b483b7SWojciech Drewek act |= ICE_SINGLE_ACT_LAN_ENABLE; 619873b483b7SWojciech Drewek act |= ICE_SINGLE_ACT_LB_ENABLE; 619973b483b7SWojciech Drewek } else { 620073b483b7SWojciech Drewek act |= rinfo->flags_info.act & (ICE_SINGLE_ACT_LAN_ENABLE | 620173b483b7SWojciech Drewek ICE_SINGLE_ACT_LB_ENABLE); 620273b483b7SWojciech Drewek } 620373b483b7SWojciech Drewek 62040f94570dSGrishma Kotecha switch (rinfo->sw_act.fltr_act) { 62050f94570dSGrishma Kotecha case ICE_FWD_TO_VSI: 62060f94570dSGrishma Kotecha act |= (rinfo->sw_act.fwd_id.hw_vsi_id << 62070f94570dSGrishma Kotecha ICE_SINGLE_ACT_VSI_ID_S) & ICE_SINGLE_ACT_VSI_ID_M; 62080f94570dSGrishma Kotecha act |= ICE_SINGLE_ACT_VSI_FORWARDING | ICE_SINGLE_ACT_VALID_BIT; 62090f94570dSGrishma Kotecha break; 62100f94570dSGrishma Kotecha case ICE_FWD_TO_Q: 62110f94570dSGrishma Kotecha act |= ICE_SINGLE_ACT_TO_Q; 62120f94570dSGrishma Kotecha act |= (rinfo->sw_act.fwd_id.q_id << ICE_SINGLE_ACT_Q_INDEX_S) & 62130f94570dSGrishma Kotecha ICE_SINGLE_ACT_Q_INDEX_M; 62140f94570dSGrishma Kotecha break; 62150f94570dSGrishma Kotecha case ICE_FWD_TO_QGRP: 62160f94570dSGrishma Kotecha q_rgn = rinfo->sw_act.qgrp_size > 0 ? 62170f94570dSGrishma Kotecha (u8)ilog2(rinfo->sw_act.qgrp_size) : 0; 62180f94570dSGrishma Kotecha act |= ICE_SINGLE_ACT_TO_Q; 62190f94570dSGrishma Kotecha act |= (rinfo->sw_act.fwd_id.q_id << ICE_SINGLE_ACT_Q_INDEX_S) & 62200f94570dSGrishma Kotecha ICE_SINGLE_ACT_Q_INDEX_M; 62210f94570dSGrishma Kotecha act |= (q_rgn << ICE_SINGLE_ACT_Q_REGION_S) & 62220f94570dSGrishma Kotecha ICE_SINGLE_ACT_Q_REGION_M; 62230f94570dSGrishma Kotecha break; 62240f94570dSGrishma Kotecha case ICE_DROP_PACKET: 62250f94570dSGrishma Kotecha act |= ICE_SINGLE_ACT_VSI_FORWARDING | ICE_SINGLE_ACT_DROP | 62260f94570dSGrishma Kotecha ICE_SINGLE_ACT_VALID_BIT; 62270f94570dSGrishma Kotecha break; 6228bccd9bceSMarcin Szycik case ICE_NOP: 6229bccd9bceSMarcin Szycik act |= FIELD_PREP(ICE_SINGLE_ACT_VSI_ID_M, 6230bccd9bceSMarcin Szycik rinfo->sw_act.fwd_id.hw_vsi_id); 6231bccd9bceSMarcin Szycik act &= ~ICE_SINGLE_ACT_VALID_BIT; 6232bccd9bceSMarcin Szycik break; 62330f94570dSGrishma Kotecha default: 6234d54699e2STony Nguyen status = -EIO; 62350f94570dSGrishma Kotecha goto err_ice_add_adv_rule; 62360f94570dSGrishma Kotecha } 62370f94570dSGrishma Kotecha 623840fd7492SMichal Swiatkowski /* If there is no matching criteria for direction there 623940fd7492SMichal Swiatkowski * is only one difference between Rx and Tx: 624040fd7492SMichal Swiatkowski * - get switch id base on VSI number from source field (Tx) 624140fd7492SMichal Swiatkowski * - get switch id base on port number (Rx) 62420f94570dSGrishma Kotecha * 624340fd7492SMichal Swiatkowski * If matching on direction metadata is chose rule direction is 624440fd7492SMichal Swiatkowski * extracted from type value set here. 62450f94570dSGrishma Kotecha */ 624640fd7492SMichal Swiatkowski if (rinfo->sw_act.flag & ICE_FLTR_TX) { 62476e1ff618SAlexander Lobakin s_rule->hdr.type = cpu_to_le16(ICE_AQC_SW_RULES_T_LKUP_TX); 62486e1ff618SAlexander Lobakin s_rule->src = cpu_to_le16(rinfo->sw_act.src); 624940fd7492SMichal Swiatkowski } else { 625040fd7492SMichal Swiatkowski s_rule->hdr.type = cpu_to_le16(ICE_AQC_SW_RULES_T_LKUP_RX); 625140fd7492SMichal Swiatkowski s_rule->src = cpu_to_le16(hw->port_info->lport); 62520f94570dSGrishma Kotecha } 62530f94570dSGrishma Kotecha 62546e1ff618SAlexander Lobakin s_rule->recipe_id = cpu_to_le16(rid); 62556e1ff618SAlexander Lobakin s_rule->act = cpu_to_le32(act); 62560f94570dSGrishma Kotecha 6257e33163a4SAlexander Lobakin status = ice_fill_adv_dummy_packet(lkups, lkups_cnt, s_rule, profile); 62580f94570dSGrishma Kotecha if (status) 62590f94570dSGrishma Kotecha goto err_ice_add_adv_rule; 62600f94570dSGrishma Kotecha 626103592a14SMichal Swiatkowski status = ice_fill_adv_packet_tun(hw, rinfo->tun_type, s_rule->hdr_data, 6262e33163a4SAlexander Lobakin profile->offsets); 62638b032a55SMichal Swiatkowski if (status) 62648b032a55SMichal Swiatkowski goto err_ice_add_adv_rule; 62658b032a55SMichal Swiatkowski 626603592a14SMichal Swiatkowski status = ice_fill_adv_packet_vlan(hw, rinfo->vlan_type, 6267ea71b967SMartyna Szapar-Mudlaw s_rule->hdr_data, 6268ea71b967SMartyna Szapar-Mudlaw profile->offsets); 6269ea71b967SMartyna Szapar-Mudlaw if (status) 6270ea71b967SMartyna Szapar-Mudlaw goto err_ice_add_adv_rule; 6271ea71b967SMartyna Szapar-Mudlaw 62720f94570dSGrishma Kotecha status = ice_aq_sw_rules(hw, (struct ice_aqc_sw_rules *)s_rule, 62730f94570dSGrishma Kotecha rule_buf_sz, 1, ice_aqc_opc_add_sw_rules, 62740f94570dSGrishma Kotecha NULL); 62750f94570dSGrishma Kotecha if (status) 62760f94570dSGrishma Kotecha goto err_ice_add_adv_rule; 62770f94570dSGrishma Kotecha adv_fltr = devm_kzalloc(ice_hw_to_dev(hw), 62780f94570dSGrishma Kotecha sizeof(struct ice_adv_fltr_mgmt_list_entry), 62790f94570dSGrishma Kotecha GFP_KERNEL); 62800f94570dSGrishma Kotecha if (!adv_fltr) { 6281d54699e2STony Nguyen status = -ENOMEM; 62820f94570dSGrishma Kotecha goto err_ice_add_adv_rule; 62830f94570dSGrishma Kotecha } 62840f94570dSGrishma Kotecha 62850f94570dSGrishma Kotecha adv_fltr->lkups = devm_kmemdup(ice_hw_to_dev(hw), lkups, 62860f94570dSGrishma Kotecha lkups_cnt * sizeof(*lkups), GFP_KERNEL); 62870f94570dSGrishma Kotecha if (!adv_fltr->lkups) { 6288d54699e2STony Nguyen status = -ENOMEM; 62890f94570dSGrishma Kotecha goto err_ice_add_adv_rule; 62900f94570dSGrishma Kotecha } 62910f94570dSGrishma Kotecha 62920f94570dSGrishma Kotecha adv_fltr->lkups_cnt = lkups_cnt; 62930f94570dSGrishma Kotecha adv_fltr->rule_info = *rinfo; 62946e1ff618SAlexander Lobakin adv_fltr->rule_info.fltr_rule_id = le16_to_cpu(s_rule->index); 62950f94570dSGrishma Kotecha sw = hw->switch_info; 62960f94570dSGrishma Kotecha sw->recp_list[rid].adv_rule = true; 62970f94570dSGrishma Kotecha rule_head = &sw->recp_list[rid].filt_rules; 62980f94570dSGrishma Kotecha 62990f94570dSGrishma Kotecha if (rinfo->sw_act.fltr_act == ICE_FWD_TO_VSI) 63000f94570dSGrishma Kotecha adv_fltr->vsi_count = 1; 63010f94570dSGrishma Kotecha 63020f94570dSGrishma Kotecha /* Add rule entry to book keeping list */ 63030f94570dSGrishma Kotecha list_add(&adv_fltr->list_entry, rule_head); 63040f94570dSGrishma Kotecha if (added_entry) { 63050f94570dSGrishma Kotecha added_entry->rid = rid; 63060f94570dSGrishma Kotecha added_entry->rule_id = adv_fltr->rule_info.fltr_rule_id; 63070f94570dSGrishma Kotecha added_entry->vsi_handle = rinfo->sw_act.vsi_handle; 63080f94570dSGrishma Kotecha } 63090f94570dSGrishma Kotecha err_ice_add_adv_rule: 63100f94570dSGrishma Kotecha if (status && adv_fltr) { 63110f94570dSGrishma Kotecha devm_kfree(ice_hw_to_dev(hw), adv_fltr->lkups); 63120f94570dSGrishma Kotecha devm_kfree(ice_hw_to_dev(hw), adv_fltr); 63130f94570dSGrishma Kotecha } 63140f94570dSGrishma Kotecha 63150f94570dSGrishma Kotecha kfree(s_rule); 63160f94570dSGrishma Kotecha 631726395726SMartyna Szapar-Mudlaw free_pkt_profile: 631826395726SMartyna Szapar-Mudlaw if (profile->match & ICE_PKT_KMALLOC) { 631926395726SMartyna Szapar-Mudlaw kfree(profile->offsets); 632026395726SMartyna Szapar-Mudlaw kfree(profile->pkt); 632126395726SMartyna Szapar-Mudlaw kfree(profile); 632226395726SMartyna Szapar-Mudlaw } 632326395726SMartyna Szapar-Mudlaw 63240f94570dSGrishma Kotecha return status; 63250f94570dSGrishma Kotecha } 63260f94570dSGrishma Kotecha 63270f94570dSGrishma Kotecha /** 6328334cb062SAnirudh Venkataramanan * ice_replay_vsi_fltr - Replay filters for requested VSI 63290f9d5027SAnirudh Venkataramanan * @hw: pointer to the hardware structure 6330334cb062SAnirudh Venkataramanan * @vsi_handle: driver VSI handle 6331f9867df6SAnirudh Venkataramanan * @recp_id: Recipe ID for which rules need to be replayed 6332334cb062SAnirudh Venkataramanan * @list_head: list for which filters need to be replayed 6333334cb062SAnirudh Venkataramanan * 6334334cb062SAnirudh Venkataramanan * Replays the filter of recipe recp_id for a VSI represented via vsi_handle. 6335334cb062SAnirudh Venkataramanan * It is required to pass valid VSI handle. 63360f9d5027SAnirudh Venkataramanan */ 63375e24d598STony Nguyen static int 6338334cb062SAnirudh Venkataramanan ice_replay_vsi_fltr(struct ice_hw *hw, u16 vsi_handle, u8 recp_id, 6339334cb062SAnirudh Venkataramanan struct list_head *list_head) 63400f9d5027SAnirudh Venkataramanan { 63410f9d5027SAnirudh Venkataramanan struct ice_fltr_mgmt_list_entry *itr; 63425e24d598STony Nguyen int status = 0; 6343334cb062SAnirudh Venkataramanan u16 hw_vsi_id; 63440f9d5027SAnirudh Venkataramanan 63450f9d5027SAnirudh Venkataramanan if (list_empty(list_head)) 63460f9d5027SAnirudh Venkataramanan return status; 6347334cb062SAnirudh Venkataramanan hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle); 63480f9d5027SAnirudh Venkataramanan 6349334cb062SAnirudh Venkataramanan list_for_each_entry(itr, list_head, list_entry) { 63500f9d5027SAnirudh Venkataramanan struct ice_fltr_list_entry f_entry; 63510f9d5027SAnirudh Venkataramanan 63520f9d5027SAnirudh Venkataramanan f_entry.fltr_info = itr->fltr_info; 6353334cb062SAnirudh Venkataramanan if (itr->vsi_count < 2 && recp_id != ICE_SW_LKUP_VLAN && 6354334cb062SAnirudh Venkataramanan itr->fltr_info.vsi_handle == vsi_handle) { 6355f9867df6SAnirudh Venkataramanan /* update the src in case it is VSI num */ 6356334cb062SAnirudh Venkataramanan if (f_entry.fltr_info.src_id == ICE_SRC_ID_VSI) 6357334cb062SAnirudh Venkataramanan f_entry.fltr_info.src = hw_vsi_id; 63580f9d5027SAnirudh Venkataramanan status = ice_add_rule_internal(hw, recp_id, &f_entry); 63590f9d5027SAnirudh Venkataramanan if (status) 63600f9d5027SAnirudh Venkataramanan goto end; 63610f9d5027SAnirudh Venkataramanan continue; 63620f9d5027SAnirudh Venkataramanan } 6363072f0c3dSDave Ertman if (!itr->vsi_list_info || 6364072f0c3dSDave Ertman !test_bit(vsi_handle, itr->vsi_list_info->vsi_map)) 6365334cb062SAnirudh Venkataramanan continue; 6366334cb062SAnirudh Venkataramanan /* Clearing it so that the logic can add it back */ 6367334cb062SAnirudh Venkataramanan clear_bit(vsi_handle, itr->vsi_list_info->vsi_map); 6368334cb062SAnirudh Venkataramanan f_entry.fltr_info.vsi_handle = vsi_handle; 63690f9d5027SAnirudh Venkataramanan f_entry.fltr_info.fltr_act = ICE_FWD_TO_VSI; 6370f9867df6SAnirudh Venkataramanan /* update the src in case it is VSI num */ 6371334cb062SAnirudh Venkataramanan if (f_entry.fltr_info.src_id == ICE_SRC_ID_VSI) 6372334cb062SAnirudh Venkataramanan f_entry.fltr_info.src = hw_vsi_id; 63730f9d5027SAnirudh Venkataramanan if (recp_id == ICE_SW_LKUP_VLAN) 63740f9d5027SAnirudh Venkataramanan status = ice_add_vlan_internal(hw, &f_entry); 63750f9d5027SAnirudh Venkataramanan else 6376334cb062SAnirudh Venkataramanan status = ice_add_rule_internal(hw, recp_id, &f_entry); 63770f9d5027SAnirudh Venkataramanan if (status) 63780f9d5027SAnirudh Venkataramanan goto end; 63790f9d5027SAnirudh Venkataramanan } 63800f9d5027SAnirudh Venkataramanan end: 63810f9d5027SAnirudh Venkataramanan return status; 63820f9d5027SAnirudh Venkataramanan } 63830f9d5027SAnirudh Venkataramanan 63840f9d5027SAnirudh Venkataramanan /** 63858bb98f33SShivanshu Shukla * ice_adv_rem_update_vsi_list 63868bb98f33SShivanshu Shukla * @hw: pointer to the hardware structure 63878bb98f33SShivanshu Shukla * @vsi_handle: VSI handle of the VSI to remove 63888bb98f33SShivanshu Shukla * @fm_list: filter management entry for which the VSI list management needs to 63898bb98f33SShivanshu Shukla * be done 63908bb98f33SShivanshu Shukla */ 63915e24d598STony Nguyen static int 63928bb98f33SShivanshu Shukla ice_adv_rem_update_vsi_list(struct ice_hw *hw, u16 vsi_handle, 63938bb98f33SShivanshu Shukla struct ice_adv_fltr_mgmt_list_entry *fm_list) 63948bb98f33SShivanshu Shukla { 63958bb98f33SShivanshu Shukla struct ice_vsi_list_map_info *vsi_list_info; 63968bb98f33SShivanshu Shukla enum ice_sw_lkup_type lkup_type; 63978bb98f33SShivanshu Shukla u16 vsi_list_id; 63985518ac2aSTony Nguyen int status; 63998bb98f33SShivanshu Shukla 64008bb98f33SShivanshu Shukla if (fm_list->rule_info.sw_act.fltr_act != ICE_FWD_TO_VSI_LIST || 64018bb98f33SShivanshu Shukla fm_list->vsi_count == 0) 6402d54699e2STony Nguyen return -EINVAL; 64038bb98f33SShivanshu Shukla 64048bb98f33SShivanshu Shukla /* A rule with the VSI being removed does not exist */ 64058bb98f33SShivanshu Shukla if (!test_bit(vsi_handle, fm_list->vsi_list_info->vsi_map)) 6406d54699e2STony Nguyen return -ENOENT; 64078bb98f33SShivanshu Shukla 64088bb98f33SShivanshu Shukla lkup_type = ICE_SW_LKUP_LAST; 64098bb98f33SShivanshu Shukla vsi_list_id = fm_list->rule_info.sw_act.fwd_id.vsi_list_id; 64108bb98f33SShivanshu Shukla status = ice_update_vsi_list_rule(hw, &vsi_handle, 1, vsi_list_id, true, 64118bb98f33SShivanshu Shukla ice_aqc_opc_update_sw_rules, 64128bb98f33SShivanshu Shukla lkup_type); 64138bb98f33SShivanshu Shukla if (status) 64148bb98f33SShivanshu Shukla return status; 64158bb98f33SShivanshu Shukla 64168bb98f33SShivanshu Shukla fm_list->vsi_count--; 64178bb98f33SShivanshu Shukla clear_bit(vsi_handle, fm_list->vsi_list_info->vsi_map); 64188bb98f33SShivanshu Shukla vsi_list_info = fm_list->vsi_list_info; 64198bb98f33SShivanshu Shukla if (fm_list->vsi_count == 1) { 64208bb98f33SShivanshu Shukla struct ice_fltr_info tmp_fltr; 64218bb98f33SShivanshu Shukla u16 rem_vsi_handle; 64228bb98f33SShivanshu Shukla 64238bb98f33SShivanshu Shukla rem_vsi_handle = find_first_bit(vsi_list_info->vsi_map, 64248bb98f33SShivanshu Shukla ICE_MAX_VSI); 64258bb98f33SShivanshu Shukla if (!ice_is_vsi_valid(hw, rem_vsi_handle)) 6426d54699e2STony Nguyen return -EIO; 64278bb98f33SShivanshu Shukla 64288bb98f33SShivanshu Shukla /* Make sure VSI list is empty before removing it below */ 64298bb98f33SShivanshu Shukla status = ice_update_vsi_list_rule(hw, &rem_vsi_handle, 1, 64308bb98f33SShivanshu Shukla vsi_list_id, true, 64318bb98f33SShivanshu Shukla ice_aqc_opc_update_sw_rules, 64328bb98f33SShivanshu Shukla lkup_type); 64338bb98f33SShivanshu Shukla if (status) 64348bb98f33SShivanshu Shukla return status; 64358bb98f33SShivanshu Shukla 64368bb98f33SShivanshu Shukla memset(&tmp_fltr, 0, sizeof(tmp_fltr)); 64378bb98f33SShivanshu Shukla tmp_fltr.flag = fm_list->rule_info.sw_act.flag; 64388bb98f33SShivanshu Shukla tmp_fltr.fltr_rule_id = fm_list->rule_info.fltr_rule_id; 64398bb98f33SShivanshu Shukla fm_list->rule_info.sw_act.fltr_act = ICE_FWD_TO_VSI; 64408bb98f33SShivanshu Shukla tmp_fltr.fltr_act = ICE_FWD_TO_VSI; 64418bb98f33SShivanshu Shukla tmp_fltr.fwd_id.hw_vsi_id = 64428bb98f33SShivanshu Shukla ice_get_hw_vsi_num(hw, rem_vsi_handle); 64438bb98f33SShivanshu Shukla fm_list->rule_info.sw_act.fwd_id.hw_vsi_id = 64448bb98f33SShivanshu Shukla ice_get_hw_vsi_num(hw, rem_vsi_handle); 64458bb98f33SShivanshu Shukla fm_list->rule_info.sw_act.vsi_handle = rem_vsi_handle; 64468bb98f33SShivanshu Shukla 64478bb98f33SShivanshu Shukla /* Update the previous switch rule of "MAC forward to VSI" to 64488bb98f33SShivanshu Shukla * "MAC fwd to VSI list" 64498bb98f33SShivanshu Shukla */ 64508bb98f33SShivanshu Shukla status = ice_update_pkt_fwd_rule(hw, &tmp_fltr); 64518bb98f33SShivanshu Shukla if (status) { 64528bb98f33SShivanshu Shukla ice_debug(hw, ICE_DBG_SW, "Failed to update pkt fwd rule to FWD_TO_VSI on HW VSI %d, error %d\n", 64538bb98f33SShivanshu Shukla tmp_fltr.fwd_id.hw_vsi_id, status); 64548bb98f33SShivanshu Shukla return status; 64558bb98f33SShivanshu Shukla } 64568bb98f33SShivanshu Shukla fm_list->vsi_list_info->ref_cnt--; 64578bb98f33SShivanshu Shukla 64588bb98f33SShivanshu Shukla /* Remove the VSI list since it is no longer used */ 64598bb98f33SShivanshu Shukla status = ice_remove_vsi_list_rule(hw, vsi_list_id, lkup_type); 64608bb98f33SShivanshu Shukla if (status) { 64618bb98f33SShivanshu Shukla ice_debug(hw, ICE_DBG_SW, "Failed to remove VSI list %d, error %d\n", 64628bb98f33SShivanshu Shukla vsi_list_id, status); 64638bb98f33SShivanshu Shukla return status; 64648bb98f33SShivanshu Shukla } 64658bb98f33SShivanshu Shukla 64668bb98f33SShivanshu Shukla list_del(&vsi_list_info->list_entry); 64678bb98f33SShivanshu Shukla devm_kfree(ice_hw_to_dev(hw), vsi_list_info); 64688bb98f33SShivanshu Shukla fm_list->vsi_list_info = NULL; 64698bb98f33SShivanshu Shukla } 64708bb98f33SShivanshu Shukla 64718bb98f33SShivanshu Shukla return status; 64728bb98f33SShivanshu Shukla } 64738bb98f33SShivanshu Shukla 64748bb98f33SShivanshu Shukla /** 64758bb98f33SShivanshu Shukla * ice_rem_adv_rule - removes existing advanced switch rule 64768bb98f33SShivanshu Shukla * @hw: pointer to the hardware structure 64778bb98f33SShivanshu Shukla * @lkups: information on the words that needs to be looked up. All words 64788bb98f33SShivanshu Shukla * together makes one recipe 64798bb98f33SShivanshu Shukla * @lkups_cnt: num of entries in the lkups array 64808bb98f33SShivanshu Shukla * @rinfo: Its the pointer to the rule information for the rule 64818bb98f33SShivanshu Shukla * 64828bb98f33SShivanshu Shukla * This function can be used to remove 1 rule at a time. The lkups is 64838bb98f33SShivanshu Shukla * used to describe all the words that forms the "lookup" portion of the 64848bb98f33SShivanshu Shukla * rule. These words can span multiple protocols. Callers to this function 64858bb98f33SShivanshu Shukla * need to pass in a list of protocol headers with lookup information along 64868bb98f33SShivanshu Shukla * and mask that determines which words are valid from the given protocol 64878bb98f33SShivanshu Shukla * header. rinfo describes other information related to this rule such as 64888bb98f33SShivanshu Shukla * forwarding IDs, priority of this rule, etc. 64898bb98f33SShivanshu Shukla */ 64905e24d598STony Nguyen static int 64918bb98f33SShivanshu Shukla ice_rem_adv_rule(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups, 64928bb98f33SShivanshu Shukla u16 lkups_cnt, struct ice_adv_rule_info *rinfo) 64938bb98f33SShivanshu Shukla { 64948bb98f33SShivanshu Shukla struct ice_adv_fltr_mgmt_list_entry *list_elem; 64958bb98f33SShivanshu Shukla struct ice_prot_lkup_ext lkup_exts; 64968bb98f33SShivanshu Shukla bool remove_rule = false; 64978bb98f33SShivanshu Shukla struct mutex *rule_lock; /* Lock to protect filter rule list */ 64988bb98f33SShivanshu Shukla u16 i, rid, vsi_handle; 64995518ac2aSTony Nguyen int status = 0; 65008bb98f33SShivanshu Shukla 65018bb98f33SShivanshu Shukla memset(&lkup_exts, 0, sizeof(lkup_exts)); 65028bb98f33SShivanshu Shukla for (i = 0; i < lkups_cnt; i++) { 65038bb98f33SShivanshu Shukla u16 count; 65048bb98f33SShivanshu Shukla 65058bb98f33SShivanshu Shukla if (lkups[i].type >= ICE_PROTOCOL_LAST) 6506d54699e2STony Nguyen return -EIO; 65078bb98f33SShivanshu Shukla 65088bb98f33SShivanshu Shukla count = ice_fill_valid_words(&lkups[i], &lkup_exts); 65098bb98f33SShivanshu Shukla if (!count) 6510d54699e2STony Nguyen return -EIO; 65118bb98f33SShivanshu Shukla } 65128bb98f33SShivanshu Shukla 6513bccd9bceSMarcin Szycik rid = ice_find_recp(hw, &lkup_exts, rinfo); 65148bb98f33SShivanshu Shukla /* If did not find a recipe that match the existing criteria */ 65158bb98f33SShivanshu Shukla if (rid == ICE_MAX_NUM_RECIPES) 6516d54699e2STony Nguyen return -EINVAL; 65178bb98f33SShivanshu Shukla 65188bb98f33SShivanshu Shukla rule_lock = &hw->switch_info->recp_list[rid].filt_rule_lock; 65198bb98f33SShivanshu Shukla list_elem = ice_find_adv_rule_entry(hw, lkups, lkups_cnt, rid, rinfo); 65208bb98f33SShivanshu Shukla /* the rule is already removed */ 65218bb98f33SShivanshu Shukla if (!list_elem) 65228bb98f33SShivanshu Shukla return 0; 65238bb98f33SShivanshu Shukla mutex_lock(rule_lock); 65248bb98f33SShivanshu Shukla if (list_elem->rule_info.sw_act.fltr_act != ICE_FWD_TO_VSI_LIST) { 65258bb98f33SShivanshu Shukla remove_rule = true; 65268bb98f33SShivanshu Shukla } else if (list_elem->vsi_count > 1) { 65278bb98f33SShivanshu Shukla remove_rule = false; 65288bb98f33SShivanshu Shukla vsi_handle = rinfo->sw_act.vsi_handle; 65298bb98f33SShivanshu Shukla status = ice_adv_rem_update_vsi_list(hw, vsi_handle, list_elem); 65308bb98f33SShivanshu Shukla } else { 65318bb98f33SShivanshu Shukla vsi_handle = rinfo->sw_act.vsi_handle; 65328bb98f33SShivanshu Shukla status = ice_adv_rem_update_vsi_list(hw, vsi_handle, list_elem); 65338bb98f33SShivanshu Shukla if (status) { 65348bb98f33SShivanshu Shukla mutex_unlock(rule_lock); 65358bb98f33SShivanshu Shukla return status; 65368bb98f33SShivanshu Shukla } 65378bb98f33SShivanshu Shukla if (list_elem->vsi_count == 0) 65388bb98f33SShivanshu Shukla remove_rule = true; 65398bb98f33SShivanshu Shukla } 65408bb98f33SShivanshu Shukla mutex_unlock(rule_lock); 65418bb98f33SShivanshu Shukla if (remove_rule) { 65426e1ff618SAlexander Lobakin struct ice_sw_rule_lkup_rx_tx *s_rule; 65438bb98f33SShivanshu Shukla u16 rule_buf_sz; 65448bb98f33SShivanshu Shukla 65456e1ff618SAlexander Lobakin rule_buf_sz = ICE_SW_RULE_RX_TX_NO_HDR_SIZE(s_rule); 65468bb98f33SShivanshu Shukla s_rule = kzalloc(rule_buf_sz, GFP_KERNEL); 65478bb98f33SShivanshu Shukla if (!s_rule) 6548d54699e2STony Nguyen return -ENOMEM; 65496e1ff618SAlexander Lobakin s_rule->act = 0; 65506e1ff618SAlexander Lobakin s_rule->index = cpu_to_le16(list_elem->rule_info.fltr_rule_id); 65516e1ff618SAlexander Lobakin s_rule->hdr_len = 0; 65528bb98f33SShivanshu Shukla status = ice_aq_sw_rules(hw, (struct ice_aqc_sw_rules *)s_rule, 65538bb98f33SShivanshu Shukla rule_buf_sz, 1, 65548bb98f33SShivanshu Shukla ice_aqc_opc_remove_sw_rules, NULL); 6555d54699e2STony Nguyen if (!status || status == -ENOENT) { 65568bb98f33SShivanshu Shukla struct ice_switch_info *sw = hw->switch_info; 65578bb98f33SShivanshu Shukla 65588bb98f33SShivanshu Shukla mutex_lock(rule_lock); 65598bb98f33SShivanshu Shukla list_del(&list_elem->list_entry); 65608bb98f33SShivanshu Shukla devm_kfree(ice_hw_to_dev(hw), list_elem->lkups); 65618bb98f33SShivanshu Shukla devm_kfree(ice_hw_to_dev(hw), list_elem); 65628bb98f33SShivanshu Shukla mutex_unlock(rule_lock); 65638bb98f33SShivanshu Shukla if (list_empty(&sw->recp_list[rid].filt_rules)) 65648bb98f33SShivanshu Shukla sw->recp_list[rid].adv_rule = false; 65658bb98f33SShivanshu Shukla } 65668bb98f33SShivanshu Shukla kfree(s_rule); 65678bb98f33SShivanshu Shukla } 65688bb98f33SShivanshu Shukla return status; 65698bb98f33SShivanshu Shukla } 65708bb98f33SShivanshu Shukla 65718bb98f33SShivanshu Shukla /** 65728bb98f33SShivanshu Shukla * ice_rem_adv_rule_by_id - removes existing advanced switch rule by ID 65738bb98f33SShivanshu Shukla * @hw: pointer to the hardware structure 65748bb98f33SShivanshu Shukla * @remove_entry: data struct which holds rule_id, VSI handle and recipe ID 65758bb98f33SShivanshu Shukla * 65768bb98f33SShivanshu Shukla * This function is used to remove 1 rule at a time. The removal is based on 65778bb98f33SShivanshu Shukla * the remove_entry parameter. This function will remove rule for a given 65788bb98f33SShivanshu Shukla * vsi_handle with a given rule_id which is passed as parameter in remove_entry 65798bb98f33SShivanshu Shukla */ 65805e24d598STony Nguyen int 65818bb98f33SShivanshu Shukla ice_rem_adv_rule_by_id(struct ice_hw *hw, 65828bb98f33SShivanshu Shukla struct ice_rule_query_data *remove_entry) 65838bb98f33SShivanshu Shukla { 65848bb98f33SShivanshu Shukla struct ice_adv_fltr_mgmt_list_entry *list_itr; 65858bb98f33SShivanshu Shukla struct list_head *list_head; 65868bb98f33SShivanshu Shukla struct ice_adv_rule_info rinfo; 65878bb98f33SShivanshu Shukla struct ice_switch_info *sw; 65888bb98f33SShivanshu Shukla 65898bb98f33SShivanshu Shukla sw = hw->switch_info; 65908bb98f33SShivanshu Shukla if (!sw->recp_list[remove_entry->rid].recp_created) 6591d54699e2STony Nguyen return -EINVAL; 65928bb98f33SShivanshu Shukla list_head = &sw->recp_list[remove_entry->rid].filt_rules; 65938bb98f33SShivanshu Shukla list_for_each_entry(list_itr, list_head, list_entry) { 65948bb98f33SShivanshu Shukla if (list_itr->rule_info.fltr_rule_id == 65958bb98f33SShivanshu Shukla remove_entry->rule_id) { 65968bb98f33SShivanshu Shukla rinfo = list_itr->rule_info; 65978bb98f33SShivanshu Shukla rinfo.sw_act.vsi_handle = remove_entry->vsi_handle; 65988bb98f33SShivanshu Shukla return ice_rem_adv_rule(hw, list_itr->lkups, 65998bb98f33SShivanshu Shukla list_itr->lkups_cnt, &rinfo); 66008bb98f33SShivanshu Shukla } 66018bb98f33SShivanshu Shukla } 66028bb98f33SShivanshu Shukla /* either list is empty or unable to find rule */ 6603d54699e2STony Nguyen return -ENOENT; 66048bb98f33SShivanshu Shukla } 66058bb98f33SShivanshu Shukla 66068bb98f33SShivanshu Shukla /** 6607c36a2b97SVictor Raj * ice_replay_vsi_adv_rule - Replay advanced rule for requested VSI 6608c36a2b97SVictor Raj * @hw: pointer to the hardware structure 6609c36a2b97SVictor Raj * @vsi_handle: driver VSI handle 6610c36a2b97SVictor Raj * @list_head: list for which filters need to be replayed 6611c36a2b97SVictor Raj * 6612c36a2b97SVictor Raj * Replay the advanced rule for the given VSI. 6613c36a2b97SVictor Raj */ 6614c36a2b97SVictor Raj static int 6615c36a2b97SVictor Raj ice_replay_vsi_adv_rule(struct ice_hw *hw, u16 vsi_handle, 6616c36a2b97SVictor Raj struct list_head *list_head) 6617c36a2b97SVictor Raj { 6618c36a2b97SVictor Raj struct ice_rule_query_data added_entry = { 0 }; 6619c36a2b97SVictor Raj struct ice_adv_fltr_mgmt_list_entry *adv_fltr; 6620c36a2b97SVictor Raj int status = 0; 6621c36a2b97SVictor Raj 6622c36a2b97SVictor Raj if (list_empty(list_head)) 6623c36a2b97SVictor Raj return status; 6624c36a2b97SVictor Raj list_for_each_entry(adv_fltr, list_head, list_entry) { 6625c36a2b97SVictor Raj struct ice_adv_rule_info *rinfo = &adv_fltr->rule_info; 6626c36a2b97SVictor Raj u16 lk_cnt = adv_fltr->lkups_cnt; 6627c36a2b97SVictor Raj 6628c36a2b97SVictor Raj if (vsi_handle != rinfo->sw_act.vsi_handle) 6629c36a2b97SVictor Raj continue; 6630c36a2b97SVictor Raj status = ice_add_adv_rule(hw, adv_fltr->lkups, lk_cnt, rinfo, 6631c36a2b97SVictor Raj &added_entry); 6632c36a2b97SVictor Raj if (status) 6633c36a2b97SVictor Raj break; 6634c36a2b97SVictor Raj } 6635c36a2b97SVictor Raj return status; 6636c36a2b97SVictor Raj } 6637c36a2b97SVictor Raj 6638c36a2b97SVictor Raj /** 6639334cb062SAnirudh Venkataramanan * ice_replay_vsi_all_fltr - replay all filters stored in bookkeeping lists 66400f9d5027SAnirudh Venkataramanan * @hw: pointer to the hardware structure 6641334cb062SAnirudh Venkataramanan * @vsi_handle: driver VSI handle 66420f9d5027SAnirudh Venkataramanan * 6643334cb062SAnirudh Venkataramanan * Replays filters for requested VSI via vsi_handle. 66440f9d5027SAnirudh Venkataramanan */ 66455e24d598STony Nguyen int ice_replay_vsi_all_fltr(struct ice_hw *hw, u16 vsi_handle) 66460f9d5027SAnirudh Venkataramanan { 66470f9d5027SAnirudh Venkataramanan struct ice_switch_info *sw = hw->switch_info; 6648c36a2b97SVictor Raj int status; 66490f9d5027SAnirudh Venkataramanan u8 i; 66500f9d5027SAnirudh Venkataramanan 6651c36a2b97SVictor Raj for (i = 0; i < ICE_MAX_NUM_RECIPES; i++) { 6652334cb062SAnirudh Venkataramanan struct list_head *head; 66530f9d5027SAnirudh Venkataramanan 6654334cb062SAnirudh Venkataramanan head = &sw->recp_list[i].filt_replay_rules; 6655c36a2b97SVictor Raj if (!sw->recp_list[i].adv_rule) 6656334cb062SAnirudh Venkataramanan status = ice_replay_vsi_fltr(hw, vsi_handle, i, head); 6657c36a2b97SVictor Raj else 6658c36a2b97SVictor Raj status = ice_replay_vsi_adv_rule(hw, vsi_handle, head); 66590f9d5027SAnirudh Venkataramanan if (status) 66600f9d5027SAnirudh Venkataramanan return status; 66610f9d5027SAnirudh Venkataramanan } 66620f9d5027SAnirudh Venkataramanan return status; 66630f9d5027SAnirudh Venkataramanan } 6664334cb062SAnirudh Venkataramanan 6665334cb062SAnirudh Venkataramanan /** 6666334cb062SAnirudh Venkataramanan * ice_rm_all_sw_replay_rule_info - deletes filter replay rules 6667f9867df6SAnirudh Venkataramanan * @hw: pointer to the HW struct 6668334cb062SAnirudh Venkataramanan * 6669334cb062SAnirudh Venkataramanan * Deletes the filter replay rules. 6670334cb062SAnirudh Venkataramanan */ 6671334cb062SAnirudh Venkataramanan void ice_rm_all_sw_replay_rule_info(struct ice_hw *hw) 6672334cb062SAnirudh Venkataramanan { 6673334cb062SAnirudh Venkataramanan struct ice_switch_info *sw = hw->switch_info; 6674334cb062SAnirudh Venkataramanan u8 i; 6675334cb062SAnirudh Venkataramanan 6676334cb062SAnirudh Venkataramanan if (!sw) 6677334cb062SAnirudh Venkataramanan return; 6678334cb062SAnirudh Venkataramanan 66798b8ef05bSVictor Raj for (i = 0; i < ICE_MAX_NUM_RECIPES; i++) { 6680334cb062SAnirudh Venkataramanan if (!list_empty(&sw->recp_list[i].filt_replay_rules)) { 6681334cb062SAnirudh Venkataramanan struct list_head *l_head; 6682334cb062SAnirudh Venkataramanan 6683334cb062SAnirudh Venkataramanan l_head = &sw->recp_list[i].filt_replay_rules; 66848b8ef05bSVictor Raj if (!sw->recp_list[i].adv_rule) 6685334cb062SAnirudh Venkataramanan ice_rem_sw_rule_info(hw, l_head); 66868b8ef05bSVictor Raj else 66878b8ef05bSVictor Raj ice_rem_adv_rule_info(hw, l_head); 6688334cb062SAnirudh Venkataramanan } 6689334cb062SAnirudh Venkataramanan } 6690334cb062SAnirudh Venkataramanan } 6691