1 /* SPDX-License-Identifier: BSD-3-Clause */ 2 /* Copyright (c) 2023, Intel Corporation 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 * 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * 3. Neither the name of the Intel Corporation nor the names of its 16 * contributors may be used to endorse or promote products derived from 17 * this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 23 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 #include "ice_common.h" 33 #include "ice_flow.h" 34 35 /* Size of known protocol header fields */ 36 #define ICE_FLOW_FLD_SZ_ETH_TYPE 2 37 #define ICE_FLOW_FLD_SZ_VLAN 2 38 #define ICE_FLOW_FLD_SZ_IPV4_ADDR 4 39 #define ICE_FLOW_FLD_SZ_IPV6_ADDR 16 40 #define ICE_FLOW_FLD_SZ_IP_DSCP 1 41 #define ICE_FLOW_FLD_SZ_IP_TTL 1 42 #define ICE_FLOW_FLD_SZ_IP_PROT 1 43 #define ICE_FLOW_FLD_SZ_PORT 2 44 #define ICE_FLOW_FLD_SZ_TCP_FLAGS 1 45 #define ICE_FLOW_FLD_SZ_ICMP_TYPE 1 46 #define ICE_FLOW_FLD_SZ_ICMP_CODE 1 47 #define ICE_FLOW_FLD_SZ_ARP_OPER 2 48 #define ICE_FLOW_FLD_SZ_GRE_KEYID 4 49 50 /* Describe properties of a protocol header field */ 51 struct ice_flow_field_info { 52 enum ice_flow_seg_hdr hdr; 53 s16 off; /* Offset from start of a protocol header, in bits */ 54 u16 size; /* Size of fields in bits */ 55 }; 56 57 #define ICE_FLOW_FLD_INFO(_hdr, _offset_bytes, _size_bytes) { \ 58 .hdr = _hdr, \ 59 .off = (_offset_bytes) * BITS_PER_BYTE, \ 60 .size = (_size_bytes) * BITS_PER_BYTE, \ 61 } 62 63 /* Table containing properties of supported protocol header fields */ 64 static const 65 struct ice_flow_field_info ice_flds_info[ICE_FLOW_FIELD_IDX_MAX] = { 66 /* Ether */ 67 /* ICE_FLOW_FIELD_IDX_ETH_DA */ 68 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ETH, 0, ETH_ALEN), 69 /* ICE_FLOW_FIELD_IDX_ETH_SA */ 70 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ETH, ETH_ALEN, ETH_ALEN), 71 /* ICE_FLOW_FIELD_IDX_S_VLAN */ 72 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_VLAN, 12, ICE_FLOW_FLD_SZ_VLAN), 73 /* ICE_FLOW_FIELD_IDX_C_VLAN */ 74 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_VLAN, 14, ICE_FLOW_FLD_SZ_VLAN), 75 /* ICE_FLOW_FIELD_IDX_ETH_TYPE */ 76 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ETH, 0, ICE_FLOW_FLD_SZ_ETH_TYPE), 77 /* IPv4 / IPv6 */ 78 /* ICE_FLOW_FIELD_IDX_IPV4_DSCP */ 79 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV4, 1, ICE_FLOW_FLD_SZ_IP_DSCP), 80 /* ICE_FLOW_FIELD_IDX_IPV6_DSCP */ 81 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV6, 0, ICE_FLOW_FLD_SZ_IP_DSCP), 82 /* ICE_FLOW_FIELD_IDX_IPV4_TTL */ 83 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_NONE, 8, ICE_FLOW_FLD_SZ_IP_TTL), 84 /* ICE_FLOW_FIELD_IDX_IPV4_PROT */ 85 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_NONE, 9, ICE_FLOW_FLD_SZ_IP_PROT), 86 /* ICE_FLOW_FIELD_IDX_IPV6_TTL */ 87 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_NONE, 7, ICE_FLOW_FLD_SZ_IP_TTL), 88 /* ICE_FLOW_FIELD_IDX_IPV4_PROT */ 89 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_NONE, 6, ICE_FLOW_FLD_SZ_IP_PROT), 90 /* ICE_FLOW_FIELD_IDX_IPV4_SA */ 91 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV4, 12, ICE_FLOW_FLD_SZ_IPV4_ADDR), 92 /* ICE_FLOW_FIELD_IDX_IPV4_DA */ 93 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV4, 16, ICE_FLOW_FLD_SZ_IPV4_ADDR), 94 /* ICE_FLOW_FIELD_IDX_IPV6_SA */ 95 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV6, 8, ICE_FLOW_FLD_SZ_IPV6_ADDR), 96 /* ICE_FLOW_FIELD_IDX_IPV6_DA */ 97 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV6, 24, ICE_FLOW_FLD_SZ_IPV6_ADDR), 98 /* Transport */ 99 /* ICE_FLOW_FIELD_IDX_TCP_SRC_PORT */ 100 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_TCP, 0, ICE_FLOW_FLD_SZ_PORT), 101 /* ICE_FLOW_FIELD_IDX_TCP_DST_PORT */ 102 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_TCP, 2, ICE_FLOW_FLD_SZ_PORT), 103 /* ICE_FLOW_FIELD_IDX_UDP_SRC_PORT */ 104 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_UDP, 0, ICE_FLOW_FLD_SZ_PORT), 105 /* ICE_FLOW_FIELD_IDX_UDP_DST_PORT */ 106 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_UDP, 2, ICE_FLOW_FLD_SZ_PORT), 107 /* ICE_FLOW_FIELD_IDX_SCTP_SRC_PORT */ 108 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_SCTP, 0, ICE_FLOW_FLD_SZ_PORT), 109 /* ICE_FLOW_FIELD_IDX_SCTP_DST_PORT */ 110 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_SCTP, 2, ICE_FLOW_FLD_SZ_PORT), 111 /* ICE_FLOW_FIELD_IDX_TCP_FLAGS */ 112 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_TCP, 13, ICE_FLOW_FLD_SZ_TCP_FLAGS), 113 /* ARP */ 114 /* ICE_FLOW_FIELD_IDX_ARP_SIP */ 115 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ARP, 14, ICE_FLOW_FLD_SZ_IPV4_ADDR), 116 /* ICE_FLOW_FIELD_IDX_ARP_DIP */ 117 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ARP, 24, ICE_FLOW_FLD_SZ_IPV4_ADDR), 118 /* ICE_FLOW_FIELD_IDX_ARP_SHA */ 119 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ARP, 8, ETH_ALEN), 120 /* ICE_FLOW_FIELD_IDX_ARP_DHA */ 121 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ARP, 18, ETH_ALEN), 122 /* ICE_FLOW_FIELD_IDX_ARP_OP */ 123 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ARP, 6, ICE_FLOW_FLD_SZ_ARP_OPER), 124 /* ICMP */ 125 /* ICE_FLOW_FIELD_IDX_ICMP_TYPE */ 126 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ICMP, 0, ICE_FLOW_FLD_SZ_ICMP_TYPE), 127 /* ICE_FLOW_FIELD_IDX_ICMP_CODE */ 128 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ICMP, 1, ICE_FLOW_FLD_SZ_ICMP_CODE), 129 /* GRE */ 130 /* ICE_FLOW_FIELD_IDX_GRE_KEYID */ 131 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_GRE, 12, ICE_FLOW_FLD_SZ_GRE_KEYID), 132 }; 133 134 /* Bitmaps indicating relevant packet types for a particular protocol header 135 * 136 * Packet types for packets with an Outer/First/Single MAC header 137 */ 138 static const u32 ice_ptypes_mac_ofos[] = { 139 0xFDC00846, 0xBFBF7F7E, 0xF70001DF, 0xFEFDFDFB, 140 0x0000077E, 0x00000000, 0x00000000, 0x00000000, 141 0x00000000, 0x00000000, 0x00000000, 0x00000000, 142 0x00000000, 0x00000000, 0x00000000, 0x00000000, 143 0x00000000, 0x00000000, 0x00000000, 0x00000000, 144 0x00000000, 0x00000000, 0x00000000, 0x00000000, 145 0x00000000, 0x00000000, 0x00000000, 0x00000000, 146 0x00000000, 0x00000000, 0x00000000, 0x00000000, 147 }; 148 149 /* Packet types for packets with an Innermost/Last MAC VLAN header */ 150 static const u32 ice_ptypes_macvlan_il[] = { 151 0x00000000, 0xBC000000, 0x000001DF, 0xF0000000, 152 0x0000077E, 0x00000000, 0x00000000, 0x00000000, 153 0x00000000, 0x00000000, 0x00000000, 0x00000000, 154 0x00000000, 0x00000000, 0x00000000, 0x00000000, 155 0x00000000, 0x00000000, 0x00000000, 0x00000000, 156 0x00000000, 0x00000000, 0x00000000, 0x00000000, 157 0x00000000, 0x00000000, 0x00000000, 0x00000000, 158 0x00000000, 0x00000000, 0x00000000, 0x00000000, 159 }; 160 161 /* Packet types for packets with an Outer/First/Single non-frag IPv4 header, 162 * does NOT include IPV4 other PTYPEs 163 */ 164 static const u32 ice_ptypes_ipv4_ofos[] = { 165 0x1D800000, 0x04000800, 0x00000000, 0x00000000, 166 0x00000000, 0x00000000, 0x00000000, 0x00000000, 167 0x00000000, 0x00000000, 0x00000000, 0x00000000, 168 0x00000000, 0x00000000, 0x00000000, 0x00000000, 169 0x00000000, 0x00000000, 0x00000000, 0x00000000, 170 0x00000000, 0x00000000, 0x00000000, 0x00000000, 171 0x00000000, 0x00000000, 0x00000000, 0x00000000, 172 0x00000000, 0x00000000, 0x00000000, 0x00000000, 173 }; 174 175 /* Packet types for packets with an Outer/First/Single non-frag IPv4 header, 176 * includes IPV4 other PTYPEs 177 */ 178 static const u32 ice_ptypes_ipv4_ofos_all[] = { 179 0x1D800000, 0x04000800, 0x00000000, 0x00000000, 180 0x00000000, 0x00000000, 0x00000000, 0x00000000, 181 0x00000000, 0x00000000, 0x00000000, 0x00000000, 182 0x00000000, 0x00000000, 0x00000000, 0x00000000, 183 0x00000000, 0x00000000, 0x00000000, 0x00000000, 184 0x00000000, 0x00000000, 0x00000000, 0x00000000, 185 0x00000000, 0x00000000, 0x00000000, 0x00000000, 186 0x00000000, 0x00000000, 0x00000000, 0x00000000, 187 }; 188 189 /* Packet types for packets with an Innermost/Last IPv4 header */ 190 static const u32 ice_ptypes_ipv4_il[] = { 191 0xE0000000, 0xB807700E, 0x80000003, 0xE01DC03B, 192 0x0000000E, 0x00000000, 0x00000000, 0x00000000, 193 0x00000000, 0x00000000, 0x00000000, 0x00000000, 194 0x00000000, 0x00000000, 0x00000000, 0x00000000, 195 0x00000000, 0x00000000, 0x00000000, 0x00000000, 196 0x00000000, 0x00000000, 0x00000000, 0x00000000, 197 0x00000000, 0x00000000, 0x00000000, 0x00000000, 198 0x00000000, 0x00000000, 0x00000000, 0x00000000, 199 }; 200 201 /* Packet types for packets with an Outer/First/Single non-frag IPv6 header, 202 * does NOT include IVP6 other PTYPEs 203 */ 204 static const u32 ice_ptypes_ipv6_ofos[] = { 205 0x00000000, 0x00000000, 0x76000000, 0x10002000, 206 0x00000000, 0x00000000, 0x00000000, 0x00000000, 207 0x00000000, 0x00000000, 0x00000000, 0x00000000, 208 0x00000000, 0x00000000, 0x00000000, 0x00000000, 209 0x00000000, 0x00000000, 0x00000000, 0x00000000, 210 0x00000000, 0x00000000, 0x00000000, 0x00000000, 211 0x00000000, 0x00000000, 0x00000000, 0x00000000, 212 0x00000000, 0x00000000, 0x00000000, 0x00000000, 213 }; 214 215 /* Packet types for packets with an Outer/First/Single non-frag IPv6 header, 216 * includes IPV6 other PTYPEs 217 */ 218 static const u32 ice_ptypes_ipv6_ofos_all[] = { 219 0x00000000, 0x00000000, 0x76000000, 0x10002000, 220 0x00000000, 0x00000000, 0x00000000, 0x00000000, 221 0x00000000, 0x00000000, 0x00000000, 0x00000000, 222 0x00000000, 0x00000000, 0x00000000, 0x00000000, 223 0x00000000, 0x00000000, 0x00000000, 0x00000000, 224 0x00000000, 0x00000000, 0x00000000, 0x00000000, 225 0x00000000, 0x00000000, 0x00000000, 0x00000000, 226 0x00000000, 0x00000000, 0x00000000, 0x00000000, 227 }; 228 229 /* Packet types for packets with an Innermost/Last IPv6 header */ 230 static const u32 ice_ptypes_ipv6_il[] = { 231 0x00000000, 0x03B80770, 0x000001DC, 0x0EE00000, 232 0x00000770, 0x00000000, 0x00000000, 0x00000000, 233 0x00000000, 0x00000000, 0x00000000, 0x00000000, 234 0x00000000, 0x00000000, 0x00000000, 0x00000000, 235 0x00000000, 0x00000000, 0x00000000, 0x00000000, 236 0x00000000, 0x00000000, 0x00000000, 0x00000000, 237 0x00000000, 0x00000000, 0x00000000, 0x00000000, 238 0x00000000, 0x00000000, 0x00000000, 0x00000000, 239 }; 240 241 /* Packet types for packets with an Outer/First/Single 242 * non-frag IPv4 header - no L4 243 */ 244 static const u32 ice_ptypes_ipv4_ofos_no_l4[] = { 245 0x10800000, 0x04000800, 0x00000000, 0x00000000, 246 0x00000000, 0x00000000, 0x00000000, 0x00000000, 247 0x00000000, 0x00000000, 0x00000000, 0x00000000, 248 0x00000000, 0x00000000, 0x00000000, 0x00000000, 249 0x00000000, 0x00000000, 0x00000000, 0x00000000, 250 0x00000000, 0x00000000, 0x00000000, 0x00000000, 251 0x00000000, 0x00000000, 0x00000000, 0x00000000, 252 0x00000000, 0x00000000, 0x00000000, 0x00000000, 253 }; 254 255 /* Packet types for packets with an Innermost/Last IPv4 header - no L4 */ 256 static const u32 ice_ptypes_ipv4_il_no_l4[] = { 257 0x60000000, 0x18043008, 0x80000002, 0x6010c021, 258 0x00000008, 0x00000000, 0x00000000, 0x00000000, 259 0x00000000, 0x00000000, 0x00000000, 0x00000000, 260 0x00000000, 0x00000000, 0x00000000, 0x00000000, 261 0x00000000, 0x00000000, 0x00000000, 0x00000000, 262 0x00000000, 0x00000000, 0x00000000, 0x00000000, 263 0x00000000, 0x00000000, 0x00000000, 0x00000000, 264 0x00000000, 0x00000000, 0x00000000, 0x00000000, 265 }; 266 267 /* Packet types for packets with an Outer/First/Single 268 * non-frag IPv6 header - no L4 269 */ 270 static const u32 ice_ptypes_ipv6_ofos_no_l4[] = { 271 0x00000000, 0x00000000, 0x42000000, 0x10002000, 272 0x00000000, 0x00000000, 0x00000000, 0x00000000, 273 0x00000000, 0x00000000, 0x00000000, 0x00000000, 274 0x00000000, 0x00000000, 0x00000000, 0x00000000, 275 0x00000000, 0x00000000, 0x00000000, 0x00000000, 276 0x00000000, 0x00000000, 0x00000000, 0x00000000, 277 0x00000000, 0x00000000, 0x00000000, 0x00000000, 278 0x00000000, 0x00000000, 0x00000000, 0x00000000, 279 }; 280 281 /* Packet types for packets with an Innermost/Last IPv6 header - no L4 */ 282 static const u32 ice_ptypes_ipv6_il_no_l4[] = { 283 0x00000000, 0x02180430, 0x0000010c, 0x086010c0, 284 0x00000430, 0x00000000, 0x00000000, 0x00000000, 285 0x00000000, 0x00000000, 0x00000000, 0x00000000, 286 0x00000000, 0x00000000, 0x00000000, 0x00000000, 287 0x00000000, 0x00000000, 0x00000000, 0x00000000, 288 0x00000000, 0x00000000, 0x00000000, 0x00000000, 289 0x00000000, 0x00000000, 0x00000000, 0x00000000, 290 0x00000000, 0x00000000, 0x00000000, 0x00000000, 291 }; 292 293 /* Packet types for packets with an Outermost/First ARP header */ 294 static const u32 ice_ptypes_arp_of[] = { 295 0x00000800, 0x00000000, 0x00000000, 0x00000000, 296 0x00000000, 0x00000000, 0x00000000, 0x00000000, 297 0x00000000, 0x00000000, 0x00000000, 0x00000000, 298 0x00000000, 0x00000000, 0x00000000, 0x00000000, 299 0x00000000, 0x00000000, 0x00000000, 0x00000000, 300 0x00000000, 0x00000000, 0x00000000, 0x00000000, 301 0x00000000, 0x00000000, 0x00000000, 0x00000000, 302 0x00000000, 0x00000000, 0x00000000, 0x00000000, 303 }; 304 305 /* UDP Packet types for non-tunneled packets or tunneled 306 * packets with inner UDP. 307 */ 308 static const u32 ice_ptypes_udp_il[] = { 309 0x81000000, 0x20204040, 0x04000010, 0x80810102, 310 0x00000040, 0x00000000, 0x00000000, 0x00000000, 311 0x00000000, 0x00000000, 0x00000000, 0x00000000, 312 0x00000000, 0x00000000, 0x00000000, 0x00000000, 313 0x00000000, 0x00000000, 0x00000000, 0x00000000, 314 0x00000000, 0x00000000, 0x00000000, 0x00000000, 315 0x00000000, 0x00000000, 0x00000000, 0x00000000, 316 0x00000000, 0x00000000, 0x00000000, 0x00000000, 317 }; 318 319 /* Packet types for packets with an Innermost/Last TCP header */ 320 static const u32 ice_ptypes_tcp_il[] = { 321 0x04000000, 0x80810102, 0x10000040, 0x02040408, 322 0x00000102, 0x00000000, 0x00000000, 0x00000000, 323 0x00000000, 0x00000000, 0x00000000, 0x00000000, 324 0x00000000, 0x00000000, 0x00000000, 0x00000000, 325 0x00000000, 0x00000000, 0x00000000, 0x00000000, 326 0x00000000, 0x00000000, 0x00000000, 0x00000000, 327 0x00000000, 0x00000000, 0x00000000, 0x00000000, 328 0x00000000, 0x00000000, 0x00000000, 0x00000000, 329 }; 330 331 /* Packet types for packets with an Innermost/Last SCTP header */ 332 static const u32 ice_ptypes_sctp_il[] = { 333 0x08000000, 0x01020204, 0x20000081, 0x04080810, 334 0x00000204, 0x00000000, 0x00000000, 0x00000000, 335 0x00000000, 0x00000000, 0x00000000, 0x00000000, 336 0x00000000, 0x00000000, 0x00000000, 0x00000000, 337 0x00000000, 0x00000000, 0x00000000, 0x00000000, 338 0x00000000, 0x00000000, 0x00000000, 0x00000000, 339 0x00000000, 0x00000000, 0x00000000, 0x00000000, 340 0x00000000, 0x00000000, 0x00000000, 0x00000000, 341 }; 342 343 /* Packet types for packets with an Outermost/First ICMP header */ 344 static const u32 ice_ptypes_icmp_of[] = { 345 0x10000000, 0x00000000, 0x00000000, 0x00000000, 346 0x00000000, 0x00000000, 0x00000000, 0x00000000, 347 0x00000000, 0x00000000, 0x00000000, 0x00000000, 348 0x00000000, 0x00000000, 0x00000000, 0x00000000, 349 0x00000000, 0x00000000, 0x00000000, 0x00000000, 350 0x00000000, 0x00000000, 0x00000000, 0x00000000, 351 0x00000000, 0x00000000, 0x00000000, 0x00000000, 352 0x00000000, 0x00000000, 0x00000000, 0x00000000, 353 }; 354 355 /* Packet types for packets with an Innermost/Last ICMP header */ 356 static const u32 ice_ptypes_icmp_il[] = { 357 0x00000000, 0x02040408, 0x40000102, 0x08101020, 358 0x00000408, 0x00000000, 0x00000000, 0x00000000, 359 0x00000000, 0x00000000, 0x00000000, 0x00000000, 360 0x00000000, 0x00000000, 0x00000000, 0x00000000, 361 0x00000000, 0x00000000, 0x00000000, 0x00000000, 362 0x00000000, 0x00000000, 0x00000000, 0x00000000, 363 0x00000000, 0x00000000, 0x00000000, 0x00000000, 364 0x00000000, 0x00000000, 0x00000000, 0x00000000, 365 }; 366 367 /* Packet types for packets with an Outermost/First GRE header */ 368 static const u32 ice_ptypes_gre_of[] = { 369 0x00000000, 0xBFBF7800, 0x000001DF, 0xFEFDE000, 370 0x0000017E, 0x00000000, 0x00000000, 0x00000000, 371 0x00000000, 0x00000000, 0x00000000, 0x00000000, 372 0x00000000, 0x00000000, 0x00000000, 0x00000000, 373 0x00000000, 0x00000000, 0x00000000, 0x00000000, 374 0x00000000, 0x00000000, 0x00000000, 0x00000000, 375 0x00000000, 0x00000000, 0x00000000, 0x00000000, 376 0x00000000, 0x00000000, 0x00000000, 0x00000000, 377 }; 378 379 /* Packet types for packets with an Innermost/Last MAC header */ 380 static const u32 ice_ptypes_mac_il[] = { 381 0x00000000, 0x00000000, 0x00000000, 0x00000000, 382 0x00000000, 0x00000000, 0x00000000, 0x00000000, 383 0x00000000, 0x00000000, 0x00000000, 0x00000000, 384 0x00000000, 0x00000000, 0x00000000, 0x00000000, 385 0x00000000, 0x00000000, 0x00000000, 0x00000000, 386 0x00000000, 0x00000000, 0x00000000, 0x00000000, 387 0x00000000, 0x00000000, 0x00000000, 0x00000000, 388 0x00000000, 0x00000000, 0x00000000, 0x00000000, 389 }; 390 391 /* Manage parameters and info. used during the creation of a flow profile */ 392 struct ice_flow_prof_params { 393 enum ice_block blk; 394 u16 entry_length; /* # of bytes formatted entry will require */ 395 u8 es_cnt; 396 struct ice_flow_prof *prof; 397 398 /* For ACL, the es[0] will have the data of ICE_RX_MDID_PKT_FLAGS_15_0 399 * This will give us the direction flags. 400 */ 401 struct ice_fv_word es[ICE_MAX_FV_WORDS]; 402 403 ice_declare_bitmap(ptypes, ICE_FLOW_PTYPE_MAX); 404 }; 405 406 #define ICE_FLOW_SEG_HDRS_L3_MASK \ 407 (ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_IPV6 | \ 408 ICE_FLOW_SEG_HDR_ARP) 409 #define ICE_FLOW_SEG_HDRS_L4_MASK \ 410 (ICE_FLOW_SEG_HDR_ICMP | ICE_FLOW_SEG_HDR_TCP | ICE_FLOW_SEG_HDR_UDP | \ 411 ICE_FLOW_SEG_HDR_SCTP) 412 /* mask for L4 protocols that are NOT part of IPV4/6 OTHER PTYPE groups */ 413 #define ICE_FLOW_SEG_HDRS_L4_MASK_NO_OTHER \ 414 (ICE_FLOW_SEG_HDR_TCP | ICE_FLOW_SEG_HDR_UDP | ICE_FLOW_SEG_HDR_SCTP) 415 416 /** 417 * ice_flow_val_hdrs - validates packet segments for valid protocol headers 418 * @segs: array of one or more packet segments that describe the flow 419 * @segs_cnt: number of packet segments provided 420 */ 421 static enum ice_status 422 ice_flow_val_hdrs(struct ice_flow_seg_info *segs, u8 segs_cnt) 423 { 424 u8 i; 425 426 for (i = 0; i < segs_cnt; i++) { 427 /* Multiple L3 headers */ 428 if (segs[i].hdrs & ICE_FLOW_SEG_HDRS_L3_MASK && 429 !ice_is_pow2(segs[i].hdrs & ICE_FLOW_SEG_HDRS_L3_MASK)) 430 return ICE_ERR_PARAM; 431 432 /* Multiple L4 headers */ 433 if (segs[i].hdrs & ICE_FLOW_SEG_HDRS_L4_MASK && 434 !ice_is_pow2(segs[i].hdrs & ICE_FLOW_SEG_HDRS_L4_MASK)) 435 return ICE_ERR_PARAM; 436 } 437 438 return ICE_SUCCESS; 439 } 440 441 /** 442 * ice_flow_proc_seg_hdrs - process protocol headers present in pkt segments 443 * @params: information about the flow to be processed 444 * 445 * This function identifies the packet types associated with the protocol 446 * headers being present in packet segments of the specified flow profile. 447 */ 448 static enum ice_status 449 ice_flow_proc_seg_hdrs(struct ice_flow_prof_params *params) 450 { 451 struct ice_flow_prof *prof; 452 u8 i; 453 454 ice_memset(params->ptypes, 0xff, sizeof(params->ptypes), 455 ICE_NONDMA_MEM); 456 457 prof = params->prof; 458 459 for (i = 0; i < params->prof->segs_cnt; i++) { 460 const ice_bitmap_t *src; 461 u32 hdrs; 462 463 hdrs = prof->segs[i].hdrs; 464 465 if (hdrs & ICE_FLOW_SEG_HDR_ETH) { 466 src = !i ? (const ice_bitmap_t *)ice_ptypes_mac_ofos : 467 (const ice_bitmap_t *)ice_ptypes_mac_il; 468 ice_and_bitmap(params->ptypes, params->ptypes, src, 469 ICE_FLOW_PTYPE_MAX); 470 } 471 472 if (i && hdrs & ICE_FLOW_SEG_HDR_VLAN) { 473 src = (const ice_bitmap_t *)ice_ptypes_macvlan_il; 474 ice_and_bitmap(params->ptypes, params->ptypes, src, 475 ICE_FLOW_PTYPE_MAX); 476 } 477 478 if (!i && hdrs & ICE_FLOW_SEG_HDR_ARP) { 479 ice_and_bitmap(params->ptypes, params->ptypes, 480 (const ice_bitmap_t *)ice_ptypes_arp_of, 481 ICE_FLOW_PTYPE_MAX); 482 } 483 484 if ((hdrs & ICE_FLOW_SEG_HDR_IPV4) && 485 (hdrs & ICE_FLOW_SEG_HDR_IPV_OTHER)) { 486 src = i ? 487 (const ice_bitmap_t *)ice_ptypes_ipv4_il : 488 (const ice_bitmap_t *)ice_ptypes_ipv4_ofos_all; 489 ice_and_bitmap(params->ptypes, params->ptypes, src, 490 ICE_FLOW_PTYPE_MAX); 491 } else if ((hdrs & ICE_FLOW_SEG_HDR_IPV6) && 492 (hdrs & ICE_FLOW_SEG_HDR_IPV_OTHER)) { 493 src = i ? 494 (const ice_bitmap_t *)ice_ptypes_ipv6_il : 495 (const ice_bitmap_t *)ice_ptypes_ipv6_ofos_all; 496 ice_and_bitmap(params->ptypes, params->ptypes, src, 497 ICE_FLOW_PTYPE_MAX); 498 } else if ((hdrs & ICE_FLOW_SEG_HDR_IPV4) && 499 !(hdrs & ICE_FLOW_SEG_HDRS_L4_MASK_NO_OTHER)) { 500 src = !i ? (const ice_bitmap_t *)ice_ptypes_ipv4_ofos_no_l4 : 501 (const ice_bitmap_t *)ice_ptypes_ipv4_il_no_l4; 502 ice_and_bitmap(params->ptypes, params->ptypes, src, 503 ICE_FLOW_PTYPE_MAX); 504 } else if (hdrs & ICE_FLOW_SEG_HDR_IPV4) { 505 src = !i ? (const ice_bitmap_t *)ice_ptypes_ipv4_ofos : 506 (const ice_bitmap_t *)ice_ptypes_ipv4_il; 507 ice_and_bitmap(params->ptypes, params->ptypes, src, 508 ICE_FLOW_PTYPE_MAX); 509 } else if ((hdrs & ICE_FLOW_SEG_HDR_IPV6) && 510 !(hdrs & ICE_FLOW_SEG_HDRS_L4_MASK_NO_OTHER)) { 511 src = !i ? (const ice_bitmap_t *)ice_ptypes_ipv6_ofos_no_l4 : 512 (const ice_bitmap_t *)ice_ptypes_ipv6_il_no_l4; 513 ice_and_bitmap(params->ptypes, params->ptypes, src, 514 ICE_FLOW_PTYPE_MAX); 515 } else if (hdrs & ICE_FLOW_SEG_HDR_IPV6) { 516 src = !i ? (const ice_bitmap_t *)ice_ptypes_ipv6_ofos : 517 (const ice_bitmap_t *)ice_ptypes_ipv6_il; 518 ice_and_bitmap(params->ptypes, params->ptypes, src, 519 ICE_FLOW_PTYPE_MAX); 520 } 521 522 if (hdrs & ICE_FLOW_SEG_HDR_UDP) { 523 src = (const ice_bitmap_t *)ice_ptypes_udp_il; 524 ice_and_bitmap(params->ptypes, params->ptypes, src, 525 ICE_FLOW_PTYPE_MAX); 526 } else if (hdrs & ICE_FLOW_SEG_HDR_TCP) { 527 ice_and_bitmap(params->ptypes, params->ptypes, 528 (const ice_bitmap_t *)ice_ptypes_tcp_il, 529 ICE_FLOW_PTYPE_MAX); 530 } else if (hdrs & ICE_FLOW_SEG_HDR_SCTP) { 531 src = (const ice_bitmap_t *)ice_ptypes_sctp_il; 532 ice_and_bitmap(params->ptypes, params->ptypes, src, 533 ICE_FLOW_PTYPE_MAX); 534 } 535 536 if (hdrs & ICE_FLOW_SEG_HDR_ICMP) { 537 src = !i ? (const ice_bitmap_t *)ice_ptypes_icmp_of : 538 (const ice_bitmap_t *)ice_ptypes_icmp_il; 539 ice_and_bitmap(params->ptypes, params->ptypes, src, 540 ICE_FLOW_PTYPE_MAX); 541 } else if (hdrs & ICE_FLOW_SEG_HDR_GRE) { 542 if (!i) { 543 src = (const ice_bitmap_t *)ice_ptypes_gre_of; 544 ice_and_bitmap(params->ptypes, params->ptypes, 545 src, ICE_FLOW_PTYPE_MAX); 546 } 547 } 548 } 549 550 return ICE_SUCCESS; 551 } 552 553 /** 554 * ice_flow_xtract_fld - Create an extraction sequence entry for the given field 555 * @hw: pointer to the HW struct 556 * @params: information about the flow to be processed 557 * @seg: packet segment index of the field to be extracted 558 * @fld: ID of field to be extracted 559 * 560 * This function determines the protocol ID, offset, and size of the given 561 * field. It then allocates one or more extraction sequence entries for the 562 * given field, and fill the entries with protocol ID and offset information. 563 */ 564 static enum ice_status 565 ice_flow_xtract_fld(struct ice_hw *hw, struct ice_flow_prof_params *params, 566 u8 seg, enum ice_flow_field fld) 567 { 568 enum ice_flow_field sib = ICE_FLOW_FIELD_IDX_MAX; 569 u8 fv_words = (u8)hw->blk[params->blk].es.fvw; 570 enum ice_prot_id prot_id = ICE_PROT_ID_INVAL; 571 struct ice_flow_fld_info *flds; 572 u16 cnt, ese_bits, i; 573 u16 off; 574 575 flds = params->prof->segs[seg].fields; 576 577 switch (fld) { 578 case ICE_FLOW_FIELD_IDX_ETH_DA: 579 case ICE_FLOW_FIELD_IDX_ETH_SA: 580 case ICE_FLOW_FIELD_IDX_S_VLAN: 581 case ICE_FLOW_FIELD_IDX_C_VLAN: 582 prot_id = seg == 0 ? ICE_PROT_MAC_OF_OR_S : ICE_PROT_MAC_IL; 583 break; 584 case ICE_FLOW_FIELD_IDX_ETH_TYPE: 585 prot_id = seg == 0 ? ICE_PROT_ETYPE_OL : ICE_PROT_ETYPE_IL; 586 break; 587 case ICE_FLOW_FIELD_IDX_IPV4_DSCP: 588 prot_id = seg == 0 ? ICE_PROT_IPV4_OF_OR_S : ICE_PROT_IPV4_IL; 589 break; 590 case ICE_FLOW_FIELD_IDX_IPV6_DSCP: 591 prot_id = seg == 0 ? ICE_PROT_IPV6_OF_OR_S : ICE_PROT_IPV6_IL; 592 break; 593 case ICE_FLOW_FIELD_IDX_IPV4_TTL: 594 case ICE_FLOW_FIELD_IDX_IPV4_PROT: 595 prot_id = seg == 0 ? ICE_PROT_IPV4_OF_OR_S : ICE_PROT_IPV4_IL; 596 /* TTL and PROT share the same extraction seq. entry. 597 * Each is considered a sibling to the other in terms of sharing 598 * the same extraction sequence entry. 599 */ 600 if (fld == ICE_FLOW_FIELD_IDX_IPV4_TTL) 601 sib = ICE_FLOW_FIELD_IDX_IPV4_PROT; 602 else 603 sib = ICE_FLOW_FIELD_IDX_IPV4_TTL; 604 break; 605 case ICE_FLOW_FIELD_IDX_IPV6_TTL: 606 case ICE_FLOW_FIELD_IDX_IPV6_PROT: 607 prot_id = seg == 0 ? ICE_PROT_IPV6_OF_OR_S : ICE_PROT_IPV6_IL; 608 /* TTL and PROT share the same extraction seq. entry. 609 * Each is considered a sibling to the other in terms of sharing 610 * the same extraction sequence entry. 611 */ 612 if (fld == ICE_FLOW_FIELD_IDX_IPV6_TTL) 613 sib = ICE_FLOW_FIELD_IDX_IPV6_PROT; 614 else 615 sib = ICE_FLOW_FIELD_IDX_IPV6_TTL; 616 break; 617 case ICE_FLOW_FIELD_IDX_IPV4_SA: 618 case ICE_FLOW_FIELD_IDX_IPV4_DA: 619 prot_id = seg == 0 ? ICE_PROT_IPV4_OF_OR_S : ICE_PROT_IPV4_IL; 620 break; 621 case ICE_FLOW_FIELD_IDX_IPV6_SA: 622 case ICE_FLOW_FIELD_IDX_IPV6_DA: 623 prot_id = seg == 0 ? ICE_PROT_IPV6_OF_OR_S : ICE_PROT_IPV6_IL; 624 break; 625 case ICE_FLOW_FIELD_IDX_TCP_SRC_PORT: 626 case ICE_FLOW_FIELD_IDX_TCP_DST_PORT: 627 case ICE_FLOW_FIELD_IDX_TCP_FLAGS: 628 prot_id = ICE_PROT_TCP_IL; 629 break; 630 case ICE_FLOW_FIELD_IDX_UDP_SRC_PORT: 631 case ICE_FLOW_FIELD_IDX_UDP_DST_PORT: 632 prot_id = ICE_PROT_UDP_IL_OR_S; 633 break; 634 case ICE_FLOW_FIELD_IDX_SCTP_SRC_PORT: 635 case ICE_FLOW_FIELD_IDX_SCTP_DST_PORT: 636 prot_id = ICE_PROT_SCTP_IL; 637 break; 638 case ICE_FLOW_FIELD_IDX_ARP_SIP: 639 case ICE_FLOW_FIELD_IDX_ARP_DIP: 640 case ICE_FLOW_FIELD_IDX_ARP_SHA: 641 case ICE_FLOW_FIELD_IDX_ARP_DHA: 642 case ICE_FLOW_FIELD_IDX_ARP_OP: 643 prot_id = ICE_PROT_ARP_OF; 644 break; 645 case ICE_FLOW_FIELD_IDX_ICMP_TYPE: 646 case ICE_FLOW_FIELD_IDX_ICMP_CODE: 647 /* ICMP type and code share the same extraction seq. entry */ 648 prot_id = (params->prof->segs[seg].hdrs & 649 ICE_FLOW_SEG_HDR_IPV4) ? 650 ICE_PROT_ICMP_IL : ICE_PROT_ICMPV6_IL; 651 sib = fld == ICE_FLOW_FIELD_IDX_ICMP_TYPE ? 652 ICE_FLOW_FIELD_IDX_ICMP_CODE : 653 ICE_FLOW_FIELD_IDX_ICMP_TYPE; 654 break; 655 case ICE_FLOW_FIELD_IDX_GRE_KEYID: 656 prot_id = ICE_PROT_GRE_OF; 657 break; 658 default: 659 return ICE_ERR_NOT_IMPL; 660 } 661 662 /* Each extraction sequence entry is a word in size, and extracts a 663 * word-aligned offset from a protocol header. 664 */ 665 ese_bits = ICE_FLOW_FV_EXTRACT_SZ * BITS_PER_BYTE; 666 667 flds[fld].xtrct.prot_id = (u8)prot_id; 668 flds[fld].xtrct.off = (ice_flds_info[fld].off / ese_bits) * 669 ICE_FLOW_FV_EXTRACT_SZ; 670 flds[fld].xtrct.disp = (u8)(ice_flds_info[fld].off % ese_bits); 671 flds[fld].xtrct.idx = params->es_cnt; 672 673 /* Adjust the next field-entry index after accommodating the number of 674 * entries this field consumes 675 */ 676 cnt = DIVIDE_AND_ROUND_UP(flds[fld].xtrct.disp + 677 ice_flds_info[fld].size, ese_bits); 678 679 /* Fill in the extraction sequence entries needed for this field */ 680 off = flds[fld].xtrct.off; 681 for (i = 0; i < cnt; i++) { 682 /* Only consume an extraction sequence entry if there is no 683 * sibling field associated with this field or the sibling entry 684 * already extracts the word shared with this field. 685 */ 686 if (sib == ICE_FLOW_FIELD_IDX_MAX || 687 flds[sib].xtrct.prot_id == ICE_PROT_ID_INVAL || 688 flds[sib].xtrct.off != off) { 689 u8 idx; 690 691 /* Make sure the number of extraction sequence required 692 * does not exceed the block's capability 693 */ 694 if (params->es_cnt >= fv_words) 695 return ICE_ERR_MAX_LIMIT; 696 697 /* some blocks require a reversed field vector layout */ 698 if (hw->blk[params->blk].es.reverse) 699 idx = fv_words - params->es_cnt - 1; 700 else 701 idx = params->es_cnt; 702 703 params->es[idx].prot_id = (u8)prot_id; 704 params->es[idx].off = off; 705 params->es_cnt++; 706 } 707 708 off += ICE_FLOW_FV_EXTRACT_SZ; 709 } 710 711 return ICE_SUCCESS; 712 } 713 714 /** 715 * ice_flow_create_xtrct_seq - Create an extraction sequence for given segments 716 * @hw: pointer to the HW struct 717 * @params: information about the flow to be processed 718 * 719 * This function iterates through all matched fields in the given segments, and 720 * creates an extraction sequence for the fields. 721 */ 722 static enum ice_status 723 ice_flow_create_xtrct_seq(struct ice_hw *hw, 724 struct ice_flow_prof_params *params) 725 { 726 enum ice_status status = ICE_SUCCESS; 727 u8 i; 728 729 for (i = 0; i < params->prof->segs_cnt; i++) { 730 u64 match = params->prof->segs[i].match; 731 enum ice_flow_field j; 732 733 ice_for_each_set_bit(j, (ice_bitmap_t *)&match, 734 ICE_FLOW_FIELD_IDX_MAX) { 735 status = ice_flow_xtract_fld(hw, params, i, j); 736 if (status) 737 return status; 738 ice_clear_bit(j, (ice_bitmap_t *)&match); 739 } 740 } 741 742 return status; 743 } 744 745 /** 746 * ice_flow_proc_segs - process all packet segments associated with a profile 747 * @hw: pointer to the HW struct 748 * @params: information about the flow to be processed 749 */ 750 static enum ice_status 751 ice_flow_proc_segs(struct ice_hw *hw, struct ice_flow_prof_params *params) 752 { 753 enum ice_status status; 754 755 status = ice_flow_proc_seg_hdrs(params); 756 if (status) 757 return status; 758 759 status = ice_flow_create_xtrct_seq(hw, params); 760 if (status) 761 return status; 762 763 switch (params->blk) { 764 case ICE_BLK_RSS: 765 status = ICE_SUCCESS; 766 break; 767 default: 768 return ICE_ERR_NOT_IMPL; 769 } 770 771 return status; 772 } 773 774 #define ICE_FLOW_FIND_PROF_CHK_FLDS 0x00000001 775 #define ICE_FLOW_FIND_PROF_CHK_VSI 0x00000002 776 #define ICE_FLOW_FIND_PROF_NOT_CHK_DIR 0x00000004 777 778 /** 779 * ice_flow_find_prof_conds - Find a profile matching headers and conditions 780 * @hw: pointer to the HW struct 781 * @blk: classification stage 782 * @dir: flow direction 783 * @segs: array of one or more packet segments that describe the flow 784 * @segs_cnt: number of packet segments provided 785 * @vsi_handle: software VSI handle to check VSI (ICE_FLOW_FIND_PROF_CHK_VSI) 786 * @conds: additional conditions to be checked (ICE_FLOW_FIND_PROF_CHK_*) 787 */ 788 static struct ice_flow_prof * 789 ice_flow_find_prof_conds(struct ice_hw *hw, enum ice_block blk, 790 enum ice_flow_dir dir, struct ice_flow_seg_info *segs, 791 u8 segs_cnt, u16 vsi_handle, u32 conds) 792 { 793 struct ice_flow_prof *p, *prof = NULL; 794 795 ice_acquire_lock(&hw->fl_profs_locks[blk]); 796 LIST_FOR_EACH_ENTRY(p, &hw->fl_profs[blk], ice_flow_prof, l_entry) 797 if ((p->dir == dir || conds & ICE_FLOW_FIND_PROF_NOT_CHK_DIR) && 798 segs_cnt && segs_cnt == p->segs_cnt) { 799 u8 i; 800 801 /* Check for profile-VSI association if specified */ 802 if ((conds & ICE_FLOW_FIND_PROF_CHK_VSI) && 803 ice_is_vsi_valid(hw, vsi_handle) && 804 !ice_is_bit_set(p->vsis, vsi_handle)) 805 continue; 806 807 /* Protocol headers must be checked. Matched fields are 808 * checked if specified. 809 */ 810 for (i = 0; i < segs_cnt; i++) 811 if (segs[i].hdrs != p->segs[i].hdrs || 812 ((conds & ICE_FLOW_FIND_PROF_CHK_FLDS) && 813 segs[i].match != p->segs[i].match)) 814 break; 815 816 /* A match is found if all segments are matched */ 817 if (i == segs_cnt) { 818 prof = p; 819 break; 820 } 821 } 822 ice_release_lock(&hw->fl_profs_locks[blk]); 823 824 return prof; 825 } 826 827 /** 828 * ice_flow_find_prof - Look up a profile matching headers and matched fields 829 * @hw: pointer to the HW struct 830 * @blk: classification stage 831 * @dir: flow direction 832 * @segs: array of one or more packet segments that describe the flow 833 * @segs_cnt: number of packet segments provided 834 */ 835 u64 836 ice_flow_find_prof(struct ice_hw *hw, enum ice_block blk, enum ice_flow_dir dir, 837 struct ice_flow_seg_info *segs, u8 segs_cnt) 838 { 839 struct ice_flow_prof *p; 840 841 p = ice_flow_find_prof_conds(hw, blk, dir, segs, segs_cnt, 842 ICE_MAX_VSI, ICE_FLOW_FIND_PROF_CHK_FLDS); 843 844 return p ? p->id : ICE_FLOW_PROF_ID_INVAL; 845 } 846 847 /** 848 * ice_flow_find_prof_id - Look up a profile with given profile ID 849 * @hw: pointer to the HW struct 850 * @blk: classification stage 851 * @prof_id: unique ID to identify this flow profile 852 */ 853 static struct ice_flow_prof * 854 ice_flow_find_prof_id(struct ice_hw *hw, enum ice_block blk, u64 prof_id) 855 { 856 struct ice_flow_prof *p; 857 858 LIST_FOR_EACH_ENTRY(p, &hw->fl_profs[blk], ice_flow_prof, l_entry) 859 if (p->id == prof_id) 860 return p; 861 862 return NULL; 863 } 864 865 /** 866 * ice_flow_get_hw_prof - return the HW profile for a specific profile ID handle 867 * @hw: pointer to the HW struct 868 * @blk: classification stage 869 * @prof_id: the profile ID handle 870 * @hw_prof_id: pointer to variable to receive the HW profile ID 871 */ 872 enum ice_status 873 ice_flow_get_hw_prof(struct ice_hw *hw, enum ice_block blk, u64 prof_id, 874 u8 *hw_prof_id) 875 { 876 enum ice_status status = ICE_ERR_DOES_NOT_EXIST; 877 struct ice_prof_map *map; 878 879 ice_acquire_lock(&hw->blk[blk].es.prof_map_lock); 880 map = ice_search_prof_id(hw, blk, prof_id); 881 if (map) { 882 *hw_prof_id = map->prof_id; 883 status = ICE_SUCCESS; 884 } 885 ice_release_lock(&hw->blk[blk].es.prof_map_lock); 886 return status; 887 } 888 889 /** 890 * ice_flow_add_prof_sync - Add a flow profile for packet segments and fields 891 * @hw: pointer to the HW struct 892 * @blk: classification stage 893 * @dir: flow direction 894 * @prof_id: unique ID to identify this flow profile 895 * @segs: array of one or more packet segments that describe the flow 896 * @segs_cnt: number of packet segments provided 897 * @acts: array of default actions 898 * @acts_cnt: number of default actions 899 * @prof: stores the returned flow profile added 900 * 901 * Assumption: the caller has acquired the lock to the profile list 902 */ 903 static enum ice_status 904 ice_flow_add_prof_sync(struct ice_hw *hw, enum ice_block blk, 905 enum ice_flow_dir dir, u64 prof_id, 906 struct ice_flow_seg_info *segs, u8 segs_cnt, 907 struct ice_flow_action *acts, u8 acts_cnt, 908 struct ice_flow_prof **prof) 909 { 910 struct ice_flow_prof_params *params; 911 enum ice_status status; 912 u8 i; 913 914 if (!prof || (acts_cnt && !acts)) 915 return ICE_ERR_BAD_PTR; 916 917 params = (struct ice_flow_prof_params *)ice_malloc(hw, sizeof(*params)); 918 if (!params) 919 return ICE_ERR_NO_MEMORY; 920 921 params->prof = (struct ice_flow_prof *) 922 ice_malloc(hw, sizeof(*params->prof)); 923 if (!params->prof) { 924 status = ICE_ERR_NO_MEMORY; 925 goto free_params; 926 } 927 928 /* initialize extraction sequence to all invalid (0xff) */ 929 for (i = 0; i < ICE_MAX_FV_WORDS; i++) { 930 params->es[i].prot_id = ICE_PROT_INVALID; 931 params->es[i].off = ICE_FV_OFFSET_INVAL; 932 } 933 934 params->blk = blk; 935 params->prof->id = prof_id; 936 params->prof->dir = dir; 937 params->prof->segs_cnt = segs_cnt; 938 939 /* Make a copy of the segments that need to be persistent in the flow 940 * profile instance 941 */ 942 for (i = 0; i < segs_cnt; i++) 943 ice_memcpy(¶ms->prof->segs[i], &segs[i], sizeof(*segs), 944 ICE_NONDMA_TO_NONDMA); 945 946 status = ice_flow_proc_segs(hw, params); 947 if (status) { 948 ice_debug(hw, ICE_DBG_FLOW, "Error processing a flow's packet segments\n"); 949 goto out; 950 } 951 952 /* Add a HW profile for this flow profile */ 953 status = ice_add_prof(hw, blk, prof_id, params->ptypes, params->es); 954 if (status) { 955 ice_debug(hw, ICE_DBG_FLOW, "Error adding a HW flow profile\n"); 956 goto out; 957 } 958 959 *prof = params->prof; 960 961 out: 962 if (status) { 963 ice_free(hw, params->prof); 964 } 965 free_params: 966 ice_free(hw, params); 967 968 return status; 969 } 970 971 /** 972 * ice_flow_rem_prof_sync - remove a flow profile 973 * @hw: pointer to the hardware structure 974 * @blk: classification stage 975 * @prof: pointer to flow profile to remove 976 * 977 * Assumption: the caller has acquired the lock to the profile list 978 */ 979 static enum ice_status 980 ice_flow_rem_prof_sync(struct ice_hw *hw, enum ice_block blk, 981 struct ice_flow_prof *prof) 982 { 983 enum ice_status status; 984 985 /* Remove all hardware profiles associated with this flow profile */ 986 status = ice_rem_prof(hw, blk, prof->id); 987 if (!status) { 988 LIST_DEL(&prof->l_entry); 989 ice_free(hw, prof); 990 } 991 992 return status; 993 } 994 995 /** 996 * ice_flow_assoc_vsig_vsi - associate a VSI with VSIG 997 * @hw: pointer to the hardware structure 998 * @blk: classification stage 999 * @vsi_handle: software VSI handle 1000 * @vsig: target VSI group 1001 * 1002 * Assumption: the caller has already verified that the VSI to 1003 * be added has the same characteristics as the VSIG and will 1004 * thereby have access to all resources added to that VSIG. 1005 */ 1006 enum ice_status 1007 ice_flow_assoc_vsig_vsi(struct ice_hw *hw, enum ice_block blk, u16 vsi_handle, 1008 u16 vsig) 1009 { 1010 enum ice_status status; 1011 1012 if (!ice_is_vsi_valid(hw, vsi_handle) || blk >= ICE_BLK_COUNT) 1013 return ICE_ERR_PARAM; 1014 1015 ice_acquire_lock(&hw->fl_profs_locks[blk]); 1016 status = ice_add_vsi_flow(hw, blk, ice_get_hw_vsi_num(hw, vsi_handle), 1017 vsig); 1018 ice_release_lock(&hw->fl_profs_locks[blk]); 1019 1020 return status; 1021 } 1022 1023 /** 1024 * ice_flow_assoc_prof - associate a VSI with a flow profile 1025 * @hw: pointer to the hardware structure 1026 * @blk: classification stage 1027 * @prof: pointer to flow profile 1028 * @vsi_handle: software VSI handle 1029 * 1030 * Assumption: the caller has acquired the lock to the profile list 1031 * and the software VSI handle has been validated 1032 */ 1033 static enum ice_status 1034 ice_flow_assoc_prof(struct ice_hw *hw, enum ice_block blk, 1035 struct ice_flow_prof *prof, u16 vsi_handle) 1036 { 1037 enum ice_status status = ICE_SUCCESS; 1038 1039 if (!ice_is_bit_set(prof->vsis, vsi_handle)) { 1040 status = ice_add_prof_id_flow(hw, blk, 1041 ice_get_hw_vsi_num(hw, 1042 vsi_handle), 1043 prof->id); 1044 if (!status) 1045 ice_set_bit(vsi_handle, prof->vsis); 1046 else 1047 ice_debug(hw, ICE_DBG_FLOW, "HW profile add failed, %d\n", 1048 status); 1049 } 1050 1051 return status; 1052 } 1053 1054 /** 1055 * ice_flow_disassoc_prof - disassociate a VSI from a flow profile 1056 * @hw: pointer to the hardware structure 1057 * @blk: classification stage 1058 * @prof: pointer to flow profile 1059 * @vsi_handle: software VSI handle 1060 * 1061 * Assumption: the caller has acquired the lock to the profile list 1062 * and the software VSI handle has been validated 1063 */ 1064 static enum ice_status 1065 ice_flow_disassoc_prof(struct ice_hw *hw, enum ice_block blk, 1066 struct ice_flow_prof *prof, u16 vsi_handle) 1067 { 1068 enum ice_status status = ICE_SUCCESS; 1069 1070 if (ice_is_bit_set(prof->vsis, vsi_handle)) { 1071 status = ice_rem_prof_id_flow(hw, blk, 1072 ice_get_hw_vsi_num(hw, 1073 vsi_handle), 1074 prof->id); 1075 if (!status) 1076 ice_clear_bit(vsi_handle, prof->vsis); 1077 else 1078 ice_debug(hw, ICE_DBG_FLOW, "HW profile remove failed, %d\n", 1079 status); 1080 } 1081 1082 return status; 1083 } 1084 1085 /** 1086 * ice_flow_add_prof - Add a flow profile for packet segments and matched fields 1087 * @hw: pointer to the HW struct 1088 * @blk: classification stage 1089 * @dir: flow direction 1090 * @prof_id: unique ID to identify this flow profile 1091 * @segs: array of one or more packet segments that describe the flow 1092 * @segs_cnt: number of packet segments provided 1093 * @acts: array of default actions 1094 * @acts_cnt: number of default actions 1095 * @prof: stores the returned flow profile added 1096 */ 1097 static enum ice_status 1098 ice_flow_add_prof(struct ice_hw *hw, enum ice_block blk, enum ice_flow_dir dir, 1099 u64 prof_id, struct ice_flow_seg_info *segs, u8 segs_cnt, 1100 struct ice_flow_action *acts, u8 acts_cnt, 1101 struct ice_flow_prof **prof) 1102 { 1103 enum ice_status status; 1104 1105 if (segs_cnt > ICE_FLOW_SEG_MAX) 1106 return ICE_ERR_MAX_LIMIT; 1107 1108 if (!segs_cnt) 1109 return ICE_ERR_PARAM; 1110 1111 if (!segs) 1112 return ICE_ERR_BAD_PTR; 1113 1114 status = ice_flow_val_hdrs(segs, segs_cnt); 1115 if (status) 1116 return status; 1117 1118 ice_acquire_lock(&hw->fl_profs_locks[blk]); 1119 1120 status = ice_flow_add_prof_sync(hw, blk, dir, prof_id, segs, segs_cnt, 1121 acts, acts_cnt, prof); 1122 if (!status) 1123 LIST_ADD(&(*prof)->l_entry, &hw->fl_profs[blk]); 1124 1125 ice_release_lock(&hw->fl_profs_locks[blk]); 1126 1127 return status; 1128 } 1129 1130 /** 1131 * ice_flow_rem_prof - Remove a flow profile and all entries associated with it 1132 * @hw: pointer to the HW struct 1133 * @blk: the block for which the flow profile is to be removed 1134 * @prof_id: unique ID of the flow profile to be removed 1135 */ 1136 static enum ice_status 1137 ice_flow_rem_prof(struct ice_hw *hw, enum ice_block blk, u64 prof_id) 1138 { 1139 struct ice_flow_prof *prof; 1140 enum ice_status status; 1141 1142 ice_acquire_lock(&hw->fl_profs_locks[blk]); 1143 1144 prof = ice_flow_find_prof_id(hw, blk, prof_id); 1145 if (!prof) { 1146 status = ICE_ERR_DOES_NOT_EXIST; 1147 goto out; 1148 } 1149 1150 /* prof becomes invalid after the call */ 1151 status = ice_flow_rem_prof_sync(hw, blk, prof); 1152 1153 out: 1154 ice_release_lock(&hw->fl_profs_locks[blk]); 1155 1156 return status; 1157 } 1158 1159 /** 1160 * ice_flow_set_fld_ext - specifies locations of field from entry's input buffer 1161 * @seg: packet segment the field being set belongs to 1162 * @fld: field to be set 1163 * @field_type: type of the field 1164 * @val_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of the value to match from 1165 * entry's input buffer 1166 * @mask_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of mask value from entry's 1167 * input buffer 1168 * @last_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of last/upper value from 1169 * entry's input buffer 1170 * 1171 * This helper function stores information of a field being matched, including 1172 * the type of the field and the locations of the value to match, the mask, and 1173 * the upper-bound value in the start of the input buffer for a flow entry. 1174 * This function should only be used for fixed-size data structures. 1175 * 1176 * This function also opportunistically determines the protocol headers to be 1177 * present based on the fields being set. Some fields cannot be used alone to 1178 * determine the protocol headers present. Sometimes, fields for particular 1179 * protocol headers are not matched. In those cases, the protocol headers 1180 * must be explicitly set. 1181 */ 1182 static void 1183 ice_flow_set_fld_ext(struct ice_flow_seg_info *seg, enum ice_flow_field fld, 1184 enum ice_flow_fld_match_type field_type, u16 val_loc, 1185 u16 mask_loc, u16 last_loc) 1186 { 1187 u64 bit = BIT_ULL(fld); 1188 1189 seg->match |= bit; 1190 if (field_type == ICE_FLOW_FLD_TYPE_RANGE) 1191 seg->range |= bit; 1192 1193 seg->fields[fld].type = field_type; 1194 seg->fields[fld].src.val = val_loc; 1195 seg->fields[fld].src.mask = mask_loc; 1196 seg->fields[fld].src.last = last_loc; 1197 1198 ICE_FLOW_SET_HDRS(seg, ice_flds_info[fld].hdr); 1199 } 1200 1201 /** 1202 * ice_flow_set_fld - specifies locations of field from entry's input buffer 1203 * @seg: packet segment the field being set belongs to 1204 * @fld: field to be set 1205 * @val_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of the value to match from 1206 * entry's input buffer 1207 * @mask_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of mask value from entry's 1208 * input buffer 1209 * @last_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of last/upper value from 1210 * entry's input buffer 1211 * @range: indicate if field being matched is to be in a range 1212 * 1213 * This function specifies the locations, in the form of byte offsets from the 1214 * start of the input buffer for a flow entry, from where the value to match, 1215 * the mask value, and upper value can be extracted. These locations are then 1216 * stored in the flow profile. When adding a flow entry associated with the 1217 * flow profile, these locations will be used to quickly extract the values and 1218 * create the content of a match entry. This function should only be used for 1219 * fixed-size data structures. 1220 */ 1221 static void 1222 ice_flow_set_fld(struct ice_flow_seg_info *seg, enum ice_flow_field fld, 1223 u16 val_loc, u16 mask_loc, u16 last_loc, bool range) 1224 { 1225 enum ice_flow_fld_match_type t = range ? 1226 ICE_FLOW_FLD_TYPE_RANGE : ICE_FLOW_FLD_TYPE_REG; 1227 1228 ice_flow_set_fld_ext(seg, fld, t, val_loc, mask_loc, last_loc); 1229 } 1230 1231 /** 1232 * ice_flow_set_fld_prefix - sets locations of prefix field from entry's buf 1233 * @seg: packet segment the field being set belongs to 1234 * @fld: field to be set 1235 * @val_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of the value to match from 1236 * entry's input buffer 1237 * @pref_loc: location of prefix value from entry's input buffer 1238 * @pref_sz: size of the location holding the prefix value 1239 * 1240 * This function specifies the locations, in the form of byte offsets from the 1241 * start of the input buffer for a flow entry, from where the value to match 1242 * and the IPv4 prefix value can be extracted. These locations are then stored 1243 * in the flow profile. When adding flow entries to the associated flow profile, 1244 * these locations can be used to quickly extract the values to create the 1245 * content of a match entry. This function should only be used for fixed-size 1246 * data structures. 1247 */ 1248 void 1249 ice_flow_set_fld_prefix(struct ice_flow_seg_info *seg, enum ice_flow_field fld, 1250 u16 val_loc, u16 pref_loc, u8 pref_sz) 1251 { 1252 /* For this type of field, the "mask" location is for the prefix value's 1253 * location and the "last" location is for the size of the location of 1254 * the prefix value. 1255 */ 1256 ice_flow_set_fld_ext(seg, fld, ICE_FLOW_FLD_TYPE_PREFIX, val_loc, 1257 pref_loc, (u16)pref_sz); 1258 } 1259 1260 #define ICE_FLOW_RSS_SEG_HDR_L3_MASKS \ 1261 (ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_IPV6) 1262 1263 #define ICE_FLOW_RSS_SEG_HDR_L4_MASKS \ 1264 (ICE_FLOW_SEG_HDR_TCP | ICE_FLOW_SEG_HDR_UDP | ICE_FLOW_SEG_HDR_SCTP) 1265 1266 #define ICE_FLOW_RSS_SEG_HDR_VAL_MASKS \ 1267 (ICE_FLOW_RSS_SEG_HDR_L3_MASKS | \ 1268 ICE_FLOW_RSS_SEG_HDR_L4_MASKS) 1269 1270 /** 1271 * ice_flow_set_rss_seg_info - setup packet segments for RSS 1272 * @segs: pointer to the flow field segment(s) 1273 * @seg_cnt: segment count 1274 * @cfg: configure parameters 1275 * 1276 * Helper function to extract fields from hash bitmap and use flow 1277 * header value to set flow field segment for further use in flow 1278 * profile entry or removal. 1279 */ 1280 static enum ice_status 1281 ice_flow_set_rss_seg_info(struct ice_flow_seg_info *segs, u8 seg_cnt, 1282 const struct ice_rss_hash_cfg *cfg) 1283 { 1284 struct ice_flow_seg_info *seg; 1285 u64 val; 1286 u16 i; 1287 1288 /* set inner most segment */ 1289 seg = &segs[seg_cnt - 1]; 1290 1291 ice_for_each_set_bit(i, (const ice_bitmap_t *)&cfg->hash_flds, 1292 (u16)ICE_FLOW_FIELD_IDX_MAX) 1293 ice_flow_set_fld(seg, (enum ice_flow_field)i, 1294 ICE_FLOW_FLD_OFF_INVAL, ICE_FLOW_FLD_OFF_INVAL, 1295 ICE_FLOW_FLD_OFF_INVAL, false); 1296 1297 ICE_FLOW_SET_HDRS(seg, cfg->addl_hdrs); 1298 1299 /* set outer most header */ 1300 if (cfg->hdr_type == ICE_RSS_INNER_HEADERS_W_OUTER_IPV4) 1301 segs[ICE_RSS_OUTER_HEADERS].hdrs |= ICE_FLOW_SEG_HDR_IPV4 | 1302 ICE_FLOW_SEG_HDR_IPV_FRAG | 1303 ICE_FLOW_SEG_HDR_IPV_OTHER; 1304 else if (cfg->hdr_type == ICE_RSS_INNER_HEADERS_W_OUTER_IPV6) 1305 segs[ICE_RSS_OUTER_HEADERS].hdrs |= ICE_FLOW_SEG_HDR_IPV6 | 1306 ICE_FLOW_SEG_HDR_IPV_FRAG | 1307 ICE_FLOW_SEG_HDR_IPV_OTHER; 1308 else if (cfg->hdr_type == ICE_RSS_INNER_HEADERS_W_OUTER_IPV4_GRE) 1309 segs[ICE_RSS_OUTER_HEADERS].hdrs |= ICE_FLOW_SEG_HDR_IPV4 | 1310 ICE_FLOW_SEG_HDR_GRE | 1311 ICE_FLOW_SEG_HDR_IPV_OTHER; 1312 else if (cfg->hdr_type == ICE_RSS_INNER_HEADERS_W_OUTER_IPV6_GRE) 1313 segs[ICE_RSS_OUTER_HEADERS].hdrs |= ICE_FLOW_SEG_HDR_IPV6 | 1314 ICE_FLOW_SEG_HDR_GRE | 1315 ICE_FLOW_SEG_HDR_IPV_OTHER; 1316 1317 if (seg->hdrs & ~ICE_FLOW_RSS_SEG_HDR_VAL_MASKS) 1318 return ICE_ERR_PARAM; 1319 1320 val = (u64)(seg->hdrs & ICE_FLOW_RSS_SEG_HDR_L3_MASKS); 1321 if (val && !ice_is_pow2(val)) 1322 return ICE_ERR_CFG; 1323 1324 val = (u64)(seg->hdrs & ICE_FLOW_RSS_SEG_HDR_L4_MASKS); 1325 if (val && !ice_is_pow2(val)) 1326 return ICE_ERR_CFG; 1327 1328 return ICE_SUCCESS; 1329 } 1330 1331 /** 1332 * ice_rem_vsi_rss_list - remove VSI from RSS list 1333 * @hw: pointer to the hardware structure 1334 * @vsi_handle: software VSI handle 1335 * 1336 * Remove the VSI from all RSS configurations in the list. 1337 */ 1338 void ice_rem_vsi_rss_list(struct ice_hw *hw, u16 vsi_handle) 1339 { 1340 struct ice_rss_cfg *r, *tmp; 1341 1342 if (LIST_EMPTY(&hw->rss_list_head)) 1343 return; 1344 1345 ice_acquire_lock(&hw->rss_locks); 1346 LIST_FOR_EACH_ENTRY_SAFE(r, tmp, &hw->rss_list_head, 1347 ice_rss_cfg, l_entry) 1348 if (ice_test_and_clear_bit(vsi_handle, r->vsis)) 1349 if (!ice_is_any_bit_set(r->vsis, ICE_MAX_VSI)) { 1350 LIST_DEL(&r->l_entry); 1351 ice_free(hw, r); 1352 } 1353 ice_release_lock(&hw->rss_locks); 1354 } 1355 1356 /** 1357 * ice_rem_vsi_rss_cfg - remove RSS configurations associated with VSI 1358 * @hw: pointer to the hardware structure 1359 * @vsi_handle: software VSI handle 1360 * 1361 * This function will iterate through all flow profiles and disassociate 1362 * the VSI from that profile. If the flow profile has no VSIs it will 1363 * be removed. 1364 */ 1365 enum ice_status ice_rem_vsi_rss_cfg(struct ice_hw *hw, u16 vsi_handle) 1366 { 1367 const enum ice_block blk = ICE_BLK_RSS; 1368 struct ice_flow_prof *p, *t; 1369 enum ice_status status = ICE_SUCCESS; 1370 u16 vsig; 1371 1372 if (!ice_is_vsi_valid(hw, vsi_handle)) 1373 return ICE_ERR_PARAM; 1374 1375 if (LIST_EMPTY(&hw->fl_profs[blk])) 1376 return ICE_SUCCESS; 1377 1378 ice_acquire_lock(&hw->rss_locks); 1379 LIST_FOR_EACH_ENTRY_SAFE(p, t, &hw->fl_profs[blk], ice_flow_prof, 1380 l_entry) { 1381 int ret; 1382 1383 /* check if vsig is already removed */ 1384 ret = ice_vsig_find_vsi(hw, blk, 1385 ice_get_hw_vsi_num(hw, vsi_handle), 1386 &vsig); 1387 if (!ret && !vsig) 1388 break; 1389 1390 if (ice_is_bit_set(p->vsis, vsi_handle)) { 1391 status = ice_flow_disassoc_prof(hw, blk, p, vsi_handle); 1392 if (status) 1393 break; 1394 1395 if (!ice_is_any_bit_set(p->vsis, ICE_MAX_VSI)) { 1396 status = ice_flow_rem_prof(hw, blk, p->id); 1397 if (status) 1398 break; 1399 } 1400 } 1401 } 1402 ice_release_lock(&hw->rss_locks); 1403 1404 return status; 1405 } 1406 1407 /** 1408 * ice_get_rss_hdr_type - get a RSS profile's header type 1409 * @prof: RSS flow profile 1410 */ 1411 static enum ice_rss_cfg_hdr_type 1412 ice_get_rss_hdr_type(struct ice_flow_prof *prof) 1413 { 1414 enum ice_rss_cfg_hdr_type hdr_type = ICE_RSS_ANY_HEADERS; 1415 1416 if (prof->segs_cnt == ICE_FLOW_SEG_SINGLE) { 1417 hdr_type = ICE_RSS_OUTER_HEADERS; 1418 } else if (prof->segs_cnt == ICE_FLOW_SEG_MAX) { 1419 if (prof->segs[ICE_RSS_OUTER_HEADERS].hdrs == ICE_FLOW_SEG_HDR_NONE) 1420 hdr_type = ICE_RSS_INNER_HEADERS; 1421 if (prof->segs[ICE_RSS_OUTER_HEADERS].hdrs & ICE_FLOW_SEG_HDR_IPV4) 1422 hdr_type = ICE_RSS_INNER_HEADERS_W_OUTER_IPV4; 1423 if (prof->segs[ICE_RSS_OUTER_HEADERS].hdrs & ICE_FLOW_SEG_HDR_IPV6) 1424 hdr_type = ICE_RSS_INNER_HEADERS_W_OUTER_IPV6; 1425 } 1426 1427 return hdr_type; 1428 } 1429 1430 /** 1431 * ice_rem_rss_list - remove RSS configuration from list 1432 * @hw: pointer to the hardware structure 1433 * @vsi_handle: software VSI handle 1434 * @prof: pointer to flow profile 1435 * 1436 * Assumption: lock has already been acquired for RSS list 1437 */ 1438 static void 1439 ice_rem_rss_list(struct ice_hw *hw, u16 vsi_handle, struct ice_flow_prof *prof) 1440 { 1441 enum ice_rss_cfg_hdr_type hdr_type; 1442 struct ice_rss_cfg *r, *tmp; 1443 1444 /* Search for RSS hash fields associated to the VSI that match the 1445 * hash configurations associated to the flow profile. If found 1446 * remove from the RSS entry list of the VSI context and delete entry. 1447 */ 1448 hdr_type = ice_get_rss_hdr_type(prof); 1449 LIST_FOR_EACH_ENTRY_SAFE(r, tmp, &hw->rss_list_head, 1450 ice_rss_cfg, l_entry) 1451 if (r->hash.hash_flds == prof->segs[prof->segs_cnt - 1].match && 1452 r->hash.addl_hdrs == prof->segs[prof->segs_cnt - 1].hdrs && 1453 r->hash.hdr_type == hdr_type) { 1454 ice_clear_bit(vsi_handle, r->vsis); 1455 if (!ice_is_any_bit_set(r->vsis, ICE_MAX_VSI)) { 1456 LIST_DEL(&r->l_entry); 1457 ice_free(hw, r); 1458 } 1459 return; 1460 } 1461 } 1462 1463 /** 1464 * ice_add_rss_list - add RSS configuration to list 1465 * @hw: pointer to the hardware structure 1466 * @vsi_handle: software VSI handle 1467 * @prof: pointer to flow profile 1468 * 1469 * Assumption: lock has already been acquired for RSS list 1470 */ 1471 static enum ice_status 1472 ice_add_rss_list(struct ice_hw *hw, u16 vsi_handle, struct ice_flow_prof *prof) 1473 { 1474 enum ice_rss_cfg_hdr_type hdr_type; 1475 struct ice_rss_cfg *r, *rss_cfg; 1476 1477 hdr_type = ice_get_rss_hdr_type(prof); 1478 LIST_FOR_EACH_ENTRY(r, &hw->rss_list_head, 1479 ice_rss_cfg, l_entry) 1480 if (r->hash.hash_flds == prof->segs[prof->segs_cnt - 1].match && 1481 r->hash.addl_hdrs == prof->segs[prof->segs_cnt - 1].hdrs && 1482 r->hash.hdr_type == hdr_type) { 1483 ice_set_bit(vsi_handle, r->vsis); 1484 return ICE_SUCCESS; 1485 } 1486 1487 rss_cfg = (struct ice_rss_cfg *)ice_malloc(hw, sizeof(*rss_cfg)); 1488 if (!rss_cfg) 1489 return ICE_ERR_NO_MEMORY; 1490 1491 rss_cfg->hash.hash_flds = prof->segs[prof->segs_cnt - 1].match; 1492 rss_cfg->hash.addl_hdrs = prof->segs[prof->segs_cnt - 1].hdrs; 1493 rss_cfg->hash.hdr_type = hdr_type; 1494 rss_cfg->hash.symm = prof->cfg.symm; 1495 ice_set_bit(vsi_handle, rss_cfg->vsis); 1496 1497 LIST_ADD_TAIL(&rss_cfg->l_entry, &hw->rss_list_head); 1498 1499 return ICE_SUCCESS; 1500 } 1501 1502 #define ICE_FLOW_PROF_HASH_S 0 1503 #define ICE_FLOW_PROF_HASH_M (0xFFFFFFFFULL << ICE_FLOW_PROF_HASH_S) 1504 #define ICE_FLOW_PROF_HDR_S 32 1505 #define ICE_FLOW_PROF_HDR_M (0x3FFFFFFFULL << ICE_FLOW_PROF_HDR_S) 1506 #define ICE_FLOW_PROF_ENCAP_S 62 1507 #define ICE_FLOW_PROF_ENCAP_M (0x3ULL << ICE_FLOW_PROF_ENCAP_S) 1508 1509 /* Flow profile ID format: 1510 * [0:31] - Packet match fields 1511 * [32:61] - Protocol header 1512 * [62:63] - Encapsulation flag: 1513 * 0 if non-tunneled 1514 * 1 if tunneled 1515 * 2 for tunneled with outer ipv4 1516 * 3 for tunneled with outer ipv6 1517 */ 1518 #define ICE_FLOW_GEN_PROFID(hash, hdr, encap) \ 1519 ((u64)(((u64)(hash) & ICE_FLOW_PROF_HASH_M) | \ 1520 (((u64)(hdr) << ICE_FLOW_PROF_HDR_S) & ICE_FLOW_PROF_HDR_M) | \ 1521 (((u64)(encap) << ICE_FLOW_PROF_ENCAP_S) & ICE_FLOW_PROF_ENCAP_M))) 1522 1523 /** 1524 * ice_add_rss_cfg_sync - add an RSS configuration 1525 * @hw: pointer to the hardware structure 1526 * @vsi_handle: software VSI handle 1527 * @cfg: configure parameters 1528 * 1529 * Assumption: lock has already been acquired for RSS list 1530 */ 1531 static enum ice_status 1532 ice_add_rss_cfg_sync(struct ice_hw *hw, u16 vsi_handle, 1533 const struct ice_rss_hash_cfg *cfg) 1534 { 1535 const enum ice_block blk = ICE_BLK_RSS; 1536 struct ice_flow_prof *prof = NULL; 1537 struct ice_flow_seg_info *segs; 1538 enum ice_status status; 1539 u8 segs_cnt; 1540 1541 if (cfg->symm) 1542 return ICE_ERR_PARAM; 1543 1544 segs_cnt = (cfg->hdr_type == ICE_RSS_OUTER_HEADERS) ? 1545 ICE_FLOW_SEG_SINGLE : ICE_FLOW_SEG_MAX; 1546 1547 segs = (struct ice_flow_seg_info *)ice_calloc(hw, segs_cnt, 1548 sizeof(*segs)); 1549 if (!segs) 1550 return ICE_ERR_NO_MEMORY; 1551 1552 /* Construct the packet segment info from the hashed fields */ 1553 status = ice_flow_set_rss_seg_info(segs, segs_cnt, cfg); 1554 if (status) 1555 goto exit; 1556 1557 /* Search for a flow profile that has matching headers, hash fields 1558 * and has the input VSI associated to it. If found, no further 1559 * operations required and exit. 1560 */ 1561 prof = ice_flow_find_prof_conds(hw, blk, ICE_FLOW_RX, segs, segs_cnt, 1562 vsi_handle, 1563 ICE_FLOW_FIND_PROF_CHK_FLDS | 1564 ICE_FLOW_FIND_PROF_CHK_VSI); 1565 if (prof) 1566 goto exit; 1567 1568 /* Check if a flow profile exists with the same protocol headers and 1569 * associated with the input VSI. If so disassociate the VSI from 1570 * this profile. The VSI will be added to a new profile created with 1571 * the protocol header and new hash field configuration. 1572 */ 1573 prof = ice_flow_find_prof_conds(hw, blk, ICE_FLOW_RX, segs, segs_cnt, 1574 vsi_handle, ICE_FLOW_FIND_PROF_CHK_VSI); 1575 if (prof) { 1576 status = ice_flow_disassoc_prof(hw, blk, prof, vsi_handle); 1577 if (!status) 1578 ice_rem_rss_list(hw, vsi_handle, prof); 1579 else 1580 goto exit; 1581 1582 /* Remove profile if it has no VSIs associated */ 1583 if (!ice_is_any_bit_set(prof->vsis, ICE_MAX_VSI)) { 1584 status = ice_flow_rem_prof(hw, blk, prof->id); 1585 if (status) 1586 goto exit; 1587 } 1588 } 1589 1590 /* Search for a profile that has same match fields only. If this 1591 * exists then associate the VSI to this profile. 1592 */ 1593 prof = ice_flow_find_prof_conds(hw, blk, ICE_FLOW_RX, segs, segs_cnt, 1594 vsi_handle, 1595 ICE_FLOW_FIND_PROF_CHK_FLDS); 1596 if (prof) { 1597 status = ice_flow_assoc_prof(hw, blk, prof, vsi_handle); 1598 if (!status) 1599 status = ice_add_rss_list(hw, vsi_handle, prof); 1600 goto exit; 1601 } 1602 1603 /* Create a new flow profile with generated profile and packet 1604 * segment information. 1605 */ 1606 status = ice_flow_add_prof(hw, blk, ICE_FLOW_RX, 1607 ICE_FLOW_GEN_PROFID(cfg->hash_flds, 1608 segs[segs_cnt - 1].hdrs, 1609 cfg->hdr_type), 1610 segs, segs_cnt, NULL, 0, &prof); 1611 if (status) 1612 goto exit; 1613 1614 status = ice_flow_assoc_prof(hw, blk, prof, vsi_handle); 1615 /* If association to a new flow profile failed then this profile can 1616 * be removed. 1617 */ 1618 if (status) { 1619 ice_flow_rem_prof(hw, blk, prof->id); 1620 goto exit; 1621 } 1622 1623 status = ice_add_rss_list(hw, vsi_handle, prof); 1624 1625 prof->cfg.symm = cfg->symm; 1626 1627 exit: 1628 ice_free(hw, segs); 1629 return status; 1630 } 1631 1632 /** 1633 * ice_add_rss_cfg - add an RSS configuration with specified hashed fields 1634 * @hw: pointer to the hardware structure 1635 * @vsi_handle: software VSI handle 1636 * @cfg: configure parameters 1637 * 1638 * This function will generate a flow profile based on fields associated with 1639 * the input fields to hash on, the flow type and use the VSI number to add 1640 * a flow entry to the profile. 1641 */ 1642 enum ice_status 1643 ice_add_rss_cfg(struct ice_hw *hw, u16 vsi_handle, 1644 const struct ice_rss_hash_cfg *cfg) 1645 { 1646 struct ice_rss_hash_cfg local_cfg; 1647 enum ice_status status; 1648 1649 if (!ice_is_vsi_valid(hw, vsi_handle) || 1650 !cfg || cfg->hdr_type > ICE_RSS_ANY_HEADERS || 1651 cfg->hash_flds == ICE_HASH_INVALID) 1652 return ICE_ERR_PARAM; 1653 1654 local_cfg = *cfg; 1655 if (cfg->hdr_type < ICE_RSS_ANY_HEADERS) { 1656 ice_acquire_lock(&hw->rss_locks); 1657 status = ice_add_rss_cfg_sync(hw, vsi_handle, &local_cfg); 1658 ice_release_lock(&hw->rss_locks); 1659 } else { 1660 ice_acquire_lock(&hw->rss_locks); 1661 local_cfg.hdr_type = ICE_RSS_OUTER_HEADERS; 1662 status = ice_add_rss_cfg_sync(hw, vsi_handle, &local_cfg); 1663 if (!status) { 1664 local_cfg.hdr_type = ICE_RSS_INNER_HEADERS; 1665 status = ice_add_rss_cfg_sync(hw, vsi_handle, 1666 &local_cfg); 1667 } 1668 ice_release_lock(&hw->rss_locks); 1669 } 1670 1671 return status; 1672 } 1673 1674 /** 1675 * ice_rem_rss_cfg_sync - remove an existing RSS configuration 1676 * @hw: pointer to the hardware structure 1677 * @vsi_handle: software VSI handle 1678 * @cfg: configure parameters 1679 * 1680 * Assumption: lock has already been acquired for RSS list 1681 */ 1682 static enum ice_status 1683 ice_rem_rss_cfg_sync(struct ice_hw *hw, u16 vsi_handle, 1684 const struct ice_rss_hash_cfg *cfg) 1685 { 1686 const enum ice_block blk = ICE_BLK_RSS; 1687 struct ice_flow_seg_info *segs; 1688 struct ice_flow_prof *prof; 1689 enum ice_status status; 1690 u8 segs_cnt; 1691 1692 segs_cnt = (cfg->hdr_type == ICE_RSS_OUTER_HEADERS) ? 1693 ICE_FLOW_SEG_SINGLE : ICE_FLOW_SEG_MAX; 1694 segs = (struct ice_flow_seg_info *)ice_calloc(hw, segs_cnt, 1695 sizeof(*segs)); 1696 if (!segs) 1697 return ICE_ERR_NO_MEMORY; 1698 1699 /* Construct the packet segment info from the hashed fields */ 1700 status = ice_flow_set_rss_seg_info(segs, segs_cnt, cfg); 1701 if (status) 1702 goto out; 1703 1704 prof = ice_flow_find_prof_conds(hw, blk, ICE_FLOW_RX, segs, segs_cnt, 1705 vsi_handle, 1706 ICE_FLOW_FIND_PROF_CHK_FLDS); 1707 if (!prof) { 1708 status = ICE_ERR_DOES_NOT_EXIST; 1709 goto out; 1710 } 1711 1712 status = ice_flow_disassoc_prof(hw, blk, prof, vsi_handle); 1713 if (status) 1714 goto out; 1715 1716 /* Remove RSS configuration from VSI context before deleting 1717 * the flow profile. 1718 */ 1719 ice_rem_rss_list(hw, vsi_handle, prof); 1720 1721 if (!ice_is_any_bit_set(prof->vsis, ICE_MAX_VSI)) 1722 status = ice_flow_rem_prof(hw, blk, prof->id); 1723 1724 out: 1725 ice_free(hw, segs); 1726 return status; 1727 } 1728 1729 /** 1730 * ice_rem_rss_cfg - remove an existing RSS config with matching hashed fields 1731 * @hw: pointer to the hardware structure 1732 * @vsi_handle: software VSI handle 1733 * @cfg: configure parameters 1734 * 1735 * This function will lookup the flow profile based on the input 1736 * hash field bitmap, iterate through the profile entry list of 1737 * that profile and find entry associated with input VSI to be 1738 * removed. Calls are made to underlying flow apis which will in 1739 * turn build or update buffers for RSS XLT1 section. 1740 */ 1741 enum ice_status 1742 ice_rem_rss_cfg(struct ice_hw *hw, u16 vsi_handle, 1743 const struct ice_rss_hash_cfg *cfg) 1744 { 1745 struct ice_rss_hash_cfg local_cfg; 1746 enum ice_status status; 1747 1748 if (!ice_is_vsi_valid(hw, vsi_handle) || 1749 !cfg || cfg->hdr_type > ICE_RSS_ANY_HEADERS || 1750 cfg->hash_flds == ICE_HASH_INVALID) 1751 return ICE_ERR_PARAM; 1752 1753 ice_acquire_lock(&hw->rss_locks); 1754 local_cfg = *cfg; 1755 if (cfg->hdr_type < ICE_RSS_ANY_HEADERS) { 1756 status = ice_rem_rss_cfg_sync(hw, vsi_handle, &local_cfg); 1757 } else { 1758 local_cfg.hdr_type = ICE_RSS_OUTER_HEADERS; 1759 status = ice_rem_rss_cfg_sync(hw, vsi_handle, &local_cfg); 1760 1761 if (!status) { 1762 local_cfg.hdr_type = ICE_RSS_INNER_HEADERS; 1763 status = ice_rem_rss_cfg_sync(hw, vsi_handle, 1764 &local_cfg); 1765 } 1766 } 1767 ice_release_lock(&hw->rss_locks); 1768 1769 return status; 1770 } 1771 1772 /* Mapping of AVF hash bit fields to an L3-L4 hash combination. 1773 * As the ice_flow_avf_hdr_field represent individual bit shifts in a hash, 1774 * convert its values to their appropriate flow L3, L4 values. 1775 */ 1776 #define ICE_FLOW_AVF_RSS_IPV4_MASKS \ 1777 (BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_OTHER) | \ 1778 BIT_ULL(ICE_AVF_FLOW_FIELD_FRAG_IPV4)) 1779 #define ICE_FLOW_AVF_RSS_TCP_IPV4_MASKS \ 1780 (BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_TCP_SYN_NO_ACK) | \ 1781 BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_TCP)) 1782 #define ICE_FLOW_AVF_RSS_UDP_IPV4_MASKS \ 1783 (BIT_ULL(ICE_AVF_FLOW_FIELD_UNICAST_IPV4_UDP) | \ 1784 BIT_ULL(ICE_AVF_FLOW_FIELD_MULTICAST_IPV4_UDP) | \ 1785 BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_UDP)) 1786 #define ICE_FLOW_AVF_RSS_ALL_IPV4_MASKS \ 1787 (ICE_FLOW_AVF_RSS_TCP_IPV4_MASKS | ICE_FLOW_AVF_RSS_UDP_IPV4_MASKS | \ 1788 ICE_FLOW_AVF_RSS_IPV4_MASKS | BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_SCTP)) 1789 1790 #define ICE_FLOW_AVF_RSS_IPV6_MASKS \ 1791 (BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_OTHER) | \ 1792 BIT_ULL(ICE_AVF_FLOW_FIELD_FRAG_IPV6)) 1793 #define ICE_FLOW_AVF_RSS_UDP_IPV6_MASKS \ 1794 (BIT_ULL(ICE_AVF_FLOW_FIELD_UNICAST_IPV6_UDP) | \ 1795 BIT_ULL(ICE_AVF_FLOW_FIELD_MULTICAST_IPV6_UDP) | \ 1796 BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_UDP)) 1797 #define ICE_FLOW_AVF_RSS_TCP_IPV6_MASKS \ 1798 (BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_TCP_SYN_NO_ACK) | \ 1799 BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_TCP)) 1800 #define ICE_FLOW_AVF_RSS_ALL_IPV6_MASKS \ 1801 (ICE_FLOW_AVF_RSS_TCP_IPV6_MASKS | ICE_FLOW_AVF_RSS_UDP_IPV6_MASKS | \ 1802 ICE_FLOW_AVF_RSS_IPV6_MASKS | BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_SCTP)) 1803 1804 /** 1805 * ice_add_avf_rss_cfg - add an RSS configuration for AVF driver 1806 * @hw: pointer to the hardware structure 1807 * @vsi_handle: software VSI handle 1808 * @avf_hash: hash bit fields (ICE_AVF_FLOW_FIELD_*) to configure 1809 * 1810 * This function will take the hash bitmap provided by the AVF driver via a 1811 * message, convert it to ICE-compatible values, and configure RSS flow 1812 * profiles. 1813 */ 1814 enum ice_status 1815 ice_add_avf_rss_cfg(struct ice_hw *hw, u16 vsi_handle, u64 avf_hash) 1816 { 1817 enum ice_status status = ICE_SUCCESS; 1818 struct ice_rss_hash_cfg hcfg; 1819 u64 hash_flds; 1820 1821 if (avf_hash == ICE_AVF_FLOW_FIELD_INVALID || 1822 !ice_is_vsi_valid(hw, vsi_handle)) 1823 return ICE_ERR_PARAM; 1824 1825 /* Make sure no unsupported bits are specified */ 1826 if (avf_hash & ~(ICE_FLOW_AVF_RSS_ALL_IPV4_MASKS | 1827 ICE_FLOW_AVF_RSS_ALL_IPV6_MASKS)) 1828 return ICE_ERR_CFG; 1829 1830 hash_flds = avf_hash; 1831 1832 /* Always create an L3 RSS configuration for any L4 RSS configuration */ 1833 if (hash_flds & ICE_FLOW_AVF_RSS_ALL_IPV4_MASKS) 1834 hash_flds |= ICE_FLOW_AVF_RSS_IPV4_MASKS; 1835 1836 if (hash_flds & ICE_FLOW_AVF_RSS_ALL_IPV6_MASKS) 1837 hash_flds |= ICE_FLOW_AVF_RSS_IPV6_MASKS; 1838 1839 /* Create the corresponding RSS configuration for each valid hash bit */ 1840 while (hash_flds) { 1841 u64 rss_hash = ICE_HASH_INVALID; 1842 1843 if (hash_flds & ICE_FLOW_AVF_RSS_ALL_IPV4_MASKS) { 1844 if (hash_flds & ICE_FLOW_AVF_RSS_IPV4_MASKS) { 1845 rss_hash = ICE_FLOW_HASH_IPV4; 1846 hash_flds &= ~ICE_FLOW_AVF_RSS_IPV4_MASKS; 1847 } else if (hash_flds & 1848 ICE_FLOW_AVF_RSS_TCP_IPV4_MASKS) { 1849 rss_hash = ICE_FLOW_HASH_IPV4 | 1850 ICE_FLOW_HASH_TCP_PORT; 1851 hash_flds &= ~ICE_FLOW_AVF_RSS_TCP_IPV4_MASKS; 1852 } else if (hash_flds & 1853 ICE_FLOW_AVF_RSS_UDP_IPV4_MASKS) { 1854 rss_hash = ICE_FLOW_HASH_IPV4 | 1855 ICE_FLOW_HASH_UDP_PORT; 1856 hash_flds &= ~ICE_FLOW_AVF_RSS_UDP_IPV4_MASKS; 1857 } else if (hash_flds & 1858 BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_SCTP)) { 1859 rss_hash = ICE_FLOW_HASH_IPV4 | 1860 ICE_FLOW_HASH_SCTP_PORT; 1861 hash_flds &= 1862 ~BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_SCTP); 1863 } 1864 } else if (hash_flds & ICE_FLOW_AVF_RSS_ALL_IPV6_MASKS) { 1865 if (hash_flds & ICE_FLOW_AVF_RSS_IPV6_MASKS) { 1866 rss_hash = ICE_FLOW_HASH_IPV6; 1867 hash_flds &= ~ICE_FLOW_AVF_RSS_IPV6_MASKS; 1868 } else if (hash_flds & 1869 ICE_FLOW_AVF_RSS_TCP_IPV6_MASKS) { 1870 rss_hash = ICE_FLOW_HASH_IPV6 | 1871 ICE_FLOW_HASH_TCP_PORT; 1872 hash_flds &= ~ICE_FLOW_AVF_RSS_TCP_IPV6_MASKS; 1873 } else if (hash_flds & 1874 ICE_FLOW_AVF_RSS_UDP_IPV6_MASKS) { 1875 rss_hash = ICE_FLOW_HASH_IPV6 | 1876 ICE_FLOW_HASH_UDP_PORT; 1877 hash_flds &= ~ICE_FLOW_AVF_RSS_UDP_IPV6_MASKS; 1878 } else if (hash_flds & 1879 BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_SCTP)) { 1880 rss_hash = ICE_FLOW_HASH_IPV6 | 1881 ICE_FLOW_HASH_SCTP_PORT; 1882 hash_flds &= 1883 ~BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_SCTP); 1884 } 1885 } 1886 1887 if (rss_hash == ICE_HASH_INVALID) 1888 return ICE_ERR_OUT_OF_RANGE; 1889 1890 hcfg.addl_hdrs = ICE_FLOW_SEG_HDR_NONE; 1891 hcfg.hash_flds = rss_hash; 1892 hcfg.symm = false; 1893 hcfg.hdr_type = ICE_RSS_ANY_HEADERS; 1894 status = ice_add_rss_cfg(hw, vsi_handle, &hcfg); 1895 if (status) 1896 break; 1897 } 1898 1899 return status; 1900 } 1901 1902 /** 1903 * ice_replay_rss_cfg - replay RSS configurations associated with VSI 1904 * @hw: pointer to the hardware structure 1905 * @vsi_handle: software VSI handle 1906 */ 1907 enum ice_status ice_replay_rss_cfg(struct ice_hw *hw, u16 vsi_handle) 1908 { 1909 enum ice_status status = ICE_SUCCESS; 1910 struct ice_rss_cfg *r; 1911 1912 if (!ice_is_vsi_valid(hw, vsi_handle)) 1913 return ICE_ERR_PARAM; 1914 1915 ice_acquire_lock(&hw->rss_locks); 1916 LIST_FOR_EACH_ENTRY(r, &hw->rss_list_head, 1917 ice_rss_cfg, l_entry) { 1918 if (ice_is_bit_set(r->vsis, vsi_handle)) { 1919 status = ice_add_rss_cfg_sync(hw, vsi_handle, &r->hash); 1920 if (status) 1921 break; 1922 } 1923 } 1924 ice_release_lock(&hw->rss_locks); 1925 1926 return status; 1927 } 1928 1929 /** 1930 * ice_get_rss_cfg - returns hashed fields for the given header types 1931 * @hw: pointer to the hardware structure 1932 * @vsi_handle: software VSI handle 1933 * @hdrs: protocol header type 1934 * 1935 * This function will return the match fields of the first instance of flow 1936 * profile having the given header types and containing input VSI 1937 */ 1938 u64 ice_get_rss_cfg(struct ice_hw *hw, u16 vsi_handle, u32 hdrs) 1939 { 1940 u64 rss_hash = ICE_HASH_INVALID; 1941 struct ice_rss_cfg *r; 1942 1943 /* verify if the protocol header is non zero and VSI is valid */ 1944 if (hdrs == ICE_FLOW_SEG_HDR_NONE || !ice_is_vsi_valid(hw, vsi_handle)) 1945 return ICE_HASH_INVALID; 1946 1947 ice_acquire_lock(&hw->rss_locks); 1948 LIST_FOR_EACH_ENTRY(r, &hw->rss_list_head, 1949 ice_rss_cfg, l_entry) 1950 if (ice_is_bit_set(r->vsis, vsi_handle) && 1951 r->hash.addl_hdrs == hdrs) { 1952 rss_hash = r->hash.hash_flds; 1953 break; 1954 } 1955 ice_release_lock(&hw->rss_locks); 1956 1957 return rss_hash; 1958 } 1959