1 /* SPDX-License-Identifier: BSD-3-Clause */
2 /* Copyright (c) 2020, Intel Corporation
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
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.
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.
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.
33 #include "ice_common.h"
36 /* Size of known protocol header fields */
37 #define ICE_FLOW_FLD_SZ_ETH_TYPE 2
38 #define ICE_FLOW_FLD_SZ_VLAN 2
39 #define ICE_FLOW_FLD_SZ_IPV4_ADDR 4
40 #define ICE_FLOW_FLD_SZ_IPV6_ADDR 16
41 #define ICE_FLOW_FLD_SZ_IP_DSCP 1
42 #define ICE_FLOW_FLD_SZ_IP_TTL 1
43 #define ICE_FLOW_FLD_SZ_IP_PROT 1
44 #define ICE_FLOW_FLD_SZ_PORT 2
45 #define ICE_FLOW_FLD_SZ_TCP_FLAGS 1
46 #define ICE_FLOW_FLD_SZ_ICMP_TYPE 1
47 #define ICE_FLOW_FLD_SZ_ICMP_CODE 1
48 #define ICE_FLOW_FLD_SZ_ARP_OPER 2
49 #define ICE_FLOW_FLD_SZ_GRE_KEYID 4
51 /* Describe properties of a protocol header field */
52 struct ice_flow_field_info {
53 enum ice_flow_seg_hdr hdr;
54 s16 off; /* Offset from start of a protocol header, in bits */
55 u16 size; /* Size of fields in bits */
58 #define ICE_FLOW_FLD_INFO(_hdr, _offset_bytes, _size_bytes) { \
60 .off = (_offset_bytes) * BITS_PER_BYTE, \
61 .size = (_size_bytes) * BITS_PER_BYTE, \
64 /* Table containing properties of supported protocol header fields */
66 struct ice_flow_field_info ice_flds_info[ICE_FLOW_FIELD_IDX_MAX] = {
68 /* ICE_FLOW_FIELD_IDX_ETH_DA */
69 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ETH, 0, ETH_ALEN),
70 /* ICE_FLOW_FIELD_IDX_ETH_SA */
71 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ETH, ETH_ALEN, ETH_ALEN),
72 /* ICE_FLOW_FIELD_IDX_S_VLAN */
73 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_VLAN, 12, ICE_FLOW_FLD_SZ_VLAN),
74 /* ICE_FLOW_FIELD_IDX_C_VLAN */
75 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_VLAN, 14, ICE_FLOW_FLD_SZ_VLAN),
76 /* ICE_FLOW_FIELD_IDX_ETH_TYPE */
77 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ETH, 0, ICE_FLOW_FLD_SZ_ETH_TYPE),
79 /* ICE_FLOW_FIELD_IDX_IPV4_DSCP */
80 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV4, 1, ICE_FLOW_FLD_SZ_IP_DSCP),
81 /* ICE_FLOW_FIELD_IDX_IPV6_DSCP */
82 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV6, 0, ICE_FLOW_FLD_SZ_IP_DSCP),
83 /* ICE_FLOW_FIELD_IDX_IPV4_TTL */
84 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_NONE, 8, ICE_FLOW_FLD_SZ_IP_TTL),
85 /* ICE_FLOW_FIELD_IDX_IPV4_PROT */
86 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_NONE, 9, ICE_FLOW_FLD_SZ_IP_PROT),
87 /* ICE_FLOW_FIELD_IDX_IPV6_TTL */
88 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_NONE, 7, ICE_FLOW_FLD_SZ_IP_TTL),
89 /* ICE_FLOW_FIELD_IDX_IPV4_PROT */
90 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_NONE, 6, ICE_FLOW_FLD_SZ_IP_PROT),
91 /* ICE_FLOW_FIELD_IDX_IPV4_SA */
92 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV4, 12, ICE_FLOW_FLD_SZ_IPV4_ADDR),
93 /* ICE_FLOW_FIELD_IDX_IPV4_DA */
94 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV4, 16, ICE_FLOW_FLD_SZ_IPV4_ADDR),
95 /* ICE_FLOW_FIELD_IDX_IPV6_SA */
96 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV6, 8, ICE_FLOW_FLD_SZ_IPV6_ADDR),
97 /* ICE_FLOW_FIELD_IDX_IPV6_DA */
98 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV6, 24, ICE_FLOW_FLD_SZ_IPV6_ADDR),
100 /* ICE_FLOW_FIELD_IDX_TCP_SRC_PORT */
101 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_TCP, 0, ICE_FLOW_FLD_SZ_PORT),
102 /* ICE_FLOW_FIELD_IDX_TCP_DST_PORT */
103 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_TCP, 2, ICE_FLOW_FLD_SZ_PORT),
104 /* ICE_FLOW_FIELD_IDX_UDP_SRC_PORT */
105 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_UDP, 0, ICE_FLOW_FLD_SZ_PORT),
106 /* ICE_FLOW_FIELD_IDX_UDP_DST_PORT */
107 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_UDP, 2, ICE_FLOW_FLD_SZ_PORT),
108 /* ICE_FLOW_FIELD_IDX_SCTP_SRC_PORT */
109 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_SCTP, 0, ICE_FLOW_FLD_SZ_PORT),
110 /* ICE_FLOW_FIELD_IDX_SCTP_DST_PORT */
111 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_SCTP, 2, ICE_FLOW_FLD_SZ_PORT),
112 /* ICE_FLOW_FIELD_IDX_TCP_FLAGS */
113 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_TCP, 13, ICE_FLOW_FLD_SZ_TCP_FLAGS),
115 /* ICE_FLOW_FIELD_IDX_ARP_SIP */
116 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ARP, 14, ICE_FLOW_FLD_SZ_IPV4_ADDR),
117 /* ICE_FLOW_FIELD_IDX_ARP_DIP */
118 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ARP, 24, ICE_FLOW_FLD_SZ_IPV4_ADDR),
119 /* ICE_FLOW_FIELD_IDX_ARP_SHA */
120 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ARP, 8, ETH_ALEN),
121 /* ICE_FLOW_FIELD_IDX_ARP_DHA */
122 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ARP, 18, ETH_ALEN),
123 /* ICE_FLOW_FIELD_IDX_ARP_OP */
124 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ARP, 6, ICE_FLOW_FLD_SZ_ARP_OPER),
126 /* ICE_FLOW_FIELD_IDX_ICMP_TYPE */
127 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ICMP, 0, ICE_FLOW_FLD_SZ_ICMP_TYPE),
128 /* ICE_FLOW_FIELD_IDX_ICMP_CODE */
129 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ICMP, 1, ICE_FLOW_FLD_SZ_ICMP_CODE),
131 /* ICE_FLOW_FIELD_IDX_GRE_KEYID */
132 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_GRE, 12, ICE_FLOW_FLD_SZ_GRE_KEYID),
135 /* Bitmaps indicating relevant packet types for a particular protocol header
137 * Packet types for packets with an Outer/First/Single MAC header
139 static const u32 ice_ptypes_mac_ofos[] = {
140 0xFDC00846, 0xBFBF7F7E, 0xF70001DF, 0xFEFDFDFB,
141 0x0000077E, 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 0x00000000, 0x00000000, 0x00000000, 0x00000000,
150 /* Packet types for packets with an Innermost/Last MAC VLAN header */
151 static const u32 ice_ptypes_macvlan_il[] = {
152 0x00000000, 0xBC000000, 0x000001DF, 0xF0000000,
153 0x0000077E, 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 0x00000000, 0x00000000, 0x00000000, 0x00000000,
162 /* Packet types for packets with an Outer/First/Single IPv4 header, does NOT
163 * include IPV4 other PTYPEs
165 static const u32 ice_ptypes_ipv4_ofos[] = {
166 0x1DC00000, 0x04000800, 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 0x00000000, 0x00000000, 0x00000000, 0x00000000,
176 /* Packet types for packets with an Outer/First/Single IPv4 header, includes
179 static const u32 ice_ptypes_ipv4_ofos_all[] = {
180 0x1DC00000, 0x04000800, 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 0x00000000, 0x00000000, 0x00000000, 0x00000000,
190 /* Packet types for packets with an Innermost/Last IPv4 header */
191 static const u32 ice_ptypes_ipv4_il[] = {
192 0xE0000000, 0xB807700E, 0x80000003, 0xE01DC03B,
193 0x0000000E, 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 0x00000000, 0x00000000, 0x00000000, 0x00000000,
202 /* Packet types for packets with an Outer/First/Single IPv6 header, does NOT
203 * include IVP6 other PTYPEs
205 static const u32 ice_ptypes_ipv6_ofos[] = {
206 0x00000000, 0x00000000, 0x77000000, 0x10002000,
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 0x00000000, 0x00000000, 0x00000000, 0x00000000,
216 /* Packet types for packets with an Outer/First/Single IPv6 header, includes
219 static const u32 ice_ptypes_ipv6_ofos_all[] = {
220 0x00000000, 0x00000000, 0x77000000, 0x10002000,
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 0x00000000, 0x00000000, 0x00000000, 0x00000000,
230 /* Packet types for packets with an Innermost/Last IPv6 header */
231 static const u32 ice_ptypes_ipv6_il[] = {
232 0x00000000, 0x03B80770, 0x000001DC, 0x0EE00000,
233 0x00000770, 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 0x00000000, 0x00000000, 0x00000000, 0x00000000,
242 /* Packet types for packets with an Outer/First/Single IPv4 header - no L4 */
243 static const u32 ice_ipv4_ofos_no_l4[] = {
244 0x10C00000, 0x04000800, 0x00000000, 0x00000000,
245 0x00000000, 0x00000000, 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,
254 /* Packet types for packets with an Innermost/Last IPv4 header - no L4 */
255 static const u32 ice_ipv4_il_no_l4[] = {
256 0x60000000, 0x18043008, 0x80000002, 0x6010c021,
257 0x00000008, 0x00000000, 0x00000000, 0x00000000,
258 0x00000000, 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,
266 /* Packet types for packets with an Outer/First/Single IPv6 header - no L4 */
267 static const u32 ice_ipv6_ofos_no_l4[] = {
268 0x00000000, 0x00000000, 0x43000000, 0x10002000,
269 0x00000000, 0x00000000, 0x00000000, 0x00000000,
270 0x00000000, 0x00000000, 0x00000000, 0x00000000,
271 0x00000000, 0x00000000, 0x00000000, 0x00000000,
272 0x00000000, 0x00000000, 0x00000000, 0x00000000,
273 0x00000000, 0x00000000, 0x00000000, 0x00000000,
274 0x00000000, 0x00000000, 0x00000000, 0x00000000,
275 0x00000000, 0x00000000, 0x00000000, 0x00000000,
278 /* Packet types for packets with an Innermost/Last IPv6 header - no L4 */
279 static const u32 ice_ipv6_il_no_l4[] = {
280 0x00000000, 0x02180430, 0x0000010c, 0x086010c0,
281 0x00000430, 0x00000000, 0x00000000, 0x00000000,
282 0x00000000, 0x00000000, 0x00000000, 0x00000000,
283 0x00000000, 0x00000000, 0x00000000, 0x00000000,
284 0x00000000, 0x00000000, 0x00000000, 0x00000000,
285 0x00000000, 0x00000000, 0x00000000, 0x00000000,
286 0x00000000, 0x00000000, 0x00000000, 0x00000000,
287 0x00000000, 0x00000000, 0x00000000, 0x00000000,
290 /* Packet types for packets with an Outermost/First ARP header */
291 static const u32 ice_ptypes_arp_of[] = {
292 0x00000800, 0x00000000, 0x00000000, 0x00000000,
293 0x00000000, 0x00000000, 0x00000000, 0x00000000,
294 0x00000000, 0x00000000, 0x00000000, 0x00000000,
295 0x00000000, 0x00000000, 0x00000000, 0x00000000,
296 0x00000000, 0x00000000, 0x00000000, 0x00000000,
297 0x00000000, 0x00000000, 0x00000000, 0x00000000,
298 0x00000000, 0x00000000, 0x00000000, 0x00000000,
299 0x00000000, 0x00000000, 0x00000000, 0x00000000,
302 /* UDP Packet types for non-tunneled packets or tunneled
303 * packets with inner UDP.
305 static const u32 ice_ptypes_udp_il[] = {
306 0x81000000, 0x20204040, 0x04000010, 0x80810102,
307 0x00000040, 0x00000000, 0x00000000, 0x00000000,
308 0x00000000, 0x00000000, 0x00000000, 0x00000000,
309 0x00000000, 0x00000000, 0x00000000, 0x00000000,
310 0x00000000, 0x00000000, 0x00000000, 0x00000000,
311 0x00000000, 0x00000000, 0x00000000, 0x00000000,
312 0x00000000, 0x00000000, 0x00000000, 0x00000000,
313 0x00000000, 0x00000000, 0x00000000, 0x00000000,
316 /* Packet types for packets with an Innermost/Last TCP header */
317 static const u32 ice_ptypes_tcp_il[] = {
318 0x04000000, 0x80810102, 0x10000040, 0x02040408,
319 0x00000102, 0x00000000, 0x00000000, 0x00000000,
320 0x00000000, 0x00000000, 0x00000000, 0x00000000,
321 0x00000000, 0x00000000, 0x00000000, 0x00000000,
322 0x00000000, 0x00000000, 0x00000000, 0x00000000,
323 0x00000000, 0x00000000, 0x00000000, 0x00000000,
324 0x00000000, 0x00000000, 0x00000000, 0x00000000,
325 0x00000000, 0x00000000, 0x00000000, 0x00000000,
328 /* Packet types for packets with an Innermost/Last SCTP header */
329 static const u32 ice_ptypes_sctp_il[] = {
330 0x08000000, 0x01020204, 0x20000081, 0x04080810,
331 0x00000204, 0x00000000, 0x00000000, 0x00000000,
332 0x00000000, 0x00000000, 0x00000000, 0x00000000,
333 0x00000000, 0x00000000, 0x00000000, 0x00000000,
334 0x00000000, 0x00000000, 0x00000000, 0x00000000,
335 0x00000000, 0x00000000, 0x00000000, 0x00000000,
336 0x00000000, 0x00000000, 0x00000000, 0x00000000,
337 0x00000000, 0x00000000, 0x00000000, 0x00000000,
340 /* Packet types for packets with an Outermost/First ICMP header */
341 static const u32 ice_ptypes_icmp_of[] = {
342 0x10000000, 0x00000000, 0x00000000, 0x00000000,
343 0x00000000, 0x00000000, 0x00000000, 0x00000000,
344 0x00000000, 0x00000000, 0x00000000, 0x00000000,
345 0x00000000, 0x00000000, 0x00000000, 0x00000000,
346 0x00000000, 0x00000000, 0x00000000, 0x00000000,
347 0x00000000, 0x00000000, 0x00000000, 0x00000000,
348 0x00000000, 0x00000000, 0x00000000, 0x00000000,
349 0x00000000, 0x00000000, 0x00000000, 0x00000000,
352 /* Packet types for packets with an Innermost/Last ICMP header */
353 static const u32 ice_ptypes_icmp_il[] = {
354 0x00000000, 0x02040408, 0x40000102, 0x08101020,
355 0x00000408, 0x00000000, 0x00000000, 0x00000000,
356 0x00000000, 0x00000000, 0x00000000, 0x00000000,
357 0x00000000, 0x00000000, 0x00000000, 0x00000000,
358 0x00000000, 0x00000000, 0x00000000, 0x00000000,
359 0x00000000, 0x00000000, 0x00000000, 0x00000000,
360 0x00000000, 0x00000000, 0x00000000, 0x00000000,
361 0x00000000, 0x00000000, 0x00000000, 0x00000000,
364 /* Packet types for packets with an Outermost/First GRE header */
365 static const u32 ice_ptypes_gre_of[] = {
366 0x00000000, 0xBFBF7800, 0x000001DF, 0xFEFDE000,
367 0x0000017E, 0x00000000, 0x00000000, 0x00000000,
368 0x00000000, 0x00000000, 0x00000000, 0x00000000,
369 0x00000000, 0x00000000, 0x00000000, 0x00000000,
370 0x00000000, 0x00000000, 0x00000000, 0x00000000,
371 0x00000000, 0x00000000, 0x00000000, 0x00000000,
372 0x00000000, 0x00000000, 0x00000000, 0x00000000,
373 0x00000000, 0x00000000, 0x00000000, 0x00000000,
376 /* Packet types for packets with an Innermost/Last MAC header */
377 static const u32 ice_ptypes_mac_il[] = {
378 0x00000000, 0x00000000, 0x00000000, 0x00000000,
379 0x00000000, 0x00000000, 0x00000000, 0x00000000,
380 0x00000000, 0x00000000, 0x00000000, 0x00000000,
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,
388 /* Manage parameters and info. used during the creation of a flow profile */
389 struct ice_flow_prof_params {
391 u16 entry_length; /* # of bytes formatted entry will require */
393 struct ice_flow_prof *prof;
395 /* For ACL, the es[0] will have the data of ICE_RX_MDID_PKT_FLAGS_15_0
396 * This will give us the direction flags.
398 struct ice_fv_word es[ICE_MAX_FV_WORDS];
399 ice_declare_bitmap(ptypes, ICE_FLOW_PTYPE_MAX);
402 #define ICE_FLOW_SEG_HDRS_L3_MASK \
403 (ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_IPV6 | \
404 ICE_FLOW_SEG_HDR_ARP)
405 #define ICE_FLOW_SEG_HDRS_L4_MASK \
406 (ICE_FLOW_SEG_HDR_ICMP | ICE_FLOW_SEG_HDR_TCP | ICE_FLOW_SEG_HDR_UDP | \
407 ICE_FLOW_SEG_HDR_SCTP)
408 /* mask for L4 protocols that are NOT part of IPV4/6 OTHER PTYPE groups */
409 #define ICE_FLOW_SEG_HDRS_L4_MASK_NO_OTHER \
410 (ICE_FLOW_SEG_HDR_TCP | ICE_FLOW_SEG_HDR_UDP | ICE_FLOW_SEG_HDR_SCTP)
413 * ice_flow_val_hdrs - validates packet segments for valid protocol headers
414 * @segs: array of one or more packet segments that describe the flow
415 * @segs_cnt: number of packet segments provided
417 static enum ice_status
418 ice_flow_val_hdrs(struct ice_flow_seg_info *segs, u8 segs_cnt)
422 for (i = 0; i < segs_cnt; i++) {
423 /* Multiple L3 headers */
424 if (segs[i].hdrs & ICE_FLOW_SEG_HDRS_L3_MASK &&
425 !ice_is_pow2(segs[i].hdrs & ICE_FLOW_SEG_HDRS_L3_MASK))
426 return ICE_ERR_PARAM;
428 /* Multiple L4 headers */
429 if (segs[i].hdrs & ICE_FLOW_SEG_HDRS_L4_MASK &&
430 !ice_is_pow2(segs[i].hdrs & ICE_FLOW_SEG_HDRS_L4_MASK))
431 return ICE_ERR_PARAM;
438 * ice_flow_proc_seg_hdrs - process protocol headers present in pkt segments
439 * @params: information about the flow to be processed
441 * This function identifies the packet types associated with the protocol
442 * headers being present in packet segments of the specified flow profile.
444 static enum ice_status
445 ice_flow_proc_seg_hdrs(struct ice_flow_prof_params *params)
447 struct ice_flow_prof *prof;
450 ice_memset(params->ptypes, 0xff, sizeof(params->ptypes),
455 for (i = 0; i < params->prof->segs_cnt; i++) {
456 const ice_bitmap_t *src;
459 hdrs = prof->segs[i].hdrs;
461 if (hdrs & ICE_FLOW_SEG_HDR_ETH) {
462 src = !i ? (const ice_bitmap_t *)ice_ptypes_mac_ofos :
463 (const ice_bitmap_t *)ice_ptypes_mac_il;
464 ice_and_bitmap(params->ptypes, params->ptypes, src,
468 if (i && hdrs & ICE_FLOW_SEG_HDR_VLAN) {
469 src = (const ice_bitmap_t *)ice_ptypes_macvlan_il;
470 ice_and_bitmap(params->ptypes, params->ptypes, src,
474 if (!i && hdrs & ICE_FLOW_SEG_HDR_ARP) {
475 ice_and_bitmap(params->ptypes, params->ptypes,
476 (const ice_bitmap_t *)ice_ptypes_arp_of,
480 if ((hdrs & ICE_FLOW_SEG_HDR_IPV4) &&
481 (hdrs & ICE_FLOW_SEG_HDR_IPV_OTHER)) {
483 (const ice_bitmap_t *)ice_ptypes_ipv4_il :
484 (const ice_bitmap_t *)ice_ptypes_ipv4_ofos_all;
485 ice_and_bitmap(params->ptypes, params->ptypes, src,
487 } else if ((hdrs & ICE_FLOW_SEG_HDR_IPV6) &&
488 (hdrs & ICE_FLOW_SEG_HDR_IPV_OTHER)) {
490 (const ice_bitmap_t *)ice_ptypes_ipv6_il :
491 (const ice_bitmap_t *)ice_ptypes_ipv6_ofos_all;
492 ice_and_bitmap(params->ptypes, params->ptypes, src,
494 } else if ((hdrs & ICE_FLOW_SEG_HDR_IPV4) &&
495 !(hdrs & ICE_FLOW_SEG_HDRS_L4_MASK_NO_OTHER)) {
496 src = !i ? (const ice_bitmap_t *)ice_ipv4_ofos_no_l4 :
497 (const ice_bitmap_t *)ice_ipv4_il_no_l4;
498 ice_and_bitmap(params->ptypes, params->ptypes, src,
500 } else if (hdrs & ICE_FLOW_SEG_HDR_IPV4) {
501 src = !i ? (const ice_bitmap_t *)ice_ptypes_ipv4_ofos :
502 (const ice_bitmap_t *)ice_ptypes_ipv4_il;
503 ice_and_bitmap(params->ptypes, params->ptypes, src,
505 } else if ((hdrs & ICE_FLOW_SEG_HDR_IPV6) &&
506 !(hdrs & ICE_FLOW_SEG_HDRS_L4_MASK_NO_OTHER)) {
507 src = !i ? (const ice_bitmap_t *)ice_ipv6_ofos_no_l4 :
508 (const ice_bitmap_t *)ice_ipv6_il_no_l4;
509 ice_and_bitmap(params->ptypes, params->ptypes, src,
511 } else if (hdrs & ICE_FLOW_SEG_HDR_IPV6) {
512 src = !i ? (const ice_bitmap_t *)ice_ptypes_ipv6_ofos :
513 (const ice_bitmap_t *)ice_ptypes_ipv6_il;
514 ice_and_bitmap(params->ptypes, params->ptypes, src,
518 if (hdrs & ICE_FLOW_SEG_HDR_UDP) {
519 src = (const ice_bitmap_t *)ice_ptypes_udp_il;
520 ice_and_bitmap(params->ptypes, params->ptypes, src,
522 } else if (hdrs & ICE_FLOW_SEG_HDR_TCP) {
523 ice_and_bitmap(params->ptypes, params->ptypes,
524 (const ice_bitmap_t *)ice_ptypes_tcp_il,
526 } else if (hdrs & ICE_FLOW_SEG_HDR_SCTP) {
527 src = (const ice_bitmap_t *)ice_ptypes_sctp_il;
528 ice_and_bitmap(params->ptypes, params->ptypes, src,
532 if (hdrs & ICE_FLOW_SEG_HDR_ICMP) {
533 src = !i ? (const ice_bitmap_t *)ice_ptypes_icmp_of :
534 (const ice_bitmap_t *)ice_ptypes_icmp_il;
535 ice_and_bitmap(params->ptypes, params->ptypes, src,
537 } else if (hdrs & ICE_FLOW_SEG_HDR_GRE) {
539 src = (const ice_bitmap_t *)ice_ptypes_gre_of;
540 ice_and_bitmap(params->ptypes, params->ptypes,
541 src, ICE_FLOW_PTYPE_MAX);
550 * ice_flow_xtract_fld - Create an extraction sequence entry for the given field
551 * @hw: pointer to the HW struct
552 * @params: information about the flow to be processed
553 * @seg: packet segment index of the field to be extracted
554 * @fld: ID of field to be extracted
556 * This function determines the protocol ID, offset, and size of the given
557 * field. It then allocates one or more extraction sequence entries for the
558 * given field, and fill the entries with protocol ID and offset information.
560 static enum ice_status
561 ice_flow_xtract_fld(struct ice_hw *hw, struct ice_flow_prof_params *params,
562 u8 seg, enum ice_flow_field fld)
564 enum ice_flow_field sib = ICE_FLOW_FIELD_IDX_MAX;
565 enum ice_prot_id prot_id = ICE_PROT_ID_INVAL;
566 u8 fv_words = hw->blk[params->blk].es.fvw;
567 struct ice_flow_fld_info *flds;
568 u16 cnt, ese_bits, i;
571 flds = params->prof->segs[seg].fields;
574 case ICE_FLOW_FIELD_IDX_ETH_DA:
575 case ICE_FLOW_FIELD_IDX_ETH_SA:
576 case ICE_FLOW_FIELD_IDX_S_VLAN:
577 case ICE_FLOW_FIELD_IDX_C_VLAN:
578 prot_id = seg == 0 ? ICE_PROT_MAC_OF_OR_S : ICE_PROT_MAC_IL;
580 case ICE_FLOW_FIELD_IDX_ETH_TYPE:
581 prot_id = seg == 0 ? ICE_PROT_ETYPE_OL : ICE_PROT_ETYPE_IL;
583 case ICE_FLOW_FIELD_IDX_IPV4_DSCP:
584 prot_id = seg == 0 ? ICE_PROT_IPV4_OF_OR_S : ICE_PROT_IPV4_IL;
586 case ICE_FLOW_FIELD_IDX_IPV6_DSCP:
587 prot_id = seg == 0 ? ICE_PROT_IPV6_OF_OR_S : ICE_PROT_IPV6_IL;
589 case ICE_FLOW_FIELD_IDX_IPV4_TTL:
590 case ICE_FLOW_FIELD_IDX_IPV4_PROT:
591 prot_id = seg == 0 ? ICE_PROT_IPV4_OF_OR_S : ICE_PROT_IPV4_IL;
593 /* TTL and PROT share the same extraction seq. entry.
594 * Each is considered a sibling to the other in terms of sharing
595 * the same extraction sequence entry.
597 if (fld == ICE_FLOW_FIELD_IDX_IPV4_TTL)
598 sib = ICE_FLOW_FIELD_IDX_IPV4_PROT;
599 else if (fld == ICE_FLOW_FIELD_IDX_IPV4_PROT)
600 sib = ICE_FLOW_FIELD_IDX_IPV4_TTL;
602 case ICE_FLOW_FIELD_IDX_IPV6_TTL:
603 case ICE_FLOW_FIELD_IDX_IPV6_PROT:
604 prot_id = seg == 0 ? ICE_PROT_IPV6_OF_OR_S : ICE_PROT_IPV6_IL;
606 /* TTL and PROT share the same extraction seq. entry.
607 * Each is considered a sibling to the other in terms of sharing
608 * the same extraction sequence entry.
610 if (fld == ICE_FLOW_FIELD_IDX_IPV6_TTL)
611 sib = ICE_FLOW_FIELD_IDX_IPV6_PROT;
612 else if (fld == ICE_FLOW_FIELD_IDX_IPV6_PROT)
613 sib = ICE_FLOW_FIELD_IDX_IPV6_TTL;
615 case ICE_FLOW_FIELD_IDX_IPV4_SA:
616 case ICE_FLOW_FIELD_IDX_IPV4_DA:
617 prot_id = seg == 0 ? ICE_PROT_IPV4_OF_OR_S : ICE_PROT_IPV4_IL;
619 case ICE_FLOW_FIELD_IDX_IPV6_SA:
620 case ICE_FLOW_FIELD_IDX_IPV6_DA:
621 prot_id = seg == 0 ? ICE_PROT_IPV6_OF_OR_S : ICE_PROT_IPV6_IL;
623 case ICE_FLOW_FIELD_IDX_TCP_SRC_PORT:
624 case ICE_FLOW_FIELD_IDX_TCP_DST_PORT:
625 case ICE_FLOW_FIELD_IDX_TCP_FLAGS:
626 prot_id = ICE_PROT_TCP_IL;
628 case ICE_FLOW_FIELD_IDX_UDP_SRC_PORT:
629 case ICE_FLOW_FIELD_IDX_UDP_DST_PORT:
630 prot_id = ICE_PROT_UDP_IL_OR_S;
632 case ICE_FLOW_FIELD_IDX_SCTP_SRC_PORT:
633 case ICE_FLOW_FIELD_IDX_SCTP_DST_PORT:
634 prot_id = ICE_PROT_SCTP_IL;
636 case ICE_FLOW_FIELD_IDX_ARP_SIP:
637 case ICE_FLOW_FIELD_IDX_ARP_DIP:
638 case ICE_FLOW_FIELD_IDX_ARP_SHA:
639 case ICE_FLOW_FIELD_IDX_ARP_DHA:
640 case ICE_FLOW_FIELD_IDX_ARP_OP:
641 prot_id = ICE_PROT_ARP_OF;
643 case ICE_FLOW_FIELD_IDX_ICMP_TYPE:
644 case ICE_FLOW_FIELD_IDX_ICMP_CODE:
645 /* ICMP type and code share the same extraction seq. entry */
646 prot_id = (params->prof->segs[seg].hdrs &
647 ICE_FLOW_SEG_HDR_IPV4) ?
648 ICE_PROT_ICMP_IL : ICE_PROT_ICMPV6_IL;
649 sib = fld == ICE_FLOW_FIELD_IDX_ICMP_TYPE ?
650 ICE_FLOW_FIELD_IDX_ICMP_CODE :
651 ICE_FLOW_FIELD_IDX_ICMP_TYPE;
653 case ICE_FLOW_FIELD_IDX_GRE_KEYID:
654 prot_id = ICE_PROT_GRE_OF;
657 return ICE_ERR_NOT_IMPL;
660 /* Each extraction sequence entry is a word in size, and extracts a
661 * word-aligned offset from a protocol header.
663 ese_bits = ICE_FLOW_FV_EXTRACT_SZ * BITS_PER_BYTE;
665 flds[fld].xtrct.prot_id = prot_id;
666 flds[fld].xtrct.off = (ice_flds_info[fld].off / ese_bits) *
667 ICE_FLOW_FV_EXTRACT_SZ;
668 flds[fld].xtrct.disp = (u8)(ice_flds_info[fld].off % ese_bits);
669 flds[fld].xtrct.idx = params->es_cnt;
671 /* Adjust the next field-entry index after accommodating the number of
672 * entries this field consumes
674 cnt = DIVIDE_AND_ROUND_UP(flds[fld].xtrct.disp +
675 ice_flds_info[fld].size, ese_bits);
677 /* Fill in the extraction sequence entries needed for this field */
678 off = flds[fld].xtrct.off;
679 for (i = 0; i < cnt; i++) {
680 /* Only consume an extraction sequence entry if there is no
681 * sibling field associated with this field or the sibling entry
682 * already extracts the word shared with this field.
684 if (sib == ICE_FLOW_FIELD_IDX_MAX ||
685 flds[sib].xtrct.prot_id == ICE_PROT_ID_INVAL ||
686 flds[sib].xtrct.off != off) {
689 /* Make sure the number of extraction sequence required
690 * does not exceed the block's capability
692 if (params->es_cnt >= fv_words)
693 return ICE_ERR_MAX_LIMIT;
695 /* some blocks require a reversed field vector layout */
696 if (hw->blk[params->blk].es.reverse)
697 idx = fv_words - params->es_cnt - 1;
699 idx = params->es_cnt;
701 params->es[idx].prot_id = prot_id;
702 params->es[idx].off = off;
706 off += ICE_FLOW_FV_EXTRACT_SZ;
713 * ice_flow_create_xtrct_seq - Create an extraction sequence for given segments
714 * @hw: pointer to the HW struct
715 * @params: information about the flow to be processed
717 * This function iterates through all matched fields in the given segments, and
718 * creates an extraction sequence for the fields.
720 static enum ice_status
721 ice_flow_create_xtrct_seq(struct ice_hw *hw,
722 struct ice_flow_prof_params *params)
724 enum ice_status status = ICE_SUCCESS;
727 for (i = 0; i < params->prof->segs_cnt; i++) {
728 u64 match = params->prof->segs[i].match;
729 enum ice_flow_field j;
731 ice_for_each_set_bit(j, (ice_bitmap_t *)&match,
732 ICE_FLOW_FIELD_IDX_MAX) {
733 status = ice_flow_xtract_fld(hw, params, i, j);
736 ice_clear_bit(j, (ice_bitmap_t *)&match);
744 * ice_flow_proc_segs - process all packet segments associated with a profile
745 * @hw: pointer to the HW struct
746 * @params: information about the flow to be processed
748 static enum ice_status
749 ice_flow_proc_segs(struct ice_hw *hw, struct ice_flow_prof_params *params)
751 enum ice_status status;
753 status = ice_flow_proc_seg_hdrs(params);
757 status = ice_flow_create_xtrct_seq(hw, params);
761 switch (params->blk) {
763 status = ICE_SUCCESS;
766 return ICE_ERR_NOT_IMPL;
772 #define ICE_FLOW_FIND_PROF_CHK_FLDS 0x00000001
773 #define ICE_FLOW_FIND_PROF_CHK_VSI 0x00000002
774 #define ICE_FLOW_FIND_PROF_NOT_CHK_DIR 0x00000004
777 * ice_flow_find_prof_conds - Find a profile matching headers and conditions
778 * @hw: pointer to the HW struct
779 * @blk: classification stage
780 * @dir: flow direction
781 * @segs: array of one or more packet segments that describe the flow
782 * @segs_cnt: number of packet segments provided
783 * @vsi_handle: software VSI handle to check VSI (ICE_FLOW_FIND_PROF_CHK_VSI)
784 * @conds: additional conditions to be checked (ICE_FLOW_FIND_PROF_CHK_*)
786 static struct ice_flow_prof *
787 ice_flow_find_prof_conds(struct ice_hw *hw, enum ice_block blk,
788 enum ice_flow_dir dir, struct ice_flow_seg_info *segs,
789 u8 segs_cnt, u16 vsi_handle, u32 conds)
791 struct ice_flow_prof *p, *prof = NULL;
793 ice_acquire_lock(&hw->fl_profs_locks[blk]);
794 LIST_FOR_EACH_ENTRY(p, &hw->fl_profs[blk], ice_flow_prof, l_entry)
795 if ((p->dir == dir || conds & ICE_FLOW_FIND_PROF_NOT_CHK_DIR) &&
796 segs_cnt && segs_cnt == p->segs_cnt) {
799 /* Check for profile-VSI association if specified */
800 if ((conds & ICE_FLOW_FIND_PROF_CHK_VSI) &&
801 ice_is_vsi_valid(hw, vsi_handle) &&
802 !ice_is_bit_set(p->vsis, vsi_handle))
805 /* Protocol headers must be checked. Matched fields are
806 * checked if specified.
808 for (i = 0; i < segs_cnt; i++)
809 if (segs[i].hdrs != p->segs[i].hdrs ||
810 ((conds & ICE_FLOW_FIND_PROF_CHK_FLDS) &&
811 segs[i].match != p->segs[i].match))
814 /* A match is found if all segments are matched */
820 ice_release_lock(&hw->fl_profs_locks[blk]);
826 * ice_flow_find_prof - Look up a profile matching headers and matched fields
827 * @hw: pointer to the HW struct
828 * @blk: classification stage
829 * @dir: flow direction
830 * @segs: array of one or more packet segments that describe the flow
831 * @segs_cnt: number of packet segments provided
834 ice_flow_find_prof(struct ice_hw *hw, enum ice_block blk, enum ice_flow_dir dir,
835 struct ice_flow_seg_info *segs, u8 segs_cnt)
837 struct ice_flow_prof *p;
839 p = ice_flow_find_prof_conds(hw, blk, dir, segs, segs_cnt,
840 ICE_MAX_VSI, ICE_FLOW_FIND_PROF_CHK_FLDS);
842 return p ? p->id : ICE_FLOW_PROF_ID_INVAL;
846 * ice_flow_find_prof_id - Look up a profile with given profile ID
847 * @hw: pointer to the HW struct
848 * @blk: classification stage
849 * @prof_id: unique ID to identify this flow profile
851 static struct ice_flow_prof *
852 ice_flow_find_prof_id(struct ice_hw *hw, enum ice_block blk, u64 prof_id)
854 struct ice_flow_prof *p;
856 LIST_FOR_EACH_ENTRY(p, &hw->fl_profs[blk], ice_flow_prof, l_entry)
857 if (p->id == prof_id)
864 * ice_flow_get_hw_prof - return the HW profile for a specific profile ID handle
865 * @hw: pointer to the HW struct
866 * @blk: classification stage
867 * @prof_id: the profile ID handle
868 * @hw_prof_id: pointer to variable to receive the HW profile ID
871 ice_flow_get_hw_prof(struct ice_hw *hw, enum ice_block blk, u64 prof_id,
874 enum ice_status status = ICE_ERR_DOES_NOT_EXIST;
875 struct ice_prof_map *map;
877 ice_acquire_lock(&hw->blk[blk].es.prof_map_lock);
878 map = ice_search_prof_id(hw, blk, prof_id);
880 *hw_prof_id = map->prof_id;
881 status = ICE_SUCCESS;
883 ice_release_lock(&hw->blk[blk].es.prof_map_lock);
888 * ice_flow_add_prof_sync - Add a flow profile for packet segments and fields
889 * @hw: pointer to the HW struct
890 * @blk: classification stage
891 * @dir: flow direction
892 * @prof_id: unique ID to identify this flow profile
893 * @segs: array of one or more packet segments that describe the flow
894 * @segs_cnt: number of packet segments provided
895 * @acts: array of default actions
896 * @acts_cnt: number of default actions
897 * @prof: stores the returned flow profile added
899 * Assumption: the caller has acquired the lock to the profile list
901 static enum ice_status
902 ice_flow_add_prof_sync(struct ice_hw *hw, enum ice_block blk,
903 enum ice_flow_dir dir, u64 prof_id,
904 struct ice_flow_seg_info *segs, u8 segs_cnt,
905 struct ice_flow_action *acts, u8 acts_cnt,
906 struct ice_flow_prof **prof)
908 struct ice_flow_prof_params *params;
909 enum ice_status status;
912 if (!prof || (acts_cnt && !acts))
913 return ICE_ERR_BAD_PTR;
915 params = (struct ice_flow_prof_params *)ice_malloc(hw, sizeof(*params));
917 return ICE_ERR_NO_MEMORY;
919 params->prof = (struct ice_flow_prof *)
920 ice_malloc(hw, sizeof(*params->prof));
922 status = ICE_ERR_NO_MEMORY;
926 /* initialize extraction sequence to all invalid (0xff) */
927 for (i = 0; i < ICE_MAX_FV_WORDS; i++) {
928 params->es[i].prot_id = ICE_PROT_INVALID;
929 params->es[i].off = ICE_FV_OFFSET_INVAL;
933 params->prof->id = prof_id;
934 params->prof->dir = dir;
935 params->prof->segs_cnt = segs_cnt;
937 /* Make a copy of the segments that need to be persistent in the flow
940 for (i = 0; i < segs_cnt; i++)
941 ice_memcpy(¶ms->prof->segs[i], &segs[i], sizeof(*segs),
942 ICE_NONDMA_TO_NONDMA);
944 status = ice_flow_proc_segs(hw, params);
946 ice_debug(hw, ICE_DBG_FLOW, "Error processing a flow's packet segments\n");
950 /* Add a HW profile for this flow profile */
951 status = ice_add_prof(hw, blk, prof_id, (u8 *)params->ptypes,
954 ice_debug(hw, ICE_DBG_FLOW, "Error adding a HW flow profile\n");
958 *prof = params->prof;
962 ice_free(hw, params->prof);
965 ice_free(hw, params);
971 * ice_flow_rem_prof_sync - remove a flow profile
972 * @hw: pointer to the hardware structure
973 * @blk: classification stage
974 * @prof: pointer to flow profile to remove
976 * Assumption: the caller has acquired the lock to the profile list
978 static enum ice_status
979 ice_flow_rem_prof_sync(struct ice_hw *hw, enum ice_block blk,
980 struct ice_flow_prof *prof)
982 enum ice_status status;
984 /* Remove all hardware profiles associated with this flow profile */
985 status = ice_rem_prof(hw, blk, prof->id);
987 LIST_DEL(&prof->l_entry);
995 * ice_flow_assoc_vsig_vsi - associate a VSI with VSIG
996 * @hw: pointer to the hardware structure
997 * @blk: classification stage
998 * @vsi_handle: software VSI handle
999 * @vsig: target VSI group
1001 * Assumption: the caller has already verified that the VSI to
1002 * be added has the same characteristics as the VSIG and will
1003 * thereby have access to all resources added to that VSIG.
1006 ice_flow_assoc_vsig_vsi(struct ice_hw *hw, enum ice_block blk, u16 vsi_handle,
1009 enum ice_status status;
1011 if (!ice_is_vsi_valid(hw, vsi_handle) || blk >= ICE_BLK_COUNT)
1012 return ICE_ERR_PARAM;
1014 ice_acquire_lock(&hw->fl_profs_locks[blk]);
1015 status = ice_add_vsi_flow(hw, blk, ice_get_hw_vsi_num(hw, vsi_handle),
1017 ice_release_lock(&hw->fl_profs_locks[blk]);
1023 * ice_flow_assoc_prof - associate a VSI with a flow profile
1024 * @hw: pointer to the hardware structure
1025 * @blk: classification stage
1026 * @prof: pointer to flow profile
1027 * @vsi_handle: software VSI handle
1029 * Assumption: the caller has acquired the lock to the profile list
1030 * and the software VSI handle has been validated
1032 static enum ice_status
1033 ice_flow_assoc_prof(struct ice_hw *hw, enum ice_block blk,
1034 struct ice_flow_prof *prof, u16 vsi_handle)
1036 enum ice_status status = ICE_SUCCESS;
1038 if (!ice_is_bit_set(prof->vsis, vsi_handle)) {
1039 status = ice_add_prof_id_flow(hw, blk,
1040 ice_get_hw_vsi_num(hw,
1044 ice_set_bit(vsi_handle, prof->vsis);
1046 ice_debug(hw, ICE_DBG_FLOW, "HW profile add failed, %d\n",
1054 * ice_flow_disassoc_prof - disassociate a VSI from a flow profile
1055 * @hw: pointer to the hardware structure
1056 * @blk: classification stage
1057 * @prof: pointer to flow profile
1058 * @vsi_handle: software VSI handle
1060 * Assumption: the caller has acquired the lock to the profile list
1061 * and the software VSI handle has been validated
1063 static enum ice_status
1064 ice_flow_disassoc_prof(struct ice_hw *hw, enum ice_block blk,
1065 struct ice_flow_prof *prof, u16 vsi_handle)
1067 enum ice_status status = ICE_SUCCESS;
1069 if (ice_is_bit_set(prof->vsis, vsi_handle)) {
1070 status = ice_rem_prof_id_flow(hw, blk,
1071 ice_get_hw_vsi_num(hw,
1075 ice_clear_bit(vsi_handle, prof->vsis);
1077 ice_debug(hw, ICE_DBG_FLOW, "HW profile remove failed, %d\n",
1085 * ice_flow_add_prof - Add a flow profile for packet segments and matched fields
1086 * @hw: pointer to the HW struct
1087 * @blk: classification stage
1088 * @dir: flow direction
1089 * @prof_id: unique ID to identify this flow profile
1090 * @segs: array of one or more packet segments that describe the flow
1091 * @segs_cnt: number of packet segments provided
1092 * @acts: array of default actions
1093 * @acts_cnt: number of default actions
1094 * @prof: stores the returned flow profile added
1096 static enum ice_status
1097 ice_flow_add_prof(struct ice_hw *hw, enum ice_block blk, enum ice_flow_dir dir,
1098 u64 prof_id, struct ice_flow_seg_info *segs, u8 segs_cnt,
1099 struct ice_flow_action *acts, u8 acts_cnt,
1100 struct ice_flow_prof **prof)
1102 enum ice_status status;
1104 if (segs_cnt > ICE_FLOW_SEG_MAX)
1105 return ICE_ERR_MAX_LIMIT;
1108 return ICE_ERR_PARAM;
1111 return ICE_ERR_BAD_PTR;
1113 status = ice_flow_val_hdrs(segs, segs_cnt);
1117 ice_acquire_lock(&hw->fl_profs_locks[blk]);
1119 status = ice_flow_add_prof_sync(hw, blk, dir, prof_id, segs, segs_cnt,
1120 acts, acts_cnt, prof);
1122 LIST_ADD(&(*prof)->l_entry, &hw->fl_profs[blk]);
1124 ice_release_lock(&hw->fl_profs_locks[blk]);
1130 * ice_flow_rem_prof - Remove a flow profile and all entries associated with it
1131 * @hw: pointer to the HW struct
1132 * @blk: the block for which the flow profile is to be removed
1133 * @prof_id: unique ID of the flow profile to be removed
1135 static enum ice_status
1136 ice_flow_rem_prof(struct ice_hw *hw, enum ice_block blk, u64 prof_id)
1138 struct ice_flow_prof *prof;
1139 enum ice_status status;
1141 ice_acquire_lock(&hw->fl_profs_locks[blk]);
1143 prof = ice_flow_find_prof_id(hw, blk, prof_id);
1145 status = ICE_ERR_DOES_NOT_EXIST;
1149 /* prof becomes invalid after the call */
1150 status = ice_flow_rem_prof_sync(hw, blk, prof);
1153 ice_release_lock(&hw->fl_profs_locks[blk]);
1159 * ice_flow_set_fld_ext - specifies locations of field from entry's input buffer
1160 * @seg: packet segment the field being set belongs to
1161 * @fld: field to be set
1162 * @field_type: type of the field
1163 * @val_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of the value to match from
1164 * entry's input buffer
1165 * @mask_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of mask value from entry's
1167 * @last_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of last/upper value from
1168 * entry's input buffer
1170 * This helper function stores information of a field being matched, including
1171 * the type of the field and the locations of the value to match, the mask, and
1172 * the upper-bound value in the start of the input buffer for a flow entry.
1173 * This function should only be used for fixed-size data structures.
1175 * This function also opportunistically determines the protocol headers to be
1176 * present based on the fields being set. Some fields cannot be used alone to
1177 * determine the protocol headers present. Sometimes, fields for particular
1178 * protocol headers are not matched. In those cases, the protocol headers
1179 * must be explicitly set.
1182 ice_flow_set_fld_ext(struct ice_flow_seg_info *seg, enum ice_flow_field fld,
1183 enum ice_flow_fld_match_type field_type, u16 val_loc,
1184 u16 mask_loc, u16 last_loc)
1186 u64 bit = BIT_ULL(fld);
1189 if (field_type == ICE_FLOW_FLD_TYPE_RANGE)
1192 seg->fields[fld].type = field_type;
1193 seg->fields[fld].src.val = val_loc;
1194 seg->fields[fld].src.mask = mask_loc;
1195 seg->fields[fld].src.last = last_loc;
1197 ICE_FLOW_SET_HDRS(seg, ice_flds_info[fld].hdr);
1201 * ice_flow_set_fld - specifies locations of field from entry's input buffer
1202 * @seg: packet segment the field being set belongs to
1203 * @fld: field to be set
1204 * @val_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of the value to match from
1205 * entry's input buffer
1206 * @mask_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of mask value from entry's
1208 * @last_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of last/upper value from
1209 * entry's input buffer
1210 * @range: indicate if field being matched is to be in a range
1212 * This function specifies the locations, in the form of byte offsets from the
1213 * start of the input buffer for a flow entry, from where the value to match,
1214 * the mask value, and upper value can be extracted. These locations are then
1215 * stored in the flow profile. When adding a flow entry associated with the
1216 * flow profile, these locations will be used to quickly extract the values and
1217 * create the content of a match entry. This function should only be used for
1218 * fixed-size data structures.
1221 ice_flow_set_fld(struct ice_flow_seg_info *seg, enum ice_flow_field fld,
1222 u16 val_loc, u16 mask_loc, u16 last_loc, bool range)
1224 enum ice_flow_fld_match_type t = range ?
1225 ICE_FLOW_FLD_TYPE_RANGE : ICE_FLOW_FLD_TYPE_REG;
1227 ice_flow_set_fld_ext(seg, fld, t, val_loc, mask_loc, last_loc);
1231 * ice_flow_set_fld_prefix - sets locations of prefix field from entry's buf
1232 * @seg: packet segment the field being set belongs to
1233 * @fld: field to be set
1234 * @val_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of the value to match from
1235 * entry's input buffer
1236 * @pref_loc: location of prefix value from entry's input buffer
1237 * @pref_sz: size of the location holding the prefix value
1239 * This function specifies the locations, in the form of byte offsets from the
1240 * start of the input buffer for a flow entry, from where the value to match
1241 * and the IPv4 prefix value can be extracted. These locations are then stored
1242 * in the flow profile. When adding flow entries to the associated flow profile,
1243 * these locations can be used to quickly extract the values to create the
1244 * content of a match entry. This function should only be used for fixed-size
1248 ice_flow_set_fld_prefix(struct ice_flow_seg_info *seg, enum ice_flow_field fld,
1249 u16 val_loc, u16 pref_loc, u8 pref_sz)
1251 /* For this type of field, the "mask" location is for the prefix value's
1252 * location and the "last" location is for the size of the location of
1255 ice_flow_set_fld_ext(seg, fld, ICE_FLOW_FLD_TYPE_PREFIX, val_loc,
1256 pref_loc, (u16)pref_sz);
1259 #define ICE_FLOW_RSS_SEG_HDR_L3_MASKS \
1260 (ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_IPV6)
1262 #define ICE_FLOW_RSS_SEG_HDR_L4_MASKS \
1263 (ICE_FLOW_SEG_HDR_TCP | ICE_FLOW_SEG_HDR_UDP | ICE_FLOW_SEG_HDR_SCTP)
1265 #define ICE_FLOW_RSS_SEG_HDR_VAL_MASKS \
1266 (ICE_FLOW_RSS_SEG_HDR_L3_MASKS | \
1267 ICE_FLOW_RSS_SEG_HDR_L4_MASKS)
1270 * ice_flow_set_rss_seg_info - setup packet segments for RSS
1271 * @segs: pointer to the flow field segment(s)
1272 * @hash_fields: fields to be hashed on for the segment(s)
1273 * @flow_hdr: protocol header fields within a packet segment
1275 * Helper function to extract fields from hash bitmap and use flow
1276 * header value to set flow field segment for further use in flow
1277 * profile entry or removal.
1279 static enum ice_status
1280 ice_flow_set_rss_seg_info(struct ice_flow_seg_info *segs, u64 hash_fields,
1286 ice_for_each_set_bit(i, (ice_bitmap_t *)&hash_fields,
1287 ICE_FLOW_FIELD_IDX_MAX)
1288 ice_flow_set_fld(segs, (enum ice_flow_field)i,
1289 ICE_FLOW_FLD_OFF_INVAL, ICE_FLOW_FLD_OFF_INVAL,
1290 ICE_FLOW_FLD_OFF_INVAL, false);
1292 ICE_FLOW_SET_HDRS(segs, flow_hdr);
1294 if (segs->hdrs & ~ICE_FLOW_RSS_SEG_HDR_VAL_MASKS)
1295 return ICE_ERR_PARAM;
1297 val = (u64)(segs->hdrs & ICE_FLOW_RSS_SEG_HDR_L3_MASKS);
1298 if (val && !ice_is_pow2(val))
1301 val = (u64)(segs->hdrs & ICE_FLOW_RSS_SEG_HDR_L4_MASKS);
1302 if (val && !ice_is_pow2(val))
1309 * ice_rem_vsi_rss_list - remove VSI from RSS list
1310 * @hw: pointer to the hardware structure
1311 * @vsi_handle: software VSI handle
1313 * Remove the VSI from all RSS configurations in the list.
1315 void ice_rem_vsi_rss_list(struct ice_hw *hw, u16 vsi_handle)
1317 struct ice_rss_cfg *r, *tmp;
1319 if (LIST_EMPTY(&hw->rss_list_head))
1322 ice_acquire_lock(&hw->rss_locks);
1323 LIST_FOR_EACH_ENTRY_SAFE(r, tmp, &hw->rss_list_head,
1324 ice_rss_cfg, l_entry)
1325 if (ice_test_and_clear_bit(vsi_handle, r->vsis))
1326 if (!ice_is_any_bit_set(r->vsis, ICE_MAX_VSI)) {
1327 LIST_DEL(&r->l_entry);
1330 ice_release_lock(&hw->rss_locks);
1334 * ice_rem_vsi_rss_cfg - remove RSS configurations associated with VSI
1335 * @hw: pointer to the hardware structure
1336 * @vsi_handle: software VSI handle
1338 * This function will iterate through all flow profiles and disassociate
1339 * the VSI from that profile. If the flow profile has no VSIs it will
1342 enum ice_status ice_rem_vsi_rss_cfg(struct ice_hw *hw, u16 vsi_handle)
1344 const enum ice_block blk = ICE_BLK_RSS;
1345 struct ice_flow_prof *p, *t;
1346 enum ice_status status = ICE_SUCCESS;
1348 if (!ice_is_vsi_valid(hw, vsi_handle))
1349 return ICE_ERR_PARAM;
1351 if (LIST_EMPTY(&hw->fl_profs[blk]))
1354 ice_acquire_lock(&hw->rss_locks);
1355 LIST_FOR_EACH_ENTRY_SAFE(p, t, &hw->fl_profs[blk], ice_flow_prof,
1357 if (ice_is_bit_set(p->vsis, vsi_handle)) {
1358 status = ice_flow_disassoc_prof(hw, blk, p, vsi_handle);
1362 if (!ice_is_any_bit_set(p->vsis, ICE_MAX_VSI)) {
1363 status = ice_flow_rem_prof(hw, blk, p->id);
1368 ice_release_lock(&hw->rss_locks);
1374 * ice_rem_rss_list - remove RSS configuration from list
1375 * @hw: pointer to the hardware structure
1376 * @vsi_handle: software VSI handle
1377 * @prof: pointer to flow profile
1379 * Assumption: lock has already been acquired for RSS list
1382 ice_rem_rss_list(struct ice_hw *hw, u16 vsi_handle, struct ice_flow_prof *prof)
1384 struct ice_rss_cfg *r, *tmp;
1386 /* Search for RSS hash fields associated to the VSI that match the
1387 * hash configurations associated to the flow profile. If found
1388 * remove from the RSS entry list of the VSI context and delete entry.
1390 LIST_FOR_EACH_ENTRY_SAFE(r, tmp, &hw->rss_list_head,
1391 ice_rss_cfg, l_entry)
1392 if (r->hashed_flds == prof->segs[prof->segs_cnt - 1].match &&
1393 r->packet_hdr == prof->segs[prof->segs_cnt - 1].hdrs) {
1394 ice_clear_bit(vsi_handle, r->vsis);
1395 if (!ice_is_any_bit_set(r->vsis, ICE_MAX_VSI)) {
1396 LIST_DEL(&r->l_entry);
1404 * ice_add_rss_list - add RSS configuration to list
1405 * @hw: pointer to the hardware structure
1406 * @vsi_handle: software VSI handle
1407 * @prof: pointer to flow profile
1409 * Assumption: lock has already been acquired for RSS list
1411 static enum ice_status
1412 ice_add_rss_list(struct ice_hw *hw, u16 vsi_handle, struct ice_flow_prof *prof)
1414 struct ice_rss_cfg *r, *rss_cfg;
1416 LIST_FOR_EACH_ENTRY(r, &hw->rss_list_head,
1417 ice_rss_cfg, l_entry)
1418 if (r->hashed_flds == prof->segs[prof->segs_cnt - 1].match &&
1419 r->packet_hdr == prof->segs[prof->segs_cnt - 1].hdrs) {
1420 ice_set_bit(vsi_handle, r->vsis);
1424 rss_cfg = (struct ice_rss_cfg *)ice_malloc(hw, sizeof(*rss_cfg));
1426 return ICE_ERR_NO_MEMORY;
1428 rss_cfg->hashed_flds = prof->segs[prof->segs_cnt - 1].match;
1429 rss_cfg->packet_hdr = prof->segs[prof->segs_cnt - 1].hdrs;
1430 ice_set_bit(vsi_handle, rss_cfg->vsis);
1432 LIST_ADD_TAIL(&rss_cfg->l_entry, &hw->rss_list_head);
1437 #define ICE_FLOW_PROF_HASH_S 0
1438 #define ICE_FLOW_PROF_HASH_M (0xFFFFFFFFULL << ICE_FLOW_PROF_HASH_S)
1439 #define ICE_FLOW_PROF_HDR_S 32
1440 #define ICE_FLOW_PROF_HDR_M (0x3FFFFFFFULL << ICE_FLOW_PROF_HDR_S)
1441 #define ICE_FLOW_PROF_ENCAP_S 63
1442 #define ICE_FLOW_PROF_ENCAP_M (BIT_ULL(ICE_FLOW_PROF_ENCAP_S))
1444 #define ICE_RSS_OUTER_HEADERS 1
1445 #define ICE_RSS_INNER_HEADERS 2
1447 /* Flow profile ID format:
1448 * [0:31] - Packet match fields
1449 * [32:62] - Protocol header
1450 * [63] - Encapsulation flag, 0 if non-tunneled, 1 if tunneled
1452 #define ICE_FLOW_GEN_PROFID(hash, hdr, segs_cnt) \
1453 (u64)(((u64)(hash) & ICE_FLOW_PROF_HASH_M) | \
1454 (((u64)(hdr) << ICE_FLOW_PROF_HDR_S) & ICE_FLOW_PROF_HDR_M) | \
1455 ((u8)((segs_cnt) - 1) ? ICE_FLOW_PROF_ENCAP_M : 0))
1458 * ice_add_rss_cfg_sync - add an RSS configuration
1459 * @hw: pointer to the hardware structure
1460 * @vsi_handle: software VSI handle
1461 * @hashed_flds: hash bit fields (ICE_FLOW_HASH_*) to configure
1462 * @addl_hdrs: protocol header fields
1463 * @segs_cnt: packet segment count
1465 * Assumption: lock has already been acquired for RSS list
1467 static enum ice_status
1468 ice_add_rss_cfg_sync(struct ice_hw *hw, u16 vsi_handle, u64 hashed_flds,
1469 u32 addl_hdrs, u8 segs_cnt)
1471 const enum ice_block blk = ICE_BLK_RSS;
1472 struct ice_flow_prof *prof = NULL;
1473 struct ice_flow_seg_info *segs;
1474 enum ice_status status;
1476 if (!segs_cnt || segs_cnt > ICE_FLOW_SEG_MAX)
1477 return ICE_ERR_PARAM;
1479 segs = (struct ice_flow_seg_info *)ice_calloc(hw, segs_cnt,
1482 return ICE_ERR_NO_MEMORY;
1484 /* Construct the packet segment info from the hashed fields */
1485 status = ice_flow_set_rss_seg_info(&segs[segs_cnt - 1], hashed_flds,
1490 /* Search for a flow profile that has matching headers, hash fields
1491 * and has the input VSI associated to it. If found, no further
1492 * operations required and exit.
1494 prof = ice_flow_find_prof_conds(hw, blk, ICE_FLOW_RX, segs, segs_cnt,
1496 ICE_FLOW_FIND_PROF_CHK_FLDS |
1497 ICE_FLOW_FIND_PROF_CHK_VSI);
1501 /* Check if a flow profile exists with the same protocol headers and
1502 * associated with the input VSI. If so disassociate the VSI from
1503 * this profile. The VSI will be added to a new profile created with
1504 * the protocol header and new hash field configuration.
1506 prof = ice_flow_find_prof_conds(hw, blk, ICE_FLOW_RX, segs, segs_cnt,
1507 vsi_handle, ICE_FLOW_FIND_PROF_CHK_VSI);
1509 status = ice_flow_disassoc_prof(hw, blk, prof, vsi_handle);
1511 ice_rem_rss_list(hw, vsi_handle, prof);
1515 /* Remove profile if it has no VSIs associated */
1516 if (!ice_is_any_bit_set(prof->vsis, ICE_MAX_VSI)) {
1517 status = ice_flow_rem_prof(hw, blk, prof->id);
1523 /* Search for a profile that has same match fields only. If this
1524 * exists then associate the VSI to this profile.
1526 prof = ice_flow_find_prof_conds(hw, blk, ICE_FLOW_RX, segs, segs_cnt,
1528 ICE_FLOW_FIND_PROF_CHK_FLDS);
1530 status = ice_flow_assoc_prof(hw, blk, prof, vsi_handle);
1532 status = ice_add_rss_list(hw, vsi_handle, prof);
1536 /* Create a new flow profile with generated profile and packet
1537 * segment information.
1539 status = ice_flow_add_prof(hw, blk, ICE_FLOW_RX,
1540 ICE_FLOW_GEN_PROFID(hashed_flds,
1541 segs[segs_cnt - 1].hdrs,
1543 segs, segs_cnt, NULL, 0, &prof);
1547 status = ice_flow_assoc_prof(hw, blk, prof, vsi_handle);
1548 /* If association to a new flow profile failed then this profile can
1552 ice_flow_rem_prof(hw, blk, prof->id);
1556 status = ice_add_rss_list(hw, vsi_handle, prof);
1564 * ice_add_rss_cfg - add an RSS configuration with specified hashed fields
1565 * @hw: pointer to the hardware structure
1566 * @vsi_handle: software VSI handle
1567 * @hashed_flds: hash bit fields (ICE_FLOW_HASH_*) to configure
1568 * @addl_hdrs: protocol header fields
1570 * This function will generate a flow profile based on fields associated with
1571 * the input fields to hash on, the flow type and use the VSI number to add
1572 * a flow entry to the profile.
1575 ice_add_rss_cfg(struct ice_hw *hw, u16 vsi_handle, u64 hashed_flds,
1578 enum ice_status status;
1580 if (hashed_flds == ICE_HASH_INVALID ||
1581 !ice_is_vsi_valid(hw, vsi_handle))
1582 return ICE_ERR_PARAM;
1584 ice_acquire_lock(&hw->rss_locks);
1585 status = ice_add_rss_cfg_sync(hw, vsi_handle, hashed_flds, addl_hdrs,
1586 ICE_RSS_OUTER_HEADERS);
1588 status = ice_add_rss_cfg_sync(hw, vsi_handle, hashed_flds,
1589 addl_hdrs, ICE_RSS_INNER_HEADERS);
1590 ice_release_lock(&hw->rss_locks);
1596 * ice_rem_rss_cfg_sync - remove an existing RSS configuration
1597 * @hw: pointer to the hardware structure
1598 * @vsi_handle: software VSI handle
1599 * @hashed_flds: Packet hash types (ICE_FLOW_HASH_*) to remove
1600 * @addl_hdrs: Protocol header fields within a packet segment
1601 * @segs_cnt: packet segment count
1603 * Assumption: lock has already been acquired for RSS list
1605 static enum ice_status
1606 ice_rem_rss_cfg_sync(struct ice_hw *hw, u16 vsi_handle, u64 hashed_flds,
1607 u32 addl_hdrs, u8 segs_cnt)
1609 const enum ice_block blk = ICE_BLK_RSS;
1610 struct ice_flow_seg_info *segs;
1611 struct ice_flow_prof *prof;
1612 enum ice_status status;
1614 segs = (struct ice_flow_seg_info *)ice_calloc(hw, segs_cnt,
1617 return ICE_ERR_NO_MEMORY;
1619 /* Construct the packet segment info from the hashed fields */
1620 status = ice_flow_set_rss_seg_info(&segs[segs_cnt - 1], hashed_flds,
1625 prof = ice_flow_find_prof_conds(hw, blk, ICE_FLOW_RX, segs, segs_cnt,
1627 ICE_FLOW_FIND_PROF_CHK_FLDS);
1629 status = ICE_ERR_DOES_NOT_EXIST;
1633 status = ice_flow_disassoc_prof(hw, blk, prof, vsi_handle);
1637 /* Remove RSS configuration from VSI context before deleting
1640 ice_rem_rss_list(hw, vsi_handle, prof);
1642 if (!ice_is_any_bit_set(prof->vsis, ICE_MAX_VSI))
1643 status = ice_flow_rem_prof(hw, blk, prof->id);
1651 * ice_rem_rss_cfg - remove an existing RSS config with matching hashed fields
1652 * @hw: pointer to the hardware structure
1653 * @vsi_handle: software VSI handle
1654 * @hashed_flds: Packet hash types (ICE_FLOW_HASH_*) to remove
1655 * @addl_hdrs: Protocol header fields within a packet segment
1657 * This function will lookup the flow profile based on the input
1658 * hash field bitmap, iterate through the profile entry list of
1659 * that profile and find entry associated with input VSI to be
1660 * removed. Calls are made to underlying flow apis which will in
1661 * turn build or update buffers for RSS XLT1 section.
1664 ice_rem_rss_cfg(struct ice_hw *hw, u16 vsi_handle, u64 hashed_flds,
1667 enum ice_status status;
1669 if (hashed_flds == ICE_HASH_INVALID ||
1670 !ice_is_vsi_valid(hw, vsi_handle))
1671 return ICE_ERR_PARAM;
1673 ice_acquire_lock(&hw->rss_locks);
1674 status = ice_rem_rss_cfg_sync(hw, vsi_handle, hashed_flds, addl_hdrs,
1675 ICE_RSS_OUTER_HEADERS);
1677 status = ice_rem_rss_cfg_sync(hw, vsi_handle, hashed_flds,
1678 addl_hdrs, ICE_RSS_INNER_HEADERS);
1679 ice_release_lock(&hw->rss_locks);
1684 /* Mapping of AVF hash bit fields to an L3-L4 hash combination.
1685 * As the ice_flow_avf_hdr_field represent individual bit shifts in a hash,
1686 * convert its values to their appropriate flow L3, L4 values.
1688 #define ICE_FLOW_AVF_RSS_IPV4_MASKS \
1689 (BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_OTHER) | \
1690 BIT_ULL(ICE_AVF_FLOW_FIELD_FRAG_IPV4))
1691 #define ICE_FLOW_AVF_RSS_TCP_IPV4_MASKS \
1692 (BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_TCP_SYN_NO_ACK) | \
1693 BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_TCP))
1694 #define ICE_FLOW_AVF_RSS_UDP_IPV4_MASKS \
1695 (BIT_ULL(ICE_AVF_FLOW_FIELD_UNICAST_IPV4_UDP) | \
1696 BIT_ULL(ICE_AVF_FLOW_FIELD_MULTICAST_IPV4_UDP) | \
1697 BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_UDP))
1698 #define ICE_FLOW_AVF_RSS_ALL_IPV4_MASKS \
1699 (ICE_FLOW_AVF_RSS_TCP_IPV4_MASKS | ICE_FLOW_AVF_RSS_UDP_IPV4_MASKS | \
1700 ICE_FLOW_AVF_RSS_IPV4_MASKS | BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_SCTP))
1702 #define ICE_FLOW_AVF_RSS_IPV6_MASKS \
1703 (BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_OTHER) | \
1704 BIT_ULL(ICE_AVF_FLOW_FIELD_FRAG_IPV6))
1705 #define ICE_FLOW_AVF_RSS_UDP_IPV6_MASKS \
1706 (BIT_ULL(ICE_AVF_FLOW_FIELD_UNICAST_IPV6_UDP) | \
1707 BIT_ULL(ICE_AVF_FLOW_FIELD_MULTICAST_IPV6_UDP) | \
1708 BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_UDP))
1709 #define ICE_FLOW_AVF_RSS_TCP_IPV6_MASKS \
1710 (BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_TCP_SYN_NO_ACK) | \
1711 BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_TCP))
1712 #define ICE_FLOW_AVF_RSS_ALL_IPV6_MASKS \
1713 (ICE_FLOW_AVF_RSS_TCP_IPV6_MASKS | ICE_FLOW_AVF_RSS_UDP_IPV6_MASKS | \
1714 ICE_FLOW_AVF_RSS_IPV6_MASKS | BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_SCTP))
1717 * ice_add_avf_rss_cfg - add an RSS configuration for AVF driver
1718 * @hw: pointer to the hardware structure
1719 * @vsi_handle: software VSI handle
1720 * @avf_hash: hash bit fields (ICE_AVF_FLOW_FIELD_*) to configure
1722 * This function will take the hash bitmap provided by the AVF driver via a
1723 * message, convert it to ICE-compatible values, and configure RSS flow
1727 ice_add_avf_rss_cfg(struct ice_hw *hw, u16 vsi_handle, u64 avf_hash)
1729 enum ice_status status = ICE_SUCCESS;
1732 if (avf_hash == ICE_AVF_FLOW_FIELD_INVALID ||
1733 !ice_is_vsi_valid(hw, vsi_handle))
1734 return ICE_ERR_PARAM;
1736 /* Make sure no unsupported bits are specified */
1737 if (avf_hash & ~(ICE_FLOW_AVF_RSS_ALL_IPV4_MASKS |
1738 ICE_FLOW_AVF_RSS_ALL_IPV6_MASKS))
1741 hash_flds = avf_hash;
1743 /* Always create an L3 RSS configuration for any L4 RSS configuration */
1744 if (hash_flds & ICE_FLOW_AVF_RSS_ALL_IPV4_MASKS)
1745 hash_flds |= ICE_FLOW_AVF_RSS_IPV4_MASKS;
1747 if (hash_flds & ICE_FLOW_AVF_RSS_ALL_IPV6_MASKS)
1748 hash_flds |= ICE_FLOW_AVF_RSS_IPV6_MASKS;
1750 /* Create the corresponding RSS configuration for each valid hash bit */
1752 u64 rss_hash = ICE_HASH_INVALID;
1754 if (hash_flds & ICE_FLOW_AVF_RSS_ALL_IPV4_MASKS) {
1755 if (hash_flds & ICE_FLOW_AVF_RSS_IPV4_MASKS) {
1756 rss_hash = ICE_FLOW_HASH_IPV4;
1757 hash_flds &= ~ICE_FLOW_AVF_RSS_IPV4_MASKS;
1758 } else if (hash_flds &
1759 ICE_FLOW_AVF_RSS_TCP_IPV4_MASKS) {
1760 rss_hash = ICE_FLOW_HASH_IPV4 |
1761 ICE_FLOW_HASH_TCP_PORT;
1762 hash_flds &= ~ICE_FLOW_AVF_RSS_TCP_IPV4_MASKS;
1763 } else if (hash_flds &
1764 ICE_FLOW_AVF_RSS_UDP_IPV4_MASKS) {
1765 rss_hash = ICE_FLOW_HASH_IPV4 |
1766 ICE_FLOW_HASH_UDP_PORT;
1767 hash_flds &= ~ICE_FLOW_AVF_RSS_UDP_IPV4_MASKS;
1768 } else if (hash_flds &
1769 BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_SCTP)) {
1770 rss_hash = ICE_FLOW_HASH_IPV4 |
1771 ICE_FLOW_HASH_SCTP_PORT;
1773 ~BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_SCTP);
1775 } else if (hash_flds & ICE_FLOW_AVF_RSS_ALL_IPV6_MASKS) {
1776 if (hash_flds & ICE_FLOW_AVF_RSS_IPV6_MASKS) {
1777 rss_hash = ICE_FLOW_HASH_IPV6;
1778 hash_flds &= ~ICE_FLOW_AVF_RSS_IPV6_MASKS;
1779 } else if (hash_flds &
1780 ICE_FLOW_AVF_RSS_TCP_IPV6_MASKS) {
1781 rss_hash = ICE_FLOW_HASH_IPV6 |
1782 ICE_FLOW_HASH_TCP_PORT;
1783 hash_flds &= ~ICE_FLOW_AVF_RSS_TCP_IPV6_MASKS;
1784 } else if (hash_flds &
1785 ICE_FLOW_AVF_RSS_UDP_IPV6_MASKS) {
1786 rss_hash = ICE_FLOW_HASH_IPV6 |
1787 ICE_FLOW_HASH_UDP_PORT;
1788 hash_flds &= ~ICE_FLOW_AVF_RSS_UDP_IPV6_MASKS;
1789 } else if (hash_flds &
1790 BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_SCTP)) {
1791 rss_hash = ICE_FLOW_HASH_IPV6 |
1792 ICE_FLOW_HASH_SCTP_PORT;
1794 ~BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_SCTP);
1798 if (rss_hash == ICE_HASH_INVALID)
1799 return ICE_ERR_OUT_OF_RANGE;
1801 status = ice_add_rss_cfg(hw, vsi_handle, rss_hash,
1802 ICE_FLOW_SEG_HDR_NONE);
1811 * ice_replay_rss_cfg - replay RSS configurations associated with VSI
1812 * @hw: pointer to the hardware structure
1813 * @vsi_handle: software VSI handle
1815 enum ice_status ice_replay_rss_cfg(struct ice_hw *hw, u16 vsi_handle)
1817 enum ice_status status = ICE_SUCCESS;
1818 struct ice_rss_cfg *r;
1820 if (!ice_is_vsi_valid(hw, vsi_handle))
1821 return ICE_ERR_PARAM;
1823 ice_acquire_lock(&hw->rss_locks);
1824 LIST_FOR_EACH_ENTRY(r, &hw->rss_list_head,
1825 ice_rss_cfg, l_entry) {
1826 if (ice_is_bit_set(r->vsis, vsi_handle)) {
1827 status = ice_add_rss_cfg_sync(hw, vsi_handle,
1830 ICE_RSS_OUTER_HEADERS);
1833 status = ice_add_rss_cfg_sync(hw, vsi_handle,
1836 ICE_RSS_INNER_HEADERS);
1841 ice_release_lock(&hw->rss_locks);
1847 * ice_get_rss_cfg - returns hashed fields for the given header types
1848 * @hw: pointer to the hardware structure
1849 * @vsi_handle: software VSI handle
1850 * @hdrs: protocol header type
1852 * This function will return the match fields of the first instance of flow
1853 * profile having the given header types and containing input VSI
1855 u64 ice_get_rss_cfg(struct ice_hw *hw, u16 vsi_handle, u32 hdrs)
1857 u64 rss_hash = ICE_HASH_INVALID;
1858 struct ice_rss_cfg *r;
1860 /* verify if the protocol header is non zero and VSI is valid */
1861 if (hdrs == ICE_FLOW_SEG_HDR_NONE || !ice_is_vsi_valid(hw, vsi_handle))
1862 return ICE_HASH_INVALID;
1864 ice_acquire_lock(&hw->rss_locks);
1865 LIST_FOR_EACH_ENTRY(r, &hw->rss_list_head,
1866 ice_rss_cfg, l_entry)
1867 if (ice_is_bit_set(r->vsis, vsi_handle) &&
1868 r->packet_hdr == hdrs) {
1869 rss_hash = r->hashed_flds;
1872 ice_release_lock(&hw->rss_locks);