1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (c) 2019, Intel Corporation. */
4 #include "ice_common.h"
7 /* Describe properties of a protocol header field */
8 struct ice_flow_field_info {
9 enum ice_flow_seg_hdr hdr;
10 s16 off; /* Offset from start of a protocol header, in bits */
11 u16 size; /* Size of fields in bits */
12 u16 mask; /* 16-bit mask for field */
15 #define ICE_FLOW_FLD_INFO(_hdr, _offset_bytes, _size_bytes) { \
17 .off = (_offset_bytes) * BITS_PER_BYTE, \
18 .size = (_size_bytes) * BITS_PER_BYTE, \
22 #define ICE_FLOW_FLD_INFO_MSK(_hdr, _offset_bytes, _size_bytes, _mask) { \
24 .off = (_offset_bytes) * BITS_PER_BYTE, \
25 .size = (_size_bytes) * BITS_PER_BYTE, \
29 /* Table containing properties of supported protocol header fields */
31 struct ice_flow_field_info ice_flds_info[ICE_FLOW_FIELD_IDX_MAX] = {
33 /* ICE_FLOW_FIELD_IDX_ETH_DA */
34 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ETH, 0, ETH_ALEN),
35 /* ICE_FLOW_FIELD_IDX_ETH_SA */
36 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ETH, ETH_ALEN, ETH_ALEN),
37 /* ICE_FLOW_FIELD_IDX_S_VLAN */
38 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_VLAN, 12, sizeof(__be16)),
39 /* ICE_FLOW_FIELD_IDX_C_VLAN */
40 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_VLAN, 14, sizeof(__be16)),
41 /* ICE_FLOW_FIELD_IDX_ETH_TYPE */
42 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ETH, 0, sizeof(__be16)),
44 /* ICE_FLOW_FIELD_IDX_IPV4_DSCP */
45 ICE_FLOW_FLD_INFO_MSK(ICE_FLOW_SEG_HDR_IPV4, 0, 1, 0x00fc),
46 /* ICE_FLOW_FIELD_IDX_IPV6_DSCP */
47 ICE_FLOW_FLD_INFO_MSK(ICE_FLOW_SEG_HDR_IPV6, 0, 1, 0x0ff0),
48 /* ICE_FLOW_FIELD_IDX_IPV4_TTL */
49 ICE_FLOW_FLD_INFO_MSK(ICE_FLOW_SEG_HDR_NONE, 8, 1, 0xff00),
50 /* ICE_FLOW_FIELD_IDX_IPV4_PROT */
51 ICE_FLOW_FLD_INFO_MSK(ICE_FLOW_SEG_HDR_NONE, 8, 1, 0x00ff),
52 /* ICE_FLOW_FIELD_IDX_IPV6_TTL */
53 ICE_FLOW_FLD_INFO_MSK(ICE_FLOW_SEG_HDR_NONE, 6, 1, 0x00ff),
54 /* ICE_FLOW_FIELD_IDX_IPV6_PROT */
55 ICE_FLOW_FLD_INFO_MSK(ICE_FLOW_SEG_HDR_NONE, 6, 1, 0xff00),
56 /* ICE_FLOW_FIELD_IDX_IPV4_SA */
57 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV4, 12, sizeof(struct in_addr)),
58 /* ICE_FLOW_FIELD_IDX_IPV4_DA */
59 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV4, 16, sizeof(struct in_addr)),
60 /* ICE_FLOW_FIELD_IDX_IPV6_SA */
61 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV6, 8, sizeof(struct in6_addr)),
62 /* ICE_FLOW_FIELD_IDX_IPV6_DA */
63 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV6, 24, sizeof(struct in6_addr)),
65 /* ICE_FLOW_FIELD_IDX_TCP_SRC_PORT */
66 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_TCP, 0, sizeof(__be16)),
67 /* ICE_FLOW_FIELD_IDX_TCP_DST_PORT */
68 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_TCP, 2, sizeof(__be16)),
69 /* ICE_FLOW_FIELD_IDX_UDP_SRC_PORT */
70 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_UDP, 0, sizeof(__be16)),
71 /* ICE_FLOW_FIELD_IDX_UDP_DST_PORT */
72 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_UDP, 2, sizeof(__be16)),
73 /* ICE_FLOW_FIELD_IDX_SCTP_SRC_PORT */
74 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_SCTP, 0, sizeof(__be16)),
75 /* ICE_FLOW_FIELD_IDX_SCTP_DST_PORT */
76 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_SCTP, 2, sizeof(__be16)),
77 /* ICE_FLOW_FIELD_IDX_TCP_FLAGS */
78 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_TCP, 13, 1),
80 /* ICE_FLOW_FIELD_IDX_ARP_SIP */
81 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ARP, 14, sizeof(struct in_addr)),
82 /* ICE_FLOW_FIELD_IDX_ARP_DIP */
83 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ARP, 24, sizeof(struct in_addr)),
84 /* ICE_FLOW_FIELD_IDX_ARP_SHA */
85 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ARP, 8, ETH_ALEN),
86 /* ICE_FLOW_FIELD_IDX_ARP_DHA */
87 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ARP, 18, ETH_ALEN),
88 /* ICE_FLOW_FIELD_IDX_ARP_OP */
89 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ARP, 6, sizeof(__be16)),
91 /* ICE_FLOW_FIELD_IDX_ICMP_TYPE */
92 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ICMP, 0, 1),
93 /* ICE_FLOW_FIELD_IDX_ICMP_CODE */
94 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ICMP, 1, 1),
96 /* ICE_FLOW_FIELD_IDX_GRE_KEYID */
97 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_GRE, 12,
98 sizeof_field(struct gre_full_hdr, key)),
100 /* ICE_FLOW_FIELD_IDX_GTPC_TEID */
101 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_GTPC_TEID, 12, sizeof(__be32)),
102 /* ICE_FLOW_FIELD_IDX_GTPU_IP_TEID */
103 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_GTPU_IP, 12, sizeof(__be32)),
104 /* ICE_FLOW_FIELD_IDX_GTPU_EH_TEID */
105 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_GTPU_EH, 12, sizeof(__be32)),
106 /* ICE_FLOW_FIELD_IDX_GTPU_EH_QFI */
107 ICE_FLOW_FLD_INFO_MSK(ICE_FLOW_SEG_HDR_GTPU_EH, 22, sizeof(__be16),
109 /* ICE_FLOW_FIELD_IDX_GTPU_UP_TEID */
110 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_GTPU_UP, 12, sizeof(__be32)),
111 /* ICE_FLOW_FIELD_IDX_GTPU_DWN_TEID */
112 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_GTPU_DWN, 12, sizeof(__be32)),
114 /* ICE_FLOW_FIELD_IDX_PPPOE_SESS_ID */
115 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_PPPOE, 2, sizeof(__be16)),
117 /* ICE_FLOW_FIELD_IDX_PFCP_SEID */
118 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_PFCP_SESSION, 12, sizeof(__be64)),
120 /* ICE_FLOW_FIELD_IDX_L2TPV3_SESS_ID */
121 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_L2TPV3, 0, sizeof(__be32)),
123 /* ICE_FLOW_FIELD_IDX_ESP_SPI */
124 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ESP, 0, sizeof(__be32)),
126 /* ICE_FLOW_FIELD_IDX_AH_SPI */
127 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_AH, 4, sizeof(__be32)),
129 /* ICE_FLOW_FIELD_IDX_NAT_T_ESP_SPI */
130 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_NAT_T_ESP, 8, sizeof(__be32)),
133 /* Bitmaps indicating relevant packet types for a particular protocol header
135 * Packet types for packets with an Outer/First/Single MAC header
137 static const u32 ice_ptypes_mac_ofos[] = {
138 0xFDC00846, 0xBFBF7F7E, 0xF70001DF, 0xFEFDFDFB,
139 0x0000077E, 0x00000000, 0x00000000, 0x00000000,
140 0x00400000, 0x03FFF000, 0x7FFFFFE0, 0x00000000,
141 0x00000000, 0x00000000, 0x00000000, 0x00000000,
142 0x00000000, 0x00000000, 0x00000000, 0x00000000,
143 0x00000000, 0x00000000, 0x00000000, 0x00000000,
144 0x00000000, 0x00000000, 0x00000000, 0x00000000,
145 0x00000000, 0x00000000, 0x00000000, 0x00000000,
148 /* Packet types for packets with an Innermost/Last MAC VLAN header */
149 static const u32 ice_ptypes_macvlan_il[] = {
150 0x00000000, 0xBC000000, 0x000001DF, 0xF0000000,
151 0x0000077E, 0x00000000, 0x00000000, 0x00000000,
152 0x00000000, 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,
160 /* Packet types for packets with an Outer/First/Single IPv4 header, does NOT
161 * include IPv4 other PTYPEs
163 static const u32 ice_ptypes_ipv4_ofos[] = {
164 0x1DC00000, 0x04000800, 0x00000000, 0x00000000,
165 0x00000000, 0x00000155, 0x00000000, 0x00000000,
166 0x00000000, 0x000FC000, 0x00000000, 0x00000000,
167 0x00000000, 0x00000000, 0x00000000, 0x00000000,
168 0x00000000, 0x00000000, 0x00000000, 0x00000000,
169 0x00000000, 0x00000000, 0x00000000, 0x00000000,
170 0x00000000, 0x00000000, 0x00000000, 0x00000000,
171 0x00000000, 0x00000000, 0x00000000, 0x00000000,
174 /* Packet types for packets with an Outer/First/Single IPv4 header, includes
177 static const u32 ice_ptypes_ipv4_ofos_all[] = {
178 0x1DC00000, 0x04000800, 0x00000000, 0x00000000,
179 0x00000000, 0x00000155, 0x00000000, 0x00000000,
180 0x00000000, 0x000FC000, 0x83E0F800, 0x00000101,
181 0x00000000, 0x00000000, 0x00000000, 0x00000000,
182 0x00000000, 0x00000000, 0x00000000, 0x00000000,
183 0x00000000, 0x00000000, 0x00000000, 0x00000000,
184 0x00000000, 0x00000000, 0x00000000, 0x00000000,
185 0x00000000, 0x00000000, 0x00000000, 0x00000000,
188 /* Packet types for packets with an Innermost/Last IPv4 header */
189 static const u32 ice_ptypes_ipv4_il[] = {
190 0xE0000000, 0xB807700E, 0x80000003, 0xE01DC03B,
191 0x0000000E, 0x00000000, 0x00000000, 0x00000000,
192 0x00000000, 0x00000000, 0x001FF800, 0x00000000,
193 0x00000000, 0x00000000, 0x00000000, 0x00000000,
194 0x00000000, 0x00000000, 0x00000000, 0x00000000,
195 0x00000000, 0x00000000, 0x00000000, 0x00000000,
196 0x00000000, 0x00000000, 0x00000000, 0x00000000,
197 0x00000000, 0x00000000, 0x00000000, 0x00000000,
200 /* Packet types for packets with an Outer/First/Single IPv6 header, does NOT
201 * include IPv6 other PTYPEs
203 static const u32 ice_ptypes_ipv6_ofos[] = {
204 0x00000000, 0x00000000, 0x77000000, 0x10002000,
205 0x00000000, 0x000002AA, 0x00000000, 0x00000000,
206 0x00000000, 0x03F00000, 0x00000000, 0x00000000,
207 0x00000000, 0x00000000, 0x00000000, 0x00000000,
208 0x00000000, 0x00000000, 0x00000000, 0x00000000,
209 0x00000000, 0x00000000, 0x00000000, 0x00000000,
210 0x00000000, 0x00000000, 0x00000000, 0x00000000,
211 0x00000000, 0x00000000, 0x00000000, 0x00000000,
214 /* Packet types for packets with an Outer/First/Single IPv6 header, includes
217 static const u32 ice_ptypes_ipv6_ofos_all[] = {
218 0x00000000, 0x00000000, 0x77000000, 0x10002000,
219 0x00000000, 0x000002AA, 0x00000000, 0x00000000,
220 0x00080F00, 0x03F00000, 0x7C1F0000, 0x00000206,
221 0x00000000, 0x00000000, 0x00000000, 0x00000000,
222 0x00000000, 0x00000000, 0x00000000, 0x00000000,
223 0x00000000, 0x00000000, 0x00000000, 0x00000000,
224 0x00000000, 0x00000000, 0x00000000, 0x00000000,
225 0x00000000, 0x00000000, 0x00000000, 0x00000000,
228 /* Packet types for packets with an Innermost/Last IPv6 header */
229 static const u32 ice_ptypes_ipv6_il[] = {
230 0x00000000, 0x03B80770, 0x000001DC, 0x0EE00000,
231 0x00000770, 0x00000000, 0x00000000, 0x00000000,
232 0x00000000, 0x00000000, 0x7FE00000, 0x00000000,
233 0x00000000, 0x00000000, 0x00000000, 0x00000000,
234 0x00000000, 0x00000000, 0x00000000, 0x00000000,
235 0x00000000, 0x00000000, 0x00000000, 0x00000000,
236 0x00000000, 0x00000000, 0x00000000, 0x00000000,
237 0x00000000, 0x00000000, 0x00000000, 0x00000000,
240 /* Packet types for packets with an Outer/First/Single IPv4 header - no L4 */
241 static const u32 ice_ptypes_ipv4_ofos_no_l4[] = {
242 0x10C00000, 0x04000800, 0x00000000, 0x00000000,
243 0x00000000, 0x00000000, 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,
252 /* Packet types for packets with an Outermost/First ARP header */
253 static const u32 ice_ptypes_arp_of[] = {
254 0x00000800, 0x00000000, 0x00000000, 0x00000000,
255 0x00000000, 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,
264 /* Packet types for packets with an Innermost/Last IPv4 header - no L4 */
265 static const u32 ice_ptypes_ipv4_il_no_l4[] = {
266 0x60000000, 0x18043008, 0x80000002, 0x6010c021,
267 0x00000008, 0x00000000, 0x00000000, 0x00000000,
268 0x00000000, 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,
276 /* Packet types for packets with an Outer/First/Single IPv6 header - no L4 */
277 static const u32 ice_ptypes_ipv6_ofos_no_l4[] = {
278 0x00000000, 0x00000000, 0x43000000, 0x10002000,
279 0x00000000, 0x00000000, 0x00000000, 0x00000000,
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,
288 /* Packet types for packets with an Innermost/Last IPv6 header - no L4 */
289 static const u32 ice_ptypes_ipv6_il_no_l4[] = {
290 0x00000000, 0x02180430, 0x0000010c, 0x086010c0,
291 0x00000430, 0x00000000, 0x00000000, 0x00000000,
292 0x00000000, 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,
300 /* UDP Packet types for non-tunneled packets or tunneled
301 * packets with inner UDP.
303 static const u32 ice_ptypes_udp_il[] = {
304 0x81000000, 0x20204040, 0x04000010, 0x80810102,
305 0x00000040, 0x00000000, 0x00000000, 0x00000000,
306 0x00000000, 0x00410000, 0x90842000, 0x00000007,
307 0x00000000, 0x00000000, 0x00000000, 0x00000000,
308 0x00000000, 0x00000000, 0x00000000, 0x00000000,
309 0x00000000, 0x00000000, 0x00000000, 0x00000000,
310 0x00000000, 0x00000000, 0x00000000, 0x00000000,
311 0x00000000, 0x00000000, 0x00000000, 0x00000000,
314 /* Packet types for packets with an Innermost/Last TCP header */
315 static const u32 ice_ptypes_tcp_il[] = {
316 0x04000000, 0x80810102, 0x10000040, 0x02040408,
317 0x00000102, 0x00000000, 0x00000000, 0x00000000,
318 0x00000000, 0x00820000, 0x21084000, 0x00000000,
319 0x00000000, 0x00000000, 0x00000000, 0x00000000,
320 0x00000000, 0x00000000, 0x00000000, 0x00000000,
321 0x00000000, 0x00000000, 0x00000000, 0x00000000,
322 0x00000000, 0x00000000, 0x00000000, 0x00000000,
323 0x00000000, 0x00000000, 0x00000000, 0x00000000,
326 /* Packet types for packets with an Innermost/Last SCTP header */
327 static const u32 ice_ptypes_sctp_il[] = {
328 0x08000000, 0x01020204, 0x20000081, 0x04080810,
329 0x00000204, 0x00000000, 0x00000000, 0x00000000,
330 0x00000000, 0x01040000, 0x00000000, 0x00000000,
331 0x00000000, 0x00000000, 0x00000000, 0x00000000,
332 0x00000000, 0x00000000, 0x00000000, 0x00000000,
333 0x00000000, 0x00000000, 0x00000000, 0x00000000,
334 0x00000000, 0x00000000, 0x00000000, 0x00000000,
335 0x00000000, 0x00000000, 0x00000000, 0x00000000,
338 /* Packet types for packets with an Outermost/First ICMP header */
339 static const u32 ice_ptypes_icmp_of[] = {
340 0x10000000, 0x00000000, 0x00000000, 0x00000000,
341 0x00000000, 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,
350 /* Packet types for packets with an Innermost/Last ICMP header */
351 static const u32 ice_ptypes_icmp_il[] = {
352 0x00000000, 0x02040408, 0x40000102, 0x08101020,
353 0x00000408, 0x00000000, 0x00000000, 0x00000000,
354 0x00000000, 0x00000000, 0x42108000, 0x00000000,
355 0x00000000, 0x00000000, 0x00000000, 0x00000000,
356 0x00000000, 0x00000000, 0x00000000, 0x00000000,
357 0x00000000, 0x00000000, 0x00000000, 0x00000000,
358 0x00000000, 0x00000000, 0x00000000, 0x00000000,
359 0x00000000, 0x00000000, 0x00000000, 0x00000000,
362 /* Packet types for packets with an Outermost/First GRE header */
363 static const u32 ice_ptypes_gre_of[] = {
364 0x00000000, 0xBFBF7800, 0x000001DF, 0xFEFDE000,
365 0x0000017E, 0x00000000, 0x00000000, 0x00000000,
366 0x00000000, 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,
374 /* Packet types for packets with an Innermost/Last MAC header */
375 static const u32 ice_ptypes_mac_il[] = {
376 0x00000000, 0x00000000, 0x00000000, 0x00000000,
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,
386 /* Packet types for GTPC */
387 static const u32 ice_ptypes_gtpc[] = {
388 0x00000000, 0x00000000, 0x00000000, 0x00000000,
389 0x00000000, 0x00000000, 0x00000000, 0x00000000,
390 0x00000000, 0x00000000, 0x00000180, 0x00000000,
391 0x00000000, 0x00000000, 0x00000000, 0x00000000,
392 0x00000000, 0x00000000, 0x00000000, 0x00000000,
393 0x00000000, 0x00000000, 0x00000000, 0x00000000,
394 0x00000000, 0x00000000, 0x00000000, 0x00000000,
395 0x00000000, 0x00000000, 0x00000000, 0x00000000,
398 /* Packet types for GTPC with TEID */
399 static const u32 ice_ptypes_gtpc_tid[] = {
400 0x00000000, 0x00000000, 0x00000000, 0x00000000,
401 0x00000000, 0x00000000, 0x00000000, 0x00000000,
402 0x00000000, 0x00000000, 0x00000060, 0x00000000,
403 0x00000000, 0x00000000, 0x00000000, 0x00000000,
404 0x00000000, 0x00000000, 0x00000000, 0x00000000,
405 0x00000000, 0x00000000, 0x00000000, 0x00000000,
406 0x00000000, 0x00000000, 0x00000000, 0x00000000,
407 0x00000000, 0x00000000, 0x00000000, 0x00000000,
410 /* Packet types for GTPU */
411 static const struct ice_ptype_attributes ice_attr_gtpu_eh[] = {
412 { ICE_MAC_IPV4_GTPU_IPV4_FRAG, ICE_PTYPE_ATTR_GTP_PDU_EH },
413 { ICE_MAC_IPV4_GTPU_IPV4_PAY, ICE_PTYPE_ATTR_GTP_PDU_EH },
414 { ICE_MAC_IPV4_GTPU_IPV4_UDP_PAY, ICE_PTYPE_ATTR_GTP_PDU_EH },
415 { ICE_MAC_IPV4_GTPU_IPV4_TCP, ICE_PTYPE_ATTR_GTP_PDU_EH },
416 { ICE_MAC_IPV4_GTPU_IPV4_ICMP, ICE_PTYPE_ATTR_GTP_PDU_EH },
417 { ICE_MAC_IPV6_GTPU_IPV4_FRAG, ICE_PTYPE_ATTR_GTP_PDU_EH },
418 { ICE_MAC_IPV6_GTPU_IPV4_PAY, ICE_PTYPE_ATTR_GTP_PDU_EH },
419 { ICE_MAC_IPV6_GTPU_IPV4_UDP_PAY, ICE_PTYPE_ATTR_GTP_PDU_EH },
420 { ICE_MAC_IPV6_GTPU_IPV4_TCP, ICE_PTYPE_ATTR_GTP_PDU_EH },
421 { ICE_MAC_IPV6_GTPU_IPV4_ICMP, ICE_PTYPE_ATTR_GTP_PDU_EH },
422 { ICE_MAC_IPV4_GTPU_IPV6_FRAG, ICE_PTYPE_ATTR_GTP_PDU_EH },
423 { ICE_MAC_IPV4_GTPU_IPV6_PAY, ICE_PTYPE_ATTR_GTP_PDU_EH },
424 { ICE_MAC_IPV4_GTPU_IPV6_UDP_PAY, ICE_PTYPE_ATTR_GTP_PDU_EH },
425 { ICE_MAC_IPV4_GTPU_IPV6_TCP, ICE_PTYPE_ATTR_GTP_PDU_EH },
426 { ICE_MAC_IPV4_GTPU_IPV6_ICMPV6, ICE_PTYPE_ATTR_GTP_PDU_EH },
427 { ICE_MAC_IPV6_GTPU_IPV6_FRAG, ICE_PTYPE_ATTR_GTP_PDU_EH },
428 { ICE_MAC_IPV6_GTPU_IPV6_PAY, ICE_PTYPE_ATTR_GTP_PDU_EH },
429 { ICE_MAC_IPV6_GTPU_IPV6_UDP_PAY, ICE_PTYPE_ATTR_GTP_PDU_EH },
430 { ICE_MAC_IPV6_GTPU_IPV6_TCP, ICE_PTYPE_ATTR_GTP_PDU_EH },
431 { ICE_MAC_IPV6_GTPU_IPV6_ICMPV6, ICE_PTYPE_ATTR_GTP_PDU_EH },
434 static const struct ice_ptype_attributes ice_attr_gtpu_down[] = {
435 { ICE_MAC_IPV4_GTPU_IPV4_FRAG, ICE_PTYPE_ATTR_GTP_DOWNLINK },
436 { ICE_MAC_IPV4_GTPU_IPV4_PAY, ICE_PTYPE_ATTR_GTP_DOWNLINK },
437 { ICE_MAC_IPV4_GTPU_IPV4_UDP_PAY, ICE_PTYPE_ATTR_GTP_DOWNLINK },
438 { ICE_MAC_IPV4_GTPU_IPV4_TCP, ICE_PTYPE_ATTR_GTP_DOWNLINK },
439 { ICE_MAC_IPV4_GTPU_IPV4_ICMP, ICE_PTYPE_ATTR_GTP_DOWNLINK },
440 { ICE_MAC_IPV6_GTPU_IPV4_FRAG, ICE_PTYPE_ATTR_GTP_DOWNLINK },
441 { ICE_MAC_IPV6_GTPU_IPV4_PAY, ICE_PTYPE_ATTR_GTP_DOWNLINK },
442 { ICE_MAC_IPV6_GTPU_IPV4_UDP_PAY, ICE_PTYPE_ATTR_GTP_DOWNLINK },
443 { ICE_MAC_IPV6_GTPU_IPV4_TCP, ICE_PTYPE_ATTR_GTP_DOWNLINK },
444 { ICE_MAC_IPV6_GTPU_IPV4_ICMP, ICE_PTYPE_ATTR_GTP_DOWNLINK },
445 { ICE_MAC_IPV4_GTPU_IPV6_FRAG, ICE_PTYPE_ATTR_GTP_DOWNLINK },
446 { ICE_MAC_IPV4_GTPU_IPV6_PAY, ICE_PTYPE_ATTR_GTP_DOWNLINK },
447 { ICE_MAC_IPV4_GTPU_IPV6_UDP_PAY, ICE_PTYPE_ATTR_GTP_DOWNLINK },
448 { ICE_MAC_IPV4_GTPU_IPV6_TCP, ICE_PTYPE_ATTR_GTP_DOWNLINK },
449 { ICE_MAC_IPV4_GTPU_IPV6_ICMPV6, ICE_PTYPE_ATTR_GTP_DOWNLINK },
450 { ICE_MAC_IPV6_GTPU_IPV6_FRAG, ICE_PTYPE_ATTR_GTP_DOWNLINK },
451 { ICE_MAC_IPV6_GTPU_IPV6_PAY, ICE_PTYPE_ATTR_GTP_DOWNLINK },
452 { ICE_MAC_IPV6_GTPU_IPV6_UDP_PAY, ICE_PTYPE_ATTR_GTP_DOWNLINK },
453 { ICE_MAC_IPV6_GTPU_IPV6_TCP, ICE_PTYPE_ATTR_GTP_DOWNLINK },
454 { ICE_MAC_IPV6_GTPU_IPV6_ICMPV6, ICE_PTYPE_ATTR_GTP_DOWNLINK },
457 static const struct ice_ptype_attributes ice_attr_gtpu_up[] = {
458 { ICE_MAC_IPV4_GTPU_IPV4_FRAG, ICE_PTYPE_ATTR_GTP_UPLINK },
459 { ICE_MAC_IPV4_GTPU_IPV4_PAY, ICE_PTYPE_ATTR_GTP_UPLINK },
460 { ICE_MAC_IPV4_GTPU_IPV4_UDP_PAY, ICE_PTYPE_ATTR_GTP_UPLINK },
461 { ICE_MAC_IPV4_GTPU_IPV4_TCP, ICE_PTYPE_ATTR_GTP_UPLINK },
462 { ICE_MAC_IPV4_GTPU_IPV4_ICMP, ICE_PTYPE_ATTR_GTP_UPLINK },
463 { ICE_MAC_IPV6_GTPU_IPV4_FRAG, ICE_PTYPE_ATTR_GTP_UPLINK },
464 { ICE_MAC_IPV6_GTPU_IPV4_PAY, ICE_PTYPE_ATTR_GTP_UPLINK },
465 { ICE_MAC_IPV6_GTPU_IPV4_UDP_PAY, ICE_PTYPE_ATTR_GTP_UPLINK },
466 { ICE_MAC_IPV6_GTPU_IPV4_TCP, ICE_PTYPE_ATTR_GTP_UPLINK },
467 { ICE_MAC_IPV6_GTPU_IPV4_ICMP, ICE_PTYPE_ATTR_GTP_UPLINK },
468 { ICE_MAC_IPV4_GTPU_IPV6_FRAG, ICE_PTYPE_ATTR_GTP_UPLINK },
469 { ICE_MAC_IPV4_GTPU_IPV6_PAY, ICE_PTYPE_ATTR_GTP_UPLINK },
470 { ICE_MAC_IPV4_GTPU_IPV6_UDP_PAY, ICE_PTYPE_ATTR_GTP_UPLINK },
471 { ICE_MAC_IPV4_GTPU_IPV6_TCP, ICE_PTYPE_ATTR_GTP_UPLINK },
472 { ICE_MAC_IPV4_GTPU_IPV6_ICMPV6, ICE_PTYPE_ATTR_GTP_UPLINK },
473 { ICE_MAC_IPV6_GTPU_IPV6_FRAG, ICE_PTYPE_ATTR_GTP_UPLINK },
474 { ICE_MAC_IPV6_GTPU_IPV6_PAY, ICE_PTYPE_ATTR_GTP_UPLINK },
475 { ICE_MAC_IPV6_GTPU_IPV6_UDP_PAY, ICE_PTYPE_ATTR_GTP_UPLINK },
476 { ICE_MAC_IPV6_GTPU_IPV6_TCP, ICE_PTYPE_ATTR_GTP_UPLINK },
477 { ICE_MAC_IPV6_GTPU_IPV6_ICMPV6, ICE_PTYPE_ATTR_GTP_UPLINK },
480 static const u32 ice_ptypes_gtpu[] = {
481 0x00000000, 0x00000000, 0x00000000, 0x00000000,
482 0x00000000, 0x00000000, 0x00000000, 0x00000000,
483 0x00000000, 0x00000000, 0x7FFFFE00, 0x00000000,
484 0x00000000, 0x00000000, 0x00000000, 0x00000000,
485 0x00000000, 0x00000000, 0x00000000, 0x00000000,
486 0x00000000, 0x00000000, 0x00000000, 0x00000000,
487 0x00000000, 0x00000000, 0x00000000, 0x00000000,
488 0x00000000, 0x00000000, 0x00000000, 0x00000000,
491 /* Packet types for PPPoE */
492 static const u32 ice_ptypes_pppoe[] = {
493 0x00000000, 0x00000000, 0x00000000, 0x00000000,
494 0x00000000, 0x00000000, 0x00000000, 0x00000000,
495 0x00000000, 0x03ffe000, 0x00000000, 0x00000000,
496 0x00000000, 0x00000000, 0x00000000, 0x00000000,
497 0x00000000, 0x00000000, 0x00000000, 0x00000000,
498 0x00000000, 0x00000000, 0x00000000, 0x00000000,
499 0x00000000, 0x00000000, 0x00000000, 0x00000000,
500 0x00000000, 0x00000000, 0x00000000, 0x00000000,
503 /* Packet types for packets with PFCP NODE header */
504 static const u32 ice_ptypes_pfcp_node[] = {
505 0x00000000, 0x00000000, 0x00000000, 0x00000000,
506 0x00000000, 0x00000000, 0x00000000, 0x00000000,
507 0x00000000, 0x00000000, 0x80000000, 0x00000002,
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 packets with PFCP SESSION header */
516 static const u32 ice_ptypes_pfcp_session[] = {
517 0x00000000, 0x00000000, 0x00000000, 0x00000000,
518 0x00000000, 0x00000000, 0x00000000, 0x00000000,
519 0x00000000, 0x00000000, 0x00000000, 0x00000005,
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 L2TPv3 */
528 static const u32 ice_ptypes_l2tpv3[] = {
529 0x00000000, 0x00000000, 0x00000000, 0x00000000,
530 0x00000000, 0x00000000, 0x00000000, 0x00000000,
531 0x00000000, 0x00000000, 0x00000000, 0x00000300,
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 ESP */
540 static const u32 ice_ptypes_esp[] = {
541 0x00000000, 0x00000000, 0x00000000, 0x00000000,
542 0x00000000, 0x00000003, 0x00000000, 0x00000000,
543 0x00000000, 0x00000000, 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,
551 /* Packet types for AH */
552 static const u32 ice_ptypes_ah[] = {
553 0x00000000, 0x00000000, 0x00000000, 0x00000000,
554 0x00000000, 0x0000000C, 0x00000000, 0x00000000,
555 0x00000000, 0x00000000, 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,
563 /* Packet types for packets with NAT_T ESP header */
564 static const u32 ice_ptypes_nat_t_esp[] = {
565 0x00000000, 0x00000000, 0x00000000, 0x00000000,
566 0x00000000, 0x00000030, 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 static const u32 ice_ptypes_mac_non_ip_ofos[] = {
576 0x00000846, 0x00000000, 0x00000000, 0x00000000,
577 0x00000000, 0x00000000, 0x00000000, 0x00000000,
578 0x00400000, 0x03FFF000, 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,
586 /* Manage parameters and info. used during the creation of a flow profile */
587 struct ice_flow_prof_params {
589 u16 entry_length; /* # of bytes formatted entry will require */
591 struct ice_flow_prof *prof;
593 /* For ACL, the es[0] will have the data of ICE_RX_MDID_PKT_FLAGS_15_0
594 * This will give us the direction flags.
596 struct ice_fv_word es[ICE_MAX_FV_WORDS];
597 /* attributes can be used to add attributes to a particular PTYPE */
598 const struct ice_ptype_attributes *attr;
601 u16 mask[ICE_MAX_FV_WORDS];
602 DECLARE_BITMAP(ptypes, ICE_FLOW_PTYPE_MAX);
605 #define ICE_FLOW_RSS_HDRS_INNER_MASK \
606 (ICE_FLOW_SEG_HDR_PPPOE | ICE_FLOW_SEG_HDR_GTPC | \
607 ICE_FLOW_SEG_HDR_GTPC_TEID | ICE_FLOW_SEG_HDR_GTPU | \
608 ICE_FLOW_SEG_HDR_PFCP_SESSION | ICE_FLOW_SEG_HDR_L2TPV3 | \
609 ICE_FLOW_SEG_HDR_ESP | ICE_FLOW_SEG_HDR_AH | \
610 ICE_FLOW_SEG_HDR_NAT_T_ESP)
612 #define ICE_FLOW_SEG_HDRS_L2_MASK \
613 (ICE_FLOW_SEG_HDR_ETH | ICE_FLOW_SEG_HDR_VLAN)
614 #define ICE_FLOW_SEG_HDRS_L3_MASK \
615 (ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_IPV6 | ICE_FLOW_SEG_HDR_ARP)
616 #define ICE_FLOW_SEG_HDRS_L4_MASK \
617 (ICE_FLOW_SEG_HDR_ICMP | ICE_FLOW_SEG_HDR_TCP | ICE_FLOW_SEG_HDR_UDP | \
618 ICE_FLOW_SEG_HDR_SCTP)
619 /* mask for L4 protocols that are NOT part of IPv4/6 OTHER PTYPE groups */
620 #define ICE_FLOW_SEG_HDRS_L4_MASK_NO_OTHER \
621 (ICE_FLOW_SEG_HDR_TCP | ICE_FLOW_SEG_HDR_UDP | ICE_FLOW_SEG_HDR_SCTP)
624 * ice_flow_val_hdrs - validates packet segments for valid protocol headers
625 * @segs: array of one or more packet segments that describe the flow
626 * @segs_cnt: number of packet segments provided
628 static enum ice_status
629 ice_flow_val_hdrs(struct ice_flow_seg_info *segs, u8 segs_cnt)
633 for (i = 0; i < segs_cnt; i++) {
634 /* Multiple L3 headers */
635 if (segs[i].hdrs & ICE_FLOW_SEG_HDRS_L3_MASK &&
636 !is_power_of_2(segs[i].hdrs & ICE_FLOW_SEG_HDRS_L3_MASK))
637 return ICE_ERR_PARAM;
639 /* Multiple L4 headers */
640 if (segs[i].hdrs & ICE_FLOW_SEG_HDRS_L4_MASK &&
641 !is_power_of_2(segs[i].hdrs & ICE_FLOW_SEG_HDRS_L4_MASK))
642 return ICE_ERR_PARAM;
648 /* Sizes of fixed known protocol headers without header options */
649 #define ICE_FLOW_PROT_HDR_SZ_MAC 14
650 #define ICE_FLOW_PROT_HDR_SZ_MAC_VLAN (ICE_FLOW_PROT_HDR_SZ_MAC + 2)
651 #define ICE_FLOW_PROT_HDR_SZ_IPV4 20
652 #define ICE_FLOW_PROT_HDR_SZ_IPV6 40
653 #define ICE_FLOW_PROT_HDR_SZ_ARP 28
654 #define ICE_FLOW_PROT_HDR_SZ_ICMP 8
655 #define ICE_FLOW_PROT_HDR_SZ_TCP 20
656 #define ICE_FLOW_PROT_HDR_SZ_UDP 8
657 #define ICE_FLOW_PROT_HDR_SZ_SCTP 12
660 * ice_flow_calc_seg_sz - calculates size of a packet segment based on headers
661 * @params: information about the flow to be processed
662 * @seg: index of packet segment whose header size is to be determined
664 static u16 ice_flow_calc_seg_sz(struct ice_flow_prof_params *params, u8 seg)
669 sz = (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_VLAN) ?
670 ICE_FLOW_PROT_HDR_SZ_MAC_VLAN : ICE_FLOW_PROT_HDR_SZ_MAC;
673 if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_IPV4)
674 sz += ICE_FLOW_PROT_HDR_SZ_IPV4;
675 else if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_IPV6)
676 sz += ICE_FLOW_PROT_HDR_SZ_IPV6;
677 else if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_ARP)
678 sz += ICE_FLOW_PROT_HDR_SZ_ARP;
679 else if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDRS_L4_MASK)
680 /* An L3 header is required if L4 is specified */
684 if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_ICMP)
685 sz += ICE_FLOW_PROT_HDR_SZ_ICMP;
686 else if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_TCP)
687 sz += ICE_FLOW_PROT_HDR_SZ_TCP;
688 else if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_UDP)
689 sz += ICE_FLOW_PROT_HDR_SZ_UDP;
690 else if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_SCTP)
691 sz += ICE_FLOW_PROT_HDR_SZ_SCTP;
697 * ice_flow_proc_seg_hdrs - process protocol headers present in pkt segments
698 * @params: information about the flow to be processed
700 * This function identifies the packet types associated with the protocol
701 * headers being present in packet segments of the specified flow profile.
703 static enum ice_status
704 ice_flow_proc_seg_hdrs(struct ice_flow_prof_params *params)
706 struct ice_flow_prof *prof;
709 memset(params->ptypes, 0xff, sizeof(params->ptypes));
713 for (i = 0; i < params->prof->segs_cnt; i++) {
714 const unsigned long *src;
717 hdrs = prof->segs[i].hdrs;
719 if (hdrs & ICE_FLOW_SEG_HDR_ETH) {
720 src = !i ? (const unsigned long *)ice_ptypes_mac_ofos :
721 (const unsigned long *)ice_ptypes_mac_il;
722 bitmap_and(params->ptypes, params->ptypes, src,
726 if (i && hdrs & ICE_FLOW_SEG_HDR_VLAN) {
727 src = (const unsigned long *)ice_ptypes_macvlan_il;
728 bitmap_and(params->ptypes, params->ptypes, src,
732 if (!i && hdrs & ICE_FLOW_SEG_HDR_ARP) {
733 bitmap_and(params->ptypes, params->ptypes,
734 (const unsigned long *)ice_ptypes_arp_of,
738 if ((hdrs & ICE_FLOW_SEG_HDR_IPV4) &&
739 (hdrs & ICE_FLOW_SEG_HDR_IPV_OTHER)) {
740 src = i ? (const unsigned long *)ice_ptypes_ipv4_il :
741 (const unsigned long *)ice_ptypes_ipv4_ofos_all;
742 bitmap_and(params->ptypes, params->ptypes, src,
744 } else if ((hdrs & ICE_FLOW_SEG_HDR_IPV6) &&
745 (hdrs & ICE_FLOW_SEG_HDR_IPV_OTHER)) {
746 src = i ? (const unsigned long *)ice_ptypes_ipv6_il :
747 (const unsigned long *)ice_ptypes_ipv6_ofos_all;
748 bitmap_and(params->ptypes, params->ptypes, src,
750 } else if ((hdrs & ICE_FLOW_SEG_HDR_IPV4) &&
751 !(hdrs & ICE_FLOW_SEG_HDRS_L4_MASK_NO_OTHER)) {
752 src = !i ? (const unsigned long *)ice_ptypes_ipv4_ofos_no_l4 :
753 (const unsigned long *)ice_ptypes_ipv4_il_no_l4;
754 bitmap_and(params->ptypes, params->ptypes, src,
756 } else if (hdrs & ICE_FLOW_SEG_HDR_IPV4) {
757 src = !i ? (const unsigned long *)ice_ptypes_ipv4_ofos :
758 (const unsigned long *)ice_ptypes_ipv4_il;
759 bitmap_and(params->ptypes, params->ptypes, src,
761 } else if ((hdrs & ICE_FLOW_SEG_HDR_IPV6) &&
762 !(hdrs & ICE_FLOW_SEG_HDRS_L4_MASK_NO_OTHER)) {
763 src = !i ? (const unsigned long *)ice_ptypes_ipv6_ofos_no_l4 :
764 (const unsigned long *)ice_ptypes_ipv6_il_no_l4;
765 bitmap_and(params->ptypes, params->ptypes, src,
767 } else if (hdrs & ICE_FLOW_SEG_HDR_IPV6) {
768 src = !i ? (const unsigned long *)ice_ptypes_ipv6_ofos :
769 (const unsigned long *)ice_ptypes_ipv6_il;
770 bitmap_and(params->ptypes, params->ptypes, src,
774 if (hdrs & ICE_FLOW_SEG_HDR_ETH_NON_IP) {
775 src = (const unsigned long *)ice_ptypes_mac_non_ip_ofos;
776 bitmap_and(params->ptypes, params->ptypes, src,
778 } else if (hdrs & ICE_FLOW_SEG_HDR_PPPOE) {
779 src = (const unsigned long *)ice_ptypes_pppoe;
780 bitmap_and(params->ptypes, params->ptypes, src,
783 src = (const unsigned long *)ice_ptypes_pppoe;
784 bitmap_andnot(params->ptypes, params->ptypes, src,
788 if (hdrs & ICE_FLOW_SEG_HDR_UDP) {
789 src = (const unsigned long *)ice_ptypes_udp_il;
790 bitmap_and(params->ptypes, params->ptypes, src,
792 } else if (hdrs & ICE_FLOW_SEG_HDR_TCP) {
793 bitmap_and(params->ptypes, params->ptypes,
794 (const unsigned long *)ice_ptypes_tcp_il,
796 } else if (hdrs & ICE_FLOW_SEG_HDR_SCTP) {
797 src = (const unsigned long *)ice_ptypes_sctp_il;
798 bitmap_and(params->ptypes, params->ptypes, src,
802 if (hdrs & ICE_FLOW_SEG_HDR_ICMP) {
803 src = !i ? (const unsigned long *)ice_ptypes_icmp_of :
804 (const unsigned long *)ice_ptypes_icmp_il;
805 bitmap_and(params->ptypes, params->ptypes, src,
807 } else if (hdrs & ICE_FLOW_SEG_HDR_GRE) {
809 src = (const unsigned long *)ice_ptypes_gre_of;
810 bitmap_and(params->ptypes, params->ptypes,
811 src, ICE_FLOW_PTYPE_MAX);
813 } else if (hdrs & ICE_FLOW_SEG_HDR_GTPC) {
814 src = (const unsigned long *)ice_ptypes_gtpc;
815 bitmap_and(params->ptypes, params->ptypes, src,
817 } else if (hdrs & ICE_FLOW_SEG_HDR_GTPC_TEID) {
818 src = (const unsigned long *)ice_ptypes_gtpc_tid;
819 bitmap_and(params->ptypes, params->ptypes, src,
821 } else if (hdrs & ICE_FLOW_SEG_HDR_GTPU_DWN) {
822 src = (const unsigned long *)ice_ptypes_gtpu;
823 bitmap_and(params->ptypes, params->ptypes, src,
826 /* Attributes for GTP packet with downlink */
827 params->attr = ice_attr_gtpu_down;
828 params->attr_cnt = ARRAY_SIZE(ice_attr_gtpu_down);
829 } else if (hdrs & ICE_FLOW_SEG_HDR_GTPU_UP) {
830 src = (const unsigned long *)ice_ptypes_gtpu;
831 bitmap_and(params->ptypes, params->ptypes, src,
834 /* Attributes for GTP packet with uplink */
835 params->attr = ice_attr_gtpu_up;
836 params->attr_cnt = ARRAY_SIZE(ice_attr_gtpu_up);
837 } else if (hdrs & ICE_FLOW_SEG_HDR_GTPU_EH) {
838 src = (const unsigned long *)ice_ptypes_gtpu;
839 bitmap_and(params->ptypes, params->ptypes, src,
842 /* Attributes for GTP packet with Extension Header */
843 params->attr = ice_attr_gtpu_eh;
844 params->attr_cnt = ARRAY_SIZE(ice_attr_gtpu_eh);
845 } else if (hdrs & ICE_FLOW_SEG_HDR_GTPU_IP) {
846 src = (const unsigned long *)ice_ptypes_gtpu;
847 bitmap_and(params->ptypes, params->ptypes, src,
849 } else if (hdrs & ICE_FLOW_SEG_HDR_L2TPV3) {
850 src = (const unsigned long *)ice_ptypes_l2tpv3;
851 bitmap_and(params->ptypes, params->ptypes, src,
853 } else if (hdrs & ICE_FLOW_SEG_HDR_ESP) {
854 src = (const unsigned long *)ice_ptypes_esp;
855 bitmap_and(params->ptypes, params->ptypes, src,
857 } else if (hdrs & ICE_FLOW_SEG_HDR_AH) {
858 src = (const unsigned long *)ice_ptypes_ah;
859 bitmap_and(params->ptypes, params->ptypes, src,
861 } else if (hdrs & ICE_FLOW_SEG_HDR_NAT_T_ESP) {
862 src = (const unsigned long *)ice_ptypes_nat_t_esp;
863 bitmap_and(params->ptypes, params->ptypes, src,
867 if (hdrs & ICE_FLOW_SEG_HDR_PFCP) {
868 if (hdrs & ICE_FLOW_SEG_HDR_PFCP_NODE)
869 src = (const unsigned long *)ice_ptypes_pfcp_node;
871 src = (const unsigned long *)ice_ptypes_pfcp_session;
873 bitmap_and(params->ptypes, params->ptypes, src,
876 src = (const unsigned long *)ice_ptypes_pfcp_node;
877 bitmap_andnot(params->ptypes, params->ptypes, src,
880 src = (const unsigned long *)ice_ptypes_pfcp_session;
881 bitmap_andnot(params->ptypes, params->ptypes, src,
890 * ice_flow_xtract_fld - Create an extraction sequence entry for the given field
891 * @hw: pointer to the HW struct
892 * @params: information about the flow to be processed
893 * @seg: packet segment index of the field to be extracted
894 * @fld: ID of field to be extracted
895 * @match: bit field of all fields
897 * This function determines the protocol ID, offset, and size of the given
898 * field. It then allocates one or more extraction sequence entries for the
899 * given field, and fill the entries with protocol ID and offset information.
901 static enum ice_status
902 ice_flow_xtract_fld(struct ice_hw *hw, struct ice_flow_prof_params *params,
903 u8 seg, enum ice_flow_field fld, u64 match)
905 enum ice_flow_field sib = ICE_FLOW_FIELD_IDX_MAX;
906 enum ice_prot_id prot_id = ICE_PROT_ID_INVAL;
907 u8 fv_words = hw->blk[params->blk].es.fvw;
908 struct ice_flow_fld_info *flds;
909 u16 cnt, ese_bits, i;
914 flds = params->prof->segs[seg].fields;
917 case ICE_FLOW_FIELD_IDX_ETH_DA:
918 case ICE_FLOW_FIELD_IDX_ETH_SA:
919 case ICE_FLOW_FIELD_IDX_S_VLAN:
920 case ICE_FLOW_FIELD_IDX_C_VLAN:
921 prot_id = seg == 0 ? ICE_PROT_MAC_OF_OR_S : ICE_PROT_MAC_IL;
923 case ICE_FLOW_FIELD_IDX_ETH_TYPE:
924 prot_id = seg == 0 ? ICE_PROT_ETYPE_OL : ICE_PROT_ETYPE_IL;
926 case ICE_FLOW_FIELD_IDX_IPV4_DSCP:
927 prot_id = seg == 0 ? ICE_PROT_IPV4_OF_OR_S : ICE_PROT_IPV4_IL;
929 case ICE_FLOW_FIELD_IDX_IPV6_DSCP:
930 prot_id = seg == 0 ? ICE_PROT_IPV6_OF_OR_S : ICE_PROT_IPV6_IL;
932 case ICE_FLOW_FIELD_IDX_IPV4_TTL:
933 case ICE_FLOW_FIELD_IDX_IPV4_PROT:
934 prot_id = seg == 0 ? ICE_PROT_IPV4_OF_OR_S : ICE_PROT_IPV4_IL;
936 /* TTL and PROT share the same extraction seq. entry.
937 * Each is considered a sibling to the other in terms of sharing
938 * the same extraction sequence entry.
940 if (fld == ICE_FLOW_FIELD_IDX_IPV4_TTL)
941 sib = ICE_FLOW_FIELD_IDX_IPV4_PROT;
942 else if (fld == ICE_FLOW_FIELD_IDX_IPV4_PROT)
943 sib = ICE_FLOW_FIELD_IDX_IPV4_TTL;
945 /* If the sibling field is also included, that field's
946 * mask needs to be included.
948 if (match & BIT(sib))
949 sib_mask = ice_flds_info[sib].mask;
951 case ICE_FLOW_FIELD_IDX_IPV6_TTL:
952 case ICE_FLOW_FIELD_IDX_IPV6_PROT:
953 prot_id = seg == 0 ? ICE_PROT_IPV6_OF_OR_S : ICE_PROT_IPV6_IL;
955 /* TTL and PROT share the same extraction seq. entry.
956 * Each is considered a sibling to the other in terms of sharing
957 * the same extraction sequence entry.
959 if (fld == ICE_FLOW_FIELD_IDX_IPV6_TTL)
960 sib = ICE_FLOW_FIELD_IDX_IPV6_PROT;
961 else if (fld == ICE_FLOW_FIELD_IDX_IPV6_PROT)
962 sib = ICE_FLOW_FIELD_IDX_IPV6_TTL;
964 /* If the sibling field is also included, that field's
965 * mask needs to be included.
967 if (match & BIT(sib))
968 sib_mask = ice_flds_info[sib].mask;
970 case ICE_FLOW_FIELD_IDX_IPV4_SA:
971 case ICE_FLOW_FIELD_IDX_IPV4_DA:
972 prot_id = seg == 0 ? ICE_PROT_IPV4_OF_OR_S : ICE_PROT_IPV4_IL;
974 case ICE_FLOW_FIELD_IDX_IPV6_SA:
975 case ICE_FLOW_FIELD_IDX_IPV6_DA:
976 prot_id = seg == 0 ? ICE_PROT_IPV6_OF_OR_S : ICE_PROT_IPV6_IL;
978 case ICE_FLOW_FIELD_IDX_TCP_SRC_PORT:
979 case ICE_FLOW_FIELD_IDX_TCP_DST_PORT:
980 case ICE_FLOW_FIELD_IDX_TCP_FLAGS:
981 prot_id = ICE_PROT_TCP_IL;
983 case ICE_FLOW_FIELD_IDX_UDP_SRC_PORT:
984 case ICE_FLOW_FIELD_IDX_UDP_DST_PORT:
985 prot_id = ICE_PROT_UDP_IL_OR_S;
987 case ICE_FLOW_FIELD_IDX_SCTP_SRC_PORT:
988 case ICE_FLOW_FIELD_IDX_SCTP_DST_PORT:
989 prot_id = ICE_PROT_SCTP_IL;
991 case ICE_FLOW_FIELD_IDX_GTPC_TEID:
992 case ICE_FLOW_FIELD_IDX_GTPU_IP_TEID:
993 case ICE_FLOW_FIELD_IDX_GTPU_UP_TEID:
994 case ICE_FLOW_FIELD_IDX_GTPU_DWN_TEID:
995 case ICE_FLOW_FIELD_IDX_GTPU_EH_TEID:
996 case ICE_FLOW_FIELD_IDX_GTPU_EH_QFI:
997 /* GTP is accessed through UDP OF protocol */
998 prot_id = ICE_PROT_UDP_OF;
1000 case ICE_FLOW_FIELD_IDX_PPPOE_SESS_ID:
1001 prot_id = ICE_PROT_PPPOE;
1003 case ICE_FLOW_FIELD_IDX_PFCP_SEID:
1004 prot_id = ICE_PROT_UDP_IL_OR_S;
1006 case ICE_FLOW_FIELD_IDX_L2TPV3_SESS_ID:
1007 prot_id = ICE_PROT_L2TPV3;
1009 case ICE_FLOW_FIELD_IDX_ESP_SPI:
1010 prot_id = ICE_PROT_ESP_F;
1012 case ICE_FLOW_FIELD_IDX_AH_SPI:
1013 prot_id = ICE_PROT_ESP_2;
1015 case ICE_FLOW_FIELD_IDX_NAT_T_ESP_SPI:
1016 prot_id = ICE_PROT_UDP_IL_OR_S;
1018 case ICE_FLOW_FIELD_IDX_ARP_SIP:
1019 case ICE_FLOW_FIELD_IDX_ARP_DIP:
1020 case ICE_FLOW_FIELD_IDX_ARP_SHA:
1021 case ICE_FLOW_FIELD_IDX_ARP_DHA:
1022 case ICE_FLOW_FIELD_IDX_ARP_OP:
1023 prot_id = ICE_PROT_ARP_OF;
1025 case ICE_FLOW_FIELD_IDX_ICMP_TYPE:
1026 case ICE_FLOW_FIELD_IDX_ICMP_CODE:
1027 /* ICMP type and code share the same extraction seq. entry */
1028 prot_id = (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_IPV4) ?
1029 ICE_PROT_ICMP_IL : ICE_PROT_ICMPV6_IL;
1030 sib = fld == ICE_FLOW_FIELD_IDX_ICMP_TYPE ?
1031 ICE_FLOW_FIELD_IDX_ICMP_CODE :
1032 ICE_FLOW_FIELD_IDX_ICMP_TYPE;
1034 case ICE_FLOW_FIELD_IDX_GRE_KEYID:
1035 prot_id = ICE_PROT_GRE_OF;
1038 return ICE_ERR_NOT_IMPL;
1041 /* Each extraction sequence entry is a word in size, and extracts a
1042 * word-aligned offset from a protocol header.
1044 ese_bits = ICE_FLOW_FV_EXTRACT_SZ * BITS_PER_BYTE;
1046 flds[fld].xtrct.prot_id = prot_id;
1047 flds[fld].xtrct.off = (ice_flds_info[fld].off / ese_bits) *
1048 ICE_FLOW_FV_EXTRACT_SZ;
1049 flds[fld].xtrct.disp = (u8)(ice_flds_info[fld].off % ese_bits);
1050 flds[fld].xtrct.idx = params->es_cnt;
1051 flds[fld].xtrct.mask = ice_flds_info[fld].mask;
1053 /* Adjust the next field-entry index after accommodating the number of
1054 * entries this field consumes
1056 cnt = DIV_ROUND_UP(flds[fld].xtrct.disp + ice_flds_info[fld].size,
1059 /* Fill in the extraction sequence entries needed for this field */
1060 off = flds[fld].xtrct.off;
1061 mask = flds[fld].xtrct.mask;
1062 for (i = 0; i < cnt; i++) {
1063 /* Only consume an extraction sequence entry if there is no
1064 * sibling field associated with this field or the sibling entry
1065 * already extracts the word shared with this field.
1067 if (sib == ICE_FLOW_FIELD_IDX_MAX ||
1068 flds[sib].xtrct.prot_id == ICE_PROT_ID_INVAL ||
1069 flds[sib].xtrct.off != off) {
1072 /* Make sure the number of extraction sequence required
1073 * does not exceed the block's capability
1075 if (params->es_cnt >= fv_words)
1076 return ICE_ERR_MAX_LIMIT;
1078 /* some blocks require a reversed field vector layout */
1079 if (hw->blk[params->blk].es.reverse)
1080 idx = fv_words - params->es_cnt - 1;
1082 idx = params->es_cnt;
1084 params->es[idx].prot_id = prot_id;
1085 params->es[idx].off = off;
1086 params->mask[idx] = mask | sib_mask;
1090 off += ICE_FLOW_FV_EXTRACT_SZ;
1097 * ice_flow_xtract_raws - Create extract sequence entries for raw bytes
1098 * @hw: pointer to the HW struct
1099 * @params: information about the flow to be processed
1100 * @seg: index of packet segment whose raw fields are to be extracted
1102 static enum ice_status
1103 ice_flow_xtract_raws(struct ice_hw *hw, struct ice_flow_prof_params *params,
1110 if (!params->prof->segs[seg].raws_cnt)
1113 if (params->prof->segs[seg].raws_cnt >
1114 ARRAY_SIZE(params->prof->segs[seg].raws))
1115 return ICE_ERR_MAX_LIMIT;
1117 /* Offsets within the segment headers are not supported */
1118 hdrs_sz = ice_flow_calc_seg_sz(params, seg);
1120 return ICE_ERR_PARAM;
1122 fv_words = hw->blk[params->blk].es.fvw;
1124 for (i = 0; i < params->prof->segs[seg].raws_cnt; i++) {
1125 struct ice_flow_seg_fld_raw *raw;
1128 raw = ¶ms->prof->segs[seg].raws[i];
1130 /* Storing extraction information */
1131 raw->info.xtrct.prot_id = ICE_PROT_MAC_OF_OR_S;
1132 raw->info.xtrct.off = (raw->off / ICE_FLOW_FV_EXTRACT_SZ) *
1133 ICE_FLOW_FV_EXTRACT_SZ;
1134 raw->info.xtrct.disp = (raw->off % ICE_FLOW_FV_EXTRACT_SZ) *
1136 raw->info.xtrct.idx = params->es_cnt;
1138 /* Determine the number of field vector entries this raw field
1141 cnt = DIV_ROUND_UP(raw->info.xtrct.disp +
1142 (raw->info.src.last * BITS_PER_BYTE),
1143 (ICE_FLOW_FV_EXTRACT_SZ * BITS_PER_BYTE));
1144 off = raw->info.xtrct.off;
1145 for (j = 0; j < cnt; j++) {
1148 /* Make sure the number of extraction sequence required
1149 * does not exceed the block's capability
1151 if (params->es_cnt >= hw->blk[params->blk].es.count ||
1152 params->es_cnt >= ICE_MAX_FV_WORDS)
1153 return ICE_ERR_MAX_LIMIT;
1155 /* some blocks require a reversed field vector layout */
1156 if (hw->blk[params->blk].es.reverse)
1157 idx = fv_words - params->es_cnt - 1;
1159 idx = params->es_cnt;
1161 params->es[idx].prot_id = raw->info.xtrct.prot_id;
1162 params->es[idx].off = off;
1164 off += ICE_FLOW_FV_EXTRACT_SZ;
1172 * ice_flow_create_xtrct_seq - Create an extraction sequence for given segments
1173 * @hw: pointer to the HW struct
1174 * @params: information about the flow to be processed
1176 * This function iterates through all matched fields in the given segments, and
1177 * creates an extraction sequence for the fields.
1179 static enum ice_status
1180 ice_flow_create_xtrct_seq(struct ice_hw *hw,
1181 struct ice_flow_prof_params *params)
1183 struct ice_flow_prof *prof = params->prof;
1184 enum ice_status status = 0;
1187 for (i = 0; i < prof->segs_cnt; i++) {
1188 u64 match = params->prof->segs[i].match;
1189 enum ice_flow_field j;
1191 for_each_set_bit(j, (unsigned long *)&match,
1192 ICE_FLOW_FIELD_IDX_MAX) {
1193 status = ice_flow_xtract_fld(hw, params, i, j, match);
1196 clear_bit(j, (unsigned long *)&match);
1199 /* Process raw matching bytes */
1200 status = ice_flow_xtract_raws(hw, params, i);
1209 * ice_flow_proc_segs - process all packet segments associated with a profile
1210 * @hw: pointer to the HW struct
1211 * @params: information about the flow to be processed
1213 static enum ice_status
1214 ice_flow_proc_segs(struct ice_hw *hw, struct ice_flow_prof_params *params)
1216 enum ice_status status;
1218 status = ice_flow_proc_seg_hdrs(params);
1222 status = ice_flow_create_xtrct_seq(hw, params);
1226 switch (params->blk) {
1232 return ICE_ERR_NOT_IMPL;
1238 #define ICE_FLOW_FIND_PROF_CHK_FLDS 0x00000001
1239 #define ICE_FLOW_FIND_PROF_CHK_VSI 0x00000002
1240 #define ICE_FLOW_FIND_PROF_NOT_CHK_DIR 0x00000004
1243 * ice_flow_find_prof_conds - Find a profile matching headers and conditions
1244 * @hw: pointer to the HW struct
1245 * @blk: classification stage
1246 * @dir: flow direction
1247 * @segs: array of one or more packet segments that describe the flow
1248 * @segs_cnt: number of packet segments provided
1249 * @vsi_handle: software VSI handle to check VSI (ICE_FLOW_FIND_PROF_CHK_VSI)
1250 * @conds: additional conditions to be checked (ICE_FLOW_FIND_PROF_CHK_*)
1252 static struct ice_flow_prof *
1253 ice_flow_find_prof_conds(struct ice_hw *hw, enum ice_block blk,
1254 enum ice_flow_dir dir, struct ice_flow_seg_info *segs,
1255 u8 segs_cnt, u16 vsi_handle, u32 conds)
1257 struct ice_flow_prof *p, *prof = NULL;
1259 mutex_lock(&hw->fl_profs_locks[blk]);
1260 list_for_each_entry(p, &hw->fl_profs[blk], l_entry)
1261 if ((p->dir == dir || conds & ICE_FLOW_FIND_PROF_NOT_CHK_DIR) &&
1262 segs_cnt && segs_cnt == p->segs_cnt) {
1265 /* Check for profile-VSI association if specified */
1266 if ((conds & ICE_FLOW_FIND_PROF_CHK_VSI) &&
1267 ice_is_vsi_valid(hw, vsi_handle) &&
1268 !test_bit(vsi_handle, p->vsis))
1271 /* Protocol headers must be checked. Matched fields are
1272 * checked if specified.
1274 for (i = 0; i < segs_cnt; i++)
1275 if (segs[i].hdrs != p->segs[i].hdrs ||
1276 ((conds & ICE_FLOW_FIND_PROF_CHK_FLDS) &&
1277 segs[i].match != p->segs[i].match))
1280 /* A match is found if all segments are matched */
1281 if (i == segs_cnt) {
1286 mutex_unlock(&hw->fl_profs_locks[blk]);
1292 * ice_flow_find_prof_id - Look up a profile with given profile ID
1293 * @hw: pointer to the HW struct
1294 * @blk: classification stage
1295 * @prof_id: unique ID to identify this flow profile
1297 static struct ice_flow_prof *
1298 ice_flow_find_prof_id(struct ice_hw *hw, enum ice_block blk, u64 prof_id)
1300 struct ice_flow_prof *p;
1302 list_for_each_entry(p, &hw->fl_profs[blk], l_entry)
1303 if (p->id == prof_id)
1310 * ice_dealloc_flow_entry - Deallocate flow entry memory
1311 * @hw: pointer to the HW struct
1312 * @entry: flow entry to be removed
1315 ice_dealloc_flow_entry(struct ice_hw *hw, struct ice_flow_entry *entry)
1321 devm_kfree(ice_hw_to_dev(hw), entry->entry);
1323 devm_kfree(ice_hw_to_dev(hw), entry);
1327 * ice_flow_rem_entry_sync - Remove a flow entry
1328 * @hw: pointer to the HW struct
1329 * @blk: classification stage
1330 * @entry: flow entry to be removed
1332 static enum ice_status
1333 ice_flow_rem_entry_sync(struct ice_hw *hw, enum ice_block __always_unused blk,
1334 struct ice_flow_entry *entry)
1337 return ICE_ERR_BAD_PTR;
1339 list_del(&entry->l_entry);
1341 ice_dealloc_flow_entry(hw, entry);
1347 * ice_flow_add_prof_sync - Add a flow profile for packet segments and fields
1348 * @hw: pointer to the HW struct
1349 * @blk: classification stage
1350 * @dir: flow direction
1351 * @prof_id: unique ID to identify this flow profile
1352 * @segs: array of one or more packet segments that describe the flow
1353 * @segs_cnt: number of packet segments provided
1354 * @prof: stores the returned flow profile added
1356 * Assumption: the caller has acquired the lock to the profile list
1358 static enum ice_status
1359 ice_flow_add_prof_sync(struct ice_hw *hw, enum ice_block blk,
1360 enum ice_flow_dir dir, u64 prof_id,
1361 struct ice_flow_seg_info *segs, u8 segs_cnt,
1362 struct ice_flow_prof **prof)
1364 struct ice_flow_prof_params *params;
1365 enum ice_status status;
1369 return ICE_ERR_BAD_PTR;
1371 params = kzalloc(sizeof(*params), GFP_KERNEL);
1373 return ICE_ERR_NO_MEMORY;
1375 params->prof = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*params->prof),
1377 if (!params->prof) {
1378 status = ICE_ERR_NO_MEMORY;
1382 /* initialize extraction sequence to all invalid (0xff) */
1383 for (i = 0; i < ICE_MAX_FV_WORDS; i++) {
1384 params->es[i].prot_id = ICE_PROT_INVALID;
1385 params->es[i].off = ICE_FV_OFFSET_INVAL;
1389 params->prof->id = prof_id;
1390 params->prof->dir = dir;
1391 params->prof->segs_cnt = segs_cnt;
1393 /* Make a copy of the segments that need to be persistent in the flow
1396 for (i = 0; i < segs_cnt; i++)
1397 memcpy(¶ms->prof->segs[i], &segs[i], sizeof(*segs));
1399 status = ice_flow_proc_segs(hw, params);
1401 ice_debug(hw, ICE_DBG_FLOW, "Error processing a flow's packet segments\n");
1405 /* Add a HW profile for this flow profile */
1406 status = ice_add_prof(hw, blk, prof_id, (u8 *)params->ptypes,
1407 params->attr, params->attr_cnt, params->es,
1410 ice_debug(hw, ICE_DBG_FLOW, "Error adding a HW flow profile\n");
1414 INIT_LIST_HEAD(¶ms->prof->entries);
1415 mutex_init(¶ms->prof->entries_lock);
1416 *prof = params->prof;
1420 devm_kfree(ice_hw_to_dev(hw), params->prof);
1428 * ice_flow_rem_prof_sync - remove a flow profile
1429 * @hw: pointer to the hardware structure
1430 * @blk: classification stage
1431 * @prof: pointer to flow profile to remove
1433 * Assumption: the caller has acquired the lock to the profile list
1435 static enum ice_status
1436 ice_flow_rem_prof_sync(struct ice_hw *hw, enum ice_block blk,
1437 struct ice_flow_prof *prof)
1439 enum ice_status status;
1441 /* Remove all remaining flow entries before removing the flow profile */
1442 if (!list_empty(&prof->entries)) {
1443 struct ice_flow_entry *e, *t;
1445 mutex_lock(&prof->entries_lock);
1447 list_for_each_entry_safe(e, t, &prof->entries, l_entry) {
1448 status = ice_flow_rem_entry_sync(hw, blk, e);
1453 mutex_unlock(&prof->entries_lock);
1456 /* Remove all hardware profiles associated with this flow profile */
1457 status = ice_rem_prof(hw, blk, prof->id);
1459 list_del(&prof->l_entry);
1460 mutex_destroy(&prof->entries_lock);
1461 devm_kfree(ice_hw_to_dev(hw), prof);
1468 * ice_flow_assoc_prof - associate a VSI with a flow profile
1469 * @hw: pointer to the hardware structure
1470 * @blk: classification stage
1471 * @prof: pointer to flow profile
1472 * @vsi_handle: software VSI handle
1474 * Assumption: the caller has acquired the lock to the profile list
1475 * and the software VSI handle has been validated
1477 static enum ice_status
1478 ice_flow_assoc_prof(struct ice_hw *hw, enum ice_block blk,
1479 struct ice_flow_prof *prof, u16 vsi_handle)
1481 enum ice_status status = 0;
1483 if (!test_bit(vsi_handle, prof->vsis)) {
1484 status = ice_add_prof_id_flow(hw, blk,
1485 ice_get_hw_vsi_num(hw,
1489 set_bit(vsi_handle, prof->vsis);
1491 ice_debug(hw, ICE_DBG_FLOW, "HW profile add failed, %d\n",
1499 * ice_flow_disassoc_prof - disassociate a VSI from a flow profile
1500 * @hw: pointer to the hardware structure
1501 * @blk: classification stage
1502 * @prof: pointer to flow profile
1503 * @vsi_handle: software VSI handle
1505 * Assumption: the caller has acquired the lock to the profile list
1506 * and the software VSI handle has been validated
1508 static enum ice_status
1509 ice_flow_disassoc_prof(struct ice_hw *hw, enum ice_block blk,
1510 struct ice_flow_prof *prof, u16 vsi_handle)
1512 enum ice_status status = 0;
1514 if (test_bit(vsi_handle, prof->vsis)) {
1515 status = ice_rem_prof_id_flow(hw, blk,
1516 ice_get_hw_vsi_num(hw,
1520 clear_bit(vsi_handle, prof->vsis);
1522 ice_debug(hw, ICE_DBG_FLOW, "HW profile remove failed, %d\n",
1530 * ice_flow_add_prof - Add a flow profile for packet segments and matched fields
1531 * @hw: pointer to the HW struct
1532 * @blk: classification stage
1533 * @dir: flow direction
1534 * @prof_id: unique ID to identify this flow profile
1535 * @segs: array of one or more packet segments that describe the flow
1536 * @segs_cnt: number of packet segments provided
1537 * @prof: stores the returned flow profile added
1540 ice_flow_add_prof(struct ice_hw *hw, enum ice_block blk, enum ice_flow_dir dir,
1541 u64 prof_id, struct ice_flow_seg_info *segs, u8 segs_cnt,
1542 struct ice_flow_prof **prof)
1544 enum ice_status status;
1546 if (segs_cnt > ICE_FLOW_SEG_MAX)
1547 return ICE_ERR_MAX_LIMIT;
1550 return ICE_ERR_PARAM;
1553 return ICE_ERR_BAD_PTR;
1555 status = ice_flow_val_hdrs(segs, segs_cnt);
1559 mutex_lock(&hw->fl_profs_locks[blk]);
1561 status = ice_flow_add_prof_sync(hw, blk, dir, prof_id, segs, segs_cnt,
1564 list_add(&(*prof)->l_entry, &hw->fl_profs[blk]);
1566 mutex_unlock(&hw->fl_profs_locks[blk]);
1572 * ice_flow_rem_prof - Remove a flow profile and all entries associated with it
1573 * @hw: pointer to the HW struct
1574 * @blk: the block for which the flow profile is to be removed
1575 * @prof_id: unique ID of the flow profile to be removed
1578 ice_flow_rem_prof(struct ice_hw *hw, enum ice_block blk, u64 prof_id)
1580 struct ice_flow_prof *prof;
1581 enum ice_status status;
1583 mutex_lock(&hw->fl_profs_locks[blk]);
1585 prof = ice_flow_find_prof_id(hw, blk, prof_id);
1587 status = ICE_ERR_DOES_NOT_EXIST;
1591 /* prof becomes invalid after the call */
1592 status = ice_flow_rem_prof_sync(hw, blk, prof);
1595 mutex_unlock(&hw->fl_profs_locks[blk]);
1601 * ice_flow_add_entry - Add a flow entry
1602 * @hw: pointer to the HW struct
1603 * @blk: classification stage
1604 * @prof_id: ID of the profile to add a new flow entry to
1605 * @entry_id: unique ID to identify this flow entry
1606 * @vsi_handle: software VSI handle for the flow entry
1607 * @prio: priority of the flow entry
1608 * @data: pointer to a data buffer containing flow entry's match values/masks
1609 * @entry_h: pointer to buffer that receives the new flow entry's handle
1612 ice_flow_add_entry(struct ice_hw *hw, enum ice_block blk, u64 prof_id,
1613 u64 entry_id, u16 vsi_handle, enum ice_flow_priority prio,
1614 void *data, u64 *entry_h)
1616 struct ice_flow_entry *e = NULL;
1617 struct ice_flow_prof *prof;
1618 enum ice_status status;
1620 /* No flow entry data is expected for RSS */
1621 if (!entry_h || (!data && blk != ICE_BLK_RSS))
1622 return ICE_ERR_BAD_PTR;
1624 if (!ice_is_vsi_valid(hw, vsi_handle))
1625 return ICE_ERR_PARAM;
1627 mutex_lock(&hw->fl_profs_locks[blk]);
1629 prof = ice_flow_find_prof_id(hw, blk, prof_id);
1631 status = ICE_ERR_DOES_NOT_EXIST;
1633 /* Allocate memory for the entry being added and associate
1634 * the VSI to the found flow profile
1636 e = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*e), GFP_KERNEL);
1638 status = ICE_ERR_NO_MEMORY;
1640 status = ice_flow_assoc_prof(hw, blk, prof, vsi_handle);
1643 mutex_unlock(&hw->fl_profs_locks[blk]);
1648 e->vsi_handle = vsi_handle;
1657 status = ICE_ERR_NOT_IMPL;
1661 mutex_lock(&prof->entries_lock);
1662 list_add(&e->l_entry, &prof->entries);
1663 mutex_unlock(&prof->entries_lock);
1665 *entry_h = ICE_FLOW_ENTRY_HNDL(e);
1670 devm_kfree(ice_hw_to_dev(hw), e->entry);
1671 devm_kfree(ice_hw_to_dev(hw), e);
1678 * ice_flow_rem_entry - Remove a flow entry
1679 * @hw: pointer to the HW struct
1680 * @blk: classification stage
1681 * @entry_h: handle to the flow entry to be removed
1683 enum ice_status ice_flow_rem_entry(struct ice_hw *hw, enum ice_block blk,
1686 struct ice_flow_entry *entry;
1687 struct ice_flow_prof *prof;
1688 enum ice_status status = 0;
1690 if (entry_h == ICE_FLOW_ENTRY_HANDLE_INVAL)
1691 return ICE_ERR_PARAM;
1693 entry = ICE_FLOW_ENTRY_PTR(entry_h);
1695 /* Retain the pointer to the flow profile as the entry will be freed */
1699 mutex_lock(&prof->entries_lock);
1700 status = ice_flow_rem_entry_sync(hw, blk, entry);
1701 mutex_unlock(&prof->entries_lock);
1708 * ice_flow_set_fld_ext - specifies locations of field from entry's input buffer
1709 * @seg: packet segment the field being set belongs to
1710 * @fld: field to be set
1711 * @field_type: type of the field
1712 * @val_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of the value to match from
1713 * entry's input buffer
1714 * @mask_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of mask value from entry's
1716 * @last_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of last/upper value from
1717 * entry's input buffer
1719 * This helper function stores information of a field being matched, including
1720 * the type of the field and the locations of the value to match, the mask, and
1721 * the upper-bound value in the start of the input buffer for a flow entry.
1722 * This function should only be used for fixed-size data structures.
1724 * This function also opportunistically determines the protocol headers to be
1725 * present based on the fields being set. Some fields cannot be used alone to
1726 * determine the protocol headers present. Sometimes, fields for particular
1727 * protocol headers are not matched. In those cases, the protocol headers
1728 * must be explicitly set.
1731 ice_flow_set_fld_ext(struct ice_flow_seg_info *seg, enum ice_flow_field fld,
1732 enum ice_flow_fld_match_type field_type, u16 val_loc,
1733 u16 mask_loc, u16 last_loc)
1735 u64 bit = BIT_ULL(fld);
1738 if (field_type == ICE_FLOW_FLD_TYPE_RANGE)
1741 seg->fields[fld].type = field_type;
1742 seg->fields[fld].src.val = val_loc;
1743 seg->fields[fld].src.mask = mask_loc;
1744 seg->fields[fld].src.last = last_loc;
1746 ICE_FLOW_SET_HDRS(seg, ice_flds_info[fld].hdr);
1750 * ice_flow_set_fld - specifies locations of field from entry's input buffer
1751 * @seg: packet segment the field being set belongs to
1752 * @fld: field to be set
1753 * @val_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of the value to match from
1754 * entry's input buffer
1755 * @mask_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of mask value from entry's
1757 * @last_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of last/upper value from
1758 * entry's input buffer
1759 * @range: indicate if field being matched is to be in a range
1761 * This function specifies the locations, in the form of byte offsets from the
1762 * start of the input buffer for a flow entry, from where the value to match,
1763 * the mask value, and upper value can be extracted. These locations are then
1764 * stored in the flow profile. When adding a flow entry associated with the
1765 * flow profile, these locations will be used to quickly extract the values and
1766 * create the content of a match entry. This function should only be used for
1767 * fixed-size data structures.
1770 ice_flow_set_fld(struct ice_flow_seg_info *seg, enum ice_flow_field fld,
1771 u16 val_loc, u16 mask_loc, u16 last_loc, bool range)
1773 enum ice_flow_fld_match_type t = range ?
1774 ICE_FLOW_FLD_TYPE_RANGE : ICE_FLOW_FLD_TYPE_REG;
1776 ice_flow_set_fld_ext(seg, fld, t, val_loc, mask_loc, last_loc);
1780 * ice_flow_add_fld_raw - sets locations of a raw field from entry's input buf
1781 * @seg: packet segment the field being set belongs to
1782 * @off: offset of the raw field from the beginning of the segment in bytes
1783 * @len: length of the raw pattern to be matched
1784 * @val_loc: location of the value to match from entry's input buffer
1785 * @mask_loc: location of mask value from entry's input buffer
1787 * This function specifies the offset of the raw field to be match from the
1788 * beginning of the specified packet segment, and the locations, in the form of
1789 * byte offsets from the start of the input buffer for a flow entry, from where
1790 * the value to match and the mask value to be extracted. These locations are
1791 * then stored in the flow profile. When adding flow entries to the associated
1792 * flow profile, these locations can be used to quickly extract the values to
1793 * create the content of a match entry. This function should only be used for
1794 * fixed-size data structures.
1797 ice_flow_add_fld_raw(struct ice_flow_seg_info *seg, u16 off, u8 len,
1798 u16 val_loc, u16 mask_loc)
1800 if (seg->raws_cnt < ICE_FLOW_SEG_RAW_FLD_MAX) {
1801 seg->raws[seg->raws_cnt].off = off;
1802 seg->raws[seg->raws_cnt].info.type = ICE_FLOW_FLD_TYPE_SIZE;
1803 seg->raws[seg->raws_cnt].info.src.val = val_loc;
1804 seg->raws[seg->raws_cnt].info.src.mask = mask_loc;
1805 /* The "last" field is used to store the length of the field */
1806 seg->raws[seg->raws_cnt].info.src.last = len;
1809 /* Overflows of "raws" will be handled as an error condition later in
1810 * the flow when this information is processed.
1815 #define ICE_FLOW_RSS_SEG_HDR_L2_MASKS \
1816 (ICE_FLOW_SEG_HDR_ETH | ICE_FLOW_SEG_HDR_VLAN)
1818 #define ICE_FLOW_RSS_SEG_HDR_L3_MASKS \
1819 (ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_IPV6)
1821 #define ICE_FLOW_RSS_SEG_HDR_L4_MASKS \
1822 (ICE_FLOW_SEG_HDR_TCP | ICE_FLOW_SEG_HDR_UDP | ICE_FLOW_SEG_HDR_SCTP)
1824 #define ICE_FLOW_RSS_SEG_HDR_VAL_MASKS \
1825 (ICE_FLOW_RSS_SEG_HDR_L2_MASKS | \
1826 ICE_FLOW_RSS_SEG_HDR_L3_MASKS | \
1827 ICE_FLOW_RSS_SEG_HDR_L4_MASKS)
1830 * ice_flow_set_rss_seg_info - setup packet segments for RSS
1831 * @segs: pointer to the flow field segment(s)
1832 * @hash_fields: fields to be hashed on for the segment(s)
1833 * @flow_hdr: protocol header fields within a packet segment
1835 * Helper function to extract fields from hash bitmap and use flow
1836 * header value to set flow field segment for further use in flow
1837 * profile entry or removal.
1839 static enum ice_status
1840 ice_flow_set_rss_seg_info(struct ice_flow_seg_info *segs, u64 hash_fields,
1846 for_each_set_bit(i, (unsigned long *)&hash_fields,
1847 ICE_FLOW_FIELD_IDX_MAX)
1848 ice_flow_set_fld(segs, (enum ice_flow_field)i,
1849 ICE_FLOW_FLD_OFF_INVAL, ICE_FLOW_FLD_OFF_INVAL,
1850 ICE_FLOW_FLD_OFF_INVAL, false);
1852 ICE_FLOW_SET_HDRS(segs, flow_hdr);
1854 if (segs->hdrs & ~ICE_FLOW_RSS_SEG_HDR_VAL_MASKS &
1855 ~ICE_FLOW_RSS_HDRS_INNER_MASK & ~ICE_FLOW_SEG_HDR_IPV_OTHER)
1856 return ICE_ERR_PARAM;
1858 val = (u64)(segs->hdrs & ICE_FLOW_RSS_SEG_HDR_L3_MASKS);
1859 if (val && !is_power_of_2(val))
1862 val = (u64)(segs->hdrs & ICE_FLOW_RSS_SEG_HDR_L4_MASKS);
1863 if (val && !is_power_of_2(val))
1870 * ice_rem_vsi_rss_list - remove VSI from RSS list
1871 * @hw: pointer to the hardware structure
1872 * @vsi_handle: software VSI handle
1874 * Remove the VSI from all RSS configurations in the list.
1876 void ice_rem_vsi_rss_list(struct ice_hw *hw, u16 vsi_handle)
1878 struct ice_rss_cfg *r, *tmp;
1880 if (list_empty(&hw->rss_list_head))
1883 mutex_lock(&hw->rss_locks);
1884 list_for_each_entry_safe(r, tmp, &hw->rss_list_head, l_entry)
1885 if (test_and_clear_bit(vsi_handle, r->vsis))
1886 if (bitmap_empty(r->vsis, ICE_MAX_VSI)) {
1887 list_del(&r->l_entry);
1888 devm_kfree(ice_hw_to_dev(hw), r);
1890 mutex_unlock(&hw->rss_locks);
1894 * ice_rem_vsi_rss_cfg - remove RSS configurations associated with VSI
1895 * @hw: pointer to the hardware structure
1896 * @vsi_handle: software VSI handle
1898 * This function will iterate through all flow profiles and disassociate
1899 * the VSI from that profile. If the flow profile has no VSIs it will
1902 enum ice_status ice_rem_vsi_rss_cfg(struct ice_hw *hw, u16 vsi_handle)
1904 const enum ice_block blk = ICE_BLK_RSS;
1905 struct ice_flow_prof *p, *t;
1906 enum ice_status status = 0;
1908 if (!ice_is_vsi_valid(hw, vsi_handle))
1909 return ICE_ERR_PARAM;
1911 if (list_empty(&hw->fl_profs[blk]))
1914 mutex_lock(&hw->rss_locks);
1915 list_for_each_entry_safe(p, t, &hw->fl_profs[blk], l_entry)
1916 if (test_bit(vsi_handle, p->vsis)) {
1917 status = ice_flow_disassoc_prof(hw, blk, p, vsi_handle);
1921 if (bitmap_empty(p->vsis, ICE_MAX_VSI)) {
1922 status = ice_flow_rem_prof(hw, blk, p->id);
1927 mutex_unlock(&hw->rss_locks);
1933 * ice_rem_rss_list - remove RSS configuration from list
1934 * @hw: pointer to the hardware structure
1935 * @vsi_handle: software VSI handle
1936 * @prof: pointer to flow profile
1938 * Assumption: lock has already been acquired for RSS list
1941 ice_rem_rss_list(struct ice_hw *hw, u16 vsi_handle, struct ice_flow_prof *prof)
1943 struct ice_rss_cfg *r, *tmp;
1945 /* Search for RSS hash fields associated to the VSI that match the
1946 * hash configurations associated to the flow profile. If found
1947 * remove from the RSS entry list of the VSI context and delete entry.
1949 list_for_each_entry_safe(r, tmp, &hw->rss_list_head, l_entry)
1950 if (r->hashed_flds == prof->segs[prof->segs_cnt - 1].match &&
1951 r->packet_hdr == prof->segs[prof->segs_cnt - 1].hdrs) {
1952 clear_bit(vsi_handle, r->vsis);
1953 if (bitmap_empty(r->vsis, ICE_MAX_VSI)) {
1954 list_del(&r->l_entry);
1955 devm_kfree(ice_hw_to_dev(hw), r);
1962 * ice_add_rss_list - add RSS configuration to 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
1969 static enum ice_status
1970 ice_add_rss_list(struct ice_hw *hw, u16 vsi_handle, struct ice_flow_prof *prof)
1972 struct ice_rss_cfg *r, *rss_cfg;
1974 list_for_each_entry(r, &hw->rss_list_head, l_entry)
1975 if (r->hashed_flds == prof->segs[prof->segs_cnt - 1].match &&
1976 r->packet_hdr == prof->segs[prof->segs_cnt - 1].hdrs) {
1977 set_bit(vsi_handle, r->vsis);
1981 rss_cfg = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*rss_cfg),
1984 return ICE_ERR_NO_MEMORY;
1986 rss_cfg->hashed_flds = prof->segs[prof->segs_cnt - 1].match;
1987 rss_cfg->packet_hdr = prof->segs[prof->segs_cnt - 1].hdrs;
1988 set_bit(vsi_handle, rss_cfg->vsis);
1990 list_add_tail(&rss_cfg->l_entry, &hw->rss_list_head);
1995 #define ICE_FLOW_PROF_HASH_S 0
1996 #define ICE_FLOW_PROF_HASH_M (0xFFFFFFFFULL << ICE_FLOW_PROF_HASH_S)
1997 #define ICE_FLOW_PROF_HDR_S 32
1998 #define ICE_FLOW_PROF_HDR_M (0x3FFFFFFFULL << ICE_FLOW_PROF_HDR_S)
1999 #define ICE_FLOW_PROF_ENCAP_S 63
2000 #define ICE_FLOW_PROF_ENCAP_M (BIT_ULL(ICE_FLOW_PROF_ENCAP_S))
2002 #define ICE_RSS_OUTER_HEADERS 1
2003 #define ICE_RSS_INNER_HEADERS 2
2005 /* Flow profile ID format:
2006 * [0:31] - Packet match fields
2007 * [32:62] - Protocol header
2008 * [63] - Encapsulation flag, 0 if non-tunneled, 1 if tunneled
2010 #define ICE_FLOW_GEN_PROFID(hash, hdr, segs_cnt) \
2011 ((u64)(((u64)(hash) & ICE_FLOW_PROF_HASH_M) | \
2012 (((u64)(hdr) << ICE_FLOW_PROF_HDR_S) & ICE_FLOW_PROF_HDR_M) | \
2013 ((u8)((segs_cnt) - 1) ? ICE_FLOW_PROF_ENCAP_M : 0)))
2016 * ice_add_rss_cfg_sync - add an RSS configuration
2017 * @hw: pointer to the hardware structure
2018 * @vsi_handle: software VSI handle
2019 * @hashed_flds: hash bit fields (ICE_FLOW_HASH_*) to configure
2020 * @addl_hdrs: protocol header fields
2021 * @segs_cnt: packet segment count
2023 * Assumption: lock has already been acquired for RSS list
2025 static enum ice_status
2026 ice_add_rss_cfg_sync(struct ice_hw *hw, u16 vsi_handle, u64 hashed_flds,
2027 u32 addl_hdrs, u8 segs_cnt)
2029 const enum ice_block blk = ICE_BLK_RSS;
2030 struct ice_flow_prof *prof = NULL;
2031 struct ice_flow_seg_info *segs;
2032 enum ice_status status;
2034 if (!segs_cnt || segs_cnt > ICE_FLOW_SEG_MAX)
2035 return ICE_ERR_PARAM;
2037 segs = kcalloc(segs_cnt, sizeof(*segs), GFP_KERNEL);
2039 return ICE_ERR_NO_MEMORY;
2041 /* Construct the packet segment info from the hashed fields */
2042 status = ice_flow_set_rss_seg_info(&segs[segs_cnt - 1], hashed_flds,
2047 /* Search for a flow profile that has matching headers, hash fields
2048 * and has the input VSI associated to it. If found, no further
2049 * operations required and exit.
2051 prof = ice_flow_find_prof_conds(hw, blk, ICE_FLOW_RX, segs, segs_cnt,
2053 ICE_FLOW_FIND_PROF_CHK_FLDS |
2054 ICE_FLOW_FIND_PROF_CHK_VSI);
2058 /* Check if a flow profile exists with the same protocol headers and
2059 * associated with the input VSI. If so disassociate the VSI from
2060 * this profile. The VSI will be added to a new profile created with
2061 * the protocol header and new hash field configuration.
2063 prof = ice_flow_find_prof_conds(hw, blk, ICE_FLOW_RX, segs, segs_cnt,
2064 vsi_handle, ICE_FLOW_FIND_PROF_CHK_VSI);
2066 status = ice_flow_disassoc_prof(hw, blk, prof, vsi_handle);
2068 ice_rem_rss_list(hw, vsi_handle, prof);
2072 /* Remove profile if it has no VSIs associated */
2073 if (bitmap_empty(prof->vsis, ICE_MAX_VSI)) {
2074 status = ice_flow_rem_prof(hw, blk, prof->id);
2080 /* Search for a profile that has same match fields only. If this
2081 * exists then associate the VSI to this profile.
2083 prof = ice_flow_find_prof_conds(hw, blk, ICE_FLOW_RX, segs, segs_cnt,
2085 ICE_FLOW_FIND_PROF_CHK_FLDS);
2087 status = ice_flow_assoc_prof(hw, blk, prof, vsi_handle);
2089 status = ice_add_rss_list(hw, vsi_handle, prof);
2093 /* Create a new flow profile with generated profile and packet
2094 * segment information.
2096 status = ice_flow_add_prof(hw, blk, ICE_FLOW_RX,
2097 ICE_FLOW_GEN_PROFID(hashed_flds,
2098 segs[segs_cnt - 1].hdrs,
2100 segs, segs_cnt, &prof);
2104 status = ice_flow_assoc_prof(hw, blk, prof, vsi_handle);
2105 /* If association to a new flow profile failed then this profile can
2109 ice_flow_rem_prof(hw, blk, prof->id);
2113 status = ice_add_rss_list(hw, vsi_handle, prof);
2121 * ice_add_rss_cfg - add an RSS configuration with specified hashed fields
2122 * @hw: pointer to the hardware structure
2123 * @vsi_handle: software VSI handle
2124 * @hashed_flds: hash bit fields (ICE_FLOW_HASH_*) to configure
2125 * @addl_hdrs: protocol header fields
2127 * This function will generate a flow profile based on fields associated with
2128 * the input fields to hash on, the flow type and use the VSI number to add
2129 * a flow entry to the profile.
2132 ice_add_rss_cfg(struct ice_hw *hw, u16 vsi_handle, u64 hashed_flds,
2135 enum ice_status status;
2137 if (hashed_flds == ICE_HASH_INVALID ||
2138 !ice_is_vsi_valid(hw, vsi_handle))
2139 return ICE_ERR_PARAM;
2141 mutex_lock(&hw->rss_locks);
2142 status = ice_add_rss_cfg_sync(hw, vsi_handle, hashed_flds, addl_hdrs,
2143 ICE_RSS_OUTER_HEADERS);
2145 status = ice_add_rss_cfg_sync(hw, vsi_handle, hashed_flds,
2146 addl_hdrs, ICE_RSS_INNER_HEADERS);
2147 mutex_unlock(&hw->rss_locks);
2153 * ice_rem_rss_cfg_sync - remove an existing RSS configuration
2154 * @hw: pointer to the hardware structure
2155 * @vsi_handle: software VSI handle
2156 * @hashed_flds: Packet hash types (ICE_FLOW_HASH_*) to remove
2157 * @addl_hdrs: Protocol header fields within a packet segment
2158 * @segs_cnt: packet segment count
2160 * Assumption: lock has already been acquired for RSS list
2162 static enum ice_status
2163 ice_rem_rss_cfg_sync(struct ice_hw *hw, u16 vsi_handle, u64 hashed_flds,
2164 u32 addl_hdrs, u8 segs_cnt)
2166 const enum ice_block blk = ICE_BLK_RSS;
2167 struct ice_flow_seg_info *segs;
2168 struct ice_flow_prof *prof;
2169 enum ice_status status;
2171 segs = kcalloc(segs_cnt, sizeof(*segs), GFP_KERNEL);
2173 return ICE_ERR_NO_MEMORY;
2175 /* Construct the packet segment info from the hashed fields */
2176 status = ice_flow_set_rss_seg_info(&segs[segs_cnt - 1], hashed_flds,
2181 prof = ice_flow_find_prof_conds(hw, blk, ICE_FLOW_RX, segs, segs_cnt,
2183 ICE_FLOW_FIND_PROF_CHK_FLDS);
2185 status = ICE_ERR_DOES_NOT_EXIST;
2189 status = ice_flow_disassoc_prof(hw, blk, prof, vsi_handle);
2193 /* Remove RSS configuration from VSI context before deleting
2196 ice_rem_rss_list(hw, vsi_handle, prof);
2198 if (bitmap_empty(prof->vsis, ICE_MAX_VSI))
2199 status = ice_flow_rem_prof(hw, blk, prof->id);
2207 * ice_rem_rss_cfg - remove an existing RSS config with matching hashed fields
2208 * @hw: pointer to the hardware structure
2209 * @vsi_handle: software VSI handle
2210 * @hashed_flds: Packet hash types (ICE_FLOW_HASH_*) to remove
2211 * @addl_hdrs: Protocol header fields within a packet segment
2213 * This function will lookup the flow profile based on the input
2214 * hash field bitmap, iterate through the profile entry list of
2215 * that profile and find entry associated with input VSI to be
2216 * removed. Calls are made to underlying flow s which will APIs
2217 * turn build or update buffers for RSS XLT1 section.
2219 enum ice_status __maybe_unused
2220 ice_rem_rss_cfg(struct ice_hw *hw, u16 vsi_handle, u64 hashed_flds,
2223 enum ice_status status;
2225 if (hashed_flds == ICE_HASH_INVALID ||
2226 !ice_is_vsi_valid(hw, vsi_handle))
2227 return ICE_ERR_PARAM;
2229 mutex_lock(&hw->rss_locks);
2230 status = ice_rem_rss_cfg_sync(hw, vsi_handle, hashed_flds, addl_hdrs,
2231 ICE_RSS_OUTER_HEADERS);
2233 status = ice_rem_rss_cfg_sync(hw, vsi_handle, hashed_flds,
2234 addl_hdrs, ICE_RSS_INNER_HEADERS);
2235 mutex_unlock(&hw->rss_locks);
2240 /* Mapping of AVF hash bit fields to an L3-L4 hash combination.
2241 * As the ice_flow_avf_hdr_field represent individual bit shifts in a hash,
2242 * convert its values to their appropriate flow L3, L4 values.
2244 #define ICE_FLOW_AVF_RSS_IPV4_MASKS \
2245 (BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_OTHER) | \
2246 BIT_ULL(ICE_AVF_FLOW_FIELD_FRAG_IPV4))
2247 #define ICE_FLOW_AVF_RSS_TCP_IPV4_MASKS \
2248 (BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_TCP_SYN_NO_ACK) | \
2249 BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_TCP))
2250 #define ICE_FLOW_AVF_RSS_UDP_IPV4_MASKS \
2251 (BIT_ULL(ICE_AVF_FLOW_FIELD_UNICAST_IPV4_UDP) | \
2252 BIT_ULL(ICE_AVF_FLOW_FIELD_MULTICAST_IPV4_UDP) | \
2253 BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_UDP))
2254 #define ICE_FLOW_AVF_RSS_ALL_IPV4_MASKS \
2255 (ICE_FLOW_AVF_RSS_TCP_IPV4_MASKS | ICE_FLOW_AVF_RSS_UDP_IPV4_MASKS | \
2256 ICE_FLOW_AVF_RSS_IPV4_MASKS | BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_SCTP))
2258 #define ICE_FLOW_AVF_RSS_IPV6_MASKS \
2259 (BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_OTHER) | \
2260 BIT_ULL(ICE_AVF_FLOW_FIELD_FRAG_IPV6))
2261 #define ICE_FLOW_AVF_RSS_UDP_IPV6_MASKS \
2262 (BIT_ULL(ICE_AVF_FLOW_FIELD_UNICAST_IPV6_UDP) | \
2263 BIT_ULL(ICE_AVF_FLOW_FIELD_MULTICAST_IPV6_UDP) | \
2264 BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_UDP))
2265 #define ICE_FLOW_AVF_RSS_TCP_IPV6_MASKS \
2266 (BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_TCP_SYN_NO_ACK) | \
2267 BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_TCP))
2268 #define ICE_FLOW_AVF_RSS_ALL_IPV6_MASKS \
2269 (ICE_FLOW_AVF_RSS_TCP_IPV6_MASKS | ICE_FLOW_AVF_RSS_UDP_IPV6_MASKS | \
2270 ICE_FLOW_AVF_RSS_IPV6_MASKS | BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_SCTP))
2273 * ice_add_avf_rss_cfg - add an RSS configuration for AVF driver
2274 * @hw: pointer to the hardware structure
2275 * @vsi_handle: software VSI handle
2276 * @avf_hash: hash bit fields (ICE_AVF_FLOW_FIELD_*) to configure
2278 * This function will take the hash bitmap provided by the AVF driver via a
2279 * message, convert it to ICE-compatible values, and configure RSS flow
2283 ice_add_avf_rss_cfg(struct ice_hw *hw, u16 vsi_handle, u64 avf_hash)
2285 enum ice_status status = 0;
2288 if (avf_hash == ICE_AVF_FLOW_FIELD_INVALID ||
2289 !ice_is_vsi_valid(hw, vsi_handle))
2290 return ICE_ERR_PARAM;
2292 /* Make sure no unsupported bits are specified */
2293 if (avf_hash & ~(ICE_FLOW_AVF_RSS_ALL_IPV4_MASKS |
2294 ICE_FLOW_AVF_RSS_ALL_IPV6_MASKS))
2297 hash_flds = avf_hash;
2299 /* Always create an L3 RSS configuration for any L4 RSS configuration */
2300 if (hash_flds & ICE_FLOW_AVF_RSS_ALL_IPV4_MASKS)
2301 hash_flds |= ICE_FLOW_AVF_RSS_IPV4_MASKS;
2303 if (hash_flds & ICE_FLOW_AVF_RSS_ALL_IPV6_MASKS)
2304 hash_flds |= ICE_FLOW_AVF_RSS_IPV6_MASKS;
2306 /* Create the corresponding RSS configuration for each valid hash bit */
2308 u64 rss_hash = ICE_HASH_INVALID;
2310 if (hash_flds & ICE_FLOW_AVF_RSS_ALL_IPV4_MASKS) {
2311 if (hash_flds & ICE_FLOW_AVF_RSS_IPV4_MASKS) {
2312 rss_hash = ICE_FLOW_HASH_IPV4;
2313 hash_flds &= ~ICE_FLOW_AVF_RSS_IPV4_MASKS;
2314 } else if (hash_flds &
2315 ICE_FLOW_AVF_RSS_TCP_IPV4_MASKS) {
2316 rss_hash = ICE_FLOW_HASH_IPV4 |
2317 ICE_FLOW_HASH_TCP_PORT;
2318 hash_flds &= ~ICE_FLOW_AVF_RSS_TCP_IPV4_MASKS;
2319 } else if (hash_flds &
2320 ICE_FLOW_AVF_RSS_UDP_IPV4_MASKS) {
2321 rss_hash = ICE_FLOW_HASH_IPV4 |
2322 ICE_FLOW_HASH_UDP_PORT;
2323 hash_flds &= ~ICE_FLOW_AVF_RSS_UDP_IPV4_MASKS;
2324 } else if (hash_flds &
2325 BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_SCTP)) {
2326 rss_hash = ICE_FLOW_HASH_IPV4 |
2327 ICE_FLOW_HASH_SCTP_PORT;
2329 ~BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_SCTP);
2331 } else if (hash_flds & ICE_FLOW_AVF_RSS_ALL_IPV6_MASKS) {
2332 if (hash_flds & ICE_FLOW_AVF_RSS_IPV6_MASKS) {
2333 rss_hash = ICE_FLOW_HASH_IPV6;
2334 hash_flds &= ~ICE_FLOW_AVF_RSS_IPV6_MASKS;
2335 } else if (hash_flds &
2336 ICE_FLOW_AVF_RSS_TCP_IPV6_MASKS) {
2337 rss_hash = ICE_FLOW_HASH_IPV6 |
2338 ICE_FLOW_HASH_TCP_PORT;
2339 hash_flds &= ~ICE_FLOW_AVF_RSS_TCP_IPV6_MASKS;
2340 } else if (hash_flds &
2341 ICE_FLOW_AVF_RSS_UDP_IPV6_MASKS) {
2342 rss_hash = ICE_FLOW_HASH_IPV6 |
2343 ICE_FLOW_HASH_UDP_PORT;
2344 hash_flds &= ~ICE_FLOW_AVF_RSS_UDP_IPV6_MASKS;
2345 } else if (hash_flds &
2346 BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_SCTP)) {
2347 rss_hash = ICE_FLOW_HASH_IPV6 |
2348 ICE_FLOW_HASH_SCTP_PORT;
2350 ~BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_SCTP);
2354 if (rss_hash == ICE_HASH_INVALID)
2355 return ICE_ERR_OUT_OF_RANGE;
2357 status = ice_add_rss_cfg(hw, vsi_handle, rss_hash,
2358 ICE_FLOW_SEG_HDR_NONE);
2367 * ice_replay_rss_cfg - replay RSS configurations associated with VSI
2368 * @hw: pointer to the hardware structure
2369 * @vsi_handle: software VSI handle
2371 enum ice_status ice_replay_rss_cfg(struct ice_hw *hw, u16 vsi_handle)
2373 enum ice_status status = 0;
2374 struct ice_rss_cfg *r;
2376 if (!ice_is_vsi_valid(hw, vsi_handle))
2377 return ICE_ERR_PARAM;
2379 mutex_lock(&hw->rss_locks);
2380 list_for_each_entry(r, &hw->rss_list_head, l_entry) {
2381 if (test_bit(vsi_handle, r->vsis)) {
2382 status = ice_add_rss_cfg_sync(hw, vsi_handle,
2385 ICE_RSS_OUTER_HEADERS);
2388 status = ice_add_rss_cfg_sync(hw, vsi_handle,
2391 ICE_RSS_INNER_HEADERS);
2396 mutex_unlock(&hw->rss_locks);
2402 * ice_get_rss_cfg - returns hashed fields for the given header types
2403 * @hw: pointer to the hardware structure
2404 * @vsi_handle: software VSI handle
2405 * @hdrs: protocol header type
2407 * This function will return the match fields of the first instance of flow
2408 * profile having the given header types and containing input VSI
2410 u64 ice_get_rss_cfg(struct ice_hw *hw, u16 vsi_handle, u32 hdrs)
2412 u64 rss_hash = ICE_HASH_INVALID;
2413 struct ice_rss_cfg *r;
2415 /* verify if the protocol header is non zero and VSI is valid */
2416 if (hdrs == ICE_FLOW_SEG_HDR_NONE || !ice_is_vsi_valid(hw, vsi_handle))
2417 return ICE_HASH_INVALID;
2419 mutex_lock(&hw->rss_locks);
2420 list_for_each_entry(r, &hw->rss_list_head, l_entry)
2421 if (test_bit(vsi_handle, r->vsis) &&
2422 r->packet_hdr == hdrs) {
2423 rss_hash = r->hashed_flds;
2426 mutex_unlock(&hw->rss_locks);