1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (c) 2019, Intel Corporation. */
4 #include "ice_common.h"
8 /* Describe properties of a protocol header field */
9 struct ice_flow_field_info {
10 enum ice_flow_seg_hdr hdr;
11 s16 off; /* Offset from start of a protocol header, in bits */
12 u16 size; /* Size of fields in bits */
13 u16 mask; /* 16-bit mask for field */
16 #define ICE_FLOW_FLD_INFO(_hdr, _offset_bytes, _size_bytes) { \
18 .off = (_offset_bytes) * BITS_PER_BYTE, \
19 .size = (_size_bytes) * BITS_PER_BYTE, \
23 #define ICE_FLOW_FLD_INFO_MSK(_hdr, _offset_bytes, _size_bytes, _mask) { \
25 .off = (_offset_bytes) * BITS_PER_BYTE, \
26 .size = (_size_bytes) * BITS_PER_BYTE, \
30 /* Table containing properties of supported protocol header fields */
32 struct ice_flow_field_info ice_flds_info[ICE_FLOW_FIELD_IDX_MAX] = {
34 /* ICE_FLOW_FIELD_IDX_ETH_DA */
35 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ETH, 0, ETH_ALEN),
36 /* ICE_FLOW_FIELD_IDX_ETH_SA */
37 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ETH, ETH_ALEN, ETH_ALEN),
38 /* ICE_FLOW_FIELD_IDX_S_VLAN */
39 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_VLAN, 12, sizeof(__be16)),
40 /* ICE_FLOW_FIELD_IDX_C_VLAN */
41 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_VLAN, 14, sizeof(__be16)),
42 /* ICE_FLOW_FIELD_IDX_ETH_TYPE */
43 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ETH, 0, sizeof(__be16)),
45 /* ICE_FLOW_FIELD_IDX_IPV4_DSCP */
46 ICE_FLOW_FLD_INFO_MSK(ICE_FLOW_SEG_HDR_IPV4, 0, 1, 0x00fc),
47 /* ICE_FLOW_FIELD_IDX_IPV6_DSCP */
48 ICE_FLOW_FLD_INFO_MSK(ICE_FLOW_SEG_HDR_IPV6, 0, 1, 0x0ff0),
49 /* ICE_FLOW_FIELD_IDX_IPV4_TTL */
50 ICE_FLOW_FLD_INFO_MSK(ICE_FLOW_SEG_HDR_NONE, 8, 1, 0xff00),
51 /* ICE_FLOW_FIELD_IDX_IPV4_PROT */
52 ICE_FLOW_FLD_INFO_MSK(ICE_FLOW_SEG_HDR_NONE, 8, 1, 0x00ff),
53 /* ICE_FLOW_FIELD_IDX_IPV6_TTL */
54 ICE_FLOW_FLD_INFO_MSK(ICE_FLOW_SEG_HDR_NONE, 6, 1, 0x00ff),
55 /* ICE_FLOW_FIELD_IDX_IPV6_PROT */
56 ICE_FLOW_FLD_INFO_MSK(ICE_FLOW_SEG_HDR_NONE, 6, 1, 0xff00),
57 /* ICE_FLOW_FIELD_IDX_IPV4_SA */
58 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV4, 12, sizeof(struct in_addr)),
59 /* ICE_FLOW_FIELD_IDX_IPV4_DA */
60 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV4, 16, sizeof(struct in_addr)),
61 /* ICE_FLOW_FIELD_IDX_IPV6_SA */
62 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV6, 8, sizeof(struct in6_addr)),
63 /* ICE_FLOW_FIELD_IDX_IPV6_DA */
64 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV6, 24, sizeof(struct in6_addr)),
66 /* ICE_FLOW_FIELD_IDX_TCP_SRC_PORT */
67 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_TCP, 0, sizeof(__be16)),
68 /* ICE_FLOW_FIELD_IDX_TCP_DST_PORT */
69 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_TCP, 2, sizeof(__be16)),
70 /* ICE_FLOW_FIELD_IDX_UDP_SRC_PORT */
71 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_UDP, 0, sizeof(__be16)),
72 /* ICE_FLOW_FIELD_IDX_UDP_DST_PORT */
73 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_UDP, 2, sizeof(__be16)),
74 /* ICE_FLOW_FIELD_IDX_SCTP_SRC_PORT */
75 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_SCTP, 0, sizeof(__be16)),
76 /* ICE_FLOW_FIELD_IDX_SCTP_DST_PORT */
77 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_SCTP, 2, sizeof(__be16)),
78 /* ICE_FLOW_FIELD_IDX_TCP_FLAGS */
79 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_TCP, 13, 1),
81 /* ICE_FLOW_FIELD_IDX_ARP_SIP */
82 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ARP, 14, sizeof(struct in_addr)),
83 /* ICE_FLOW_FIELD_IDX_ARP_DIP */
84 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ARP, 24, sizeof(struct in_addr)),
85 /* ICE_FLOW_FIELD_IDX_ARP_SHA */
86 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ARP, 8, ETH_ALEN),
87 /* ICE_FLOW_FIELD_IDX_ARP_DHA */
88 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ARP, 18, ETH_ALEN),
89 /* ICE_FLOW_FIELD_IDX_ARP_OP */
90 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ARP, 6, sizeof(__be16)),
92 /* ICE_FLOW_FIELD_IDX_ICMP_TYPE */
93 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ICMP, 0, 1),
94 /* ICE_FLOW_FIELD_IDX_ICMP_CODE */
95 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ICMP, 1, 1),
97 /* ICE_FLOW_FIELD_IDX_GRE_KEYID */
98 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_GRE, 12,
99 sizeof_field(struct gre_full_hdr, key)),
101 /* ICE_FLOW_FIELD_IDX_GTPC_TEID */
102 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_GTPC_TEID, 12, sizeof(__be32)),
103 /* ICE_FLOW_FIELD_IDX_GTPU_IP_TEID */
104 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_GTPU_IP, 12, sizeof(__be32)),
105 /* ICE_FLOW_FIELD_IDX_GTPU_EH_TEID */
106 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_GTPU_EH, 12, sizeof(__be32)),
107 /* ICE_FLOW_FIELD_IDX_GTPU_EH_QFI */
108 ICE_FLOW_FLD_INFO_MSK(ICE_FLOW_SEG_HDR_GTPU_EH, 22, sizeof(__be16),
110 /* ICE_FLOW_FIELD_IDX_GTPU_UP_TEID */
111 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_GTPU_UP, 12, sizeof(__be32)),
112 /* ICE_FLOW_FIELD_IDX_GTPU_DWN_TEID */
113 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_GTPU_DWN, 12, sizeof(__be32)),
115 /* ICE_FLOW_FIELD_IDX_PPPOE_SESS_ID */
116 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_PPPOE, 2, sizeof(__be16)),
118 /* ICE_FLOW_FIELD_IDX_PFCP_SEID */
119 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_PFCP_SESSION, 12, sizeof(__be64)),
121 /* ICE_FLOW_FIELD_IDX_L2TPV3_SESS_ID */
122 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_L2TPV3, 0, sizeof(__be32)),
124 /* ICE_FLOW_FIELD_IDX_ESP_SPI */
125 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ESP, 0, sizeof(__be32)),
127 /* ICE_FLOW_FIELD_IDX_AH_SPI */
128 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_AH, 4, sizeof(__be32)),
130 /* ICE_FLOW_FIELD_IDX_NAT_T_ESP_SPI */
131 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_NAT_T_ESP, 8, sizeof(__be32)),
134 /* Bitmaps indicating relevant packet types for a particular protocol header
136 * Packet types for packets with an Outer/First/Single MAC header
138 static const u32 ice_ptypes_mac_ofos[] = {
139 0xFDC00846, 0xBFBF7F7E, 0xF70001DF, 0xFEFDFDFB,
140 0x0000077E, 0x00000000, 0x00000000, 0x00000000,
141 0x00400000, 0x03FFF000, 0x7FFFFFE0, 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,
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,
161 /* Packet types for packets with an Outer/First/Single IPv4 header, does NOT
162 * include IPv4 other PTYPEs
164 static const u32 ice_ptypes_ipv4_ofos[] = {
165 0x1DC00000, 0x04000800, 0x00000000, 0x00000000,
166 0x00000000, 0x00000155, 0x00000000, 0x00000000,
167 0x00000000, 0x000FC000, 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,
175 /* Packet types for packets with an Outer/First/Single IPv4 header, includes
178 static const u32 ice_ptypes_ipv4_ofos_all[] = {
179 0x1DC00000, 0x04000800, 0x00000000, 0x00000000,
180 0x00000000, 0x00000155, 0x00000000, 0x00000000,
181 0x00000000, 0x000FC000, 0x83E0F800, 0x00000101,
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,
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, 0x001FF800, 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,
201 /* Packet types for packets with an Outer/First/Single IPv6 header, does NOT
202 * include IPv6 other PTYPEs
204 static const u32 ice_ptypes_ipv6_ofos[] = {
205 0x00000000, 0x00000000, 0x77000000, 0x10002000,
206 0x00000000, 0x000002AA, 0x00000000, 0x00000000,
207 0x00000000, 0x03F00000, 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,
215 /* Packet types for packets with an Outer/First/Single IPv6 header, includes
218 static const u32 ice_ptypes_ipv6_ofos_all[] = {
219 0x00000000, 0x00000000, 0x77000000, 0x10002000,
220 0x00000000, 0x000002AA, 0x00000000, 0x00000000,
221 0x00080F00, 0x03F00000, 0x7C1F0000, 0x00000206,
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,
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, 0x7FE00000, 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,
241 /* Packet types for packets with an Outer/First/Single IPv4 header - no L4 */
242 static const u32 ice_ptypes_ipv4_ofos_no_l4[] = {
243 0x10C00000, 0x04000800, 0x00000000, 0x00000000,
244 0x00000000, 0x00000000, 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,
253 /* Packet types for packets with an Outermost/First ARP header */
254 static const u32 ice_ptypes_arp_of[] = {
255 0x00000800, 0x00000000, 0x00000000, 0x00000000,
256 0x00000000, 0x00000000, 0x00000000, 0x00000000,
257 0x00000000, 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,
265 /* Packet types for packets with an Innermost/Last IPv4 header - no L4 */
266 static const u32 ice_ptypes_ipv4_il_no_l4[] = {
267 0x60000000, 0x18043008, 0x80000002, 0x6010c021,
268 0x00000008, 0x00000000, 0x00000000, 0x00000000,
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,
277 /* Packet types for packets with an Outer/First/Single IPv6 header - no L4 */
278 static const u32 ice_ptypes_ipv6_ofos_no_l4[] = {
279 0x00000000, 0x00000000, 0x43000000, 0x10002000,
280 0x00000000, 0x00000000, 0x00000000, 0x00000000,
281 0x00000000, 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,
289 /* Packet types for packets with an Innermost/Last IPv6 header - no L4 */
290 static const u32 ice_ptypes_ipv6_il_no_l4[] = {
291 0x00000000, 0x02180430, 0x0000010c, 0x086010c0,
292 0x00000430, 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,
301 /* UDP Packet types for non-tunneled packets or tunneled
302 * packets with inner UDP.
304 static const u32 ice_ptypes_udp_il[] = {
305 0x81000000, 0x20204040, 0x04000010, 0x80810102,
306 0x00000040, 0x00000000, 0x00000000, 0x00000000,
307 0x00000000, 0x00410000, 0x90842000, 0x00000007,
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,
315 /* Packet types for packets with an Innermost/Last TCP header */
316 static const u32 ice_ptypes_tcp_il[] = {
317 0x04000000, 0x80810102, 0x10000040, 0x02040408,
318 0x00000102, 0x00000000, 0x00000000, 0x00000000,
319 0x00000000, 0x00820000, 0x21084000, 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,
327 /* Packet types for packets with an Innermost/Last SCTP header */
328 static const u32 ice_ptypes_sctp_il[] = {
329 0x08000000, 0x01020204, 0x20000081, 0x04080810,
330 0x00000204, 0x00000000, 0x00000000, 0x00000000,
331 0x00000000, 0x01040000, 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,
339 /* Packet types for packets with an Outermost/First ICMP header */
340 static const u32 ice_ptypes_icmp_of[] = {
341 0x10000000, 0x00000000, 0x00000000, 0x00000000,
342 0x00000000, 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,
351 /* Packet types for packets with an Innermost/Last ICMP header */
352 static const u32 ice_ptypes_icmp_il[] = {
353 0x00000000, 0x02040408, 0x40000102, 0x08101020,
354 0x00000408, 0x00000000, 0x00000000, 0x00000000,
355 0x00000000, 0x00000000, 0x42108000, 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,
363 /* Packet types for packets with an Outermost/First GRE header */
364 static const u32 ice_ptypes_gre_of[] = {
365 0x00000000, 0xBFBF7800, 0x000001DF, 0xFEFDE000,
366 0x0000017E, 0x00000000, 0x00000000, 0x00000000,
367 0x00000000, 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,
375 /* Packet types for packets with an Innermost/Last MAC header */
376 static const u32 ice_ptypes_mac_il[] = {
377 0x00000000, 0x00000000, 0x00000000, 0x00000000,
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,
387 /* Packet types for GTPC */
388 static const u32 ice_ptypes_gtpc[] = {
389 0x00000000, 0x00000000, 0x00000000, 0x00000000,
390 0x00000000, 0x00000000, 0x00000000, 0x00000000,
391 0x00000000, 0x00000000, 0x00000180, 0x00000000,
392 0x00000000, 0x00000000, 0x00000000, 0x00000000,
393 0x00000000, 0x00000000, 0x00000000, 0x00000000,
394 0x00000000, 0x00000000, 0x00000000, 0x00000000,
395 0x00000000, 0x00000000, 0x00000000, 0x00000000,
396 0x00000000, 0x00000000, 0x00000000, 0x00000000,
399 /* Packet types for GTPC with TEID */
400 static const u32 ice_ptypes_gtpc_tid[] = {
401 0x00000000, 0x00000000, 0x00000000, 0x00000000,
402 0x00000000, 0x00000000, 0x00000000, 0x00000000,
403 0x00000000, 0x00000000, 0x00000060, 0x00000000,
404 0x00000000, 0x00000000, 0x00000000, 0x00000000,
405 0x00000000, 0x00000000, 0x00000000, 0x00000000,
406 0x00000000, 0x00000000, 0x00000000, 0x00000000,
407 0x00000000, 0x00000000, 0x00000000, 0x00000000,
408 0x00000000, 0x00000000, 0x00000000, 0x00000000,
411 /* Packet types for GTPU */
412 static const struct ice_ptype_attributes ice_attr_gtpu_session[] = {
413 { ICE_MAC_IPV4_GTPU_IPV4_FRAG, ICE_PTYPE_ATTR_GTP_SESSION },
414 { ICE_MAC_IPV4_GTPU_IPV4_PAY, ICE_PTYPE_ATTR_GTP_SESSION },
415 { ICE_MAC_IPV4_GTPU_IPV4_UDP_PAY, ICE_PTYPE_ATTR_GTP_SESSION },
416 { ICE_MAC_IPV4_GTPU_IPV4_TCP, ICE_PTYPE_ATTR_GTP_SESSION },
417 { ICE_MAC_IPV4_GTPU_IPV4_ICMP, ICE_PTYPE_ATTR_GTP_SESSION },
418 { ICE_MAC_IPV6_GTPU_IPV4_FRAG, ICE_PTYPE_ATTR_GTP_SESSION },
419 { ICE_MAC_IPV6_GTPU_IPV4_PAY, ICE_PTYPE_ATTR_GTP_SESSION },
420 { ICE_MAC_IPV6_GTPU_IPV4_UDP_PAY, ICE_PTYPE_ATTR_GTP_SESSION },
421 { ICE_MAC_IPV6_GTPU_IPV4_TCP, ICE_PTYPE_ATTR_GTP_SESSION },
422 { ICE_MAC_IPV6_GTPU_IPV4_ICMP, ICE_PTYPE_ATTR_GTP_SESSION },
423 { ICE_MAC_IPV4_GTPU_IPV6_FRAG, ICE_PTYPE_ATTR_GTP_SESSION },
424 { ICE_MAC_IPV4_GTPU_IPV6_PAY, ICE_PTYPE_ATTR_GTP_SESSION },
425 { ICE_MAC_IPV4_GTPU_IPV6_UDP_PAY, ICE_PTYPE_ATTR_GTP_SESSION },
426 { ICE_MAC_IPV4_GTPU_IPV6_TCP, ICE_PTYPE_ATTR_GTP_SESSION },
427 { ICE_MAC_IPV4_GTPU_IPV6_ICMPV6, ICE_PTYPE_ATTR_GTP_SESSION },
428 { ICE_MAC_IPV6_GTPU_IPV6_FRAG, ICE_PTYPE_ATTR_GTP_SESSION },
429 { ICE_MAC_IPV6_GTPU_IPV6_PAY, ICE_PTYPE_ATTR_GTP_SESSION },
430 { ICE_MAC_IPV6_GTPU_IPV6_UDP_PAY, ICE_PTYPE_ATTR_GTP_SESSION },
431 { ICE_MAC_IPV6_GTPU_IPV6_TCP, ICE_PTYPE_ATTR_GTP_SESSION },
432 { ICE_MAC_IPV6_GTPU_IPV6_ICMPV6, ICE_PTYPE_ATTR_GTP_SESSION },
435 static const struct ice_ptype_attributes ice_attr_gtpu_eh[] = {
436 { ICE_MAC_IPV4_GTPU_IPV4_FRAG, ICE_PTYPE_ATTR_GTP_PDU_EH },
437 { ICE_MAC_IPV4_GTPU_IPV4_PAY, ICE_PTYPE_ATTR_GTP_PDU_EH },
438 { ICE_MAC_IPV4_GTPU_IPV4_UDP_PAY, ICE_PTYPE_ATTR_GTP_PDU_EH },
439 { ICE_MAC_IPV4_GTPU_IPV4_TCP, ICE_PTYPE_ATTR_GTP_PDU_EH },
440 { ICE_MAC_IPV4_GTPU_IPV4_ICMP, ICE_PTYPE_ATTR_GTP_PDU_EH },
441 { ICE_MAC_IPV6_GTPU_IPV4_FRAG, ICE_PTYPE_ATTR_GTP_PDU_EH },
442 { ICE_MAC_IPV6_GTPU_IPV4_PAY, ICE_PTYPE_ATTR_GTP_PDU_EH },
443 { ICE_MAC_IPV6_GTPU_IPV4_UDP_PAY, ICE_PTYPE_ATTR_GTP_PDU_EH },
444 { ICE_MAC_IPV6_GTPU_IPV4_TCP, ICE_PTYPE_ATTR_GTP_PDU_EH },
445 { ICE_MAC_IPV6_GTPU_IPV4_ICMP, ICE_PTYPE_ATTR_GTP_PDU_EH },
446 { ICE_MAC_IPV4_GTPU_IPV6_FRAG, ICE_PTYPE_ATTR_GTP_PDU_EH },
447 { ICE_MAC_IPV4_GTPU_IPV6_PAY, ICE_PTYPE_ATTR_GTP_PDU_EH },
448 { ICE_MAC_IPV4_GTPU_IPV6_UDP_PAY, ICE_PTYPE_ATTR_GTP_PDU_EH },
449 { ICE_MAC_IPV4_GTPU_IPV6_TCP, ICE_PTYPE_ATTR_GTP_PDU_EH },
450 { ICE_MAC_IPV4_GTPU_IPV6_ICMPV6, ICE_PTYPE_ATTR_GTP_PDU_EH },
451 { ICE_MAC_IPV6_GTPU_IPV6_FRAG, ICE_PTYPE_ATTR_GTP_PDU_EH },
452 { ICE_MAC_IPV6_GTPU_IPV6_PAY, ICE_PTYPE_ATTR_GTP_PDU_EH },
453 { ICE_MAC_IPV6_GTPU_IPV6_UDP_PAY, ICE_PTYPE_ATTR_GTP_PDU_EH },
454 { ICE_MAC_IPV6_GTPU_IPV6_TCP, ICE_PTYPE_ATTR_GTP_PDU_EH },
455 { ICE_MAC_IPV6_GTPU_IPV6_ICMPV6, ICE_PTYPE_ATTR_GTP_PDU_EH },
458 static const struct ice_ptype_attributes ice_attr_gtpu_down[] = {
459 { ICE_MAC_IPV4_GTPU_IPV4_FRAG, ICE_PTYPE_ATTR_GTP_DOWNLINK },
460 { ICE_MAC_IPV4_GTPU_IPV4_PAY, ICE_PTYPE_ATTR_GTP_DOWNLINK },
461 { ICE_MAC_IPV4_GTPU_IPV4_UDP_PAY, ICE_PTYPE_ATTR_GTP_DOWNLINK },
462 { ICE_MAC_IPV4_GTPU_IPV4_TCP, ICE_PTYPE_ATTR_GTP_DOWNLINK },
463 { ICE_MAC_IPV4_GTPU_IPV4_ICMP, ICE_PTYPE_ATTR_GTP_DOWNLINK },
464 { ICE_MAC_IPV6_GTPU_IPV4_FRAG, ICE_PTYPE_ATTR_GTP_DOWNLINK },
465 { ICE_MAC_IPV6_GTPU_IPV4_PAY, ICE_PTYPE_ATTR_GTP_DOWNLINK },
466 { ICE_MAC_IPV6_GTPU_IPV4_UDP_PAY, ICE_PTYPE_ATTR_GTP_DOWNLINK },
467 { ICE_MAC_IPV6_GTPU_IPV4_TCP, ICE_PTYPE_ATTR_GTP_DOWNLINK },
468 { ICE_MAC_IPV6_GTPU_IPV4_ICMP, ICE_PTYPE_ATTR_GTP_DOWNLINK },
469 { ICE_MAC_IPV4_GTPU_IPV6_FRAG, ICE_PTYPE_ATTR_GTP_DOWNLINK },
470 { ICE_MAC_IPV4_GTPU_IPV6_PAY, ICE_PTYPE_ATTR_GTP_DOWNLINK },
471 { ICE_MAC_IPV4_GTPU_IPV6_UDP_PAY, ICE_PTYPE_ATTR_GTP_DOWNLINK },
472 { ICE_MAC_IPV4_GTPU_IPV6_TCP, ICE_PTYPE_ATTR_GTP_DOWNLINK },
473 { ICE_MAC_IPV4_GTPU_IPV6_ICMPV6, ICE_PTYPE_ATTR_GTP_DOWNLINK },
474 { ICE_MAC_IPV6_GTPU_IPV6_FRAG, ICE_PTYPE_ATTR_GTP_DOWNLINK },
475 { ICE_MAC_IPV6_GTPU_IPV6_PAY, ICE_PTYPE_ATTR_GTP_DOWNLINK },
476 { ICE_MAC_IPV6_GTPU_IPV6_UDP_PAY, ICE_PTYPE_ATTR_GTP_DOWNLINK },
477 { ICE_MAC_IPV6_GTPU_IPV6_TCP, ICE_PTYPE_ATTR_GTP_DOWNLINK },
478 { ICE_MAC_IPV6_GTPU_IPV6_ICMPV6, ICE_PTYPE_ATTR_GTP_DOWNLINK },
481 static const struct ice_ptype_attributes ice_attr_gtpu_up[] = {
482 { ICE_MAC_IPV4_GTPU_IPV4_FRAG, ICE_PTYPE_ATTR_GTP_UPLINK },
483 { ICE_MAC_IPV4_GTPU_IPV4_PAY, ICE_PTYPE_ATTR_GTP_UPLINK },
484 { ICE_MAC_IPV4_GTPU_IPV4_UDP_PAY, ICE_PTYPE_ATTR_GTP_UPLINK },
485 { ICE_MAC_IPV4_GTPU_IPV4_TCP, ICE_PTYPE_ATTR_GTP_UPLINK },
486 { ICE_MAC_IPV4_GTPU_IPV4_ICMP, ICE_PTYPE_ATTR_GTP_UPLINK },
487 { ICE_MAC_IPV6_GTPU_IPV4_FRAG, ICE_PTYPE_ATTR_GTP_UPLINK },
488 { ICE_MAC_IPV6_GTPU_IPV4_PAY, ICE_PTYPE_ATTR_GTP_UPLINK },
489 { ICE_MAC_IPV6_GTPU_IPV4_UDP_PAY, ICE_PTYPE_ATTR_GTP_UPLINK },
490 { ICE_MAC_IPV6_GTPU_IPV4_TCP, ICE_PTYPE_ATTR_GTP_UPLINK },
491 { ICE_MAC_IPV6_GTPU_IPV4_ICMP, ICE_PTYPE_ATTR_GTP_UPLINK },
492 { ICE_MAC_IPV4_GTPU_IPV6_FRAG, ICE_PTYPE_ATTR_GTP_UPLINK },
493 { ICE_MAC_IPV4_GTPU_IPV6_PAY, ICE_PTYPE_ATTR_GTP_UPLINK },
494 { ICE_MAC_IPV4_GTPU_IPV6_UDP_PAY, ICE_PTYPE_ATTR_GTP_UPLINK },
495 { ICE_MAC_IPV4_GTPU_IPV6_TCP, ICE_PTYPE_ATTR_GTP_UPLINK },
496 { ICE_MAC_IPV4_GTPU_IPV6_ICMPV6, ICE_PTYPE_ATTR_GTP_UPLINK },
497 { ICE_MAC_IPV6_GTPU_IPV6_FRAG, ICE_PTYPE_ATTR_GTP_UPLINK },
498 { ICE_MAC_IPV6_GTPU_IPV6_PAY, ICE_PTYPE_ATTR_GTP_UPLINK },
499 { ICE_MAC_IPV6_GTPU_IPV6_UDP_PAY, ICE_PTYPE_ATTR_GTP_UPLINK },
500 { ICE_MAC_IPV6_GTPU_IPV6_TCP, ICE_PTYPE_ATTR_GTP_UPLINK },
501 { ICE_MAC_IPV6_GTPU_IPV6_ICMPV6, ICE_PTYPE_ATTR_GTP_UPLINK },
504 static const u32 ice_ptypes_gtpu[] = {
505 0x00000000, 0x00000000, 0x00000000, 0x00000000,
506 0x00000000, 0x00000000, 0x00000000, 0x00000000,
507 0x00000000, 0x00000000, 0x7FFFFE00, 0x00000000,
508 0x00000000, 0x00000000, 0x00000000, 0x00000000,
509 0x00000000, 0x00000000, 0x00000000, 0x00000000,
510 0x00000000, 0x00000000, 0x00000000, 0x00000000,
511 0x00000000, 0x00000000, 0x00000000, 0x00000000,
512 0x00000000, 0x00000000, 0x00000000, 0x00000000,
515 /* Packet types for PPPoE */
516 static const u32 ice_ptypes_pppoe[] = {
517 0x00000000, 0x00000000, 0x00000000, 0x00000000,
518 0x00000000, 0x00000000, 0x00000000, 0x00000000,
519 0x00000000, 0x03ffe000, 0x00000000, 0x00000000,
520 0x00000000, 0x00000000, 0x00000000, 0x00000000,
521 0x00000000, 0x00000000, 0x00000000, 0x00000000,
522 0x00000000, 0x00000000, 0x00000000, 0x00000000,
523 0x00000000, 0x00000000, 0x00000000, 0x00000000,
524 0x00000000, 0x00000000, 0x00000000, 0x00000000,
527 /* Packet types for packets with PFCP NODE header */
528 static const u32 ice_ptypes_pfcp_node[] = {
529 0x00000000, 0x00000000, 0x00000000, 0x00000000,
530 0x00000000, 0x00000000, 0x00000000, 0x00000000,
531 0x00000000, 0x00000000, 0x80000000, 0x00000002,
532 0x00000000, 0x00000000, 0x00000000, 0x00000000,
533 0x00000000, 0x00000000, 0x00000000, 0x00000000,
534 0x00000000, 0x00000000, 0x00000000, 0x00000000,
535 0x00000000, 0x00000000, 0x00000000, 0x00000000,
536 0x00000000, 0x00000000, 0x00000000, 0x00000000,
539 /* Packet types for packets with PFCP SESSION header */
540 static const u32 ice_ptypes_pfcp_session[] = {
541 0x00000000, 0x00000000, 0x00000000, 0x00000000,
542 0x00000000, 0x00000000, 0x00000000, 0x00000000,
543 0x00000000, 0x00000000, 0x00000000, 0x00000005,
544 0x00000000, 0x00000000, 0x00000000, 0x00000000,
545 0x00000000, 0x00000000, 0x00000000, 0x00000000,
546 0x00000000, 0x00000000, 0x00000000, 0x00000000,
547 0x00000000, 0x00000000, 0x00000000, 0x00000000,
548 0x00000000, 0x00000000, 0x00000000, 0x00000000,
551 /* Packet types for L2TPv3 */
552 static const u32 ice_ptypes_l2tpv3[] = {
553 0x00000000, 0x00000000, 0x00000000, 0x00000000,
554 0x00000000, 0x00000000, 0x00000000, 0x00000000,
555 0x00000000, 0x00000000, 0x00000000, 0x00000300,
556 0x00000000, 0x00000000, 0x00000000, 0x00000000,
557 0x00000000, 0x00000000, 0x00000000, 0x00000000,
558 0x00000000, 0x00000000, 0x00000000, 0x00000000,
559 0x00000000, 0x00000000, 0x00000000, 0x00000000,
560 0x00000000, 0x00000000, 0x00000000, 0x00000000,
563 /* Packet types for ESP */
564 static const u32 ice_ptypes_esp[] = {
565 0x00000000, 0x00000000, 0x00000000, 0x00000000,
566 0x00000000, 0x00000003, 0x00000000, 0x00000000,
567 0x00000000, 0x00000000, 0x00000000, 0x00000000,
568 0x00000000, 0x00000000, 0x00000000, 0x00000000,
569 0x00000000, 0x00000000, 0x00000000, 0x00000000,
570 0x00000000, 0x00000000, 0x00000000, 0x00000000,
571 0x00000000, 0x00000000, 0x00000000, 0x00000000,
572 0x00000000, 0x00000000, 0x00000000, 0x00000000,
575 /* Packet types for AH */
576 static const u32 ice_ptypes_ah[] = {
577 0x00000000, 0x00000000, 0x00000000, 0x00000000,
578 0x00000000, 0x0000000C, 0x00000000, 0x00000000,
579 0x00000000, 0x00000000, 0x00000000, 0x00000000,
580 0x00000000, 0x00000000, 0x00000000, 0x00000000,
581 0x00000000, 0x00000000, 0x00000000, 0x00000000,
582 0x00000000, 0x00000000, 0x00000000, 0x00000000,
583 0x00000000, 0x00000000, 0x00000000, 0x00000000,
584 0x00000000, 0x00000000, 0x00000000, 0x00000000,
587 /* Packet types for packets with NAT_T ESP header */
588 static const u32 ice_ptypes_nat_t_esp[] = {
589 0x00000000, 0x00000000, 0x00000000, 0x00000000,
590 0x00000000, 0x00000030, 0x00000000, 0x00000000,
591 0x00000000, 0x00000000, 0x00000000, 0x00000000,
592 0x00000000, 0x00000000, 0x00000000, 0x00000000,
593 0x00000000, 0x00000000, 0x00000000, 0x00000000,
594 0x00000000, 0x00000000, 0x00000000, 0x00000000,
595 0x00000000, 0x00000000, 0x00000000, 0x00000000,
596 0x00000000, 0x00000000, 0x00000000, 0x00000000,
599 static const u32 ice_ptypes_mac_non_ip_ofos[] = {
600 0x00000846, 0x00000000, 0x00000000, 0x00000000,
601 0x00000000, 0x00000000, 0x00000000, 0x00000000,
602 0x00400000, 0x03FFF000, 0x00000000, 0x00000000,
603 0x00000000, 0x00000000, 0x00000000, 0x00000000,
604 0x00000000, 0x00000000, 0x00000000, 0x00000000,
605 0x00000000, 0x00000000, 0x00000000, 0x00000000,
606 0x00000000, 0x00000000, 0x00000000, 0x00000000,
607 0x00000000, 0x00000000, 0x00000000, 0x00000000,
610 /* Manage parameters and info. used during the creation of a flow profile */
611 struct ice_flow_prof_params {
613 u16 entry_length; /* # of bytes formatted entry will require */
615 struct ice_flow_prof *prof;
617 /* For ACL, the es[0] will have the data of ICE_RX_MDID_PKT_FLAGS_15_0
618 * This will give us the direction flags.
620 struct ice_fv_word es[ICE_MAX_FV_WORDS];
621 /* attributes can be used to add attributes to a particular PTYPE */
622 const struct ice_ptype_attributes *attr;
625 u16 mask[ICE_MAX_FV_WORDS];
626 DECLARE_BITMAP(ptypes, ICE_FLOW_PTYPE_MAX);
629 #define ICE_FLOW_RSS_HDRS_INNER_MASK \
630 (ICE_FLOW_SEG_HDR_PPPOE | ICE_FLOW_SEG_HDR_GTPC | \
631 ICE_FLOW_SEG_HDR_GTPC_TEID | ICE_FLOW_SEG_HDR_GTPU | \
632 ICE_FLOW_SEG_HDR_PFCP_SESSION | ICE_FLOW_SEG_HDR_L2TPV3 | \
633 ICE_FLOW_SEG_HDR_ESP | ICE_FLOW_SEG_HDR_AH | \
634 ICE_FLOW_SEG_HDR_NAT_T_ESP)
636 #define ICE_FLOW_SEG_HDRS_L3_MASK \
637 (ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_IPV6 | ICE_FLOW_SEG_HDR_ARP)
638 #define ICE_FLOW_SEG_HDRS_L4_MASK \
639 (ICE_FLOW_SEG_HDR_ICMP | ICE_FLOW_SEG_HDR_TCP | ICE_FLOW_SEG_HDR_UDP | \
640 ICE_FLOW_SEG_HDR_SCTP)
641 /* mask for L4 protocols that are NOT part of IPv4/6 OTHER PTYPE groups */
642 #define ICE_FLOW_SEG_HDRS_L4_MASK_NO_OTHER \
643 (ICE_FLOW_SEG_HDR_TCP | ICE_FLOW_SEG_HDR_UDP | ICE_FLOW_SEG_HDR_SCTP)
646 * ice_flow_val_hdrs - validates packet segments for valid protocol headers
647 * @segs: array of one or more packet segments that describe the flow
648 * @segs_cnt: number of packet segments provided
650 static int ice_flow_val_hdrs(struct ice_flow_seg_info *segs, u8 segs_cnt)
654 for (i = 0; i < segs_cnt; i++) {
655 /* Multiple L3 headers */
656 if (segs[i].hdrs & ICE_FLOW_SEG_HDRS_L3_MASK &&
657 !is_power_of_2(segs[i].hdrs & ICE_FLOW_SEG_HDRS_L3_MASK))
660 /* Multiple L4 headers */
661 if (segs[i].hdrs & ICE_FLOW_SEG_HDRS_L4_MASK &&
662 !is_power_of_2(segs[i].hdrs & ICE_FLOW_SEG_HDRS_L4_MASK))
669 /* Sizes of fixed known protocol headers without header options */
670 #define ICE_FLOW_PROT_HDR_SZ_MAC 14
671 #define ICE_FLOW_PROT_HDR_SZ_MAC_VLAN (ICE_FLOW_PROT_HDR_SZ_MAC + 2)
672 #define ICE_FLOW_PROT_HDR_SZ_IPV4 20
673 #define ICE_FLOW_PROT_HDR_SZ_IPV6 40
674 #define ICE_FLOW_PROT_HDR_SZ_ARP 28
675 #define ICE_FLOW_PROT_HDR_SZ_ICMP 8
676 #define ICE_FLOW_PROT_HDR_SZ_TCP 20
677 #define ICE_FLOW_PROT_HDR_SZ_UDP 8
678 #define ICE_FLOW_PROT_HDR_SZ_SCTP 12
681 * ice_flow_calc_seg_sz - calculates size of a packet segment based on headers
682 * @params: information about the flow to be processed
683 * @seg: index of packet segment whose header size is to be determined
685 static u16 ice_flow_calc_seg_sz(struct ice_flow_prof_params *params, u8 seg)
690 sz = (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_VLAN) ?
691 ICE_FLOW_PROT_HDR_SZ_MAC_VLAN : ICE_FLOW_PROT_HDR_SZ_MAC;
694 if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_IPV4)
695 sz += ICE_FLOW_PROT_HDR_SZ_IPV4;
696 else if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_IPV6)
697 sz += ICE_FLOW_PROT_HDR_SZ_IPV6;
698 else if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_ARP)
699 sz += ICE_FLOW_PROT_HDR_SZ_ARP;
700 else if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDRS_L4_MASK)
701 /* An L3 header is required if L4 is specified */
705 if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_ICMP)
706 sz += ICE_FLOW_PROT_HDR_SZ_ICMP;
707 else if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_TCP)
708 sz += ICE_FLOW_PROT_HDR_SZ_TCP;
709 else if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_UDP)
710 sz += ICE_FLOW_PROT_HDR_SZ_UDP;
711 else if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_SCTP)
712 sz += ICE_FLOW_PROT_HDR_SZ_SCTP;
718 * ice_flow_proc_seg_hdrs - process protocol headers present in pkt segments
719 * @params: information about the flow to be processed
721 * This function identifies the packet types associated with the protocol
722 * headers being present in packet segments of the specified flow profile.
724 static int ice_flow_proc_seg_hdrs(struct ice_flow_prof_params *params)
726 struct ice_flow_prof *prof;
729 memset(params->ptypes, 0xff, sizeof(params->ptypes));
733 for (i = 0; i < params->prof->segs_cnt; i++) {
734 const unsigned long *src;
737 hdrs = prof->segs[i].hdrs;
739 if (hdrs & ICE_FLOW_SEG_HDR_ETH) {
740 src = !i ? (const unsigned long *)ice_ptypes_mac_ofos :
741 (const unsigned long *)ice_ptypes_mac_il;
742 bitmap_and(params->ptypes, params->ptypes, src,
746 if (i && hdrs & ICE_FLOW_SEG_HDR_VLAN) {
747 src = (const unsigned long *)ice_ptypes_macvlan_il;
748 bitmap_and(params->ptypes, params->ptypes, src,
752 if (!i && hdrs & ICE_FLOW_SEG_HDR_ARP) {
753 bitmap_and(params->ptypes, params->ptypes,
754 (const unsigned long *)ice_ptypes_arp_of,
758 if ((hdrs & ICE_FLOW_SEG_HDR_IPV4) &&
759 (hdrs & ICE_FLOW_SEG_HDR_IPV_OTHER)) {
760 src = i ? (const unsigned long *)ice_ptypes_ipv4_il :
761 (const unsigned long *)ice_ptypes_ipv4_ofos_all;
762 bitmap_and(params->ptypes, params->ptypes, src,
764 } else if ((hdrs & ICE_FLOW_SEG_HDR_IPV6) &&
765 (hdrs & ICE_FLOW_SEG_HDR_IPV_OTHER)) {
766 src = i ? (const unsigned long *)ice_ptypes_ipv6_il :
767 (const unsigned long *)ice_ptypes_ipv6_ofos_all;
768 bitmap_and(params->ptypes, params->ptypes, src,
770 } else if ((hdrs & ICE_FLOW_SEG_HDR_IPV4) &&
771 !(hdrs & ICE_FLOW_SEG_HDRS_L4_MASK_NO_OTHER)) {
772 src = !i ? (const unsigned long *)ice_ptypes_ipv4_ofos_no_l4 :
773 (const unsigned long *)ice_ptypes_ipv4_il_no_l4;
774 bitmap_and(params->ptypes, params->ptypes, src,
776 } else if (hdrs & ICE_FLOW_SEG_HDR_IPV4) {
777 src = !i ? (const unsigned long *)ice_ptypes_ipv4_ofos :
778 (const unsigned long *)ice_ptypes_ipv4_il;
779 bitmap_and(params->ptypes, params->ptypes, src,
781 } else if ((hdrs & ICE_FLOW_SEG_HDR_IPV6) &&
782 !(hdrs & ICE_FLOW_SEG_HDRS_L4_MASK_NO_OTHER)) {
783 src = !i ? (const unsigned long *)ice_ptypes_ipv6_ofos_no_l4 :
784 (const unsigned long *)ice_ptypes_ipv6_il_no_l4;
785 bitmap_and(params->ptypes, params->ptypes, src,
787 } else if (hdrs & ICE_FLOW_SEG_HDR_IPV6) {
788 src = !i ? (const unsigned long *)ice_ptypes_ipv6_ofos :
789 (const unsigned long *)ice_ptypes_ipv6_il;
790 bitmap_and(params->ptypes, params->ptypes, src,
794 if (hdrs & ICE_FLOW_SEG_HDR_ETH_NON_IP) {
795 src = (const unsigned long *)ice_ptypes_mac_non_ip_ofos;
796 bitmap_and(params->ptypes, params->ptypes, src,
798 } else if (hdrs & ICE_FLOW_SEG_HDR_PPPOE) {
799 src = (const unsigned long *)ice_ptypes_pppoe;
800 bitmap_and(params->ptypes, params->ptypes, src,
803 src = (const unsigned long *)ice_ptypes_pppoe;
804 bitmap_andnot(params->ptypes, params->ptypes, src,
808 if (hdrs & ICE_FLOW_SEG_HDR_UDP) {
809 src = (const unsigned long *)ice_ptypes_udp_il;
810 bitmap_and(params->ptypes, params->ptypes, src,
812 } else if (hdrs & ICE_FLOW_SEG_HDR_TCP) {
813 bitmap_and(params->ptypes, params->ptypes,
814 (const unsigned long *)ice_ptypes_tcp_il,
816 } else if (hdrs & ICE_FLOW_SEG_HDR_SCTP) {
817 src = (const unsigned long *)ice_ptypes_sctp_il;
818 bitmap_and(params->ptypes, params->ptypes, src,
822 if (hdrs & ICE_FLOW_SEG_HDR_ICMP) {
823 src = !i ? (const unsigned long *)ice_ptypes_icmp_of :
824 (const unsigned long *)ice_ptypes_icmp_il;
825 bitmap_and(params->ptypes, params->ptypes, src,
827 } else if (hdrs & ICE_FLOW_SEG_HDR_GRE) {
829 src = (const unsigned long *)ice_ptypes_gre_of;
830 bitmap_and(params->ptypes, params->ptypes,
831 src, ICE_FLOW_PTYPE_MAX);
833 } else if (hdrs & ICE_FLOW_SEG_HDR_GTPC) {
834 src = (const unsigned long *)ice_ptypes_gtpc;
835 bitmap_and(params->ptypes, params->ptypes, src,
837 } else if (hdrs & ICE_FLOW_SEG_HDR_GTPC_TEID) {
838 src = (const unsigned long *)ice_ptypes_gtpc_tid;
839 bitmap_and(params->ptypes, params->ptypes, src,
841 } else if (hdrs & ICE_FLOW_SEG_HDR_GTPU_DWN) {
842 src = (const unsigned long *)ice_ptypes_gtpu;
843 bitmap_and(params->ptypes, params->ptypes, src,
846 /* Attributes for GTP packet with downlink */
847 params->attr = ice_attr_gtpu_down;
848 params->attr_cnt = ARRAY_SIZE(ice_attr_gtpu_down);
849 } else if (hdrs & ICE_FLOW_SEG_HDR_GTPU_UP) {
850 src = (const unsigned long *)ice_ptypes_gtpu;
851 bitmap_and(params->ptypes, params->ptypes, src,
854 /* Attributes for GTP packet with uplink */
855 params->attr = ice_attr_gtpu_up;
856 params->attr_cnt = ARRAY_SIZE(ice_attr_gtpu_up);
857 } else if (hdrs & ICE_FLOW_SEG_HDR_GTPU_EH) {
858 src = (const unsigned long *)ice_ptypes_gtpu;
859 bitmap_and(params->ptypes, params->ptypes, src,
862 /* Attributes for GTP packet with Extension Header */
863 params->attr = ice_attr_gtpu_eh;
864 params->attr_cnt = ARRAY_SIZE(ice_attr_gtpu_eh);
865 } else if (hdrs & ICE_FLOW_SEG_HDR_GTPU_IP) {
866 src = (const unsigned long *)ice_ptypes_gtpu;
867 bitmap_and(params->ptypes, params->ptypes, src,
869 } else if (hdrs & ICE_FLOW_SEG_HDR_L2TPV3) {
870 src = (const unsigned long *)ice_ptypes_l2tpv3;
871 bitmap_and(params->ptypes, params->ptypes, src,
873 } else if (hdrs & ICE_FLOW_SEG_HDR_ESP) {
874 src = (const unsigned long *)ice_ptypes_esp;
875 bitmap_and(params->ptypes, params->ptypes, src,
877 } else if (hdrs & ICE_FLOW_SEG_HDR_AH) {
878 src = (const unsigned long *)ice_ptypes_ah;
879 bitmap_and(params->ptypes, params->ptypes, src,
881 } else if (hdrs & ICE_FLOW_SEG_HDR_NAT_T_ESP) {
882 src = (const unsigned long *)ice_ptypes_nat_t_esp;
883 bitmap_and(params->ptypes, params->ptypes, src,
887 if (hdrs & ICE_FLOW_SEG_HDR_PFCP) {
888 if (hdrs & ICE_FLOW_SEG_HDR_PFCP_NODE)
889 src = (const unsigned long *)ice_ptypes_pfcp_node;
891 src = (const unsigned long *)ice_ptypes_pfcp_session;
893 bitmap_and(params->ptypes, params->ptypes, src,
896 src = (const unsigned long *)ice_ptypes_pfcp_node;
897 bitmap_andnot(params->ptypes, params->ptypes, src,
900 src = (const unsigned long *)ice_ptypes_pfcp_session;
901 bitmap_andnot(params->ptypes, params->ptypes, src,
910 * ice_flow_xtract_fld - Create an extraction sequence entry for the given field
911 * @hw: pointer to the HW struct
912 * @params: information about the flow to be processed
913 * @seg: packet segment index of the field to be extracted
914 * @fld: ID of field to be extracted
915 * @match: bit field of all fields
917 * This function determines the protocol ID, offset, and size of the given
918 * field. It then allocates one or more extraction sequence entries for the
919 * given field, and fill the entries with protocol ID and offset information.
922 ice_flow_xtract_fld(struct ice_hw *hw, struct ice_flow_prof_params *params,
923 u8 seg, enum ice_flow_field fld, u64 match)
925 enum ice_flow_field sib = ICE_FLOW_FIELD_IDX_MAX;
926 enum ice_prot_id prot_id = ICE_PROT_ID_INVAL;
927 u8 fv_words = hw->blk[params->blk].es.fvw;
928 struct ice_flow_fld_info *flds;
929 u16 cnt, ese_bits, i;
934 flds = params->prof->segs[seg].fields;
937 case ICE_FLOW_FIELD_IDX_ETH_DA:
938 case ICE_FLOW_FIELD_IDX_ETH_SA:
939 case ICE_FLOW_FIELD_IDX_S_VLAN:
940 case ICE_FLOW_FIELD_IDX_C_VLAN:
941 prot_id = seg == 0 ? ICE_PROT_MAC_OF_OR_S : ICE_PROT_MAC_IL;
943 case ICE_FLOW_FIELD_IDX_ETH_TYPE:
944 prot_id = seg == 0 ? ICE_PROT_ETYPE_OL : ICE_PROT_ETYPE_IL;
946 case ICE_FLOW_FIELD_IDX_IPV4_DSCP:
947 prot_id = seg == 0 ? ICE_PROT_IPV4_OF_OR_S : ICE_PROT_IPV4_IL;
949 case ICE_FLOW_FIELD_IDX_IPV6_DSCP:
950 prot_id = seg == 0 ? ICE_PROT_IPV6_OF_OR_S : ICE_PROT_IPV6_IL;
952 case ICE_FLOW_FIELD_IDX_IPV4_TTL:
953 case ICE_FLOW_FIELD_IDX_IPV4_PROT:
954 prot_id = seg == 0 ? ICE_PROT_IPV4_OF_OR_S : ICE_PROT_IPV4_IL;
956 /* TTL and PROT share the same extraction seq. entry.
957 * Each is considered a sibling to the other in terms of sharing
958 * the same extraction sequence entry.
960 if (fld == ICE_FLOW_FIELD_IDX_IPV4_TTL)
961 sib = ICE_FLOW_FIELD_IDX_IPV4_PROT;
962 else if (fld == ICE_FLOW_FIELD_IDX_IPV4_PROT)
963 sib = ICE_FLOW_FIELD_IDX_IPV4_TTL;
965 /* If the sibling field is also included, that field's
966 * mask needs to be included.
968 if (match & BIT(sib))
969 sib_mask = ice_flds_info[sib].mask;
971 case ICE_FLOW_FIELD_IDX_IPV6_TTL:
972 case ICE_FLOW_FIELD_IDX_IPV6_PROT:
973 prot_id = seg == 0 ? ICE_PROT_IPV6_OF_OR_S : ICE_PROT_IPV6_IL;
975 /* TTL and PROT share the same extraction seq. entry.
976 * Each is considered a sibling to the other in terms of sharing
977 * the same extraction sequence entry.
979 if (fld == ICE_FLOW_FIELD_IDX_IPV6_TTL)
980 sib = ICE_FLOW_FIELD_IDX_IPV6_PROT;
981 else if (fld == ICE_FLOW_FIELD_IDX_IPV6_PROT)
982 sib = ICE_FLOW_FIELD_IDX_IPV6_TTL;
984 /* If the sibling field is also included, that field's
985 * mask needs to be included.
987 if (match & BIT(sib))
988 sib_mask = ice_flds_info[sib].mask;
990 case ICE_FLOW_FIELD_IDX_IPV4_SA:
991 case ICE_FLOW_FIELD_IDX_IPV4_DA:
992 prot_id = seg == 0 ? ICE_PROT_IPV4_OF_OR_S : ICE_PROT_IPV4_IL;
994 case ICE_FLOW_FIELD_IDX_IPV6_SA:
995 case ICE_FLOW_FIELD_IDX_IPV6_DA:
996 prot_id = seg == 0 ? ICE_PROT_IPV6_OF_OR_S : ICE_PROT_IPV6_IL;
998 case ICE_FLOW_FIELD_IDX_TCP_SRC_PORT:
999 case ICE_FLOW_FIELD_IDX_TCP_DST_PORT:
1000 case ICE_FLOW_FIELD_IDX_TCP_FLAGS:
1001 prot_id = ICE_PROT_TCP_IL;
1003 case ICE_FLOW_FIELD_IDX_UDP_SRC_PORT:
1004 case ICE_FLOW_FIELD_IDX_UDP_DST_PORT:
1005 prot_id = ICE_PROT_UDP_IL_OR_S;
1007 case ICE_FLOW_FIELD_IDX_SCTP_SRC_PORT:
1008 case ICE_FLOW_FIELD_IDX_SCTP_DST_PORT:
1009 prot_id = ICE_PROT_SCTP_IL;
1011 case ICE_FLOW_FIELD_IDX_GTPC_TEID:
1012 case ICE_FLOW_FIELD_IDX_GTPU_IP_TEID:
1013 case ICE_FLOW_FIELD_IDX_GTPU_UP_TEID:
1014 case ICE_FLOW_FIELD_IDX_GTPU_DWN_TEID:
1015 case ICE_FLOW_FIELD_IDX_GTPU_EH_TEID:
1016 case ICE_FLOW_FIELD_IDX_GTPU_EH_QFI:
1017 /* GTP is accessed through UDP OF protocol */
1018 prot_id = ICE_PROT_UDP_OF;
1020 case ICE_FLOW_FIELD_IDX_PPPOE_SESS_ID:
1021 prot_id = ICE_PROT_PPPOE;
1023 case ICE_FLOW_FIELD_IDX_PFCP_SEID:
1024 prot_id = ICE_PROT_UDP_IL_OR_S;
1026 case ICE_FLOW_FIELD_IDX_L2TPV3_SESS_ID:
1027 prot_id = ICE_PROT_L2TPV3;
1029 case ICE_FLOW_FIELD_IDX_ESP_SPI:
1030 prot_id = ICE_PROT_ESP_F;
1032 case ICE_FLOW_FIELD_IDX_AH_SPI:
1033 prot_id = ICE_PROT_ESP_2;
1035 case ICE_FLOW_FIELD_IDX_NAT_T_ESP_SPI:
1036 prot_id = ICE_PROT_UDP_IL_OR_S;
1038 case ICE_FLOW_FIELD_IDX_ARP_SIP:
1039 case ICE_FLOW_FIELD_IDX_ARP_DIP:
1040 case ICE_FLOW_FIELD_IDX_ARP_SHA:
1041 case ICE_FLOW_FIELD_IDX_ARP_DHA:
1042 case ICE_FLOW_FIELD_IDX_ARP_OP:
1043 prot_id = ICE_PROT_ARP_OF;
1045 case ICE_FLOW_FIELD_IDX_ICMP_TYPE:
1046 case ICE_FLOW_FIELD_IDX_ICMP_CODE:
1047 /* ICMP type and code share the same extraction seq. entry */
1048 prot_id = (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_IPV4) ?
1049 ICE_PROT_ICMP_IL : ICE_PROT_ICMPV6_IL;
1050 sib = fld == ICE_FLOW_FIELD_IDX_ICMP_TYPE ?
1051 ICE_FLOW_FIELD_IDX_ICMP_CODE :
1052 ICE_FLOW_FIELD_IDX_ICMP_TYPE;
1054 case ICE_FLOW_FIELD_IDX_GRE_KEYID:
1055 prot_id = ICE_PROT_GRE_OF;
1061 /* Each extraction sequence entry is a word in size, and extracts a
1062 * word-aligned offset from a protocol header.
1064 ese_bits = ICE_FLOW_FV_EXTRACT_SZ * BITS_PER_BYTE;
1066 flds[fld].xtrct.prot_id = prot_id;
1067 flds[fld].xtrct.off = (ice_flds_info[fld].off / ese_bits) *
1068 ICE_FLOW_FV_EXTRACT_SZ;
1069 flds[fld].xtrct.disp = (u8)(ice_flds_info[fld].off % ese_bits);
1070 flds[fld].xtrct.idx = params->es_cnt;
1071 flds[fld].xtrct.mask = ice_flds_info[fld].mask;
1073 /* Adjust the next field-entry index after accommodating the number of
1074 * entries this field consumes
1076 cnt = DIV_ROUND_UP(flds[fld].xtrct.disp + ice_flds_info[fld].size,
1079 /* Fill in the extraction sequence entries needed for this field */
1080 off = flds[fld].xtrct.off;
1081 mask = flds[fld].xtrct.mask;
1082 for (i = 0; i < cnt; i++) {
1083 /* Only consume an extraction sequence entry if there is no
1084 * sibling field associated with this field or the sibling entry
1085 * already extracts the word shared with this field.
1087 if (sib == ICE_FLOW_FIELD_IDX_MAX ||
1088 flds[sib].xtrct.prot_id == ICE_PROT_ID_INVAL ||
1089 flds[sib].xtrct.off != off) {
1092 /* Make sure the number of extraction sequence required
1093 * does not exceed the block's capability
1095 if (params->es_cnt >= fv_words)
1098 /* some blocks require a reversed field vector layout */
1099 if (hw->blk[params->blk].es.reverse)
1100 idx = fv_words - params->es_cnt - 1;
1102 idx = params->es_cnt;
1104 params->es[idx].prot_id = prot_id;
1105 params->es[idx].off = off;
1106 params->mask[idx] = mask | sib_mask;
1110 off += ICE_FLOW_FV_EXTRACT_SZ;
1117 * ice_flow_xtract_raws - Create extract sequence entries for raw bytes
1118 * @hw: pointer to the HW struct
1119 * @params: information about the flow to be processed
1120 * @seg: index of packet segment whose raw fields are to be extracted
1123 ice_flow_xtract_raws(struct ice_hw *hw, struct ice_flow_prof_params *params,
1130 if (!params->prof->segs[seg].raws_cnt)
1133 if (params->prof->segs[seg].raws_cnt >
1134 ARRAY_SIZE(params->prof->segs[seg].raws))
1137 /* Offsets within the segment headers are not supported */
1138 hdrs_sz = ice_flow_calc_seg_sz(params, seg);
1142 fv_words = hw->blk[params->blk].es.fvw;
1144 for (i = 0; i < params->prof->segs[seg].raws_cnt; i++) {
1145 struct ice_flow_seg_fld_raw *raw;
1148 raw = ¶ms->prof->segs[seg].raws[i];
1150 /* Storing extraction information */
1151 raw->info.xtrct.prot_id = ICE_PROT_MAC_OF_OR_S;
1152 raw->info.xtrct.off = (raw->off / ICE_FLOW_FV_EXTRACT_SZ) *
1153 ICE_FLOW_FV_EXTRACT_SZ;
1154 raw->info.xtrct.disp = (raw->off % ICE_FLOW_FV_EXTRACT_SZ) *
1156 raw->info.xtrct.idx = params->es_cnt;
1158 /* Determine the number of field vector entries this raw field
1161 cnt = DIV_ROUND_UP(raw->info.xtrct.disp +
1162 (raw->info.src.last * BITS_PER_BYTE),
1163 (ICE_FLOW_FV_EXTRACT_SZ * BITS_PER_BYTE));
1164 off = raw->info.xtrct.off;
1165 for (j = 0; j < cnt; j++) {
1168 /* Make sure the number of extraction sequence required
1169 * does not exceed the block's capability
1171 if (params->es_cnt >= hw->blk[params->blk].es.count ||
1172 params->es_cnt >= ICE_MAX_FV_WORDS)
1175 /* some blocks require a reversed field vector layout */
1176 if (hw->blk[params->blk].es.reverse)
1177 idx = fv_words - params->es_cnt - 1;
1179 idx = params->es_cnt;
1181 params->es[idx].prot_id = raw->info.xtrct.prot_id;
1182 params->es[idx].off = off;
1184 off += ICE_FLOW_FV_EXTRACT_SZ;
1192 * ice_flow_create_xtrct_seq - Create an extraction sequence for given segments
1193 * @hw: pointer to the HW struct
1194 * @params: information about the flow to be processed
1196 * This function iterates through all matched fields in the given segments, and
1197 * creates an extraction sequence for the fields.
1200 ice_flow_create_xtrct_seq(struct ice_hw *hw,
1201 struct ice_flow_prof_params *params)
1203 struct ice_flow_prof *prof = params->prof;
1207 for (i = 0; i < prof->segs_cnt; i++) {
1208 u64 match = params->prof->segs[i].match;
1209 enum ice_flow_field j;
1211 for_each_set_bit(j, (unsigned long *)&match,
1212 ICE_FLOW_FIELD_IDX_MAX) {
1213 status = ice_flow_xtract_fld(hw, params, i, j, match);
1216 clear_bit(j, (unsigned long *)&match);
1219 /* Process raw matching bytes */
1220 status = ice_flow_xtract_raws(hw, params, i);
1229 * ice_flow_proc_segs - process all packet segments associated with a profile
1230 * @hw: pointer to the HW struct
1231 * @params: information about the flow to be processed
1234 ice_flow_proc_segs(struct ice_hw *hw, struct ice_flow_prof_params *params)
1238 status = ice_flow_proc_seg_hdrs(params);
1242 status = ice_flow_create_xtrct_seq(hw, params);
1246 switch (params->blk) {
1258 #define ICE_FLOW_FIND_PROF_CHK_FLDS 0x00000001
1259 #define ICE_FLOW_FIND_PROF_CHK_VSI 0x00000002
1260 #define ICE_FLOW_FIND_PROF_NOT_CHK_DIR 0x00000004
1261 #define ICE_FLOW_FIND_PROF_CHK_SYMM 0x00000008
1264 * ice_flow_find_prof_conds - Find a profile matching headers and conditions
1265 * @hw: pointer to the HW struct
1266 * @blk: classification stage
1267 * @dir: flow direction
1268 * @segs: array of one or more packet segments that describe the flow
1269 * @segs_cnt: number of packet segments provided
1270 * @symm: symmetric setting for RSS profiles
1271 * @vsi_handle: software VSI handle to check VSI (ICE_FLOW_FIND_PROF_CHK_VSI)
1272 * @conds: additional conditions to be checked (ICE_FLOW_FIND_PROF_CHK_*)
1274 static struct ice_flow_prof *
1275 ice_flow_find_prof_conds(struct ice_hw *hw, enum ice_block blk,
1276 enum ice_flow_dir dir, struct ice_flow_seg_info *segs,
1277 u8 segs_cnt, bool symm, u16 vsi_handle, u32 conds)
1279 struct ice_flow_prof *p, *prof = NULL;
1281 mutex_lock(&hw->fl_profs_locks[blk]);
1282 list_for_each_entry(p, &hw->fl_profs[blk], l_entry)
1283 if ((p->dir == dir || conds & ICE_FLOW_FIND_PROF_NOT_CHK_DIR) &&
1284 segs_cnt && segs_cnt == p->segs_cnt) {
1287 /* Check for profile-VSI association if specified */
1288 if ((conds & ICE_FLOW_FIND_PROF_CHK_VSI) &&
1289 ice_is_vsi_valid(hw, vsi_handle) &&
1290 !test_bit(vsi_handle, p->vsis))
1293 /* Check for symmetric settings */
1294 if ((conds & ICE_FLOW_FIND_PROF_CHK_SYMM) &&
1298 /* Protocol headers must be checked. Matched fields are
1299 * checked if specified.
1301 for (i = 0; i < segs_cnt; i++)
1302 if (segs[i].hdrs != p->segs[i].hdrs ||
1303 ((conds & ICE_FLOW_FIND_PROF_CHK_FLDS) &&
1304 segs[i].match != p->segs[i].match))
1307 /* A match is found if all segments are matched */
1308 if (i == segs_cnt) {
1313 mutex_unlock(&hw->fl_profs_locks[blk]);
1319 * ice_flow_find_prof_id - Look up a profile with given profile ID
1320 * @hw: pointer to the HW struct
1321 * @blk: classification stage
1322 * @prof_id: unique ID to identify this flow profile
1324 static struct ice_flow_prof *
1325 ice_flow_find_prof_id(struct ice_hw *hw, enum ice_block blk, u64 prof_id)
1327 struct ice_flow_prof *p;
1329 list_for_each_entry(p, &hw->fl_profs[blk], l_entry)
1330 if (p->id == prof_id)
1337 * ice_flow_rem_entry_sync - Remove a flow entry
1338 * @hw: pointer to the HW struct
1339 * @blk: classification stage
1340 * @entry: flow entry to be removed
1343 ice_flow_rem_entry_sync(struct ice_hw *hw, enum ice_block __always_unused blk,
1344 struct ice_flow_entry *entry)
1349 list_del(&entry->l_entry);
1351 devm_kfree(ice_hw_to_dev(hw), entry);
1357 * ice_flow_add_prof_sync - Add a flow profile for packet segments and fields
1358 * @hw: pointer to the HW struct
1359 * @blk: classification stage
1360 * @dir: flow direction
1361 * @segs: array of one or more packet segments that describe the flow
1362 * @segs_cnt: number of packet segments provided
1363 * @symm: symmetric setting for RSS profiles
1364 * @prof: stores the returned flow profile added
1366 * Assumption: the caller has acquired the lock to the profile list
1369 ice_flow_add_prof_sync(struct ice_hw *hw, enum ice_block blk,
1370 enum ice_flow_dir dir,
1371 struct ice_flow_seg_info *segs, u8 segs_cnt,
1372 bool symm, struct ice_flow_prof **prof)
1374 struct ice_flow_prof_params *params;
1375 struct ice_prof_id *ids;
1383 ids = &hw->blk[blk].prof_id;
1384 prof_id = find_first_zero_bit(ids->id, ids->count);
1385 if (prof_id >= ids->count)
1388 params = kzalloc(sizeof(*params), GFP_KERNEL);
1392 params->prof = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*params->prof),
1394 if (!params->prof) {
1399 /* initialize extraction sequence to all invalid (0xff) */
1400 for (i = 0; i < ICE_MAX_FV_WORDS; i++) {
1401 params->es[i].prot_id = ICE_PROT_INVALID;
1402 params->es[i].off = ICE_FV_OFFSET_INVAL;
1406 params->prof->id = prof_id;
1407 params->prof->dir = dir;
1408 params->prof->segs_cnt = segs_cnt;
1409 params->prof->symm = symm;
1411 /* Make a copy of the segments that need to be persistent in the flow
1414 for (i = 0; i < segs_cnt; i++)
1415 memcpy(¶ms->prof->segs[i], &segs[i], sizeof(*segs));
1417 status = ice_flow_proc_segs(hw, params);
1419 ice_debug(hw, ICE_DBG_FLOW, "Error processing a flow's packet segments\n");
1423 /* Add a HW profile for this flow profile */
1424 status = ice_add_prof(hw, blk, prof_id, (u8 *)params->ptypes,
1425 params->attr, params->attr_cnt, params->es,
1426 params->mask, symm, true);
1428 ice_debug(hw, ICE_DBG_FLOW, "Error adding a HW flow profile\n");
1432 INIT_LIST_HEAD(¶ms->prof->entries);
1433 mutex_init(¶ms->prof->entries_lock);
1434 set_bit(prof_id, ids->id);
1435 *prof = params->prof;
1439 devm_kfree(ice_hw_to_dev(hw), params->prof);
1447 * ice_flow_rem_prof_sync - remove a flow profile
1448 * @hw: pointer to the hardware structure
1449 * @blk: classification stage
1450 * @prof: pointer to flow profile to remove
1452 * Assumption: the caller has acquired the lock to the profile list
1455 ice_flow_rem_prof_sync(struct ice_hw *hw, enum ice_block blk,
1456 struct ice_flow_prof *prof)
1460 /* Remove all remaining flow entries before removing the flow profile */
1461 if (!list_empty(&prof->entries)) {
1462 struct ice_flow_entry *e, *t;
1464 mutex_lock(&prof->entries_lock);
1466 list_for_each_entry_safe(e, t, &prof->entries, l_entry) {
1467 status = ice_flow_rem_entry_sync(hw, blk, e);
1472 mutex_unlock(&prof->entries_lock);
1475 /* Remove all hardware profiles associated with this flow profile */
1476 status = ice_rem_prof(hw, blk, prof->id);
1478 clear_bit(prof->id, hw->blk[blk].prof_id.id);
1479 list_del(&prof->l_entry);
1480 mutex_destroy(&prof->entries_lock);
1481 devm_kfree(ice_hw_to_dev(hw), prof);
1488 * ice_flow_assoc_prof - associate a VSI with a flow profile
1489 * @hw: pointer to the hardware structure
1490 * @blk: classification stage
1491 * @prof: pointer to flow profile
1492 * @vsi_handle: software VSI handle
1494 * Assumption: the caller has acquired the lock to the profile list
1495 * and the software VSI handle has been validated
1498 ice_flow_assoc_prof(struct ice_hw *hw, enum ice_block blk,
1499 struct ice_flow_prof *prof, u16 vsi_handle)
1503 if (!test_bit(vsi_handle, prof->vsis)) {
1504 status = ice_add_prof_id_flow(hw, blk,
1505 ice_get_hw_vsi_num(hw,
1509 set_bit(vsi_handle, prof->vsis);
1511 ice_debug(hw, ICE_DBG_FLOW, "HW profile add failed, %d\n",
1519 * ice_flow_disassoc_prof - disassociate a VSI from a flow profile
1520 * @hw: pointer to the hardware structure
1521 * @blk: classification stage
1522 * @prof: pointer to flow profile
1523 * @vsi_handle: software VSI handle
1525 * Assumption: the caller has acquired the lock to the profile list
1526 * and the software VSI handle has been validated
1529 ice_flow_disassoc_prof(struct ice_hw *hw, enum ice_block blk,
1530 struct ice_flow_prof *prof, u16 vsi_handle)
1534 if (test_bit(vsi_handle, prof->vsis)) {
1535 status = ice_rem_prof_id_flow(hw, blk,
1536 ice_get_hw_vsi_num(hw,
1540 clear_bit(vsi_handle, prof->vsis);
1542 ice_debug(hw, ICE_DBG_FLOW, "HW profile remove failed, %d\n",
1549 #define FLAG_GTP_EH_PDU_LINK BIT_ULL(13)
1550 #define FLAG_GTP_EH_PDU BIT_ULL(14)
1552 #define HI_BYTE_IN_WORD GENMASK(15, 8)
1553 #define LO_BYTE_IN_WORD GENMASK(7, 0)
1555 #define FLAG_GTPU_MSK \
1556 (FLAG_GTP_EH_PDU | FLAG_GTP_EH_PDU_LINK)
1557 #define FLAG_GTPU_UP \
1558 (FLAG_GTP_EH_PDU | FLAG_GTP_EH_PDU_LINK)
1559 #define FLAG_GTPU_DW FLAG_GTP_EH_PDU
1562 * ice_flow_set_parser_prof - Set flow profile based on the parsed profile info
1563 * @hw: pointer to the HW struct
1564 * @dest_vsi: dest VSI
1565 * @fdir_vsi: fdir programming VSI
1566 * @prof: stores parsed profile info from raw flow
1567 * @blk: classification blk
1569 * Return: 0 on success or negative errno on failure.
1572 ice_flow_set_parser_prof(struct ice_hw *hw, u16 dest_vsi, u16 fdir_vsi,
1573 struct ice_parser_profile *prof, enum ice_block blk)
1575 u64 id = find_first_bit(prof->ptypes, ICE_FLOW_PTYPE_MAX);
1576 struct ice_flow_prof_params *params __free(kfree);
1577 u8 fv_words = hw->blk[blk].es.fvw;
1581 params = kzalloc(sizeof(*params), GFP_KERNEL);
1585 for (i = 0; i < ICE_MAX_FV_WORDS; i++) {
1586 params->es[i].prot_id = ICE_PROT_INVALID;
1587 params->es[i].off = ICE_FV_OFFSET_INVAL;
1590 for (i = 0; i < prof->fv_num; i++) {
1591 if (hw->blk[blk].es.reverse)
1592 idx = fv_words - i - 1;
1595 params->es[idx].prot_id = prof->fv[i].proto_id;
1596 params->es[idx].off = prof->fv[i].offset;
1597 params->mask[idx] = (((prof->fv[i].msk) << BITS_PER_BYTE) &
1599 (((prof->fv[i].msk) >> BITS_PER_BYTE) &
1603 switch (prof->flags) {
1605 params->attr = ice_attr_gtpu_down;
1606 params->attr_cnt = ARRAY_SIZE(ice_attr_gtpu_down);
1609 params->attr = ice_attr_gtpu_up;
1610 params->attr_cnt = ARRAY_SIZE(ice_attr_gtpu_up);
1613 if (prof->flags_msk & FLAG_GTPU_MSK) {
1614 params->attr = ice_attr_gtpu_session;
1615 params->attr_cnt = ARRAY_SIZE(ice_attr_gtpu_session);
1620 status = ice_add_prof(hw, blk, id, (u8 *)prof->ptypes,
1621 params->attr, params->attr_cnt,
1622 params->es, params->mask, false, false);
1626 status = ice_flow_assoc_fdir_prof(hw, blk, dest_vsi, fdir_vsi, id);
1628 ice_rem_prof(hw, blk, id);
1634 * ice_flow_add_prof - Add a flow profile for packet segments and matched fields
1635 * @hw: pointer to the HW struct
1636 * @blk: classification stage
1637 * @dir: flow direction
1638 * @segs: array of one or more packet segments that describe the flow
1639 * @segs_cnt: number of packet segments provided
1640 * @symm: symmetric setting for RSS profiles
1641 * @prof: stores the returned flow profile added
1644 ice_flow_add_prof(struct ice_hw *hw, enum ice_block blk, enum ice_flow_dir dir,
1645 struct ice_flow_seg_info *segs, u8 segs_cnt,
1646 bool symm, struct ice_flow_prof **prof)
1650 if (segs_cnt > ICE_FLOW_SEG_MAX)
1659 status = ice_flow_val_hdrs(segs, segs_cnt);
1663 mutex_lock(&hw->fl_profs_locks[blk]);
1665 status = ice_flow_add_prof_sync(hw, blk, dir, segs, segs_cnt,
1668 list_add(&(*prof)->l_entry, &hw->fl_profs[blk]);
1670 mutex_unlock(&hw->fl_profs_locks[blk]);
1676 * ice_flow_rem_prof - Remove a flow profile and all entries associated with it
1677 * @hw: pointer to the HW struct
1678 * @blk: the block for which the flow profile is to be removed
1679 * @prof_id: unique ID of the flow profile to be removed
1681 int ice_flow_rem_prof(struct ice_hw *hw, enum ice_block blk, u64 prof_id)
1683 struct ice_flow_prof *prof;
1686 mutex_lock(&hw->fl_profs_locks[blk]);
1688 prof = ice_flow_find_prof_id(hw, blk, prof_id);
1694 /* prof becomes invalid after the call */
1695 status = ice_flow_rem_prof_sync(hw, blk, prof);
1698 mutex_unlock(&hw->fl_profs_locks[blk]);
1704 * ice_flow_add_entry - Add a flow entry
1705 * @hw: pointer to the HW struct
1706 * @blk: classification stage
1707 * @prof_id: ID of the profile to add a new flow entry to
1708 * @entry_id: unique ID to identify this flow entry
1709 * @vsi_handle: software VSI handle for the flow entry
1710 * @prio: priority of the flow entry
1711 * @data: pointer to a data buffer containing flow entry's match values/masks
1712 * @entry_h: pointer to buffer that receives the new flow entry's handle
1715 ice_flow_add_entry(struct ice_hw *hw, enum ice_block blk, u64 prof_id,
1716 u64 entry_id, u16 vsi_handle, enum ice_flow_priority prio,
1717 void *data, u64 *entry_h)
1719 struct ice_flow_entry *e = NULL;
1720 struct ice_flow_prof *prof;
1723 /* No flow entry data is expected for RSS */
1724 if (!entry_h || (!data && blk != ICE_BLK_RSS))
1727 if (!ice_is_vsi_valid(hw, vsi_handle))
1730 mutex_lock(&hw->fl_profs_locks[blk]);
1732 prof = ice_flow_find_prof_id(hw, blk, prof_id);
1736 /* Allocate memory for the entry being added and associate
1737 * the VSI to the found flow profile
1739 e = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*e), GFP_KERNEL);
1743 status = ice_flow_assoc_prof(hw, blk, prof, vsi_handle);
1746 mutex_unlock(&hw->fl_profs_locks[blk]);
1751 e->vsi_handle = vsi_handle;
1760 status = -EOPNOTSUPP;
1764 mutex_lock(&prof->entries_lock);
1765 list_add(&e->l_entry, &prof->entries);
1766 mutex_unlock(&prof->entries_lock);
1768 *entry_h = ICE_FLOW_ENTRY_HNDL(e);
1772 devm_kfree(ice_hw_to_dev(hw), e);
1778 * ice_flow_rem_entry - Remove a flow entry
1779 * @hw: pointer to the HW struct
1780 * @blk: classification stage
1781 * @entry_h: handle to the flow entry to be removed
1783 int ice_flow_rem_entry(struct ice_hw *hw, enum ice_block blk, u64 entry_h)
1785 struct ice_flow_entry *entry;
1786 struct ice_flow_prof *prof;
1789 if (entry_h == ICE_FLOW_ENTRY_HANDLE_INVAL)
1792 entry = ICE_FLOW_ENTRY_PTR(entry_h);
1794 /* Retain the pointer to the flow profile as the entry will be freed */
1798 mutex_lock(&prof->entries_lock);
1799 status = ice_flow_rem_entry_sync(hw, blk, entry);
1800 mutex_unlock(&prof->entries_lock);
1807 * ice_flow_set_fld_ext - specifies locations of field from entry's input buffer
1808 * @seg: packet segment the field being set belongs to
1809 * @fld: field to be set
1810 * @field_type: type of the field
1811 * @val_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of the value to match from
1812 * entry's input buffer
1813 * @mask_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of mask value from entry's
1815 * @last_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of last/upper value from
1816 * entry's input buffer
1818 * This helper function stores information of a field being matched, including
1819 * the type of the field and the locations of the value to match, the mask, and
1820 * the upper-bound value in the start of the input buffer for a flow entry.
1821 * This function should only be used for fixed-size data structures.
1823 * This function also opportunistically determines the protocol headers to be
1824 * present based on the fields being set. Some fields cannot be used alone to
1825 * determine the protocol headers present. Sometimes, fields for particular
1826 * protocol headers are not matched. In those cases, the protocol headers
1827 * must be explicitly set.
1830 ice_flow_set_fld_ext(struct ice_flow_seg_info *seg, enum ice_flow_field fld,
1831 enum ice_flow_fld_match_type field_type, u16 val_loc,
1832 u16 mask_loc, u16 last_loc)
1834 u64 bit = BIT_ULL(fld);
1837 if (field_type == ICE_FLOW_FLD_TYPE_RANGE)
1840 seg->fields[fld].type = field_type;
1841 seg->fields[fld].src.val = val_loc;
1842 seg->fields[fld].src.mask = mask_loc;
1843 seg->fields[fld].src.last = last_loc;
1845 ICE_FLOW_SET_HDRS(seg, ice_flds_info[fld].hdr);
1849 * ice_flow_set_fld - specifies locations of field from entry's input buffer
1850 * @seg: packet segment the field being set belongs to
1851 * @fld: field to be set
1852 * @val_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of the value to match from
1853 * entry's input buffer
1854 * @mask_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of mask value from entry's
1856 * @last_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of last/upper value from
1857 * entry's input buffer
1858 * @range: indicate if field being matched is to be in a range
1860 * This function specifies the locations, in the form of byte offsets from the
1861 * start of the input buffer for a flow entry, from where the value to match,
1862 * the mask value, and upper value can be extracted. These locations are then
1863 * stored in the flow profile. When adding a flow entry associated with the
1864 * flow profile, these locations will be used to quickly extract the values and
1865 * create the content of a match entry. This function should only be used for
1866 * fixed-size data structures.
1869 ice_flow_set_fld(struct ice_flow_seg_info *seg, enum ice_flow_field fld,
1870 u16 val_loc, u16 mask_loc, u16 last_loc, bool range)
1872 enum ice_flow_fld_match_type t = range ?
1873 ICE_FLOW_FLD_TYPE_RANGE : ICE_FLOW_FLD_TYPE_REG;
1875 ice_flow_set_fld_ext(seg, fld, t, val_loc, mask_loc, last_loc);
1879 * ice_flow_add_fld_raw - sets locations of a raw field from entry's input buf
1880 * @seg: packet segment the field being set belongs to
1881 * @off: offset of the raw field from the beginning of the segment in bytes
1882 * @len: length of the raw pattern to be matched
1883 * @val_loc: location of the value to match from entry's input buffer
1884 * @mask_loc: location of mask value from entry's input buffer
1886 * This function specifies the offset of the raw field to be match from the
1887 * beginning of the specified packet segment, and the locations, in the form of
1888 * byte offsets from the start of the input buffer for a flow entry, from where
1889 * the value to match and the mask value to be extracted. These locations are
1890 * then stored in the flow profile. When adding flow entries to the associated
1891 * flow profile, these locations can be used to quickly extract the values to
1892 * create the content of a match entry. This function should only be used for
1893 * fixed-size data structures.
1896 ice_flow_add_fld_raw(struct ice_flow_seg_info *seg, u16 off, u8 len,
1897 u16 val_loc, u16 mask_loc)
1899 if (seg->raws_cnt < ICE_FLOW_SEG_RAW_FLD_MAX) {
1900 seg->raws[seg->raws_cnt].off = off;
1901 seg->raws[seg->raws_cnt].info.type = ICE_FLOW_FLD_TYPE_SIZE;
1902 seg->raws[seg->raws_cnt].info.src.val = val_loc;
1903 seg->raws[seg->raws_cnt].info.src.mask = mask_loc;
1904 /* The "last" field is used to store the length of the field */
1905 seg->raws[seg->raws_cnt].info.src.last = len;
1908 /* Overflows of "raws" will be handled as an error condition later in
1909 * the flow when this information is processed.
1915 * ice_flow_rem_vsi_prof - remove VSI from flow profile
1916 * @hw: pointer to the hardware structure
1917 * @vsi_handle: software VSI handle
1918 * @prof_id: unique ID to identify this flow profile
1920 * This function removes the flow entries associated to the input
1921 * VSI handle and disassociate the VSI from the flow profile.
1923 int ice_flow_rem_vsi_prof(struct ice_hw *hw, u16 vsi_handle, u64 prof_id)
1925 struct ice_flow_prof *prof;
1928 if (!ice_is_vsi_valid(hw, vsi_handle))
1931 /* find flow profile pointer with input package block and profile ID */
1932 prof = ice_flow_find_prof_id(hw, ICE_BLK_FD, prof_id);
1934 ice_debug(hw, ICE_DBG_PKG, "Cannot find flow profile id=%llu\n",
1939 /* Remove all remaining flow entries before removing the flow profile */
1940 if (!list_empty(&prof->entries)) {
1941 struct ice_flow_entry *e, *t;
1943 mutex_lock(&prof->entries_lock);
1944 list_for_each_entry_safe(e, t, &prof->entries, l_entry) {
1945 if (e->vsi_handle != vsi_handle)
1948 status = ice_flow_rem_entry_sync(hw, ICE_BLK_FD, e);
1952 mutex_unlock(&prof->entries_lock);
1957 /* disassociate the flow profile from sw VSI handle */
1958 status = ice_flow_disassoc_prof(hw, ICE_BLK_FD, prof, vsi_handle);
1960 ice_debug(hw, ICE_DBG_PKG, "ice_flow_disassoc_prof() failed with status=%d\n",
1965 #define ICE_FLOW_RSS_SEG_HDR_L2_MASKS \
1966 (ICE_FLOW_SEG_HDR_ETH | ICE_FLOW_SEG_HDR_VLAN)
1968 #define ICE_FLOW_RSS_SEG_HDR_L3_MASKS \
1969 (ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_IPV6)
1971 #define ICE_FLOW_RSS_SEG_HDR_L4_MASKS \
1972 (ICE_FLOW_SEG_HDR_TCP | ICE_FLOW_SEG_HDR_UDP | ICE_FLOW_SEG_HDR_SCTP)
1974 #define ICE_FLOW_RSS_SEG_HDR_VAL_MASKS \
1975 (ICE_FLOW_RSS_SEG_HDR_L2_MASKS | \
1976 ICE_FLOW_RSS_SEG_HDR_L3_MASKS | \
1977 ICE_FLOW_RSS_SEG_HDR_L4_MASKS)
1980 * ice_flow_set_rss_seg_info - setup packet segments for RSS
1981 * @segs: pointer to the flow field segment(s)
1982 * @seg_cnt: segment count
1983 * @cfg: configure parameters
1985 * Helper function to extract fields from hash bitmap and use flow
1986 * header value to set flow field segment for further use in flow
1987 * profile entry or removal.
1990 ice_flow_set_rss_seg_info(struct ice_flow_seg_info *segs, u8 seg_cnt,
1991 const struct ice_rss_hash_cfg *cfg)
1993 struct ice_flow_seg_info *seg;
1997 /* set inner most segment */
1998 seg = &segs[seg_cnt - 1];
2000 for_each_set_bit(i, (const unsigned long *)&cfg->hash_flds,
2001 (u16)ICE_FLOW_FIELD_IDX_MAX)
2002 ice_flow_set_fld(seg, (enum ice_flow_field)i,
2003 ICE_FLOW_FLD_OFF_INVAL, ICE_FLOW_FLD_OFF_INVAL,
2004 ICE_FLOW_FLD_OFF_INVAL, false);
2006 ICE_FLOW_SET_HDRS(seg, cfg->addl_hdrs);
2008 /* set outer most header */
2009 if (cfg->hdr_type == ICE_RSS_INNER_HEADERS_W_OUTER_IPV4)
2010 segs[ICE_RSS_OUTER_HEADERS].hdrs |= ICE_FLOW_SEG_HDR_IPV4 |
2011 ICE_FLOW_SEG_HDR_IPV_OTHER;
2012 else if (cfg->hdr_type == ICE_RSS_INNER_HEADERS_W_OUTER_IPV6)
2013 segs[ICE_RSS_OUTER_HEADERS].hdrs |= ICE_FLOW_SEG_HDR_IPV6 |
2014 ICE_FLOW_SEG_HDR_IPV_OTHER;
2016 if (seg->hdrs & ~ICE_FLOW_RSS_SEG_HDR_VAL_MASKS &
2017 ~ICE_FLOW_RSS_HDRS_INNER_MASK & ~ICE_FLOW_SEG_HDR_IPV_OTHER)
2020 val = (u64)(seg->hdrs & ICE_FLOW_RSS_SEG_HDR_L3_MASKS);
2021 if (val && !is_power_of_2(val))
2024 val = (u64)(seg->hdrs & ICE_FLOW_RSS_SEG_HDR_L4_MASKS);
2025 if (val && !is_power_of_2(val))
2032 * ice_rem_vsi_rss_list - remove VSI from RSS list
2033 * @hw: pointer to the hardware structure
2034 * @vsi_handle: software VSI handle
2036 * Remove the VSI from all RSS configurations in the list.
2038 void ice_rem_vsi_rss_list(struct ice_hw *hw, u16 vsi_handle)
2040 struct ice_rss_cfg *r, *tmp;
2042 if (list_empty(&hw->rss_list_head))
2045 mutex_lock(&hw->rss_locks);
2046 list_for_each_entry_safe(r, tmp, &hw->rss_list_head, l_entry)
2047 if (test_and_clear_bit(vsi_handle, r->vsis))
2048 if (bitmap_empty(r->vsis, ICE_MAX_VSI)) {
2049 list_del(&r->l_entry);
2050 devm_kfree(ice_hw_to_dev(hw), r);
2052 mutex_unlock(&hw->rss_locks);
2056 * ice_rem_vsi_rss_cfg - remove RSS configurations associated with VSI
2057 * @hw: pointer to the hardware structure
2058 * @vsi_handle: software VSI handle
2060 * This function will iterate through all flow profiles and disassociate
2061 * the VSI from that profile. If the flow profile has no VSIs it will
2064 int ice_rem_vsi_rss_cfg(struct ice_hw *hw, u16 vsi_handle)
2066 const enum ice_block blk = ICE_BLK_RSS;
2067 struct ice_flow_prof *p, *t;
2070 if (!ice_is_vsi_valid(hw, vsi_handle))
2073 if (list_empty(&hw->fl_profs[blk]))
2076 mutex_lock(&hw->rss_locks);
2077 list_for_each_entry_safe(p, t, &hw->fl_profs[blk], l_entry)
2078 if (test_bit(vsi_handle, p->vsis)) {
2079 status = ice_flow_disassoc_prof(hw, blk, p, vsi_handle);
2083 if (bitmap_empty(p->vsis, ICE_MAX_VSI)) {
2084 status = ice_flow_rem_prof(hw, blk, p->id);
2089 mutex_unlock(&hw->rss_locks);
2095 * ice_get_rss_hdr_type - get a RSS profile's header type
2096 * @prof: RSS flow profile
2098 static enum ice_rss_cfg_hdr_type
2099 ice_get_rss_hdr_type(struct ice_flow_prof *prof)
2101 if (prof->segs_cnt == ICE_FLOW_SEG_SINGLE) {
2102 return ICE_RSS_OUTER_HEADERS;
2103 } else if (prof->segs_cnt == ICE_FLOW_SEG_MAX) {
2104 const struct ice_flow_seg_info *s;
2106 s = &prof->segs[ICE_RSS_OUTER_HEADERS];
2107 if (s->hdrs == ICE_FLOW_SEG_HDR_NONE)
2108 return ICE_RSS_INNER_HEADERS;
2109 if (s->hdrs & ICE_FLOW_SEG_HDR_IPV4)
2110 return ICE_RSS_INNER_HEADERS_W_OUTER_IPV4;
2111 if (s->hdrs & ICE_FLOW_SEG_HDR_IPV6)
2112 return ICE_RSS_INNER_HEADERS_W_OUTER_IPV6;
2115 return ICE_RSS_ANY_HEADERS;
2119 ice_rss_match_prof(struct ice_rss_cfg *r, struct ice_flow_prof *prof,
2120 enum ice_rss_cfg_hdr_type hdr_type)
2122 return (r->hash.hdr_type == hdr_type &&
2123 r->hash.hash_flds == prof->segs[prof->segs_cnt - 1].match &&
2124 r->hash.addl_hdrs == prof->segs[prof->segs_cnt - 1].hdrs);
2128 * ice_rem_rss_list - remove RSS configuration from list
2129 * @hw: pointer to the hardware structure
2130 * @vsi_handle: software VSI handle
2131 * @prof: pointer to flow profile
2133 * Assumption: lock has already been acquired for RSS list
2136 ice_rem_rss_list(struct ice_hw *hw, u16 vsi_handle, struct ice_flow_prof *prof)
2138 enum ice_rss_cfg_hdr_type hdr_type;
2139 struct ice_rss_cfg *r, *tmp;
2141 /* Search for RSS hash fields associated to the VSI that match the
2142 * hash configurations associated to the flow profile. If found
2143 * remove from the RSS entry list of the VSI context and delete entry.
2145 hdr_type = ice_get_rss_hdr_type(prof);
2146 list_for_each_entry_safe(r, tmp, &hw->rss_list_head, l_entry)
2147 if (ice_rss_match_prof(r, prof, hdr_type)) {
2148 clear_bit(vsi_handle, r->vsis);
2149 if (bitmap_empty(r->vsis, ICE_MAX_VSI)) {
2150 list_del(&r->l_entry);
2151 devm_kfree(ice_hw_to_dev(hw), r);
2158 * ice_add_rss_list - add RSS configuration to list
2159 * @hw: pointer to the hardware structure
2160 * @vsi_handle: software VSI handle
2161 * @prof: pointer to flow profile
2163 * Assumption: lock has already been acquired for RSS list
2166 ice_add_rss_list(struct ice_hw *hw, u16 vsi_handle, struct ice_flow_prof *prof)
2168 enum ice_rss_cfg_hdr_type hdr_type;
2169 struct ice_rss_cfg *r, *rss_cfg;
2171 hdr_type = ice_get_rss_hdr_type(prof);
2172 list_for_each_entry(r, &hw->rss_list_head, l_entry)
2173 if (ice_rss_match_prof(r, prof, hdr_type)) {
2174 set_bit(vsi_handle, r->vsis);
2178 rss_cfg = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*rss_cfg),
2183 rss_cfg->hash.hash_flds = prof->segs[prof->segs_cnt - 1].match;
2184 rss_cfg->hash.addl_hdrs = prof->segs[prof->segs_cnt - 1].hdrs;
2185 rss_cfg->hash.hdr_type = hdr_type;
2186 rss_cfg->hash.symm = prof->symm;
2187 set_bit(vsi_handle, rss_cfg->vsis);
2189 list_add_tail(&rss_cfg->l_entry, &hw->rss_list_head);
2195 * ice_rss_config_xor_word - set the HSYMM registers for one input set word
2196 * @hw: pointer to the hardware structure
2197 * @prof_id: RSS hardware profile id
2198 * @src: the FV index used by the protocol's source field
2199 * @dst: the FV index used by the protocol's destination field
2201 * Write to the HSYMM register with the index of @src FV the value of the @dst
2202 * FV index. This will tell the hardware to XOR HSYMM[src] with INSET[dst]
2203 * while calculating the RSS input set.
2206 ice_rss_config_xor_word(struct ice_hw *hw, u8 prof_id, u8 src, u8 dst)
2208 u32 val, reg, bits_shift;
2211 reg_idx = src / GLQF_HSYMM_REG_SIZE;
2212 bits_shift = ((src % GLQF_HSYMM_REG_SIZE) << 3);
2213 val = dst | GLQF_HSYMM_ENABLE_BIT;
2215 reg = rd32(hw, GLQF_HSYMM(prof_id, reg_idx));
2216 reg = (reg & ~(0xff << bits_shift)) | (val << bits_shift);
2217 wr32(hw, GLQF_HSYMM(prof_id, reg_idx), reg);
2221 * ice_rss_config_xor - set the symmetric registers for a profile's protocol
2222 * @hw: pointer to the hardware structure
2223 * @prof_id: RSS hardware profile id
2224 * @src: the FV index used by the protocol's source field
2225 * @dst: the FV index used by the protocol's destination field
2226 * @len: length of the source/destination fields in words
2229 ice_rss_config_xor(struct ice_hw *hw, u8 prof_id, u8 src, u8 dst, u8 len)
2232 ICE_FLOW_SW_FIELD_VECTOR_MAX / ICE_FLOW_FV_EXTRACT_SZ - 1;
2235 for (i = 0; i < len; i++) {
2236 ice_rss_config_xor_word(hw, prof_id,
2237 /* Yes, field vector in GLQF_HSYMM and
2238 * GLQF_HINSET is inversed!
2240 fv_last_word - (src + i),
2241 fv_last_word - (dst + i));
2242 ice_rss_config_xor_word(hw, prof_id,
2243 fv_last_word - (dst + i),
2244 fv_last_word - (src + i));
2249 * ice_rss_set_symm - set the symmetric settings for an RSS profile
2250 * @hw: pointer to the hardware structure
2251 * @prof: pointer to flow profile
2253 * The symmetric hash will result from XORing the protocol's fields with
2254 * indexes in GLQF_HSYMM and GLQF_HINSET. This function configures the profile's
2255 * GLQF_HSYMM registers.
2257 static void ice_rss_set_symm(struct ice_hw *hw, struct ice_flow_prof *prof)
2259 struct ice_prof_map *map;
2262 mutex_lock(&hw->blk[ICE_BLK_RSS].es.prof_map_lock);
2263 map = ice_search_prof_id(hw, ICE_BLK_RSS, prof->id);
2265 prof_id = map->prof_id;
2266 mutex_unlock(&hw->blk[ICE_BLK_RSS].es.prof_map_lock);
2271 /* clear to default */
2272 for (m = 0; m < GLQF_HSYMM_REG_PER_PROF; m++)
2273 wr32(hw, GLQF_HSYMM(prof_id, m), 0);
2276 struct ice_flow_seg_xtrct *ipv4_src, *ipv4_dst;
2277 struct ice_flow_seg_xtrct *ipv6_src, *ipv6_dst;
2278 struct ice_flow_seg_xtrct *sctp_src, *sctp_dst;
2279 struct ice_flow_seg_xtrct *tcp_src, *tcp_dst;
2280 struct ice_flow_seg_xtrct *udp_src, *udp_dst;
2281 struct ice_flow_seg_info *seg;
2283 seg = &prof->segs[prof->segs_cnt - 1];
2285 ipv4_src = &seg->fields[ICE_FLOW_FIELD_IDX_IPV4_SA].xtrct;
2286 ipv4_dst = &seg->fields[ICE_FLOW_FIELD_IDX_IPV4_DA].xtrct;
2288 ipv6_src = &seg->fields[ICE_FLOW_FIELD_IDX_IPV6_SA].xtrct;
2289 ipv6_dst = &seg->fields[ICE_FLOW_FIELD_IDX_IPV6_DA].xtrct;
2291 tcp_src = &seg->fields[ICE_FLOW_FIELD_IDX_TCP_SRC_PORT].xtrct;
2292 tcp_dst = &seg->fields[ICE_FLOW_FIELD_IDX_TCP_DST_PORT].xtrct;
2294 udp_src = &seg->fields[ICE_FLOW_FIELD_IDX_UDP_SRC_PORT].xtrct;
2295 udp_dst = &seg->fields[ICE_FLOW_FIELD_IDX_UDP_DST_PORT].xtrct;
2297 sctp_src = &seg->fields[ICE_FLOW_FIELD_IDX_SCTP_SRC_PORT].xtrct;
2298 sctp_dst = &seg->fields[ICE_FLOW_FIELD_IDX_SCTP_DST_PORT].xtrct;
2301 if (ipv4_src->prot_id != 0 && ipv4_dst->prot_id != 0)
2302 ice_rss_config_xor(hw, prof_id,
2303 ipv4_src->idx, ipv4_dst->idx, 2);
2306 if (ipv6_src->prot_id != 0 && ipv6_dst->prot_id != 0)
2307 ice_rss_config_xor(hw, prof_id,
2308 ipv6_src->idx, ipv6_dst->idx, 8);
2311 if (tcp_src->prot_id != 0 && tcp_dst->prot_id != 0)
2312 ice_rss_config_xor(hw, prof_id,
2313 tcp_src->idx, tcp_dst->idx, 1);
2316 if (udp_src->prot_id != 0 && udp_dst->prot_id != 0)
2317 ice_rss_config_xor(hw, prof_id,
2318 udp_src->idx, udp_dst->idx, 1);
2321 if (sctp_src->prot_id != 0 && sctp_dst->prot_id != 0)
2322 ice_rss_config_xor(hw, prof_id,
2323 sctp_src->idx, sctp_dst->idx, 1);
2328 * ice_add_rss_cfg_sync - add an RSS configuration
2329 * @hw: pointer to the hardware structure
2330 * @vsi_handle: software VSI handle
2331 * @cfg: configure parameters
2333 * Assumption: lock has already been acquired for RSS list
2336 ice_add_rss_cfg_sync(struct ice_hw *hw, u16 vsi_handle,
2337 const struct ice_rss_hash_cfg *cfg)
2339 const enum ice_block blk = ICE_BLK_RSS;
2340 struct ice_flow_prof *prof = NULL;
2341 struct ice_flow_seg_info *segs;
2345 segs_cnt = (cfg->hdr_type == ICE_RSS_OUTER_HEADERS) ?
2346 ICE_FLOW_SEG_SINGLE : ICE_FLOW_SEG_MAX;
2348 segs = kcalloc(segs_cnt, sizeof(*segs), GFP_KERNEL);
2352 /* Construct the packet segment info from the hashed fields */
2353 status = ice_flow_set_rss_seg_info(segs, segs_cnt, cfg);
2357 /* Search for a flow profile that has matching headers, hash fields,
2358 * symm and has the input VSI associated to it. If found, no further
2359 * operations required and exit.
2361 prof = ice_flow_find_prof_conds(hw, blk, ICE_FLOW_RX, segs, segs_cnt,
2362 cfg->symm, vsi_handle,
2363 ICE_FLOW_FIND_PROF_CHK_FLDS |
2364 ICE_FLOW_FIND_PROF_CHK_SYMM |
2365 ICE_FLOW_FIND_PROF_CHK_VSI);
2369 /* Check if a flow profile exists with the same protocol headers and
2370 * associated with the input VSI. If so disassociate the VSI from
2371 * this profile. The VSI will be added to a new profile created with
2372 * the protocol header and new hash field configuration.
2374 prof = ice_flow_find_prof_conds(hw, blk, ICE_FLOW_RX, segs, segs_cnt,
2375 cfg->symm, vsi_handle,
2376 ICE_FLOW_FIND_PROF_CHK_VSI);
2378 status = ice_flow_disassoc_prof(hw, blk, prof, vsi_handle);
2380 ice_rem_rss_list(hw, vsi_handle, prof);
2384 /* Remove profile if it has no VSIs associated */
2385 if (bitmap_empty(prof->vsis, ICE_MAX_VSI)) {
2386 status = ice_flow_rem_prof(hw, blk, prof->id);
2392 /* Search for a profile that has the same match fields and symmetric
2393 * setting. If this exists then associate the VSI to this profile.
2395 prof = ice_flow_find_prof_conds(hw, blk, ICE_FLOW_RX, segs, segs_cnt,
2396 cfg->symm, vsi_handle,
2397 ICE_FLOW_FIND_PROF_CHK_SYMM |
2398 ICE_FLOW_FIND_PROF_CHK_FLDS);
2400 status = ice_flow_assoc_prof(hw, blk, prof, vsi_handle);
2402 status = ice_add_rss_list(hw, vsi_handle, prof);
2406 /* Create a new flow profile with packet segment information. */
2407 status = ice_flow_add_prof(hw, blk, ICE_FLOW_RX,
2408 segs, segs_cnt, cfg->symm, &prof);
2412 prof->symm = cfg->symm;
2413 ice_rss_set_symm(hw, prof);
2414 status = ice_flow_assoc_prof(hw, blk, prof, vsi_handle);
2415 /* If association to a new flow profile failed then this profile can
2419 ice_flow_rem_prof(hw, blk, prof->id);
2423 status = ice_add_rss_list(hw, vsi_handle, prof);
2431 * ice_add_rss_cfg - add an RSS configuration with specified hashed fields
2432 * @hw: pointer to the hardware structure
2433 * @vsi: VSI to add the RSS configuration to
2434 * @cfg: configure parameters
2436 * This function will generate a flow profile based on fields associated with
2437 * the input fields to hash on, the flow type and use the VSI number to add
2438 * a flow entry to the profile.
2441 ice_add_rss_cfg(struct ice_hw *hw, struct ice_vsi *vsi,
2442 const struct ice_rss_hash_cfg *cfg)
2444 struct ice_rss_hash_cfg local_cfg;
2451 vsi_handle = vsi->idx;
2452 if (!ice_is_vsi_valid(hw, vsi_handle) ||
2453 !cfg || cfg->hdr_type > ICE_RSS_ANY_HEADERS ||
2454 cfg->hash_flds == ICE_HASH_INVALID)
2457 mutex_lock(&hw->rss_locks);
2459 if (cfg->hdr_type < ICE_RSS_ANY_HEADERS) {
2460 status = ice_add_rss_cfg_sync(hw, vsi_handle, &local_cfg);
2462 local_cfg.hdr_type = ICE_RSS_OUTER_HEADERS;
2463 status = ice_add_rss_cfg_sync(hw, vsi_handle, &local_cfg);
2465 local_cfg.hdr_type = ICE_RSS_INNER_HEADERS;
2466 status = ice_add_rss_cfg_sync(hw, vsi_handle,
2470 mutex_unlock(&hw->rss_locks);
2476 * ice_rem_rss_cfg_sync - remove an existing RSS configuration
2477 * @hw: pointer to the hardware structure
2478 * @vsi_handle: software VSI handle
2479 * @cfg: configure parameters
2481 * Assumption: lock has already been acquired for RSS list
2484 ice_rem_rss_cfg_sync(struct ice_hw *hw, u16 vsi_handle,
2485 const struct ice_rss_hash_cfg *cfg)
2487 const enum ice_block blk = ICE_BLK_RSS;
2488 struct ice_flow_seg_info *segs;
2489 struct ice_flow_prof *prof;
2493 segs_cnt = (cfg->hdr_type == ICE_RSS_OUTER_HEADERS) ?
2494 ICE_FLOW_SEG_SINGLE : ICE_FLOW_SEG_MAX;
2495 segs = kcalloc(segs_cnt, sizeof(*segs), GFP_KERNEL);
2499 /* Construct the packet segment info from the hashed fields */
2500 status = ice_flow_set_rss_seg_info(segs, segs_cnt, cfg);
2504 prof = ice_flow_find_prof_conds(hw, blk, ICE_FLOW_RX, segs, segs_cnt,
2505 cfg->symm, vsi_handle,
2506 ICE_FLOW_FIND_PROF_CHK_FLDS);
2512 status = ice_flow_disassoc_prof(hw, blk, prof, vsi_handle);
2516 /* Remove RSS configuration from VSI context before deleting
2519 ice_rem_rss_list(hw, vsi_handle, prof);
2521 if (bitmap_empty(prof->vsis, ICE_MAX_VSI))
2522 status = ice_flow_rem_prof(hw, blk, prof->id);
2530 * ice_rem_rss_cfg - remove an existing RSS config with matching hashed fields
2531 * @hw: pointer to the hardware structure
2532 * @vsi_handle: software VSI handle
2533 * @cfg: configure parameters
2535 * This function will lookup the flow profile based on the input
2536 * hash field bitmap, iterate through the profile entry list of
2537 * that profile and find entry associated with input VSI to be
2538 * removed. Calls are made to underlying flow apis which will in
2539 * turn build or update buffers for RSS XLT1 section.
2542 ice_rem_rss_cfg(struct ice_hw *hw, u16 vsi_handle,
2543 const struct ice_rss_hash_cfg *cfg)
2545 struct ice_rss_hash_cfg local_cfg;
2548 if (!ice_is_vsi_valid(hw, vsi_handle) ||
2549 !cfg || cfg->hdr_type > ICE_RSS_ANY_HEADERS ||
2550 cfg->hash_flds == ICE_HASH_INVALID)
2553 mutex_lock(&hw->rss_locks);
2555 if (cfg->hdr_type < ICE_RSS_ANY_HEADERS) {
2556 status = ice_rem_rss_cfg_sync(hw, vsi_handle, &local_cfg);
2558 local_cfg.hdr_type = ICE_RSS_OUTER_HEADERS;
2559 status = ice_rem_rss_cfg_sync(hw, vsi_handle, &local_cfg);
2561 local_cfg.hdr_type = ICE_RSS_INNER_HEADERS;
2562 status = ice_rem_rss_cfg_sync(hw, vsi_handle,
2566 mutex_unlock(&hw->rss_locks);
2571 /* Mapping of AVF hash bit fields to an L3-L4 hash combination.
2572 * As the ice_flow_avf_hdr_field represent individual bit shifts in a hash,
2573 * convert its values to their appropriate flow L3, L4 values.
2575 #define ICE_FLOW_AVF_RSS_IPV4_MASKS \
2576 (BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_OTHER) | \
2577 BIT_ULL(ICE_AVF_FLOW_FIELD_FRAG_IPV4))
2578 #define ICE_FLOW_AVF_RSS_TCP_IPV4_MASKS \
2579 (BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_TCP_SYN_NO_ACK) | \
2580 BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_TCP))
2581 #define ICE_FLOW_AVF_RSS_UDP_IPV4_MASKS \
2582 (BIT_ULL(ICE_AVF_FLOW_FIELD_UNICAST_IPV4_UDP) | \
2583 BIT_ULL(ICE_AVF_FLOW_FIELD_MULTICAST_IPV4_UDP) | \
2584 BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_UDP))
2585 #define ICE_FLOW_AVF_RSS_ALL_IPV4_MASKS \
2586 (ICE_FLOW_AVF_RSS_TCP_IPV4_MASKS | ICE_FLOW_AVF_RSS_UDP_IPV4_MASKS | \
2587 ICE_FLOW_AVF_RSS_IPV4_MASKS | BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_SCTP))
2589 #define ICE_FLOW_AVF_RSS_IPV6_MASKS \
2590 (BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_OTHER) | \
2591 BIT_ULL(ICE_AVF_FLOW_FIELD_FRAG_IPV6))
2592 #define ICE_FLOW_AVF_RSS_UDP_IPV6_MASKS \
2593 (BIT_ULL(ICE_AVF_FLOW_FIELD_UNICAST_IPV6_UDP) | \
2594 BIT_ULL(ICE_AVF_FLOW_FIELD_MULTICAST_IPV6_UDP) | \
2595 BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_UDP))
2596 #define ICE_FLOW_AVF_RSS_TCP_IPV6_MASKS \
2597 (BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_TCP_SYN_NO_ACK) | \
2598 BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_TCP))
2599 #define ICE_FLOW_AVF_RSS_ALL_IPV6_MASKS \
2600 (ICE_FLOW_AVF_RSS_TCP_IPV6_MASKS | ICE_FLOW_AVF_RSS_UDP_IPV6_MASKS | \
2601 ICE_FLOW_AVF_RSS_IPV6_MASKS | BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_SCTP))
2604 * ice_add_avf_rss_cfg - add an RSS configuration for AVF driver
2605 * @hw: pointer to the hardware structure
2607 * @avf_hash: hash bit fields (ICE_AVF_FLOW_FIELD_*) to configure
2609 * This function will take the hash bitmap provided by the AVF driver via a
2610 * message, convert it to ICE-compatible values, and configure RSS flow
2613 int ice_add_avf_rss_cfg(struct ice_hw *hw, struct ice_vsi *vsi, u64 avf_hash)
2615 struct ice_rss_hash_cfg hcfg;
2623 vsi_handle = vsi->idx;
2624 if (avf_hash == ICE_AVF_FLOW_FIELD_INVALID ||
2625 !ice_is_vsi_valid(hw, vsi_handle))
2628 /* Make sure no unsupported bits are specified */
2629 if (avf_hash & ~(ICE_FLOW_AVF_RSS_ALL_IPV4_MASKS |
2630 ICE_FLOW_AVF_RSS_ALL_IPV6_MASKS))
2633 hash_flds = avf_hash;
2635 /* Always create an L3 RSS configuration for any L4 RSS configuration */
2636 if (hash_flds & ICE_FLOW_AVF_RSS_ALL_IPV4_MASKS)
2637 hash_flds |= ICE_FLOW_AVF_RSS_IPV4_MASKS;
2639 if (hash_flds & ICE_FLOW_AVF_RSS_ALL_IPV6_MASKS)
2640 hash_flds |= ICE_FLOW_AVF_RSS_IPV6_MASKS;
2642 /* Create the corresponding RSS configuration for each valid hash bit */
2644 u64 rss_hash = ICE_HASH_INVALID;
2646 if (hash_flds & ICE_FLOW_AVF_RSS_ALL_IPV4_MASKS) {
2647 if (hash_flds & ICE_FLOW_AVF_RSS_IPV4_MASKS) {
2648 rss_hash = ICE_FLOW_HASH_IPV4;
2649 hash_flds &= ~ICE_FLOW_AVF_RSS_IPV4_MASKS;
2650 } else if (hash_flds &
2651 ICE_FLOW_AVF_RSS_TCP_IPV4_MASKS) {
2652 rss_hash = ICE_FLOW_HASH_IPV4 |
2653 ICE_FLOW_HASH_TCP_PORT;
2654 hash_flds &= ~ICE_FLOW_AVF_RSS_TCP_IPV4_MASKS;
2655 } else if (hash_flds &
2656 ICE_FLOW_AVF_RSS_UDP_IPV4_MASKS) {
2657 rss_hash = ICE_FLOW_HASH_IPV4 |
2658 ICE_FLOW_HASH_UDP_PORT;
2659 hash_flds &= ~ICE_FLOW_AVF_RSS_UDP_IPV4_MASKS;
2660 } else if (hash_flds &
2661 BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_SCTP)) {
2662 rss_hash = ICE_FLOW_HASH_IPV4 |
2663 ICE_FLOW_HASH_SCTP_PORT;
2665 ~BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_SCTP);
2667 } else if (hash_flds & ICE_FLOW_AVF_RSS_ALL_IPV6_MASKS) {
2668 if (hash_flds & ICE_FLOW_AVF_RSS_IPV6_MASKS) {
2669 rss_hash = ICE_FLOW_HASH_IPV6;
2670 hash_flds &= ~ICE_FLOW_AVF_RSS_IPV6_MASKS;
2671 } else if (hash_flds &
2672 ICE_FLOW_AVF_RSS_TCP_IPV6_MASKS) {
2673 rss_hash = ICE_FLOW_HASH_IPV6 |
2674 ICE_FLOW_HASH_TCP_PORT;
2675 hash_flds &= ~ICE_FLOW_AVF_RSS_TCP_IPV6_MASKS;
2676 } else if (hash_flds &
2677 ICE_FLOW_AVF_RSS_UDP_IPV6_MASKS) {
2678 rss_hash = ICE_FLOW_HASH_IPV6 |
2679 ICE_FLOW_HASH_UDP_PORT;
2680 hash_flds &= ~ICE_FLOW_AVF_RSS_UDP_IPV6_MASKS;
2681 } else if (hash_flds &
2682 BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_SCTP)) {
2683 rss_hash = ICE_FLOW_HASH_IPV6 |
2684 ICE_FLOW_HASH_SCTP_PORT;
2686 ~BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_SCTP);
2690 if (rss_hash == ICE_HASH_INVALID)
2693 hcfg.addl_hdrs = ICE_FLOW_SEG_HDR_NONE;
2694 hcfg.hash_flds = rss_hash;
2695 hcfg.hdr_type = ICE_RSS_ANY_HEADERS;
2697 status = ice_add_rss_cfg(hw, vsi, &hcfg);
2705 static bool rss_cfg_symm_valid(u64 hfld)
2707 return !((!!(hfld & ICE_FLOW_HASH_FLD_IPV4_SA) ^
2708 !!(hfld & ICE_FLOW_HASH_FLD_IPV4_DA)) ||
2709 (!!(hfld & ICE_FLOW_HASH_FLD_IPV6_SA) ^
2710 !!(hfld & ICE_FLOW_HASH_FLD_IPV6_DA)) ||
2711 (!!(hfld & ICE_FLOW_HASH_FLD_TCP_SRC_PORT) ^
2712 !!(hfld & ICE_FLOW_HASH_FLD_TCP_DST_PORT)) ||
2713 (!!(hfld & ICE_FLOW_HASH_FLD_UDP_SRC_PORT) ^
2714 !!(hfld & ICE_FLOW_HASH_FLD_UDP_DST_PORT)) ||
2715 (!!(hfld & ICE_FLOW_HASH_FLD_SCTP_SRC_PORT) ^
2716 !!(hfld & ICE_FLOW_HASH_FLD_SCTP_DST_PORT)));
2720 * ice_set_rss_cfg_symm - set symmtery for all VSI's RSS configurations
2721 * @hw: pointer to the hardware structure
2722 * @vsi: VSI to set/unset Symmetric RSS
2723 * @symm: TRUE to set Symmetric RSS hashing
2725 int ice_set_rss_cfg_symm(struct ice_hw *hw, struct ice_vsi *vsi, bool symm)
2727 struct ice_rss_hash_cfg local;
2728 struct ice_rss_cfg *r, *tmp;
2729 u16 vsi_handle = vsi->idx;
2732 if (!ice_is_vsi_valid(hw, vsi_handle))
2735 mutex_lock(&hw->rss_locks);
2736 list_for_each_entry_safe(r, tmp, &hw->rss_list_head, l_entry) {
2737 if (test_bit(vsi_handle, r->vsis) && r->hash.symm != symm) {
2740 if (symm && !rss_cfg_symm_valid(r->hash.hash_flds))
2743 status = ice_add_rss_cfg_sync(hw, vsi_handle, &local);
2748 mutex_unlock(&hw->rss_locks);
2754 * ice_replay_rss_cfg - replay RSS configurations associated with VSI
2755 * @hw: pointer to the hardware structure
2756 * @vsi_handle: software VSI handle
2758 int ice_replay_rss_cfg(struct ice_hw *hw, u16 vsi_handle)
2760 struct ice_rss_cfg *r;
2763 if (!ice_is_vsi_valid(hw, vsi_handle))
2766 mutex_lock(&hw->rss_locks);
2767 list_for_each_entry(r, &hw->rss_list_head, l_entry) {
2768 if (test_bit(vsi_handle, r->vsis)) {
2769 status = ice_add_rss_cfg_sync(hw, vsi_handle, &r->hash);
2774 mutex_unlock(&hw->rss_locks);
2780 * ice_get_rss_cfg - returns hashed fields for the given header types
2781 * @hw: pointer to the hardware structure
2782 * @vsi_handle: software VSI handle
2783 * @hdrs: protocol header type
2784 * @symm: whether the RSS is symmetric (bool, output)
2786 * This function will return the match fields of the first instance of flow
2787 * profile having the given header types and containing input VSI
2789 u64 ice_get_rss_cfg(struct ice_hw *hw, u16 vsi_handle, u32 hdrs, bool *symm)
2791 u64 rss_hash = ICE_HASH_INVALID;
2792 struct ice_rss_cfg *r;
2794 /* verify if the protocol header is non zero and VSI is valid */
2795 if (hdrs == ICE_FLOW_SEG_HDR_NONE || !ice_is_vsi_valid(hw, vsi_handle))
2796 return ICE_HASH_INVALID;
2798 mutex_lock(&hw->rss_locks);
2799 list_for_each_entry(r, &hw->rss_list_head, l_entry)
2800 if (test_bit(vsi_handle, r->vsis) &&
2801 r->hash.addl_hdrs == hdrs) {
2802 rss_hash = r->hash.hash_flds;
2803 *symm = r->hash.symm;
2806 mutex_unlock(&hw->rss_locks);