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_eh[] = {
413 { ICE_MAC_IPV4_GTPU_IPV4_FRAG, ICE_PTYPE_ATTR_GTP_PDU_EH },
414 { ICE_MAC_IPV4_GTPU_IPV4_PAY, ICE_PTYPE_ATTR_GTP_PDU_EH },
415 { ICE_MAC_IPV4_GTPU_IPV4_UDP_PAY, ICE_PTYPE_ATTR_GTP_PDU_EH },
416 { ICE_MAC_IPV4_GTPU_IPV4_TCP, ICE_PTYPE_ATTR_GTP_PDU_EH },
417 { ICE_MAC_IPV4_GTPU_IPV4_ICMP, ICE_PTYPE_ATTR_GTP_PDU_EH },
418 { ICE_MAC_IPV6_GTPU_IPV4_FRAG, ICE_PTYPE_ATTR_GTP_PDU_EH },
419 { ICE_MAC_IPV6_GTPU_IPV4_PAY, ICE_PTYPE_ATTR_GTP_PDU_EH },
420 { ICE_MAC_IPV6_GTPU_IPV4_UDP_PAY, ICE_PTYPE_ATTR_GTP_PDU_EH },
421 { ICE_MAC_IPV6_GTPU_IPV4_TCP, ICE_PTYPE_ATTR_GTP_PDU_EH },
422 { ICE_MAC_IPV6_GTPU_IPV4_ICMP, ICE_PTYPE_ATTR_GTP_PDU_EH },
423 { ICE_MAC_IPV4_GTPU_IPV6_FRAG, ICE_PTYPE_ATTR_GTP_PDU_EH },
424 { ICE_MAC_IPV4_GTPU_IPV6_PAY, ICE_PTYPE_ATTR_GTP_PDU_EH },
425 { ICE_MAC_IPV4_GTPU_IPV6_UDP_PAY, ICE_PTYPE_ATTR_GTP_PDU_EH },
426 { ICE_MAC_IPV4_GTPU_IPV6_TCP, ICE_PTYPE_ATTR_GTP_PDU_EH },
427 { ICE_MAC_IPV4_GTPU_IPV6_ICMPV6, ICE_PTYPE_ATTR_GTP_PDU_EH },
428 { ICE_MAC_IPV6_GTPU_IPV6_FRAG, ICE_PTYPE_ATTR_GTP_PDU_EH },
429 { ICE_MAC_IPV6_GTPU_IPV6_PAY, ICE_PTYPE_ATTR_GTP_PDU_EH },
430 { ICE_MAC_IPV6_GTPU_IPV6_UDP_PAY, ICE_PTYPE_ATTR_GTP_PDU_EH },
431 { ICE_MAC_IPV6_GTPU_IPV6_TCP, ICE_PTYPE_ATTR_GTP_PDU_EH },
432 { ICE_MAC_IPV6_GTPU_IPV6_ICMPV6, ICE_PTYPE_ATTR_GTP_PDU_EH },
435 static const struct ice_ptype_attributes ice_attr_gtpu_down[] = {
436 { ICE_MAC_IPV4_GTPU_IPV4_FRAG, ICE_PTYPE_ATTR_GTP_DOWNLINK },
437 { ICE_MAC_IPV4_GTPU_IPV4_PAY, ICE_PTYPE_ATTR_GTP_DOWNLINK },
438 { ICE_MAC_IPV4_GTPU_IPV4_UDP_PAY, ICE_PTYPE_ATTR_GTP_DOWNLINK },
439 { ICE_MAC_IPV4_GTPU_IPV4_TCP, ICE_PTYPE_ATTR_GTP_DOWNLINK },
440 { ICE_MAC_IPV4_GTPU_IPV4_ICMP, ICE_PTYPE_ATTR_GTP_DOWNLINK },
441 { ICE_MAC_IPV6_GTPU_IPV4_FRAG, ICE_PTYPE_ATTR_GTP_DOWNLINK },
442 { ICE_MAC_IPV6_GTPU_IPV4_PAY, ICE_PTYPE_ATTR_GTP_DOWNLINK },
443 { ICE_MAC_IPV6_GTPU_IPV4_UDP_PAY, ICE_PTYPE_ATTR_GTP_DOWNLINK },
444 { ICE_MAC_IPV6_GTPU_IPV4_TCP, ICE_PTYPE_ATTR_GTP_DOWNLINK },
445 { ICE_MAC_IPV6_GTPU_IPV4_ICMP, ICE_PTYPE_ATTR_GTP_DOWNLINK },
446 { ICE_MAC_IPV4_GTPU_IPV6_FRAG, ICE_PTYPE_ATTR_GTP_DOWNLINK },
447 { ICE_MAC_IPV4_GTPU_IPV6_PAY, ICE_PTYPE_ATTR_GTP_DOWNLINK },
448 { ICE_MAC_IPV4_GTPU_IPV6_UDP_PAY, ICE_PTYPE_ATTR_GTP_DOWNLINK },
449 { ICE_MAC_IPV4_GTPU_IPV6_TCP, ICE_PTYPE_ATTR_GTP_DOWNLINK },
450 { ICE_MAC_IPV4_GTPU_IPV6_ICMPV6, ICE_PTYPE_ATTR_GTP_DOWNLINK },
451 { ICE_MAC_IPV6_GTPU_IPV6_FRAG, ICE_PTYPE_ATTR_GTP_DOWNLINK },
452 { ICE_MAC_IPV6_GTPU_IPV6_PAY, ICE_PTYPE_ATTR_GTP_DOWNLINK },
453 { ICE_MAC_IPV6_GTPU_IPV6_UDP_PAY, ICE_PTYPE_ATTR_GTP_DOWNLINK },
454 { ICE_MAC_IPV6_GTPU_IPV6_TCP, ICE_PTYPE_ATTR_GTP_DOWNLINK },
455 { ICE_MAC_IPV6_GTPU_IPV6_ICMPV6, ICE_PTYPE_ATTR_GTP_DOWNLINK },
458 static const struct ice_ptype_attributes ice_attr_gtpu_up[] = {
459 { ICE_MAC_IPV4_GTPU_IPV4_FRAG, ICE_PTYPE_ATTR_GTP_UPLINK },
460 { ICE_MAC_IPV4_GTPU_IPV4_PAY, ICE_PTYPE_ATTR_GTP_UPLINK },
461 { ICE_MAC_IPV4_GTPU_IPV4_UDP_PAY, ICE_PTYPE_ATTR_GTP_UPLINK },
462 { ICE_MAC_IPV4_GTPU_IPV4_TCP, ICE_PTYPE_ATTR_GTP_UPLINK },
463 { ICE_MAC_IPV4_GTPU_IPV4_ICMP, ICE_PTYPE_ATTR_GTP_UPLINK },
464 { ICE_MAC_IPV6_GTPU_IPV4_FRAG, ICE_PTYPE_ATTR_GTP_UPLINK },
465 { ICE_MAC_IPV6_GTPU_IPV4_PAY, ICE_PTYPE_ATTR_GTP_UPLINK },
466 { ICE_MAC_IPV6_GTPU_IPV4_UDP_PAY, ICE_PTYPE_ATTR_GTP_UPLINK },
467 { ICE_MAC_IPV6_GTPU_IPV4_TCP, ICE_PTYPE_ATTR_GTP_UPLINK },
468 { ICE_MAC_IPV6_GTPU_IPV4_ICMP, ICE_PTYPE_ATTR_GTP_UPLINK },
469 { ICE_MAC_IPV4_GTPU_IPV6_FRAG, ICE_PTYPE_ATTR_GTP_UPLINK },
470 { ICE_MAC_IPV4_GTPU_IPV6_PAY, ICE_PTYPE_ATTR_GTP_UPLINK },
471 { ICE_MAC_IPV4_GTPU_IPV6_UDP_PAY, ICE_PTYPE_ATTR_GTP_UPLINK },
472 { ICE_MAC_IPV4_GTPU_IPV6_TCP, ICE_PTYPE_ATTR_GTP_UPLINK },
473 { ICE_MAC_IPV4_GTPU_IPV6_ICMPV6, ICE_PTYPE_ATTR_GTP_UPLINK },
474 { ICE_MAC_IPV6_GTPU_IPV6_FRAG, ICE_PTYPE_ATTR_GTP_UPLINK },
475 { ICE_MAC_IPV6_GTPU_IPV6_PAY, ICE_PTYPE_ATTR_GTP_UPLINK },
476 { ICE_MAC_IPV6_GTPU_IPV6_UDP_PAY, ICE_PTYPE_ATTR_GTP_UPLINK },
477 { ICE_MAC_IPV6_GTPU_IPV6_TCP, ICE_PTYPE_ATTR_GTP_UPLINK },
478 { ICE_MAC_IPV6_GTPU_IPV6_ICMPV6, ICE_PTYPE_ATTR_GTP_UPLINK },
481 static const u32 ice_ptypes_gtpu[] = {
482 0x00000000, 0x00000000, 0x00000000, 0x00000000,
483 0x00000000, 0x00000000, 0x00000000, 0x00000000,
484 0x00000000, 0x00000000, 0x7FFFFE00, 0x00000000,
485 0x00000000, 0x00000000, 0x00000000, 0x00000000,
486 0x00000000, 0x00000000, 0x00000000, 0x00000000,
487 0x00000000, 0x00000000, 0x00000000, 0x00000000,
488 0x00000000, 0x00000000, 0x00000000, 0x00000000,
489 0x00000000, 0x00000000, 0x00000000, 0x00000000,
492 /* Packet types for PPPoE */
493 static const u32 ice_ptypes_pppoe[] = {
494 0x00000000, 0x00000000, 0x00000000, 0x00000000,
495 0x00000000, 0x00000000, 0x00000000, 0x00000000,
496 0x00000000, 0x03ffe000, 0x00000000, 0x00000000,
497 0x00000000, 0x00000000, 0x00000000, 0x00000000,
498 0x00000000, 0x00000000, 0x00000000, 0x00000000,
499 0x00000000, 0x00000000, 0x00000000, 0x00000000,
500 0x00000000, 0x00000000, 0x00000000, 0x00000000,
501 0x00000000, 0x00000000, 0x00000000, 0x00000000,
504 /* Packet types for packets with PFCP NODE header */
505 static const u32 ice_ptypes_pfcp_node[] = {
506 0x00000000, 0x00000000, 0x00000000, 0x00000000,
507 0x00000000, 0x00000000, 0x00000000, 0x00000000,
508 0x00000000, 0x00000000, 0x80000000, 0x00000002,
509 0x00000000, 0x00000000, 0x00000000, 0x00000000,
510 0x00000000, 0x00000000, 0x00000000, 0x00000000,
511 0x00000000, 0x00000000, 0x00000000, 0x00000000,
512 0x00000000, 0x00000000, 0x00000000, 0x00000000,
513 0x00000000, 0x00000000, 0x00000000, 0x00000000,
516 /* Packet types for packets with PFCP SESSION header */
517 static const u32 ice_ptypes_pfcp_session[] = {
518 0x00000000, 0x00000000, 0x00000000, 0x00000000,
519 0x00000000, 0x00000000, 0x00000000, 0x00000000,
520 0x00000000, 0x00000000, 0x00000000, 0x00000005,
521 0x00000000, 0x00000000, 0x00000000, 0x00000000,
522 0x00000000, 0x00000000, 0x00000000, 0x00000000,
523 0x00000000, 0x00000000, 0x00000000, 0x00000000,
524 0x00000000, 0x00000000, 0x00000000, 0x00000000,
525 0x00000000, 0x00000000, 0x00000000, 0x00000000,
528 /* Packet types for L2TPv3 */
529 static const u32 ice_ptypes_l2tpv3[] = {
530 0x00000000, 0x00000000, 0x00000000, 0x00000000,
531 0x00000000, 0x00000000, 0x00000000, 0x00000000,
532 0x00000000, 0x00000000, 0x00000000, 0x00000300,
533 0x00000000, 0x00000000, 0x00000000, 0x00000000,
534 0x00000000, 0x00000000, 0x00000000, 0x00000000,
535 0x00000000, 0x00000000, 0x00000000, 0x00000000,
536 0x00000000, 0x00000000, 0x00000000, 0x00000000,
537 0x00000000, 0x00000000, 0x00000000, 0x00000000,
540 /* Packet types for ESP */
541 static const u32 ice_ptypes_esp[] = {
542 0x00000000, 0x00000000, 0x00000000, 0x00000000,
543 0x00000000, 0x00000003, 0x00000000, 0x00000000,
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,
549 0x00000000, 0x00000000, 0x00000000, 0x00000000,
552 /* Packet types for AH */
553 static const u32 ice_ptypes_ah[] = {
554 0x00000000, 0x00000000, 0x00000000, 0x00000000,
555 0x00000000, 0x0000000C, 0x00000000, 0x00000000,
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,
561 0x00000000, 0x00000000, 0x00000000, 0x00000000,
564 /* Packet types for packets with NAT_T ESP header */
565 static const u32 ice_ptypes_nat_t_esp[] = {
566 0x00000000, 0x00000000, 0x00000000, 0x00000000,
567 0x00000000, 0x00000030, 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,
573 0x00000000, 0x00000000, 0x00000000, 0x00000000,
576 static const u32 ice_ptypes_mac_non_ip_ofos[] = {
577 0x00000846, 0x00000000, 0x00000000, 0x00000000,
578 0x00000000, 0x00000000, 0x00000000, 0x00000000,
579 0x00400000, 0x03FFF000, 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 /* Manage parameters and info. used during the creation of a flow profile */
588 struct ice_flow_prof_params {
590 u16 entry_length; /* # of bytes formatted entry will require */
592 struct ice_flow_prof *prof;
594 /* For ACL, the es[0] will have the data of ICE_RX_MDID_PKT_FLAGS_15_0
595 * This will give us the direction flags.
597 struct ice_fv_word es[ICE_MAX_FV_WORDS];
598 /* attributes can be used to add attributes to a particular PTYPE */
599 const struct ice_ptype_attributes *attr;
602 u16 mask[ICE_MAX_FV_WORDS];
603 DECLARE_BITMAP(ptypes, ICE_FLOW_PTYPE_MAX);
606 #define ICE_FLOW_RSS_HDRS_INNER_MASK \
607 (ICE_FLOW_SEG_HDR_PPPOE | ICE_FLOW_SEG_HDR_GTPC | \
608 ICE_FLOW_SEG_HDR_GTPC_TEID | ICE_FLOW_SEG_HDR_GTPU | \
609 ICE_FLOW_SEG_HDR_PFCP_SESSION | ICE_FLOW_SEG_HDR_L2TPV3 | \
610 ICE_FLOW_SEG_HDR_ESP | ICE_FLOW_SEG_HDR_AH | \
611 ICE_FLOW_SEG_HDR_NAT_T_ESP)
613 #define ICE_FLOW_SEG_HDRS_L3_MASK \
614 (ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_IPV6 | ICE_FLOW_SEG_HDR_ARP)
615 #define ICE_FLOW_SEG_HDRS_L4_MASK \
616 (ICE_FLOW_SEG_HDR_ICMP | ICE_FLOW_SEG_HDR_TCP | ICE_FLOW_SEG_HDR_UDP | \
617 ICE_FLOW_SEG_HDR_SCTP)
618 /* mask for L4 protocols that are NOT part of IPv4/6 OTHER PTYPE groups */
619 #define ICE_FLOW_SEG_HDRS_L4_MASK_NO_OTHER \
620 (ICE_FLOW_SEG_HDR_TCP | ICE_FLOW_SEG_HDR_UDP | ICE_FLOW_SEG_HDR_SCTP)
623 * ice_flow_val_hdrs - validates packet segments for valid protocol headers
624 * @segs: array of one or more packet segments that describe the flow
625 * @segs_cnt: number of packet segments provided
627 static int ice_flow_val_hdrs(struct ice_flow_seg_info *segs, u8 segs_cnt)
631 for (i = 0; i < segs_cnt; i++) {
632 /* Multiple L3 headers */
633 if (segs[i].hdrs & ICE_FLOW_SEG_HDRS_L3_MASK &&
634 !is_power_of_2(segs[i].hdrs & ICE_FLOW_SEG_HDRS_L3_MASK))
637 /* Multiple L4 headers */
638 if (segs[i].hdrs & ICE_FLOW_SEG_HDRS_L4_MASK &&
639 !is_power_of_2(segs[i].hdrs & ICE_FLOW_SEG_HDRS_L4_MASK))
646 /* Sizes of fixed known protocol headers without header options */
647 #define ICE_FLOW_PROT_HDR_SZ_MAC 14
648 #define ICE_FLOW_PROT_HDR_SZ_MAC_VLAN (ICE_FLOW_PROT_HDR_SZ_MAC + 2)
649 #define ICE_FLOW_PROT_HDR_SZ_IPV4 20
650 #define ICE_FLOW_PROT_HDR_SZ_IPV6 40
651 #define ICE_FLOW_PROT_HDR_SZ_ARP 28
652 #define ICE_FLOW_PROT_HDR_SZ_ICMP 8
653 #define ICE_FLOW_PROT_HDR_SZ_TCP 20
654 #define ICE_FLOW_PROT_HDR_SZ_UDP 8
655 #define ICE_FLOW_PROT_HDR_SZ_SCTP 12
658 * ice_flow_calc_seg_sz - calculates size of a packet segment based on headers
659 * @params: information about the flow to be processed
660 * @seg: index of packet segment whose header size is to be determined
662 static u16 ice_flow_calc_seg_sz(struct ice_flow_prof_params *params, u8 seg)
667 sz = (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_VLAN) ?
668 ICE_FLOW_PROT_HDR_SZ_MAC_VLAN : ICE_FLOW_PROT_HDR_SZ_MAC;
671 if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_IPV4)
672 sz += ICE_FLOW_PROT_HDR_SZ_IPV4;
673 else if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_IPV6)
674 sz += ICE_FLOW_PROT_HDR_SZ_IPV6;
675 else if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_ARP)
676 sz += ICE_FLOW_PROT_HDR_SZ_ARP;
677 else if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDRS_L4_MASK)
678 /* An L3 header is required if L4 is specified */
682 if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_ICMP)
683 sz += ICE_FLOW_PROT_HDR_SZ_ICMP;
684 else if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_TCP)
685 sz += ICE_FLOW_PROT_HDR_SZ_TCP;
686 else if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_UDP)
687 sz += ICE_FLOW_PROT_HDR_SZ_UDP;
688 else if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_SCTP)
689 sz += ICE_FLOW_PROT_HDR_SZ_SCTP;
695 * ice_flow_proc_seg_hdrs - process protocol headers present in pkt segments
696 * @params: information about the flow to be processed
698 * This function identifies the packet types associated with the protocol
699 * headers being present in packet segments of the specified flow profile.
701 static int ice_flow_proc_seg_hdrs(struct ice_flow_prof_params *params)
703 struct ice_flow_prof *prof;
706 memset(params->ptypes, 0xff, sizeof(params->ptypes));
710 for (i = 0; i < params->prof->segs_cnt; i++) {
711 const unsigned long *src;
714 hdrs = prof->segs[i].hdrs;
716 if (hdrs & ICE_FLOW_SEG_HDR_ETH) {
717 src = !i ? (const unsigned long *)ice_ptypes_mac_ofos :
718 (const unsigned long *)ice_ptypes_mac_il;
719 bitmap_and(params->ptypes, params->ptypes, src,
723 if (i && hdrs & ICE_FLOW_SEG_HDR_VLAN) {
724 src = (const unsigned long *)ice_ptypes_macvlan_il;
725 bitmap_and(params->ptypes, params->ptypes, src,
729 if (!i && hdrs & ICE_FLOW_SEG_HDR_ARP) {
730 bitmap_and(params->ptypes, params->ptypes,
731 (const unsigned long *)ice_ptypes_arp_of,
735 if ((hdrs & ICE_FLOW_SEG_HDR_IPV4) &&
736 (hdrs & ICE_FLOW_SEG_HDR_IPV_OTHER)) {
737 src = i ? (const unsigned long *)ice_ptypes_ipv4_il :
738 (const unsigned long *)ice_ptypes_ipv4_ofos_all;
739 bitmap_and(params->ptypes, params->ptypes, src,
741 } else if ((hdrs & ICE_FLOW_SEG_HDR_IPV6) &&
742 (hdrs & ICE_FLOW_SEG_HDR_IPV_OTHER)) {
743 src = i ? (const unsigned long *)ice_ptypes_ipv6_il :
744 (const unsigned long *)ice_ptypes_ipv6_ofos_all;
745 bitmap_and(params->ptypes, params->ptypes, src,
747 } else if ((hdrs & ICE_FLOW_SEG_HDR_IPV4) &&
748 !(hdrs & ICE_FLOW_SEG_HDRS_L4_MASK_NO_OTHER)) {
749 src = !i ? (const unsigned long *)ice_ptypes_ipv4_ofos_no_l4 :
750 (const unsigned long *)ice_ptypes_ipv4_il_no_l4;
751 bitmap_and(params->ptypes, params->ptypes, src,
753 } else if (hdrs & ICE_FLOW_SEG_HDR_IPV4) {
754 src = !i ? (const unsigned long *)ice_ptypes_ipv4_ofos :
755 (const unsigned long *)ice_ptypes_ipv4_il;
756 bitmap_and(params->ptypes, params->ptypes, src,
758 } else if ((hdrs & ICE_FLOW_SEG_HDR_IPV6) &&
759 !(hdrs & ICE_FLOW_SEG_HDRS_L4_MASK_NO_OTHER)) {
760 src = !i ? (const unsigned long *)ice_ptypes_ipv6_ofos_no_l4 :
761 (const unsigned long *)ice_ptypes_ipv6_il_no_l4;
762 bitmap_and(params->ptypes, params->ptypes, src,
764 } else if (hdrs & ICE_FLOW_SEG_HDR_IPV6) {
765 src = !i ? (const unsigned long *)ice_ptypes_ipv6_ofos :
766 (const unsigned long *)ice_ptypes_ipv6_il;
767 bitmap_and(params->ptypes, params->ptypes, src,
771 if (hdrs & ICE_FLOW_SEG_HDR_ETH_NON_IP) {
772 src = (const unsigned long *)ice_ptypes_mac_non_ip_ofos;
773 bitmap_and(params->ptypes, params->ptypes, src,
775 } else if (hdrs & ICE_FLOW_SEG_HDR_PPPOE) {
776 src = (const unsigned long *)ice_ptypes_pppoe;
777 bitmap_and(params->ptypes, params->ptypes, src,
780 src = (const unsigned long *)ice_ptypes_pppoe;
781 bitmap_andnot(params->ptypes, params->ptypes, src,
785 if (hdrs & ICE_FLOW_SEG_HDR_UDP) {
786 src = (const unsigned long *)ice_ptypes_udp_il;
787 bitmap_and(params->ptypes, params->ptypes, src,
789 } else if (hdrs & ICE_FLOW_SEG_HDR_TCP) {
790 bitmap_and(params->ptypes, params->ptypes,
791 (const unsigned long *)ice_ptypes_tcp_il,
793 } else if (hdrs & ICE_FLOW_SEG_HDR_SCTP) {
794 src = (const unsigned long *)ice_ptypes_sctp_il;
795 bitmap_and(params->ptypes, params->ptypes, src,
799 if (hdrs & ICE_FLOW_SEG_HDR_ICMP) {
800 src = !i ? (const unsigned long *)ice_ptypes_icmp_of :
801 (const unsigned long *)ice_ptypes_icmp_il;
802 bitmap_and(params->ptypes, params->ptypes, src,
804 } else if (hdrs & ICE_FLOW_SEG_HDR_GRE) {
806 src = (const unsigned long *)ice_ptypes_gre_of;
807 bitmap_and(params->ptypes, params->ptypes,
808 src, ICE_FLOW_PTYPE_MAX);
810 } else if (hdrs & ICE_FLOW_SEG_HDR_GTPC) {
811 src = (const unsigned long *)ice_ptypes_gtpc;
812 bitmap_and(params->ptypes, params->ptypes, src,
814 } else if (hdrs & ICE_FLOW_SEG_HDR_GTPC_TEID) {
815 src = (const unsigned long *)ice_ptypes_gtpc_tid;
816 bitmap_and(params->ptypes, params->ptypes, src,
818 } else if (hdrs & ICE_FLOW_SEG_HDR_GTPU_DWN) {
819 src = (const unsigned long *)ice_ptypes_gtpu;
820 bitmap_and(params->ptypes, params->ptypes, src,
823 /* Attributes for GTP packet with downlink */
824 params->attr = ice_attr_gtpu_down;
825 params->attr_cnt = ARRAY_SIZE(ice_attr_gtpu_down);
826 } else if (hdrs & ICE_FLOW_SEG_HDR_GTPU_UP) {
827 src = (const unsigned long *)ice_ptypes_gtpu;
828 bitmap_and(params->ptypes, params->ptypes, src,
831 /* Attributes for GTP packet with uplink */
832 params->attr = ice_attr_gtpu_up;
833 params->attr_cnt = ARRAY_SIZE(ice_attr_gtpu_up);
834 } else if (hdrs & ICE_FLOW_SEG_HDR_GTPU_EH) {
835 src = (const unsigned long *)ice_ptypes_gtpu;
836 bitmap_and(params->ptypes, params->ptypes, src,
839 /* Attributes for GTP packet with Extension Header */
840 params->attr = ice_attr_gtpu_eh;
841 params->attr_cnt = ARRAY_SIZE(ice_attr_gtpu_eh);
842 } else if (hdrs & ICE_FLOW_SEG_HDR_GTPU_IP) {
843 src = (const unsigned long *)ice_ptypes_gtpu;
844 bitmap_and(params->ptypes, params->ptypes, src,
846 } else if (hdrs & ICE_FLOW_SEG_HDR_L2TPV3) {
847 src = (const unsigned long *)ice_ptypes_l2tpv3;
848 bitmap_and(params->ptypes, params->ptypes, src,
850 } else if (hdrs & ICE_FLOW_SEG_HDR_ESP) {
851 src = (const unsigned long *)ice_ptypes_esp;
852 bitmap_and(params->ptypes, params->ptypes, src,
854 } else if (hdrs & ICE_FLOW_SEG_HDR_AH) {
855 src = (const unsigned long *)ice_ptypes_ah;
856 bitmap_and(params->ptypes, params->ptypes, src,
858 } else if (hdrs & ICE_FLOW_SEG_HDR_NAT_T_ESP) {
859 src = (const unsigned long *)ice_ptypes_nat_t_esp;
860 bitmap_and(params->ptypes, params->ptypes, src,
864 if (hdrs & ICE_FLOW_SEG_HDR_PFCP) {
865 if (hdrs & ICE_FLOW_SEG_HDR_PFCP_NODE)
866 src = (const unsigned long *)ice_ptypes_pfcp_node;
868 src = (const unsigned long *)ice_ptypes_pfcp_session;
870 bitmap_and(params->ptypes, params->ptypes, src,
873 src = (const unsigned long *)ice_ptypes_pfcp_node;
874 bitmap_andnot(params->ptypes, params->ptypes, src,
877 src = (const unsigned long *)ice_ptypes_pfcp_session;
878 bitmap_andnot(params->ptypes, params->ptypes, src,
887 * ice_flow_xtract_fld - Create an extraction sequence entry for the given field
888 * @hw: pointer to the HW struct
889 * @params: information about the flow to be processed
890 * @seg: packet segment index of the field to be extracted
891 * @fld: ID of field to be extracted
892 * @match: bit field of all fields
894 * This function determines the protocol ID, offset, and size of the given
895 * field. It then allocates one or more extraction sequence entries for the
896 * given field, and fill the entries with protocol ID and offset information.
899 ice_flow_xtract_fld(struct ice_hw *hw, struct ice_flow_prof_params *params,
900 u8 seg, enum ice_flow_field fld, u64 match)
902 enum ice_flow_field sib = ICE_FLOW_FIELD_IDX_MAX;
903 enum ice_prot_id prot_id = ICE_PROT_ID_INVAL;
904 u8 fv_words = hw->blk[params->blk].es.fvw;
905 struct ice_flow_fld_info *flds;
906 u16 cnt, ese_bits, i;
911 flds = params->prof->segs[seg].fields;
914 case ICE_FLOW_FIELD_IDX_ETH_DA:
915 case ICE_FLOW_FIELD_IDX_ETH_SA:
916 case ICE_FLOW_FIELD_IDX_S_VLAN:
917 case ICE_FLOW_FIELD_IDX_C_VLAN:
918 prot_id = seg == 0 ? ICE_PROT_MAC_OF_OR_S : ICE_PROT_MAC_IL;
920 case ICE_FLOW_FIELD_IDX_ETH_TYPE:
921 prot_id = seg == 0 ? ICE_PROT_ETYPE_OL : ICE_PROT_ETYPE_IL;
923 case ICE_FLOW_FIELD_IDX_IPV4_DSCP:
924 prot_id = seg == 0 ? ICE_PROT_IPV4_OF_OR_S : ICE_PROT_IPV4_IL;
926 case ICE_FLOW_FIELD_IDX_IPV6_DSCP:
927 prot_id = seg == 0 ? ICE_PROT_IPV6_OF_OR_S : ICE_PROT_IPV6_IL;
929 case ICE_FLOW_FIELD_IDX_IPV4_TTL:
930 case ICE_FLOW_FIELD_IDX_IPV4_PROT:
931 prot_id = seg == 0 ? ICE_PROT_IPV4_OF_OR_S : ICE_PROT_IPV4_IL;
933 /* TTL and PROT share the same extraction seq. entry.
934 * Each is considered a sibling to the other in terms of sharing
935 * the same extraction sequence entry.
937 if (fld == ICE_FLOW_FIELD_IDX_IPV4_TTL)
938 sib = ICE_FLOW_FIELD_IDX_IPV4_PROT;
939 else if (fld == ICE_FLOW_FIELD_IDX_IPV4_PROT)
940 sib = ICE_FLOW_FIELD_IDX_IPV4_TTL;
942 /* If the sibling field is also included, that field's
943 * mask needs to be included.
945 if (match & BIT(sib))
946 sib_mask = ice_flds_info[sib].mask;
948 case ICE_FLOW_FIELD_IDX_IPV6_TTL:
949 case ICE_FLOW_FIELD_IDX_IPV6_PROT:
950 prot_id = seg == 0 ? ICE_PROT_IPV6_OF_OR_S : ICE_PROT_IPV6_IL;
952 /* TTL and PROT share the same extraction seq. entry.
953 * Each is considered a sibling to the other in terms of sharing
954 * the same extraction sequence entry.
956 if (fld == ICE_FLOW_FIELD_IDX_IPV6_TTL)
957 sib = ICE_FLOW_FIELD_IDX_IPV6_PROT;
958 else if (fld == ICE_FLOW_FIELD_IDX_IPV6_PROT)
959 sib = ICE_FLOW_FIELD_IDX_IPV6_TTL;
961 /* If the sibling field is also included, that field's
962 * mask needs to be included.
964 if (match & BIT(sib))
965 sib_mask = ice_flds_info[sib].mask;
967 case ICE_FLOW_FIELD_IDX_IPV4_SA:
968 case ICE_FLOW_FIELD_IDX_IPV4_DA:
969 prot_id = seg == 0 ? ICE_PROT_IPV4_OF_OR_S : ICE_PROT_IPV4_IL;
971 case ICE_FLOW_FIELD_IDX_IPV6_SA:
972 case ICE_FLOW_FIELD_IDX_IPV6_DA:
973 prot_id = seg == 0 ? ICE_PROT_IPV6_OF_OR_S : ICE_PROT_IPV6_IL;
975 case ICE_FLOW_FIELD_IDX_TCP_SRC_PORT:
976 case ICE_FLOW_FIELD_IDX_TCP_DST_PORT:
977 case ICE_FLOW_FIELD_IDX_TCP_FLAGS:
978 prot_id = ICE_PROT_TCP_IL;
980 case ICE_FLOW_FIELD_IDX_UDP_SRC_PORT:
981 case ICE_FLOW_FIELD_IDX_UDP_DST_PORT:
982 prot_id = ICE_PROT_UDP_IL_OR_S;
984 case ICE_FLOW_FIELD_IDX_SCTP_SRC_PORT:
985 case ICE_FLOW_FIELD_IDX_SCTP_DST_PORT:
986 prot_id = ICE_PROT_SCTP_IL;
988 case ICE_FLOW_FIELD_IDX_GTPC_TEID:
989 case ICE_FLOW_FIELD_IDX_GTPU_IP_TEID:
990 case ICE_FLOW_FIELD_IDX_GTPU_UP_TEID:
991 case ICE_FLOW_FIELD_IDX_GTPU_DWN_TEID:
992 case ICE_FLOW_FIELD_IDX_GTPU_EH_TEID:
993 case ICE_FLOW_FIELD_IDX_GTPU_EH_QFI:
994 /* GTP is accessed through UDP OF protocol */
995 prot_id = ICE_PROT_UDP_OF;
997 case ICE_FLOW_FIELD_IDX_PPPOE_SESS_ID:
998 prot_id = ICE_PROT_PPPOE;
1000 case ICE_FLOW_FIELD_IDX_PFCP_SEID:
1001 prot_id = ICE_PROT_UDP_IL_OR_S;
1003 case ICE_FLOW_FIELD_IDX_L2TPV3_SESS_ID:
1004 prot_id = ICE_PROT_L2TPV3;
1006 case ICE_FLOW_FIELD_IDX_ESP_SPI:
1007 prot_id = ICE_PROT_ESP_F;
1009 case ICE_FLOW_FIELD_IDX_AH_SPI:
1010 prot_id = ICE_PROT_ESP_2;
1012 case ICE_FLOW_FIELD_IDX_NAT_T_ESP_SPI:
1013 prot_id = ICE_PROT_UDP_IL_OR_S;
1015 case ICE_FLOW_FIELD_IDX_ARP_SIP:
1016 case ICE_FLOW_FIELD_IDX_ARP_DIP:
1017 case ICE_FLOW_FIELD_IDX_ARP_SHA:
1018 case ICE_FLOW_FIELD_IDX_ARP_DHA:
1019 case ICE_FLOW_FIELD_IDX_ARP_OP:
1020 prot_id = ICE_PROT_ARP_OF;
1022 case ICE_FLOW_FIELD_IDX_ICMP_TYPE:
1023 case ICE_FLOW_FIELD_IDX_ICMP_CODE:
1024 /* ICMP type and code share the same extraction seq. entry */
1025 prot_id = (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_IPV4) ?
1026 ICE_PROT_ICMP_IL : ICE_PROT_ICMPV6_IL;
1027 sib = fld == ICE_FLOW_FIELD_IDX_ICMP_TYPE ?
1028 ICE_FLOW_FIELD_IDX_ICMP_CODE :
1029 ICE_FLOW_FIELD_IDX_ICMP_TYPE;
1031 case ICE_FLOW_FIELD_IDX_GRE_KEYID:
1032 prot_id = ICE_PROT_GRE_OF;
1038 /* Each extraction sequence entry is a word in size, and extracts a
1039 * word-aligned offset from a protocol header.
1041 ese_bits = ICE_FLOW_FV_EXTRACT_SZ * BITS_PER_BYTE;
1043 flds[fld].xtrct.prot_id = prot_id;
1044 flds[fld].xtrct.off = (ice_flds_info[fld].off / ese_bits) *
1045 ICE_FLOW_FV_EXTRACT_SZ;
1046 flds[fld].xtrct.disp = (u8)(ice_flds_info[fld].off % ese_bits);
1047 flds[fld].xtrct.idx = params->es_cnt;
1048 flds[fld].xtrct.mask = ice_flds_info[fld].mask;
1050 /* Adjust the next field-entry index after accommodating the number of
1051 * entries this field consumes
1053 cnt = DIV_ROUND_UP(flds[fld].xtrct.disp + ice_flds_info[fld].size,
1056 /* Fill in the extraction sequence entries needed for this field */
1057 off = flds[fld].xtrct.off;
1058 mask = flds[fld].xtrct.mask;
1059 for (i = 0; i < cnt; i++) {
1060 /* Only consume an extraction sequence entry if there is no
1061 * sibling field associated with this field or the sibling entry
1062 * already extracts the word shared with this field.
1064 if (sib == ICE_FLOW_FIELD_IDX_MAX ||
1065 flds[sib].xtrct.prot_id == ICE_PROT_ID_INVAL ||
1066 flds[sib].xtrct.off != off) {
1069 /* Make sure the number of extraction sequence required
1070 * does not exceed the block's capability
1072 if (params->es_cnt >= fv_words)
1075 /* some blocks require a reversed field vector layout */
1076 if (hw->blk[params->blk].es.reverse)
1077 idx = fv_words - params->es_cnt - 1;
1079 idx = params->es_cnt;
1081 params->es[idx].prot_id = prot_id;
1082 params->es[idx].off = off;
1083 params->mask[idx] = mask | sib_mask;
1087 off += ICE_FLOW_FV_EXTRACT_SZ;
1094 * ice_flow_xtract_raws - Create extract sequence entries for raw bytes
1095 * @hw: pointer to the HW struct
1096 * @params: information about the flow to be processed
1097 * @seg: index of packet segment whose raw fields are to be extracted
1100 ice_flow_xtract_raws(struct ice_hw *hw, struct ice_flow_prof_params *params,
1107 if (!params->prof->segs[seg].raws_cnt)
1110 if (params->prof->segs[seg].raws_cnt >
1111 ARRAY_SIZE(params->prof->segs[seg].raws))
1114 /* Offsets within the segment headers are not supported */
1115 hdrs_sz = ice_flow_calc_seg_sz(params, seg);
1119 fv_words = hw->blk[params->blk].es.fvw;
1121 for (i = 0; i < params->prof->segs[seg].raws_cnt; i++) {
1122 struct ice_flow_seg_fld_raw *raw;
1125 raw = ¶ms->prof->segs[seg].raws[i];
1127 /* Storing extraction information */
1128 raw->info.xtrct.prot_id = ICE_PROT_MAC_OF_OR_S;
1129 raw->info.xtrct.off = (raw->off / ICE_FLOW_FV_EXTRACT_SZ) *
1130 ICE_FLOW_FV_EXTRACT_SZ;
1131 raw->info.xtrct.disp = (raw->off % ICE_FLOW_FV_EXTRACT_SZ) *
1133 raw->info.xtrct.idx = params->es_cnt;
1135 /* Determine the number of field vector entries this raw field
1138 cnt = DIV_ROUND_UP(raw->info.xtrct.disp +
1139 (raw->info.src.last * BITS_PER_BYTE),
1140 (ICE_FLOW_FV_EXTRACT_SZ * BITS_PER_BYTE));
1141 off = raw->info.xtrct.off;
1142 for (j = 0; j < cnt; j++) {
1145 /* Make sure the number of extraction sequence required
1146 * does not exceed the block's capability
1148 if (params->es_cnt >= hw->blk[params->blk].es.count ||
1149 params->es_cnt >= ICE_MAX_FV_WORDS)
1152 /* some blocks require a reversed field vector layout */
1153 if (hw->blk[params->blk].es.reverse)
1154 idx = fv_words - params->es_cnt - 1;
1156 idx = params->es_cnt;
1158 params->es[idx].prot_id = raw->info.xtrct.prot_id;
1159 params->es[idx].off = off;
1161 off += ICE_FLOW_FV_EXTRACT_SZ;
1169 * ice_flow_create_xtrct_seq - Create an extraction sequence for given segments
1170 * @hw: pointer to the HW struct
1171 * @params: information about the flow to be processed
1173 * This function iterates through all matched fields in the given segments, and
1174 * creates an extraction sequence for the fields.
1177 ice_flow_create_xtrct_seq(struct ice_hw *hw,
1178 struct ice_flow_prof_params *params)
1180 struct ice_flow_prof *prof = params->prof;
1184 for (i = 0; i < prof->segs_cnt; i++) {
1185 u64 match = params->prof->segs[i].match;
1186 enum ice_flow_field j;
1188 for_each_set_bit(j, (unsigned long *)&match,
1189 ICE_FLOW_FIELD_IDX_MAX) {
1190 status = ice_flow_xtract_fld(hw, params, i, j, match);
1193 clear_bit(j, (unsigned long *)&match);
1196 /* Process raw matching bytes */
1197 status = ice_flow_xtract_raws(hw, params, i);
1206 * ice_flow_proc_segs - process all packet segments associated with a profile
1207 * @hw: pointer to the HW struct
1208 * @params: information about the flow to be processed
1211 ice_flow_proc_segs(struct ice_hw *hw, struct ice_flow_prof_params *params)
1215 status = ice_flow_proc_seg_hdrs(params);
1219 status = ice_flow_create_xtrct_seq(hw, params);
1223 switch (params->blk) {
1235 #define ICE_FLOW_FIND_PROF_CHK_FLDS 0x00000001
1236 #define ICE_FLOW_FIND_PROF_CHK_VSI 0x00000002
1237 #define ICE_FLOW_FIND_PROF_NOT_CHK_DIR 0x00000004
1240 * ice_flow_find_prof_conds - Find a profile matching headers and conditions
1241 * @hw: pointer to the HW struct
1242 * @blk: classification stage
1243 * @dir: flow direction
1244 * @segs: array of one or more packet segments that describe the flow
1245 * @segs_cnt: number of packet segments provided
1246 * @vsi_handle: software VSI handle to check VSI (ICE_FLOW_FIND_PROF_CHK_VSI)
1247 * @conds: additional conditions to be checked (ICE_FLOW_FIND_PROF_CHK_*)
1249 static struct ice_flow_prof *
1250 ice_flow_find_prof_conds(struct ice_hw *hw, enum ice_block blk,
1251 enum ice_flow_dir dir, struct ice_flow_seg_info *segs,
1252 u8 segs_cnt, u16 vsi_handle, u32 conds)
1254 struct ice_flow_prof *p, *prof = NULL;
1256 mutex_lock(&hw->fl_profs_locks[blk]);
1257 list_for_each_entry(p, &hw->fl_profs[blk], l_entry)
1258 if ((p->dir == dir || conds & ICE_FLOW_FIND_PROF_NOT_CHK_DIR) &&
1259 segs_cnt && segs_cnt == p->segs_cnt) {
1262 /* Check for profile-VSI association if specified */
1263 if ((conds & ICE_FLOW_FIND_PROF_CHK_VSI) &&
1264 ice_is_vsi_valid(hw, vsi_handle) &&
1265 !test_bit(vsi_handle, p->vsis))
1268 /* Protocol headers must be checked. Matched fields are
1269 * checked if specified.
1271 for (i = 0; i < segs_cnt; i++)
1272 if (segs[i].hdrs != p->segs[i].hdrs ||
1273 ((conds & ICE_FLOW_FIND_PROF_CHK_FLDS) &&
1274 segs[i].match != p->segs[i].match))
1277 /* A match is found if all segments are matched */
1278 if (i == segs_cnt) {
1283 mutex_unlock(&hw->fl_profs_locks[blk]);
1289 * ice_flow_find_prof_id - Look up a profile with given profile ID
1290 * @hw: pointer to the HW struct
1291 * @blk: classification stage
1292 * @prof_id: unique ID to identify this flow profile
1294 static struct ice_flow_prof *
1295 ice_flow_find_prof_id(struct ice_hw *hw, enum ice_block blk, u64 prof_id)
1297 struct ice_flow_prof *p;
1299 list_for_each_entry(p, &hw->fl_profs[blk], l_entry)
1300 if (p->id == prof_id)
1307 * ice_flow_rem_entry_sync - Remove a flow entry
1308 * @hw: pointer to the HW struct
1309 * @blk: classification stage
1310 * @entry: flow entry to be removed
1313 ice_flow_rem_entry_sync(struct ice_hw *hw, enum ice_block __always_unused blk,
1314 struct ice_flow_entry *entry)
1319 list_del(&entry->l_entry);
1321 devm_kfree(ice_hw_to_dev(hw), entry->entry);
1322 devm_kfree(ice_hw_to_dev(hw), entry);
1328 * ice_flow_add_prof_sync - Add a flow profile for packet segments and fields
1329 * @hw: pointer to the HW struct
1330 * @blk: classification stage
1331 * @dir: flow direction
1332 * @prof_id: unique ID to identify this flow profile
1333 * @segs: array of one or more packet segments that describe the flow
1334 * @segs_cnt: number of packet segments provided
1335 * @prof: stores the returned flow profile added
1337 * Assumption: the caller has acquired the lock to the profile list
1340 ice_flow_add_prof_sync(struct ice_hw *hw, enum ice_block blk,
1341 enum ice_flow_dir dir, u64 prof_id,
1342 struct ice_flow_seg_info *segs, u8 segs_cnt,
1343 struct ice_flow_prof **prof)
1345 struct ice_flow_prof_params *params;
1352 params = kzalloc(sizeof(*params), GFP_KERNEL);
1356 params->prof = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*params->prof),
1358 if (!params->prof) {
1363 /* initialize extraction sequence to all invalid (0xff) */
1364 for (i = 0; i < ICE_MAX_FV_WORDS; i++) {
1365 params->es[i].prot_id = ICE_PROT_INVALID;
1366 params->es[i].off = ICE_FV_OFFSET_INVAL;
1370 params->prof->id = prof_id;
1371 params->prof->dir = dir;
1372 params->prof->segs_cnt = segs_cnt;
1374 /* Make a copy of the segments that need to be persistent in the flow
1377 for (i = 0; i < segs_cnt; i++)
1378 memcpy(¶ms->prof->segs[i], &segs[i], sizeof(*segs));
1380 status = ice_flow_proc_segs(hw, params);
1382 ice_debug(hw, ICE_DBG_FLOW, "Error processing a flow's packet segments\n");
1386 /* Add a HW profile for this flow profile */
1387 status = ice_add_prof(hw, blk, prof_id, (u8 *)params->ptypes,
1388 params->attr, params->attr_cnt, params->es,
1391 ice_debug(hw, ICE_DBG_FLOW, "Error adding a HW flow profile\n");
1395 INIT_LIST_HEAD(¶ms->prof->entries);
1396 mutex_init(¶ms->prof->entries_lock);
1397 *prof = params->prof;
1401 devm_kfree(ice_hw_to_dev(hw), params->prof);
1409 * ice_flow_rem_prof_sync - remove a flow profile
1410 * @hw: pointer to the hardware structure
1411 * @blk: classification stage
1412 * @prof: pointer to flow profile to remove
1414 * Assumption: the caller has acquired the lock to the profile list
1417 ice_flow_rem_prof_sync(struct ice_hw *hw, enum ice_block blk,
1418 struct ice_flow_prof *prof)
1422 /* Remove all remaining flow entries before removing the flow profile */
1423 if (!list_empty(&prof->entries)) {
1424 struct ice_flow_entry *e, *t;
1426 mutex_lock(&prof->entries_lock);
1428 list_for_each_entry_safe(e, t, &prof->entries, l_entry) {
1429 status = ice_flow_rem_entry_sync(hw, blk, e);
1434 mutex_unlock(&prof->entries_lock);
1437 /* Remove all hardware profiles associated with this flow profile */
1438 status = ice_rem_prof(hw, blk, prof->id);
1440 list_del(&prof->l_entry);
1441 mutex_destroy(&prof->entries_lock);
1442 devm_kfree(ice_hw_to_dev(hw), prof);
1449 * ice_flow_assoc_prof - associate a VSI with a flow profile
1450 * @hw: pointer to the hardware structure
1451 * @blk: classification stage
1452 * @prof: pointer to flow profile
1453 * @vsi_handle: software VSI handle
1455 * Assumption: the caller has acquired the lock to the profile list
1456 * and the software VSI handle has been validated
1459 ice_flow_assoc_prof(struct ice_hw *hw, enum ice_block blk,
1460 struct ice_flow_prof *prof, u16 vsi_handle)
1464 if (!test_bit(vsi_handle, prof->vsis)) {
1465 status = ice_add_prof_id_flow(hw, blk,
1466 ice_get_hw_vsi_num(hw,
1470 set_bit(vsi_handle, prof->vsis);
1472 ice_debug(hw, ICE_DBG_FLOW, "HW profile add failed, %d\n",
1480 * ice_flow_disassoc_prof - disassociate a VSI from a flow profile
1481 * @hw: pointer to the hardware structure
1482 * @blk: classification stage
1483 * @prof: pointer to flow profile
1484 * @vsi_handle: software VSI handle
1486 * Assumption: the caller has acquired the lock to the profile list
1487 * and the software VSI handle has been validated
1490 ice_flow_disassoc_prof(struct ice_hw *hw, enum ice_block blk,
1491 struct ice_flow_prof *prof, u16 vsi_handle)
1495 if (test_bit(vsi_handle, prof->vsis)) {
1496 status = ice_rem_prof_id_flow(hw, blk,
1497 ice_get_hw_vsi_num(hw,
1501 clear_bit(vsi_handle, prof->vsis);
1503 ice_debug(hw, ICE_DBG_FLOW, "HW profile remove failed, %d\n",
1511 * ice_flow_add_prof - Add a flow profile for packet segments and matched fields
1512 * @hw: pointer to the HW struct
1513 * @blk: classification stage
1514 * @dir: flow direction
1515 * @prof_id: unique ID to identify this flow profile
1516 * @segs: array of one or more packet segments that describe the flow
1517 * @segs_cnt: number of packet segments provided
1518 * @prof: stores the returned flow profile added
1521 ice_flow_add_prof(struct ice_hw *hw, enum ice_block blk, enum ice_flow_dir dir,
1522 u64 prof_id, struct ice_flow_seg_info *segs, u8 segs_cnt,
1523 struct ice_flow_prof **prof)
1527 if (segs_cnt > ICE_FLOW_SEG_MAX)
1536 status = ice_flow_val_hdrs(segs, segs_cnt);
1540 mutex_lock(&hw->fl_profs_locks[blk]);
1542 status = ice_flow_add_prof_sync(hw, blk, dir, prof_id, segs, segs_cnt,
1545 list_add(&(*prof)->l_entry, &hw->fl_profs[blk]);
1547 mutex_unlock(&hw->fl_profs_locks[blk]);
1553 * ice_flow_rem_prof - Remove a flow profile and all entries associated with it
1554 * @hw: pointer to the HW struct
1555 * @blk: the block for which the flow profile is to be removed
1556 * @prof_id: unique ID of the flow profile to be removed
1558 int ice_flow_rem_prof(struct ice_hw *hw, enum ice_block blk, u64 prof_id)
1560 struct ice_flow_prof *prof;
1563 mutex_lock(&hw->fl_profs_locks[blk]);
1565 prof = ice_flow_find_prof_id(hw, blk, prof_id);
1571 /* prof becomes invalid after the call */
1572 status = ice_flow_rem_prof_sync(hw, blk, prof);
1575 mutex_unlock(&hw->fl_profs_locks[blk]);
1581 * ice_flow_add_entry - Add a flow entry
1582 * @hw: pointer to the HW struct
1583 * @blk: classification stage
1584 * @prof_id: ID of the profile to add a new flow entry to
1585 * @entry_id: unique ID to identify this flow entry
1586 * @vsi_handle: software VSI handle for the flow entry
1587 * @prio: priority of the flow entry
1588 * @data: pointer to a data buffer containing flow entry's match values/masks
1589 * @entry_h: pointer to buffer that receives the new flow entry's handle
1592 ice_flow_add_entry(struct ice_hw *hw, enum ice_block blk, u64 prof_id,
1593 u64 entry_id, u16 vsi_handle, enum ice_flow_priority prio,
1594 void *data, u64 *entry_h)
1596 struct ice_flow_entry *e = NULL;
1597 struct ice_flow_prof *prof;
1600 /* No flow entry data is expected for RSS */
1601 if (!entry_h || (!data && blk != ICE_BLK_RSS))
1604 if (!ice_is_vsi_valid(hw, vsi_handle))
1607 mutex_lock(&hw->fl_profs_locks[blk]);
1609 prof = ice_flow_find_prof_id(hw, blk, prof_id);
1613 /* Allocate memory for the entry being added and associate
1614 * the VSI to the found flow profile
1616 e = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*e), GFP_KERNEL);
1620 status = ice_flow_assoc_prof(hw, blk, prof, vsi_handle);
1623 mutex_unlock(&hw->fl_profs_locks[blk]);
1628 e->vsi_handle = vsi_handle;
1637 status = -EOPNOTSUPP;
1641 mutex_lock(&prof->entries_lock);
1642 list_add(&e->l_entry, &prof->entries);
1643 mutex_unlock(&prof->entries_lock);
1645 *entry_h = ICE_FLOW_ENTRY_HNDL(e);
1649 devm_kfree(ice_hw_to_dev(hw), e->entry);
1650 devm_kfree(ice_hw_to_dev(hw), e);
1657 * ice_flow_rem_entry - Remove a flow entry
1658 * @hw: pointer to the HW struct
1659 * @blk: classification stage
1660 * @entry_h: handle to the flow entry to be removed
1662 int ice_flow_rem_entry(struct ice_hw *hw, enum ice_block blk, u64 entry_h)
1664 struct ice_flow_entry *entry;
1665 struct ice_flow_prof *prof;
1668 if (entry_h == ICE_FLOW_ENTRY_HANDLE_INVAL)
1671 entry = ICE_FLOW_ENTRY_PTR(entry_h);
1673 /* Retain the pointer to the flow profile as the entry will be freed */
1677 mutex_lock(&prof->entries_lock);
1678 status = ice_flow_rem_entry_sync(hw, blk, entry);
1679 mutex_unlock(&prof->entries_lock);
1686 * ice_flow_set_fld_ext - specifies locations of field from entry's input buffer
1687 * @seg: packet segment the field being set belongs to
1688 * @fld: field to be set
1689 * @field_type: type of the field
1690 * @val_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of the value to match from
1691 * entry's input buffer
1692 * @mask_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of mask value from entry's
1694 * @last_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of last/upper value from
1695 * entry's input buffer
1697 * This helper function stores information of a field being matched, including
1698 * the type of the field and the locations of the value to match, the mask, and
1699 * the upper-bound value in the start of the input buffer for a flow entry.
1700 * This function should only be used for fixed-size data structures.
1702 * This function also opportunistically determines the protocol headers to be
1703 * present based on the fields being set. Some fields cannot be used alone to
1704 * determine the protocol headers present. Sometimes, fields for particular
1705 * protocol headers are not matched. In those cases, the protocol headers
1706 * must be explicitly set.
1709 ice_flow_set_fld_ext(struct ice_flow_seg_info *seg, enum ice_flow_field fld,
1710 enum ice_flow_fld_match_type field_type, u16 val_loc,
1711 u16 mask_loc, u16 last_loc)
1713 u64 bit = BIT_ULL(fld);
1716 if (field_type == ICE_FLOW_FLD_TYPE_RANGE)
1719 seg->fields[fld].type = field_type;
1720 seg->fields[fld].src.val = val_loc;
1721 seg->fields[fld].src.mask = mask_loc;
1722 seg->fields[fld].src.last = last_loc;
1724 ICE_FLOW_SET_HDRS(seg, ice_flds_info[fld].hdr);
1728 * ice_flow_set_fld - specifies locations of field from entry's input buffer
1729 * @seg: packet segment the field being set belongs to
1730 * @fld: field to be set
1731 * @val_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of the value to match from
1732 * entry's input buffer
1733 * @mask_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of mask value from entry's
1735 * @last_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of last/upper value from
1736 * entry's input buffer
1737 * @range: indicate if field being matched is to be in a range
1739 * This function specifies the locations, in the form of byte offsets from the
1740 * start of the input buffer for a flow entry, from where the value to match,
1741 * the mask value, and upper value can be extracted. These locations are then
1742 * stored in the flow profile. When adding a flow entry associated with the
1743 * flow profile, these locations will be used to quickly extract the values and
1744 * create the content of a match entry. This function should only be used for
1745 * fixed-size data structures.
1748 ice_flow_set_fld(struct ice_flow_seg_info *seg, enum ice_flow_field fld,
1749 u16 val_loc, u16 mask_loc, u16 last_loc, bool range)
1751 enum ice_flow_fld_match_type t = range ?
1752 ICE_FLOW_FLD_TYPE_RANGE : ICE_FLOW_FLD_TYPE_REG;
1754 ice_flow_set_fld_ext(seg, fld, t, val_loc, mask_loc, last_loc);
1758 * ice_flow_add_fld_raw - sets locations of a raw field from entry's input buf
1759 * @seg: packet segment the field being set belongs to
1760 * @off: offset of the raw field from the beginning of the segment in bytes
1761 * @len: length of the raw pattern to be matched
1762 * @val_loc: location of the value to match from entry's input buffer
1763 * @mask_loc: location of mask value from entry's input buffer
1765 * This function specifies the offset of the raw field to be match from the
1766 * beginning of the specified packet segment, and the locations, in the form of
1767 * byte offsets from the start of the input buffer for a flow entry, from where
1768 * the value to match and the mask value to be extracted. These locations are
1769 * then stored in the flow profile. When adding flow entries to the associated
1770 * flow profile, these locations can be used to quickly extract the values to
1771 * create the content of a match entry. This function should only be used for
1772 * fixed-size data structures.
1775 ice_flow_add_fld_raw(struct ice_flow_seg_info *seg, u16 off, u8 len,
1776 u16 val_loc, u16 mask_loc)
1778 if (seg->raws_cnt < ICE_FLOW_SEG_RAW_FLD_MAX) {
1779 seg->raws[seg->raws_cnt].off = off;
1780 seg->raws[seg->raws_cnt].info.type = ICE_FLOW_FLD_TYPE_SIZE;
1781 seg->raws[seg->raws_cnt].info.src.val = val_loc;
1782 seg->raws[seg->raws_cnt].info.src.mask = mask_loc;
1783 /* The "last" field is used to store the length of the field */
1784 seg->raws[seg->raws_cnt].info.src.last = len;
1787 /* Overflows of "raws" will be handled as an error condition later in
1788 * the flow when this information is processed.
1794 * ice_flow_rem_vsi_prof - remove VSI from flow profile
1795 * @hw: pointer to the hardware structure
1796 * @vsi_handle: software VSI handle
1797 * @prof_id: unique ID to identify this flow profile
1799 * This function removes the flow entries associated to the input
1800 * VSI handle and disassociate the VSI from the flow profile.
1802 int ice_flow_rem_vsi_prof(struct ice_hw *hw, u16 vsi_handle, u64 prof_id)
1804 struct ice_flow_prof *prof;
1807 if (!ice_is_vsi_valid(hw, vsi_handle))
1810 /* find flow profile pointer with input package block and profile ID */
1811 prof = ice_flow_find_prof_id(hw, ICE_BLK_FD, prof_id);
1813 ice_debug(hw, ICE_DBG_PKG, "Cannot find flow profile id=%llu\n",
1818 /* Remove all remaining flow entries before removing the flow profile */
1819 if (!list_empty(&prof->entries)) {
1820 struct ice_flow_entry *e, *t;
1822 mutex_lock(&prof->entries_lock);
1823 list_for_each_entry_safe(e, t, &prof->entries, l_entry) {
1824 if (e->vsi_handle != vsi_handle)
1827 status = ice_flow_rem_entry_sync(hw, ICE_BLK_FD, e);
1831 mutex_unlock(&prof->entries_lock);
1836 /* disassociate the flow profile from sw VSI handle */
1837 status = ice_flow_disassoc_prof(hw, ICE_BLK_FD, prof, vsi_handle);
1839 ice_debug(hw, ICE_DBG_PKG, "ice_flow_disassoc_prof() failed with status=%d\n",
1844 #define ICE_FLOW_RSS_SEG_HDR_L2_MASKS \
1845 (ICE_FLOW_SEG_HDR_ETH | ICE_FLOW_SEG_HDR_VLAN)
1847 #define ICE_FLOW_RSS_SEG_HDR_L3_MASKS \
1848 (ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_IPV6)
1850 #define ICE_FLOW_RSS_SEG_HDR_L4_MASKS \
1851 (ICE_FLOW_SEG_HDR_TCP | ICE_FLOW_SEG_HDR_UDP | ICE_FLOW_SEG_HDR_SCTP)
1853 #define ICE_FLOW_RSS_SEG_HDR_VAL_MASKS \
1854 (ICE_FLOW_RSS_SEG_HDR_L2_MASKS | \
1855 ICE_FLOW_RSS_SEG_HDR_L3_MASKS | \
1856 ICE_FLOW_RSS_SEG_HDR_L4_MASKS)
1859 * ice_flow_set_rss_seg_info - setup packet segments for RSS
1860 * @segs: pointer to the flow field segment(s)
1861 * @hash_fields: fields to be hashed on for the segment(s)
1862 * @flow_hdr: protocol header fields within a packet segment
1864 * Helper function to extract fields from hash bitmap and use flow
1865 * header value to set flow field segment for further use in flow
1866 * profile entry or removal.
1869 ice_flow_set_rss_seg_info(struct ice_flow_seg_info *segs, u64 hash_fields,
1875 for_each_set_bit(i, (unsigned long *)&hash_fields,
1876 ICE_FLOW_FIELD_IDX_MAX)
1877 ice_flow_set_fld(segs, (enum ice_flow_field)i,
1878 ICE_FLOW_FLD_OFF_INVAL, ICE_FLOW_FLD_OFF_INVAL,
1879 ICE_FLOW_FLD_OFF_INVAL, false);
1881 ICE_FLOW_SET_HDRS(segs, flow_hdr);
1883 if (segs->hdrs & ~ICE_FLOW_RSS_SEG_HDR_VAL_MASKS &
1884 ~ICE_FLOW_RSS_HDRS_INNER_MASK & ~ICE_FLOW_SEG_HDR_IPV_OTHER)
1887 val = (u64)(segs->hdrs & ICE_FLOW_RSS_SEG_HDR_L3_MASKS);
1888 if (val && !is_power_of_2(val))
1891 val = (u64)(segs->hdrs & ICE_FLOW_RSS_SEG_HDR_L4_MASKS);
1892 if (val && !is_power_of_2(val))
1899 * ice_rem_vsi_rss_list - remove VSI from RSS list
1900 * @hw: pointer to the hardware structure
1901 * @vsi_handle: software VSI handle
1903 * Remove the VSI from all RSS configurations in the list.
1905 void ice_rem_vsi_rss_list(struct ice_hw *hw, u16 vsi_handle)
1907 struct ice_rss_cfg *r, *tmp;
1909 if (list_empty(&hw->rss_list_head))
1912 mutex_lock(&hw->rss_locks);
1913 list_for_each_entry_safe(r, tmp, &hw->rss_list_head, l_entry)
1914 if (test_and_clear_bit(vsi_handle, r->vsis))
1915 if (bitmap_empty(r->vsis, ICE_MAX_VSI)) {
1916 list_del(&r->l_entry);
1917 devm_kfree(ice_hw_to_dev(hw), r);
1919 mutex_unlock(&hw->rss_locks);
1923 * ice_rem_vsi_rss_cfg - remove RSS configurations associated with VSI
1924 * @hw: pointer to the hardware structure
1925 * @vsi_handle: software VSI handle
1927 * This function will iterate through all flow profiles and disassociate
1928 * the VSI from that profile. If the flow profile has no VSIs it will
1931 int ice_rem_vsi_rss_cfg(struct ice_hw *hw, u16 vsi_handle)
1933 const enum ice_block blk = ICE_BLK_RSS;
1934 struct ice_flow_prof *p, *t;
1937 if (!ice_is_vsi_valid(hw, vsi_handle))
1940 if (list_empty(&hw->fl_profs[blk]))
1943 mutex_lock(&hw->rss_locks);
1944 list_for_each_entry_safe(p, t, &hw->fl_profs[blk], l_entry)
1945 if (test_bit(vsi_handle, p->vsis)) {
1946 status = ice_flow_disassoc_prof(hw, blk, p, vsi_handle);
1950 if (bitmap_empty(p->vsis, ICE_MAX_VSI)) {
1951 status = ice_flow_rem_prof(hw, blk, p->id);
1956 mutex_unlock(&hw->rss_locks);
1962 * ice_rem_rss_list - remove RSS configuration from list
1963 * @hw: pointer to the hardware structure
1964 * @vsi_handle: software VSI handle
1965 * @prof: pointer to flow profile
1967 * Assumption: lock has already been acquired for RSS list
1970 ice_rem_rss_list(struct ice_hw *hw, u16 vsi_handle, struct ice_flow_prof *prof)
1972 struct ice_rss_cfg *r, *tmp;
1974 /* Search for RSS hash fields associated to the VSI that match the
1975 * hash configurations associated to the flow profile. If found
1976 * remove from the RSS entry list of the VSI context and delete entry.
1978 list_for_each_entry_safe(r, tmp, &hw->rss_list_head, l_entry)
1979 if (r->hashed_flds == prof->segs[prof->segs_cnt - 1].match &&
1980 r->packet_hdr == prof->segs[prof->segs_cnt - 1].hdrs) {
1981 clear_bit(vsi_handle, r->vsis);
1982 if (bitmap_empty(r->vsis, ICE_MAX_VSI)) {
1983 list_del(&r->l_entry);
1984 devm_kfree(ice_hw_to_dev(hw), r);
1991 * ice_add_rss_list - add RSS configuration to list
1992 * @hw: pointer to the hardware structure
1993 * @vsi_handle: software VSI handle
1994 * @prof: pointer to flow profile
1996 * Assumption: lock has already been acquired for RSS list
1999 ice_add_rss_list(struct ice_hw *hw, u16 vsi_handle, struct ice_flow_prof *prof)
2001 struct ice_rss_cfg *r, *rss_cfg;
2003 list_for_each_entry(r, &hw->rss_list_head, l_entry)
2004 if (r->hashed_flds == prof->segs[prof->segs_cnt - 1].match &&
2005 r->packet_hdr == prof->segs[prof->segs_cnt - 1].hdrs) {
2006 set_bit(vsi_handle, r->vsis);
2010 rss_cfg = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*rss_cfg),
2015 rss_cfg->hashed_flds = prof->segs[prof->segs_cnt - 1].match;
2016 rss_cfg->packet_hdr = prof->segs[prof->segs_cnt - 1].hdrs;
2017 set_bit(vsi_handle, rss_cfg->vsis);
2019 list_add_tail(&rss_cfg->l_entry, &hw->rss_list_head);
2024 #define ICE_FLOW_PROF_HASH_S 0
2025 #define ICE_FLOW_PROF_HASH_M (0xFFFFFFFFULL << ICE_FLOW_PROF_HASH_S)
2026 #define ICE_FLOW_PROF_HDR_S 32
2027 #define ICE_FLOW_PROF_HDR_M (0x3FFFFFFFULL << ICE_FLOW_PROF_HDR_S)
2028 #define ICE_FLOW_PROF_ENCAP_S 63
2029 #define ICE_FLOW_PROF_ENCAP_M (BIT_ULL(ICE_FLOW_PROF_ENCAP_S))
2031 #define ICE_RSS_OUTER_HEADERS 1
2032 #define ICE_RSS_INNER_HEADERS 2
2034 /* Flow profile ID format:
2035 * [0:31] - Packet match fields
2036 * [32:62] - Protocol header
2037 * [63] - Encapsulation flag, 0 if non-tunneled, 1 if tunneled
2039 #define ICE_FLOW_GEN_PROFID(hash, hdr, segs_cnt) \
2040 ((u64)(((u64)(hash) & ICE_FLOW_PROF_HASH_M) | \
2041 (((u64)(hdr) << ICE_FLOW_PROF_HDR_S) & ICE_FLOW_PROF_HDR_M) | \
2042 ((u8)((segs_cnt) - 1) ? ICE_FLOW_PROF_ENCAP_M : 0)))
2045 * ice_add_rss_cfg_sync - add an RSS configuration
2046 * @hw: pointer to the hardware structure
2047 * @vsi_handle: software VSI handle
2048 * @hashed_flds: hash bit fields (ICE_FLOW_HASH_*) to configure
2049 * @addl_hdrs: protocol header fields
2050 * @segs_cnt: packet segment count
2052 * Assumption: lock has already been acquired for RSS list
2055 ice_add_rss_cfg_sync(struct ice_hw *hw, u16 vsi_handle, u64 hashed_flds,
2056 u32 addl_hdrs, u8 segs_cnt)
2058 const enum ice_block blk = ICE_BLK_RSS;
2059 struct ice_flow_prof *prof = NULL;
2060 struct ice_flow_seg_info *segs;
2063 if (!segs_cnt || segs_cnt > ICE_FLOW_SEG_MAX)
2066 segs = kcalloc(segs_cnt, sizeof(*segs), GFP_KERNEL);
2070 /* Construct the packet segment info from the hashed fields */
2071 status = ice_flow_set_rss_seg_info(&segs[segs_cnt - 1], hashed_flds,
2076 /* Search for a flow profile that has matching headers, hash fields
2077 * and has the input VSI associated to it. If found, no further
2078 * operations required and exit.
2080 prof = ice_flow_find_prof_conds(hw, blk, ICE_FLOW_RX, segs, segs_cnt,
2082 ICE_FLOW_FIND_PROF_CHK_FLDS |
2083 ICE_FLOW_FIND_PROF_CHK_VSI);
2087 /* Check if a flow profile exists with the same protocol headers and
2088 * associated with the input VSI. If so disassociate the VSI from
2089 * this profile. The VSI will be added to a new profile created with
2090 * the protocol header and new hash field configuration.
2092 prof = ice_flow_find_prof_conds(hw, blk, ICE_FLOW_RX, segs, segs_cnt,
2093 vsi_handle, ICE_FLOW_FIND_PROF_CHK_VSI);
2095 status = ice_flow_disassoc_prof(hw, blk, prof, vsi_handle);
2097 ice_rem_rss_list(hw, vsi_handle, prof);
2101 /* Remove profile if it has no VSIs associated */
2102 if (bitmap_empty(prof->vsis, ICE_MAX_VSI)) {
2103 status = ice_flow_rem_prof(hw, blk, prof->id);
2109 /* Search for a profile that has same match fields only. If this
2110 * exists then associate the VSI to this profile.
2112 prof = ice_flow_find_prof_conds(hw, blk, ICE_FLOW_RX, segs, segs_cnt,
2114 ICE_FLOW_FIND_PROF_CHK_FLDS);
2116 status = ice_flow_assoc_prof(hw, blk, prof, vsi_handle);
2118 status = ice_add_rss_list(hw, vsi_handle, prof);
2122 /* Create a new flow profile with generated profile and packet
2123 * segment information.
2125 status = ice_flow_add_prof(hw, blk, ICE_FLOW_RX,
2126 ICE_FLOW_GEN_PROFID(hashed_flds,
2127 segs[segs_cnt - 1].hdrs,
2129 segs, segs_cnt, &prof);
2133 status = ice_flow_assoc_prof(hw, blk, prof, vsi_handle);
2134 /* If association to a new flow profile failed then this profile can
2138 ice_flow_rem_prof(hw, blk, prof->id);
2142 status = ice_add_rss_list(hw, vsi_handle, prof);
2150 * ice_add_rss_cfg - add an RSS configuration with specified hashed fields
2151 * @hw: pointer to the hardware structure
2152 * @vsi_handle: software VSI handle
2153 * @hashed_flds: hash bit fields (ICE_FLOW_HASH_*) to configure
2154 * @addl_hdrs: protocol header fields
2156 * This function will generate a flow profile based on fields associated with
2157 * the input fields to hash on, the flow type and use the VSI number to add
2158 * a flow entry to the profile.
2161 ice_add_rss_cfg(struct ice_hw *hw, u16 vsi_handle, u64 hashed_flds,
2166 if (hashed_flds == ICE_HASH_INVALID ||
2167 !ice_is_vsi_valid(hw, vsi_handle))
2170 mutex_lock(&hw->rss_locks);
2171 status = ice_add_rss_cfg_sync(hw, vsi_handle, hashed_flds, addl_hdrs,
2172 ICE_RSS_OUTER_HEADERS);
2174 status = ice_add_rss_cfg_sync(hw, vsi_handle, hashed_flds,
2175 addl_hdrs, ICE_RSS_INNER_HEADERS);
2176 mutex_unlock(&hw->rss_locks);
2182 * ice_rem_rss_cfg_sync - remove an existing RSS configuration
2183 * @hw: pointer to the hardware structure
2184 * @vsi_handle: software VSI handle
2185 * @hashed_flds: Packet hash types (ICE_FLOW_HASH_*) to remove
2186 * @addl_hdrs: Protocol header fields within a packet segment
2187 * @segs_cnt: packet segment count
2189 * Assumption: lock has already been acquired for RSS list
2192 ice_rem_rss_cfg_sync(struct ice_hw *hw, u16 vsi_handle, u64 hashed_flds,
2193 u32 addl_hdrs, u8 segs_cnt)
2195 const enum ice_block blk = ICE_BLK_RSS;
2196 struct ice_flow_seg_info *segs;
2197 struct ice_flow_prof *prof;
2200 segs = kcalloc(segs_cnt, sizeof(*segs), GFP_KERNEL);
2204 /* Construct the packet segment info from the hashed fields */
2205 status = ice_flow_set_rss_seg_info(&segs[segs_cnt - 1], hashed_flds,
2210 prof = ice_flow_find_prof_conds(hw, blk, ICE_FLOW_RX, segs, segs_cnt,
2212 ICE_FLOW_FIND_PROF_CHK_FLDS);
2218 status = ice_flow_disassoc_prof(hw, blk, prof, vsi_handle);
2222 /* Remove RSS configuration from VSI context before deleting
2225 ice_rem_rss_list(hw, vsi_handle, prof);
2227 if (bitmap_empty(prof->vsis, ICE_MAX_VSI))
2228 status = ice_flow_rem_prof(hw, blk, prof->id);
2236 * ice_rem_rss_cfg - remove an existing RSS config with matching hashed fields
2237 * @hw: pointer to the hardware structure
2238 * @vsi_handle: software VSI handle
2239 * @hashed_flds: Packet hash types (ICE_FLOW_HASH_*) to remove
2240 * @addl_hdrs: Protocol header fields within a packet segment
2242 * This function will lookup the flow profile based on the input
2243 * hash field bitmap, iterate through the profile entry list of
2244 * that profile and find entry associated with input VSI to be
2245 * removed. Calls are made to underlying flow s which will APIs
2246 * turn build or update buffers for RSS XLT1 section.
2249 ice_rem_rss_cfg(struct ice_hw *hw, u16 vsi_handle, u64 hashed_flds,
2254 if (hashed_flds == ICE_HASH_INVALID ||
2255 !ice_is_vsi_valid(hw, vsi_handle))
2258 mutex_lock(&hw->rss_locks);
2259 status = ice_rem_rss_cfg_sync(hw, vsi_handle, hashed_flds, addl_hdrs,
2260 ICE_RSS_OUTER_HEADERS);
2262 status = ice_rem_rss_cfg_sync(hw, vsi_handle, hashed_flds,
2263 addl_hdrs, ICE_RSS_INNER_HEADERS);
2264 mutex_unlock(&hw->rss_locks);
2269 /* Mapping of AVF hash bit fields to an L3-L4 hash combination.
2270 * As the ice_flow_avf_hdr_field represent individual bit shifts in a hash,
2271 * convert its values to their appropriate flow L3, L4 values.
2273 #define ICE_FLOW_AVF_RSS_IPV4_MASKS \
2274 (BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_OTHER) | \
2275 BIT_ULL(ICE_AVF_FLOW_FIELD_FRAG_IPV4))
2276 #define ICE_FLOW_AVF_RSS_TCP_IPV4_MASKS \
2277 (BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_TCP_SYN_NO_ACK) | \
2278 BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_TCP))
2279 #define ICE_FLOW_AVF_RSS_UDP_IPV4_MASKS \
2280 (BIT_ULL(ICE_AVF_FLOW_FIELD_UNICAST_IPV4_UDP) | \
2281 BIT_ULL(ICE_AVF_FLOW_FIELD_MULTICAST_IPV4_UDP) | \
2282 BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_UDP))
2283 #define ICE_FLOW_AVF_RSS_ALL_IPV4_MASKS \
2284 (ICE_FLOW_AVF_RSS_TCP_IPV4_MASKS | ICE_FLOW_AVF_RSS_UDP_IPV4_MASKS | \
2285 ICE_FLOW_AVF_RSS_IPV4_MASKS | BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_SCTP))
2287 #define ICE_FLOW_AVF_RSS_IPV6_MASKS \
2288 (BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_OTHER) | \
2289 BIT_ULL(ICE_AVF_FLOW_FIELD_FRAG_IPV6))
2290 #define ICE_FLOW_AVF_RSS_UDP_IPV6_MASKS \
2291 (BIT_ULL(ICE_AVF_FLOW_FIELD_UNICAST_IPV6_UDP) | \
2292 BIT_ULL(ICE_AVF_FLOW_FIELD_MULTICAST_IPV6_UDP) | \
2293 BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_UDP))
2294 #define ICE_FLOW_AVF_RSS_TCP_IPV6_MASKS \
2295 (BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_TCP_SYN_NO_ACK) | \
2296 BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_TCP))
2297 #define ICE_FLOW_AVF_RSS_ALL_IPV6_MASKS \
2298 (ICE_FLOW_AVF_RSS_TCP_IPV6_MASKS | ICE_FLOW_AVF_RSS_UDP_IPV6_MASKS | \
2299 ICE_FLOW_AVF_RSS_IPV6_MASKS | BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_SCTP))
2302 * ice_add_avf_rss_cfg - add an RSS configuration for AVF driver
2303 * @hw: pointer to the hardware structure
2304 * @vsi_handle: software VSI handle
2305 * @avf_hash: hash bit fields (ICE_AVF_FLOW_FIELD_*) to configure
2307 * This function will take the hash bitmap provided by the AVF driver via a
2308 * message, convert it to ICE-compatible values, and configure RSS flow
2311 int ice_add_avf_rss_cfg(struct ice_hw *hw, u16 vsi_handle, u64 avf_hash)
2316 if (avf_hash == ICE_AVF_FLOW_FIELD_INVALID ||
2317 !ice_is_vsi_valid(hw, vsi_handle))
2320 /* Make sure no unsupported bits are specified */
2321 if (avf_hash & ~(ICE_FLOW_AVF_RSS_ALL_IPV4_MASKS |
2322 ICE_FLOW_AVF_RSS_ALL_IPV6_MASKS))
2325 hash_flds = avf_hash;
2327 /* Always create an L3 RSS configuration for any L4 RSS configuration */
2328 if (hash_flds & ICE_FLOW_AVF_RSS_ALL_IPV4_MASKS)
2329 hash_flds |= ICE_FLOW_AVF_RSS_IPV4_MASKS;
2331 if (hash_flds & ICE_FLOW_AVF_RSS_ALL_IPV6_MASKS)
2332 hash_flds |= ICE_FLOW_AVF_RSS_IPV6_MASKS;
2334 /* Create the corresponding RSS configuration for each valid hash bit */
2336 u64 rss_hash = ICE_HASH_INVALID;
2338 if (hash_flds & ICE_FLOW_AVF_RSS_ALL_IPV4_MASKS) {
2339 if (hash_flds & ICE_FLOW_AVF_RSS_IPV4_MASKS) {
2340 rss_hash = ICE_FLOW_HASH_IPV4;
2341 hash_flds &= ~ICE_FLOW_AVF_RSS_IPV4_MASKS;
2342 } else if (hash_flds &
2343 ICE_FLOW_AVF_RSS_TCP_IPV4_MASKS) {
2344 rss_hash = ICE_FLOW_HASH_IPV4 |
2345 ICE_FLOW_HASH_TCP_PORT;
2346 hash_flds &= ~ICE_FLOW_AVF_RSS_TCP_IPV4_MASKS;
2347 } else if (hash_flds &
2348 ICE_FLOW_AVF_RSS_UDP_IPV4_MASKS) {
2349 rss_hash = ICE_FLOW_HASH_IPV4 |
2350 ICE_FLOW_HASH_UDP_PORT;
2351 hash_flds &= ~ICE_FLOW_AVF_RSS_UDP_IPV4_MASKS;
2352 } else if (hash_flds &
2353 BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_SCTP)) {
2354 rss_hash = ICE_FLOW_HASH_IPV4 |
2355 ICE_FLOW_HASH_SCTP_PORT;
2357 ~BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_SCTP);
2359 } else if (hash_flds & ICE_FLOW_AVF_RSS_ALL_IPV6_MASKS) {
2360 if (hash_flds & ICE_FLOW_AVF_RSS_IPV6_MASKS) {
2361 rss_hash = ICE_FLOW_HASH_IPV6;
2362 hash_flds &= ~ICE_FLOW_AVF_RSS_IPV6_MASKS;
2363 } else if (hash_flds &
2364 ICE_FLOW_AVF_RSS_TCP_IPV6_MASKS) {
2365 rss_hash = ICE_FLOW_HASH_IPV6 |
2366 ICE_FLOW_HASH_TCP_PORT;
2367 hash_flds &= ~ICE_FLOW_AVF_RSS_TCP_IPV6_MASKS;
2368 } else if (hash_flds &
2369 ICE_FLOW_AVF_RSS_UDP_IPV6_MASKS) {
2370 rss_hash = ICE_FLOW_HASH_IPV6 |
2371 ICE_FLOW_HASH_UDP_PORT;
2372 hash_flds &= ~ICE_FLOW_AVF_RSS_UDP_IPV6_MASKS;
2373 } else if (hash_flds &
2374 BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_SCTP)) {
2375 rss_hash = ICE_FLOW_HASH_IPV6 |
2376 ICE_FLOW_HASH_SCTP_PORT;
2378 ~BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_SCTP);
2382 if (rss_hash == ICE_HASH_INVALID)
2385 status = ice_add_rss_cfg(hw, vsi_handle, rss_hash,
2386 ICE_FLOW_SEG_HDR_NONE);
2395 * ice_replay_rss_cfg - replay RSS configurations associated with VSI
2396 * @hw: pointer to the hardware structure
2397 * @vsi_handle: software VSI handle
2399 int ice_replay_rss_cfg(struct ice_hw *hw, u16 vsi_handle)
2401 struct ice_rss_cfg *r;
2404 if (!ice_is_vsi_valid(hw, vsi_handle))
2407 mutex_lock(&hw->rss_locks);
2408 list_for_each_entry(r, &hw->rss_list_head, l_entry) {
2409 if (test_bit(vsi_handle, r->vsis)) {
2410 status = ice_add_rss_cfg_sync(hw, vsi_handle,
2413 ICE_RSS_OUTER_HEADERS);
2416 status = ice_add_rss_cfg_sync(hw, vsi_handle,
2419 ICE_RSS_INNER_HEADERS);
2424 mutex_unlock(&hw->rss_locks);
2430 * ice_get_rss_cfg - returns hashed fields for the given header types
2431 * @hw: pointer to the hardware structure
2432 * @vsi_handle: software VSI handle
2433 * @hdrs: protocol header type
2435 * This function will return the match fields of the first instance of flow
2436 * profile having the given header types and containing input VSI
2438 u64 ice_get_rss_cfg(struct ice_hw *hw, u16 vsi_handle, u32 hdrs)
2440 u64 rss_hash = ICE_HASH_INVALID;
2441 struct ice_rss_cfg *r;
2443 /* verify if the protocol header is non zero and VSI is valid */
2444 if (hdrs == ICE_FLOW_SEG_HDR_NONE || !ice_is_vsi_valid(hw, vsi_handle))
2445 return ICE_HASH_INVALID;
2447 mutex_lock(&hw->rss_locks);
2448 list_for_each_entry(r, &hw->rss_list_head, l_entry)
2449 if (test_bit(vsi_handle, r->vsis) &&
2450 r->packet_hdr == hdrs) {
2451 rss_hash = r->hashed_flds;
2454 mutex_unlock(&hw->rss_locks);