Loading...
1// SPDX-License-Identifier: GPL-2.0
2/* Copyright (c) 2019, Intel Corporation. */
3
4#include "ice_common.h"
5#include "ice_flow.h"
6#include <net/gre.h>
7
8/* Describe properties of a protocol header field */
9struct 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 */
14};
15
16#define ICE_FLOW_FLD_INFO(_hdr, _offset_bytes, _size_bytes) { \
17 .hdr = _hdr, \
18 .off = (_offset_bytes) * BITS_PER_BYTE, \
19 .size = (_size_bytes) * BITS_PER_BYTE, \
20 .mask = 0, \
21}
22
23#define ICE_FLOW_FLD_INFO_MSK(_hdr, _offset_bytes, _size_bytes, _mask) { \
24 .hdr = _hdr, \
25 .off = (_offset_bytes) * BITS_PER_BYTE, \
26 .size = (_size_bytes) * BITS_PER_BYTE, \
27 .mask = _mask, \
28}
29
30/* Table containing properties of supported protocol header fields */
31static const
32struct ice_flow_field_info ice_flds_info[ICE_FLOW_FIELD_IDX_MAX] = {
33 /* Ether */
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)),
44 /* IPv4 / IPv6 */
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)),
65 /* Transport */
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),
80 /* ARP */
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)),
91 /* ICMP */
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),
96 /* GRE */
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)),
100 /* GTP */
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),
109 0x3f00),
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)),
114 /* PPPoE */
115 /* ICE_FLOW_FIELD_IDX_PPPOE_SESS_ID */
116 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_PPPOE, 2, sizeof(__be16)),
117 /* PFCP */
118 /* ICE_FLOW_FIELD_IDX_PFCP_SEID */
119 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_PFCP_SESSION, 12, sizeof(__be64)),
120 /* L2TPv3 */
121 /* ICE_FLOW_FIELD_IDX_L2TPV3_SESS_ID */
122 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_L2TPV3, 0, sizeof(__be32)),
123 /* ESP */
124 /* ICE_FLOW_FIELD_IDX_ESP_SPI */
125 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ESP, 0, sizeof(__be32)),
126 /* AH */
127 /* ICE_FLOW_FIELD_IDX_AH_SPI */
128 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_AH, 4, sizeof(__be32)),
129 /* NAT_T_ESP */
130 /* ICE_FLOW_FIELD_IDX_NAT_T_ESP_SPI */
131 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_NAT_T_ESP, 8, sizeof(__be32)),
132};
133
134/* Bitmaps indicating relevant packet types for a particular protocol header
135 *
136 * Packet types for packets with an Outer/First/Single MAC header
137 */
138static 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,
147};
148
149/* Packet types for packets with an Innermost/Last MAC VLAN header */
150static const u32 ice_ptypes_macvlan_il[] = {
151 0x00000000, 0xBC000000, 0x000001DF, 0xF0000000,
152 0x0000077E, 0x00000000, 0x00000000, 0x00000000,
153 0x00000000, 0x00000000, 0x00000000, 0x00000000,
154 0x00000000, 0x00000000, 0x00000000, 0x00000000,
155 0x00000000, 0x00000000, 0x00000000, 0x00000000,
156 0x00000000, 0x00000000, 0x00000000, 0x00000000,
157 0x00000000, 0x00000000, 0x00000000, 0x00000000,
158 0x00000000, 0x00000000, 0x00000000, 0x00000000,
159};
160
161/* Packet types for packets with an Outer/First/Single IPv4 header, does NOT
162 * include IPv4 other PTYPEs
163 */
164static 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,
173};
174
175/* Packet types for packets with an Outer/First/Single IPv4 header, includes
176 * IPv4 other PTYPEs
177 */
178static 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,
187};
188
189/* Packet types for packets with an Innermost/Last IPv4 header */
190static 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,
199};
200
201/* Packet types for packets with an Outer/First/Single IPv6 header, does NOT
202 * include IPv6 other PTYPEs
203 */
204static 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,
213};
214
215/* Packet types for packets with an Outer/First/Single IPv6 header, includes
216 * IPv6 other PTYPEs
217 */
218static 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,
227};
228
229/* Packet types for packets with an Innermost/Last IPv6 header */
230static 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,
239};
240
241/* Packet types for packets with an Outer/First/Single IPv4 header - no L4 */
242static 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,
251};
252
253/* Packet types for packets with an Outermost/First ARP header */
254static 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,
263};
264
265/* Packet types for packets with an Innermost/Last IPv4 header - no L4 */
266static 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,
275};
276
277/* Packet types for packets with an Outer/First/Single IPv6 header - no L4 */
278static 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,
287};
288
289/* Packet types for packets with an Innermost/Last IPv6 header - no L4 */
290static 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,
299};
300
301/* UDP Packet types for non-tunneled packets or tunneled
302 * packets with inner UDP.
303 */
304static 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,
313};
314
315/* Packet types for packets with an Innermost/Last TCP header */
316static 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,
325};
326
327/* Packet types for packets with an Innermost/Last SCTP header */
328static 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,
337};
338
339/* Packet types for packets with an Outermost/First ICMP header */
340static 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,
349};
350
351/* Packet types for packets with an Innermost/Last ICMP header */
352static 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,
361};
362
363/* Packet types for packets with an Outermost/First GRE header */
364static 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,
373};
374
375/* Packet types for packets with an Innermost/Last MAC header */
376static 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,
385};
386
387/* Packet types for GTPC */
388static 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,
397};
398
399/* Packet types for GTPC with TEID */
400static 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,
409};
410
411/* Packet types for GTPU */
412static const struct ice_ptype_attributes ice_attr_gtpu_session[] = {
413 { ICE_MAC_IPV4_GTPU_IPV4_FRAG, ICE_PTYPE_ATTR_GTP_SESSION },
414 { ICE_MAC_IPV4_GTPU_IPV4_PAY, ICE_PTYPE_ATTR_GTP_SESSION },
415 { ICE_MAC_IPV4_GTPU_IPV4_UDP_PAY, ICE_PTYPE_ATTR_GTP_SESSION },
416 { ICE_MAC_IPV4_GTPU_IPV4_TCP, ICE_PTYPE_ATTR_GTP_SESSION },
417 { ICE_MAC_IPV4_GTPU_IPV4_ICMP, ICE_PTYPE_ATTR_GTP_SESSION },
418 { ICE_MAC_IPV6_GTPU_IPV4_FRAG, ICE_PTYPE_ATTR_GTP_SESSION },
419 { ICE_MAC_IPV6_GTPU_IPV4_PAY, ICE_PTYPE_ATTR_GTP_SESSION },
420 { ICE_MAC_IPV6_GTPU_IPV4_UDP_PAY, ICE_PTYPE_ATTR_GTP_SESSION },
421 { ICE_MAC_IPV6_GTPU_IPV4_TCP, ICE_PTYPE_ATTR_GTP_SESSION },
422 { ICE_MAC_IPV6_GTPU_IPV4_ICMP, ICE_PTYPE_ATTR_GTP_SESSION },
423 { ICE_MAC_IPV4_GTPU_IPV6_FRAG, ICE_PTYPE_ATTR_GTP_SESSION },
424 { ICE_MAC_IPV4_GTPU_IPV6_PAY, ICE_PTYPE_ATTR_GTP_SESSION },
425 { ICE_MAC_IPV4_GTPU_IPV6_UDP_PAY, ICE_PTYPE_ATTR_GTP_SESSION },
426 { ICE_MAC_IPV4_GTPU_IPV6_TCP, ICE_PTYPE_ATTR_GTP_SESSION },
427 { ICE_MAC_IPV4_GTPU_IPV6_ICMPV6, ICE_PTYPE_ATTR_GTP_SESSION },
428 { ICE_MAC_IPV6_GTPU_IPV6_FRAG, ICE_PTYPE_ATTR_GTP_SESSION },
429 { ICE_MAC_IPV6_GTPU_IPV6_PAY, ICE_PTYPE_ATTR_GTP_SESSION },
430 { ICE_MAC_IPV6_GTPU_IPV6_UDP_PAY, ICE_PTYPE_ATTR_GTP_SESSION },
431 { ICE_MAC_IPV6_GTPU_IPV6_TCP, ICE_PTYPE_ATTR_GTP_SESSION },
432 { ICE_MAC_IPV6_GTPU_IPV6_ICMPV6, ICE_PTYPE_ATTR_GTP_SESSION },
433};
434
435static const struct ice_ptype_attributes ice_attr_gtpu_eh[] = {
436 { ICE_MAC_IPV4_GTPU_IPV4_FRAG, ICE_PTYPE_ATTR_GTP_PDU_EH },
437 { ICE_MAC_IPV4_GTPU_IPV4_PAY, ICE_PTYPE_ATTR_GTP_PDU_EH },
438 { ICE_MAC_IPV4_GTPU_IPV4_UDP_PAY, ICE_PTYPE_ATTR_GTP_PDU_EH },
439 { ICE_MAC_IPV4_GTPU_IPV4_TCP, ICE_PTYPE_ATTR_GTP_PDU_EH },
440 { ICE_MAC_IPV4_GTPU_IPV4_ICMP, ICE_PTYPE_ATTR_GTP_PDU_EH },
441 { ICE_MAC_IPV6_GTPU_IPV4_FRAG, ICE_PTYPE_ATTR_GTP_PDU_EH },
442 { ICE_MAC_IPV6_GTPU_IPV4_PAY, ICE_PTYPE_ATTR_GTP_PDU_EH },
443 { ICE_MAC_IPV6_GTPU_IPV4_UDP_PAY, ICE_PTYPE_ATTR_GTP_PDU_EH },
444 { ICE_MAC_IPV6_GTPU_IPV4_TCP, ICE_PTYPE_ATTR_GTP_PDU_EH },
445 { ICE_MAC_IPV6_GTPU_IPV4_ICMP, ICE_PTYPE_ATTR_GTP_PDU_EH },
446 { ICE_MAC_IPV4_GTPU_IPV6_FRAG, ICE_PTYPE_ATTR_GTP_PDU_EH },
447 { ICE_MAC_IPV4_GTPU_IPV6_PAY, ICE_PTYPE_ATTR_GTP_PDU_EH },
448 { ICE_MAC_IPV4_GTPU_IPV6_UDP_PAY, ICE_PTYPE_ATTR_GTP_PDU_EH },
449 { ICE_MAC_IPV4_GTPU_IPV6_TCP, ICE_PTYPE_ATTR_GTP_PDU_EH },
450 { ICE_MAC_IPV4_GTPU_IPV6_ICMPV6, ICE_PTYPE_ATTR_GTP_PDU_EH },
451 { ICE_MAC_IPV6_GTPU_IPV6_FRAG, ICE_PTYPE_ATTR_GTP_PDU_EH },
452 { ICE_MAC_IPV6_GTPU_IPV6_PAY, ICE_PTYPE_ATTR_GTP_PDU_EH },
453 { ICE_MAC_IPV6_GTPU_IPV6_UDP_PAY, ICE_PTYPE_ATTR_GTP_PDU_EH },
454 { ICE_MAC_IPV6_GTPU_IPV6_TCP, ICE_PTYPE_ATTR_GTP_PDU_EH },
455 { ICE_MAC_IPV6_GTPU_IPV6_ICMPV6, ICE_PTYPE_ATTR_GTP_PDU_EH },
456};
457
458static const struct ice_ptype_attributes ice_attr_gtpu_down[] = {
459 { ICE_MAC_IPV4_GTPU_IPV4_FRAG, ICE_PTYPE_ATTR_GTP_DOWNLINK },
460 { ICE_MAC_IPV4_GTPU_IPV4_PAY, ICE_PTYPE_ATTR_GTP_DOWNLINK },
461 { ICE_MAC_IPV4_GTPU_IPV4_UDP_PAY, ICE_PTYPE_ATTR_GTP_DOWNLINK },
462 { ICE_MAC_IPV4_GTPU_IPV4_TCP, ICE_PTYPE_ATTR_GTP_DOWNLINK },
463 { ICE_MAC_IPV4_GTPU_IPV4_ICMP, ICE_PTYPE_ATTR_GTP_DOWNLINK },
464 { ICE_MAC_IPV6_GTPU_IPV4_FRAG, ICE_PTYPE_ATTR_GTP_DOWNLINK },
465 { ICE_MAC_IPV6_GTPU_IPV4_PAY, ICE_PTYPE_ATTR_GTP_DOWNLINK },
466 { ICE_MAC_IPV6_GTPU_IPV4_UDP_PAY, ICE_PTYPE_ATTR_GTP_DOWNLINK },
467 { ICE_MAC_IPV6_GTPU_IPV4_TCP, ICE_PTYPE_ATTR_GTP_DOWNLINK },
468 { ICE_MAC_IPV6_GTPU_IPV4_ICMP, ICE_PTYPE_ATTR_GTP_DOWNLINK },
469 { ICE_MAC_IPV4_GTPU_IPV6_FRAG, ICE_PTYPE_ATTR_GTP_DOWNLINK },
470 { ICE_MAC_IPV4_GTPU_IPV6_PAY, ICE_PTYPE_ATTR_GTP_DOWNLINK },
471 { ICE_MAC_IPV4_GTPU_IPV6_UDP_PAY, ICE_PTYPE_ATTR_GTP_DOWNLINK },
472 { ICE_MAC_IPV4_GTPU_IPV6_TCP, ICE_PTYPE_ATTR_GTP_DOWNLINK },
473 { ICE_MAC_IPV4_GTPU_IPV6_ICMPV6, ICE_PTYPE_ATTR_GTP_DOWNLINK },
474 { ICE_MAC_IPV6_GTPU_IPV6_FRAG, ICE_PTYPE_ATTR_GTP_DOWNLINK },
475 { ICE_MAC_IPV6_GTPU_IPV6_PAY, ICE_PTYPE_ATTR_GTP_DOWNLINK },
476 { ICE_MAC_IPV6_GTPU_IPV6_UDP_PAY, ICE_PTYPE_ATTR_GTP_DOWNLINK },
477 { ICE_MAC_IPV6_GTPU_IPV6_TCP, ICE_PTYPE_ATTR_GTP_DOWNLINK },
478 { ICE_MAC_IPV6_GTPU_IPV6_ICMPV6, ICE_PTYPE_ATTR_GTP_DOWNLINK },
479};
480
481static const struct ice_ptype_attributes ice_attr_gtpu_up[] = {
482 { ICE_MAC_IPV4_GTPU_IPV4_FRAG, ICE_PTYPE_ATTR_GTP_UPLINK },
483 { ICE_MAC_IPV4_GTPU_IPV4_PAY, ICE_PTYPE_ATTR_GTP_UPLINK },
484 { ICE_MAC_IPV4_GTPU_IPV4_UDP_PAY, ICE_PTYPE_ATTR_GTP_UPLINK },
485 { ICE_MAC_IPV4_GTPU_IPV4_TCP, ICE_PTYPE_ATTR_GTP_UPLINK },
486 { ICE_MAC_IPV4_GTPU_IPV4_ICMP, ICE_PTYPE_ATTR_GTP_UPLINK },
487 { ICE_MAC_IPV6_GTPU_IPV4_FRAG, ICE_PTYPE_ATTR_GTP_UPLINK },
488 { ICE_MAC_IPV6_GTPU_IPV4_PAY, ICE_PTYPE_ATTR_GTP_UPLINK },
489 { ICE_MAC_IPV6_GTPU_IPV4_UDP_PAY, ICE_PTYPE_ATTR_GTP_UPLINK },
490 { ICE_MAC_IPV6_GTPU_IPV4_TCP, ICE_PTYPE_ATTR_GTP_UPLINK },
491 { ICE_MAC_IPV6_GTPU_IPV4_ICMP, ICE_PTYPE_ATTR_GTP_UPLINK },
492 { ICE_MAC_IPV4_GTPU_IPV6_FRAG, ICE_PTYPE_ATTR_GTP_UPLINK },
493 { ICE_MAC_IPV4_GTPU_IPV6_PAY, ICE_PTYPE_ATTR_GTP_UPLINK },
494 { ICE_MAC_IPV4_GTPU_IPV6_UDP_PAY, ICE_PTYPE_ATTR_GTP_UPLINK },
495 { ICE_MAC_IPV4_GTPU_IPV6_TCP, ICE_PTYPE_ATTR_GTP_UPLINK },
496 { ICE_MAC_IPV4_GTPU_IPV6_ICMPV6, ICE_PTYPE_ATTR_GTP_UPLINK },
497 { ICE_MAC_IPV6_GTPU_IPV6_FRAG, ICE_PTYPE_ATTR_GTP_UPLINK },
498 { ICE_MAC_IPV6_GTPU_IPV6_PAY, ICE_PTYPE_ATTR_GTP_UPLINK },
499 { ICE_MAC_IPV6_GTPU_IPV6_UDP_PAY, ICE_PTYPE_ATTR_GTP_UPLINK },
500 { ICE_MAC_IPV6_GTPU_IPV6_TCP, ICE_PTYPE_ATTR_GTP_UPLINK },
501 { ICE_MAC_IPV6_GTPU_IPV6_ICMPV6, ICE_PTYPE_ATTR_GTP_UPLINK },
502};
503
504static const u32 ice_ptypes_gtpu[] = {
505 0x00000000, 0x00000000, 0x00000000, 0x00000000,
506 0x00000000, 0x00000000, 0x00000000, 0x00000000,
507 0x00000000, 0x00000000, 0x7FFFFE00, 0x00000000,
508 0x00000000, 0x00000000, 0x00000000, 0x00000000,
509 0x00000000, 0x00000000, 0x00000000, 0x00000000,
510 0x00000000, 0x00000000, 0x00000000, 0x00000000,
511 0x00000000, 0x00000000, 0x00000000, 0x00000000,
512 0x00000000, 0x00000000, 0x00000000, 0x00000000,
513};
514
515/* Packet types for PPPoE */
516static const u32 ice_ptypes_pppoe[] = {
517 0x00000000, 0x00000000, 0x00000000, 0x00000000,
518 0x00000000, 0x00000000, 0x00000000, 0x00000000,
519 0x00000000, 0x03ffe000, 0x00000000, 0x00000000,
520 0x00000000, 0x00000000, 0x00000000, 0x00000000,
521 0x00000000, 0x00000000, 0x00000000, 0x00000000,
522 0x00000000, 0x00000000, 0x00000000, 0x00000000,
523 0x00000000, 0x00000000, 0x00000000, 0x00000000,
524 0x00000000, 0x00000000, 0x00000000, 0x00000000,
525};
526
527/* Packet types for packets with PFCP NODE header */
528static const u32 ice_ptypes_pfcp_node[] = {
529 0x00000000, 0x00000000, 0x00000000, 0x00000000,
530 0x00000000, 0x00000000, 0x00000000, 0x00000000,
531 0x00000000, 0x00000000, 0x80000000, 0x00000002,
532 0x00000000, 0x00000000, 0x00000000, 0x00000000,
533 0x00000000, 0x00000000, 0x00000000, 0x00000000,
534 0x00000000, 0x00000000, 0x00000000, 0x00000000,
535 0x00000000, 0x00000000, 0x00000000, 0x00000000,
536 0x00000000, 0x00000000, 0x00000000, 0x00000000,
537};
538
539/* Packet types for packets with PFCP SESSION header */
540static const u32 ice_ptypes_pfcp_session[] = {
541 0x00000000, 0x00000000, 0x00000000, 0x00000000,
542 0x00000000, 0x00000000, 0x00000000, 0x00000000,
543 0x00000000, 0x00000000, 0x00000000, 0x00000005,
544 0x00000000, 0x00000000, 0x00000000, 0x00000000,
545 0x00000000, 0x00000000, 0x00000000, 0x00000000,
546 0x00000000, 0x00000000, 0x00000000, 0x00000000,
547 0x00000000, 0x00000000, 0x00000000, 0x00000000,
548 0x00000000, 0x00000000, 0x00000000, 0x00000000,
549};
550
551/* Packet types for L2TPv3 */
552static const u32 ice_ptypes_l2tpv3[] = {
553 0x00000000, 0x00000000, 0x00000000, 0x00000000,
554 0x00000000, 0x00000000, 0x00000000, 0x00000000,
555 0x00000000, 0x00000000, 0x00000000, 0x00000300,
556 0x00000000, 0x00000000, 0x00000000, 0x00000000,
557 0x00000000, 0x00000000, 0x00000000, 0x00000000,
558 0x00000000, 0x00000000, 0x00000000, 0x00000000,
559 0x00000000, 0x00000000, 0x00000000, 0x00000000,
560 0x00000000, 0x00000000, 0x00000000, 0x00000000,
561};
562
563/* Packet types for ESP */
564static const u32 ice_ptypes_esp[] = {
565 0x00000000, 0x00000000, 0x00000000, 0x00000000,
566 0x00000000, 0x00000003, 0x00000000, 0x00000000,
567 0x00000000, 0x00000000, 0x00000000, 0x00000000,
568 0x00000000, 0x00000000, 0x00000000, 0x00000000,
569 0x00000000, 0x00000000, 0x00000000, 0x00000000,
570 0x00000000, 0x00000000, 0x00000000, 0x00000000,
571 0x00000000, 0x00000000, 0x00000000, 0x00000000,
572 0x00000000, 0x00000000, 0x00000000, 0x00000000,
573};
574
575/* Packet types for AH */
576static const u32 ice_ptypes_ah[] = {
577 0x00000000, 0x00000000, 0x00000000, 0x00000000,
578 0x00000000, 0x0000000C, 0x00000000, 0x00000000,
579 0x00000000, 0x00000000, 0x00000000, 0x00000000,
580 0x00000000, 0x00000000, 0x00000000, 0x00000000,
581 0x00000000, 0x00000000, 0x00000000, 0x00000000,
582 0x00000000, 0x00000000, 0x00000000, 0x00000000,
583 0x00000000, 0x00000000, 0x00000000, 0x00000000,
584 0x00000000, 0x00000000, 0x00000000, 0x00000000,
585};
586
587/* Packet types for packets with NAT_T ESP header */
588static const u32 ice_ptypes_nat_t_esp[] = {
589 0x00000000, 0x00000000, 0x00000000, 0x00000000,
590 0x00000000, 0x00000030, 0x00000000, 0x00000000,
591 0x00000000, 0x00000000, 0x00000000, 0x00000000,
592 0x00000000, 0x00000000, 0x00000000, 0x00000000,
593 0x00000000, 0x00000000, 0x00000000, 0x00000000,
594 0x00000000, 0x00000000, 0x00000000, 0x00000000,
595 0x00000000, 0x00000000, 0x00000000, 0x00000000,
596 0x00000000, 0x00000000, 0x00000000, 0x00000000,
597};
598
599static const u32 ice_ptypes_mac_non_ip_ofos[] = {
600 0x00000846, 0x00000000, 0x00000000, 0x00000000,
601 0x00000000, 0x00000000, 0x00000000, 0x00000000,
602 0x00400000, 0x03FFF000, 0x00000000, 0x00000000,
603 0x00000000, 0x00000000, 0x00000000, 0x00000000,
604 0x00000000, 0x00000000, 0x00000000, 0x00000000,
605 0x00000000, 0x00000000, 0x00000000, 0x00000000,
606 0x00000000, 0x00000000, 0x00000000, 0x00000000,
607 0x00000000, 0x00000000, 0x00000000, 0x00000000,
608};
609
610/* Manage parameters and info. used during the creation of a flow profile */
611struct ice_flow_prof_params {
612 enum ice_block blk;
613 u16 entry_length; /* # of bytes formatted entry will require */
614 u8 es_cnt;
615 struct ice_flow_prof *prof;
616
617 /* For ACL, the es[0] will have the data of ICE_RX_MDID_PKT_FLAGS_15_0
618 * This will give us the direction flags.
619 */
620 struct ice_fv_word es[ICE_MAX_FV_WORDS];
621 /* attributes can be used to add attributes to a particular PTYPE */
622 const struct ice_ptype_attributes *attr;
623 u16 attr_cnt;
624
625 u16 mask[ICE_MAX_FV_WORDS];
626 DECLARE_BITMAP(ptypes, ICE_FLOW_PTYPE_MAX);
627};
628
629#define ICE_FLOW_RSS_HDRS_INNER_MASK \
630 (ICE_FLOW_SEG_HDR_PPPOE | ICE_FLOW_SEG_HDR_GTPC | \
631 ICE_FLOW_SEG_HDR_GTPC_TEID | ICE_FLOW_SEG_HDR_GTPU | \
632 ICE_FLOW_SEG_HDR_PFCP_SESSION | ICE_FLOW_SEG_HDR_L2TPV3 | \
633 ICE_FLOW_SEG_HDR_ESP | ICE_FLOW_SEG_HDR_AH | \
634 ICE_FLOW_SEG_HDR_NAT_T_ESP)
635
636#define ICE_FLOW_SEG_HDRS_L3_MASK \
637 (ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_IPV6 | ICE_FLOW_SEG_HDR_ARP)
638#define ICE_FLOW_SEG_HDRS_L4_MASK \
639 (ICE_FLOW_SEG_HDR_ICMP | ICE_FLOW_SEG_HDR_TCP | ICE_FLOW_SEG_HDR_UDP | \
640 ICE_FLOW_SEG_HDR_SCTP)
641/* mask for L4 protocols that are NOT part of IPv4/6 OTHER PTYPE groups */
642#define ICE_FLOW_SEG_HDRS_L4_MASK_NO_OTHER \
643 (ICE_FLOW_SEG_HDR_TCP | ICE_FLOW_SEG_HDR_UDP | ICE_FLOW_SEG_HDR_SCTP)
644
645/**
646 * ice_flow_val_hdrs - validates packet segments for valid protocol headers
647 * @segs: array of one or more packet segments that describe the flow
648 * @segs_cnt: number of packet segments provided
649 */
650static int ice_flow_val_hdrs(struct ice_flow_seg_info *segs, u8 segs_cnt)
651{
652 u8 i;
653
654 for (i = 0; i < segs_cnt; i++) {
655 /* Multiple L3 headers */
656 if (segs[i].hdrs & ICE_FLOW_SEG_HDRS_L3_MASK &&
657 !is_power_of_2(segs[i].hdrs & ICE_FLOW_SEG_HDRS_L3_MASK))
658 return -EINVAL;
659
660 /* Multiple L4 headers */
661 if (segs[i].hdrs & ICE_FLOW_SEG_HDRS_L4_MASK &&
662 !is_power_of_2(segs[i].hdrs & ICE_FLOW_SEG_HDRS_L4_MASK))
663 return -EINVAL;
664 }
665
666 return 0;
667}
668
669/* Sizes of fixed known protocol headers without header options */
670#define ICE_FLOW_PROT_HDR_SZ_MAC 14
671#define ICE_FLOW_PROT_HDR_SZ_MAC_VLAN (ICE_FLOW_PROT_HDR_SZ_MAC + 2)
672#define ICE_FLOW_PROT_HDR_SZ_IPV4 20
673#define ICE_FLOW_PROT_HDR_SZ_IPV6 40
674#define ICE_FLOW_PROT_HDR_SZ_ARP 28
675#define ICE_FLOW_PROT_HDR_SZ_ICMP 8
676#define ICE_FLOW_PROT_HDR_SZ_TCP 20
677#define ICE_FLOW_PROT_HDR_SZ_UDP 8
678#define ICE_FLOW_PROT_HDR_SZ_SCTP 12
679
680/**
681 * ice_flow_calc_seg_sz - calculates size of a packet segment based on headers
682 * @params: information about the flow to be processed
683 * @seg: index of packet segment whose header size is to be determined
684 */
685static u16 ice_flow_calc_seg_sz(struct ice_flow_prof_params *params, u8 seg)
686{
687 u16 sz;
688
689 /* L2 headers */
690 sz = (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_VLAN) ?
691 ICE_FLOW_PROT_HDR_SZ_MAC_VLAN : ICE_FLOW_PROT_HDR_SZ_MAC;
692
693 /* L3 headers */
694 if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_IPV4)
695 sz += ICE_FLOW_PROT_HDR_SZ_IPV4;
696 else if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_IPV6)
697 sz += ICE_FLOW_PROT_HDR_SZ_IPV6;
698 else if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_ARP)
699 sz += ICE_FLOW_PROT_HDR_SZ_ARP;
700 else if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDRS_L4_MASK)
701 /* An L3 header is required if L4 is specified */
702 return 0;
703
704 /* L4 headers */
705 if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_ICMP)
706 sz += ICE_FLOW_PROT_HDR_SZ_ICMP;
707 else if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_TCP)
708 sz += ICE_FLOW_PROT_HDR_SZ_TCP;
709 else if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_UDP)
710 sz += ICE_FLOW_PROT_HDR_SZ_UDP;
711 else if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_SCTP)
712 sz += ICE_FLOW_PROT_HDR_SZ_SCTP;
713
714 return sz;
715}
716
717/**
718 * ice_flow_proc_seg_hdrs - process protocol headers present in pkt segments
719 * @params: information about the flow to be processed
720 *
721 * This function identifies the packet types associated with the protocol
722 * headers being present in packet segments of the specified flow profile.
723 */
724static int ice_flow_proc_seg_hdrs(struct ice_flow_prof_params *params)
725{
726 struct ice_flow_prof *prof;
727 u8 i;
728
729 memset(params->ptypes, 0xff, sizeof(params->ptypes));
730
731 prof = params->prof;
732
733 for (i = 0; i < params->prof->segs_cnt; i++) {
734 const unsigned long *src;
735 u32 hdrs;
736
737 hdrs = prof->segs[i].hdrs;
738
739 if (hdrs & ICE_FLOW_SEG_HDR_ETH) {
740 src = !i ? (const unsigned long *)ice_ptypes_mac_ofos :
741 (const unsigned long *)ice_ptypes_mac_il;
742 bitmap_and(params->ptypes, params->ptypes, src,
743 ICE_FLOW_PTYPE_MAX);
744 }
745
746 if (i && hdrs & ICE_FLOW_SEG_HDR_VLAN) {
747 src = (const unsigned long *)ice_ptypes_macvlan_il;
748 bitmap_and(params->ptypes, params->ptypes, src,
749 ICE_FLOW_PTYPE_MAX);
750 }
751
752 if (!i && hdrs & ICE_FLOW_SEG_HDR_ARP) {
753 bitmap_and(params->ptypes, params->ptypes,
754 (const unsigned long *)ice_ptypes_arp_of,
755 ICE_FLOW_PTYPE_MAX);
756 }
757
758 if ((hdrs & ICE_FLOW_SEG_HDR_IPV4) &&
759 (hdrs & ICE_FLOW_SEG_HDR_IPV_OTHER)) {
760 src = i ? (const unsigned long *)ice_ptypes_ipv4_il :
761 (const unsigned long *)ice_ptypes_ipv4_ofos_all;
762 bitmap_and(params->ptypes, params->ptypes, src,
763 ICE_FLOW_PTYPE_MAX);
764 } else if ((hdrs & ICE_FLOW_SEG_HDR_IPV6) &&
765 (hdrs & ICE_FLOW_SEG_HDR_IPV_OTHER)) {
766 src = i ? (const unsigned long *)ice_ptypes_ipv6_il :
767 (const unsigned long *)ice_ptypes_ipv6_ofos_all;
768 bitmap_and(params->ptypes, params->ptypes, src,
769 ICE_FLOW_PTYPE_MAX);
770 } else if ((hdrs & ICE_FLOW_SEG_HDR_IPV4) &&
771 !(hdrs & ICE_FLOW_SEG_HDRS_L4_MASK_NO_OTHER)) {
772 src = !i ? (const unsigned long *)ice_ptypes_ipv4_ofos_no_l4 :
773 (const unsigned long *)ice_ptypes_ipv4_il_no_l4;
774 bitmap_and(params->ptypes, params->ptypes, src,
775 ICE_FLOW_PTYPE_MAX);
776 } else if (hdrs & ICE_FLOW_SEG_HDR_IPV4) {
777 src = !i ? (const unsigned long *)ice_ptypes_ipv4_ofos :
778 (const unsigned long *)ice_ptypes_ipv4_il;
779 bitmap_and(params->ptypes, params->ptypes, src,
780 ICE_FLOW_PTYPE_MAX);
781 } else if ((hdrs & ICE_FLOW_SEG_HDR_IPV6) &&
782 !(hdrs & ICE_FLOW_SEG_HDRS_L4_MASK_NO_OTHER)) {
783 src = !i ? (const unsigned long *)ice_ptypes_ipv6_ofos_no_l4 :
784 (const unsigned long *)ice_ptypes_ipv6_il_no_l4;
785 bitmap_and(params->ptypes, params->ptypes, src,
786 ICE_FLOW_PTYPE_MAX);
787 } else if (hdrs & ICE_FLOW_SEG_HDR_IPV6) {
788 src = !i ? (const unsigned long *)ice_ptypes_ipv6_ofos :
789 (const unsigned long *)ice_ptypes_ipv6_il;
790 bitmap_and(params->ptypes, params->ptypes, src,
791 ICE_FLOW_PTYPE_MAX);
792 }
793
794 if (hdrs & ICE_FLOW_SEG_HDR_ETH_NON_IP) {
795 src = (const unsigned long *)ice_ptypes_mac_non_ip_ofos;
796 bitmap_and(params->ptypes, params->ptypes, src,
797 ICE_FLOW_PTYPE_MAX);
798 } else if (hdrs & ICE_FLOW_SEG_HDR_PPPOE) {
799 src = (const unsigned long *)ice_ptypes_pppoe;
800 bitmap_and(params->ptypes, params->ptypes, src,
801 ICE_FLOW_PTYPE_MAX);
802 } else {
803 src = (const unsigned long *)ice_ptypes_pppoe;
804 bitmap_andnot(params->ptypes, params->ptypes, src,
805 ICE_FLOW_PTYPE_MAX);
806 }
807
808 if (hdrs & ICE_FLOW_SEG_HDR_UDP) {
809 src = (const unsigned long *)ice_ptypes_udp_il;
810 bitmap_and(params->ptypes, params->ptypes, src,
811 ICE_FLOW_PTYPE_MAX);
812 } else if (hdrs & ICE_FLOW_SEG_HDR_TCP) {
813 bitmap_and(params->ptypes, params->ptypes,
814 (const unsigned long *)ice_ptypes_tcp_il,
815 ICE_FLOW_PTYPE_MAX);
816 } else if (hdrs & ICE_FLOW_SEG_HDR_SCTP) {
817 src = (const unsigned long *)ice_ptypes_sctp_il;
818 bitmap_and(params->ptypes, params->ptypes, src,
819 ICE_FLOW_PTYPE_MAX);
820 }
821
822 if (hdrs & ICE_FLOW_SEG_HDR_ICMP) {
823 src = !i ? (const unsigned long *)ice_ptypes_icmp_of :
824 (const unsigned long *)ice_ptypes_icmp_il;
825 bitmap_and(params->ptypes, params->ptypes, src,
826 ICE_FLOW_PTYPE_MAX);
827 } else if (hdrs & ICE_FLOW_SEG_HDR_GRE) {
828 if (!i) {
829 src = (const unsigned long *)ice_ptypes_gre_of;
830 bitmap_and(params->ptypes, params->ptypes,
831 src, ICE_FLOW_PTYPE_MAX);
832 }
833 } else if (hdrs & ICE_FLOW_SEG_HDR_GTPC) {
834 src = (const unsigned long *)ice_ptypes_gtpc;
835 bitmap_and(params->ptypes, params->ptypes, src,
836 ICE_FLOW_PTYPE_MAX);
837 } else if (hdrs & ICE_FLOW_SEG_HDR_GTPC_TEID) {
838 src = (const unsigned long *)ice_ptypes_gtpc_tid;
839 bitmap_and(params->ptypes, params->ptypes, src,
840 ICE_FLOW_PTYPE_MAX);
841 } else if (hdrs & ICE_FLOW_SEG_HDR_GTPU_DWN) {
842 src = (const unsigned long *)ice_ptypes_gtpu;
843 bitmap_and(params->ptypes, params->ptypes, src,
844 ICE_FLOW_PTYPE_MAX);
845
846 /* Attributes for GTP packet with downlink */
847 params->attr = ice_attr_gtpu_down;
848 params->attr_cnt = ARRAY_SIZE(ice_attr_gtpu_down);
849 } else if (hdrs & ICE_FLOW_SEG_HDR_GTPU_UP) {
850 src = (const unsigned long *)ice_ptypes_gtpu;
851 bitmap_and(params->ptypes, params->ptypes, src,
852 ICE_FLOW_PTYPE_MAX);
853
854 /* Attributes for GTP packet with uplink */
855 params->attr = ice_attr_gtpu_up;
856 params->attr_cnt = ARRAY_SIZE(ice_attr_gtpu_up);
857 } else if (hdrs & ICE_FLOW_SEG_HDR_GTPU_EH) {
858 src = (const unsigned long *)ice_ptypes_gtpu;
859 bitmap_and(params->ptypes, params->ptypes, src,
860 ICE_FLOW_PTYPE_MAX);
861
862 /* Attributes for GTP packet with Extension Header */
863 params->attr = ice_attr_gtpu_eh;
864 params->attr_cnt = ARRAY_SIZE(ice_attr_gtpu_eh);
865 } else if (hdrs & ICE_FLOW_SEG_HDR_GTPU_IP) {
866 src = (const unsigned long *)ice_ptypes_gtpu;
867 bitmap_and(params->ptypes, params->ptypes, src,
868 ICE_FLOW_PTYPE_MAX);
869 } else if (hdrs & ICE_FLOW_SEG_HDR_L2TPV3) {
870 src = (const unsigned long *)ice_ptypes_l2tpv3;
871 bitmap_and(params->ptypes, params->ptypes, src,
872 ICE_FLOW_PTYPE_MAX);
873 } else if (hdrs & ICE_FLOW_SEG_HDR_ESP) {
874 src = (const unsigned long *)ice_ptypes_esp;
875 bitmap_and(params->ptypes, params->ptypes, src,
876 ICE_FLOW_PTYPE_MAX);
877 } else if (hdrs & ICE_FLOW_SEG_HDR_AH) {
878 src = (const unsigned long *)ice_ptypes_ah;
879 bitmap_and(params->ptypes, params->ptypes, src,
880 ICE_FLOW_PTYPE_MAX);
881 } else if (hdrs & ICE_FLOW_SEG_HDR_NAT_T_ESP) {
882 src = (const unsigned long *)ice_ptypes_nat_t_esp;
883 bitmap_and(params->ptypes, params->ptypes, src,
884 ICE_FLOW_PTYPE_MAX);
885 }
886
887 if (hdrs & ICE_FLOW_SEG_HDR_PFCP) {
888 if (hdrs & ICE_FLOW_SEG_HDR_PFCP_NODE)
889 src = (const unsigned long *)ice_ptypes_pfcp_node;
890 else
891 src = (const unsigned long *)ice_ptypes_pfcp_session;
892
893 bitmap_and(params->ptypes, params->ptypes, src,
894 ICE_FLOW_PTYPE_MAX);
895 } else {
896 src = (const unsigned long *)ice_ptypes_pfcp_node;
897 bitmap_andnot(params->ptypes, params->ptypes, src,
898 ICE_FLOW_PTYPE_MAX);
899
900 src = (const unsigned long *)ice_ptypes_pfcp_session;
901 bitmap_andnot(params->ptypes, params->ptypes, src,
902 ICE_FLOW_PTYPE_MAX);
903 }
904 }
905
906 return 0;
907}
908
909/**
910 * ice_flow_xtract_fld - Create an extraction sequence entry for the given field
911 * @hw: pointer to the HW struct
912 * @params: information about the flow to be processed
913 * @seg: packet segment index of the field to be extracted
914 * @fld: ID of field to be extracted
915 * @match: bit field of all fields
916 *
917 * This function determines the protocol ID, offset, and size of the given
918 * field. It then allocates one or more extraction sequence entries for the
919 * given field, and fill the entries with protocol ID and offset information.
920 */
921static int
922ice_flow_xtract_fld(struct ice_hw *hw, struct ice_flow_prof_params *params,
923 u8 seg, enum ice_flow_field fld, u64 match)
924{
925 enum ice_flow_field sib = ICE_FLOW_FIELD_IDX_MAX;
926 enum ice_prot_id prot_id = ICE_PROT_ID_INVAL;
927 u8 fv_words = hw->blk[params->blk].es.fvw;
928 struct ice_flow_fld_info *flds;
929 u16 cnt, ese_bits, i;
930 u16 sib_mask = 0;
931 u16 mask;
932 u16 off;
933
934 flds = params->prof->segs[seg].fields;
935
936 switch (fld) {
937 case ICE_FLOW_FIELD_IDX_ETH_DA:
938 case ICE_FLOW_FIELD_IDX_ETH_SA:
939 case ICE_FLOW_FIELD_IDX_S_VLAN:
940 case ICE_FLOW_FIELD_IDX_C_VLAN:
941 prot_id = seg == 0 ? ICE_PROT_MAC_OF_OR_S : ICE_PROT_MAC_IL;
942 break;
943 case ICE_FLOW_FIELD_IDX_ETH_TYPE:
944 prot_id = seg == 0 ? ICE_PROT_ETYPE_OL : ICE_PROT_ETYPE_IL;
945 break;
946 case ICE_FLOW_FIELD_IDX_IPV4_DSCP:
947 prot_id = seg == 0 ? ICE_PROT_IPV4_OF_OR_S : ICE_PROT_IPV4_IL;
948 break;
949 case ICE_FLOW_FIELD_IDX_IPV6_DSCP:
950 prot_id = seg == 0 ? ICE_PROT_IPV6_OF_OR_S : ICE_PROT_IPV6_IL;
951 break;
952 case ICE_FLOW_FIELD_IDX_IPV4_TTL:
953 case ICE_FLOW_FIELD_IDX_IPV4_PROT:
954 prot_id = seg == 0 ? ICE_PROT_IPV4_OF_OR_S : ICE_PROT_IPV4_IL;
955
956 /* TTL and PROT share the same extraction seq. entry.
957 * Each is considered a sibling to the other in terms of sharing
958 * the same extraction sequence entry.
959 */
960 if (fld == ICE_FLOW_FIELD_IDX_IPV4_TTL)
961 sib = ICE_FLOW_FIELD_IDX_IPV4_PROT;
962 else if (fld == ICE_FLOW_FIELD_IDX_IPV4_PROT)
963 sib = ICE_FLOW_FIELD_IDX_IPV4_TTL;
964
965 /* If the sibling field is also included, that field's
966 * mask needs to be included.
967 */
968 if (match & BIT(sib))
969 sib_mask = ice_flds_info[sib].mask;
970 break;
971 case ICE_FLOW_FIELD_IDX_IPV6_TTL:
972 case ICE_FLOW_FIELD_IDX_IPV6_PROT:
973 prot_id = seg == 0 ? ICE_PROT_IPV6_OF_OR_S : ICE_PROT_IPV6_IL;
974
975 /* TTL and PROT share the same extraction seq. entry.
976 * Each is considered a sibling to the other in terms of sharing
977 * the same extraction sequence entry.
978 */
979 if (fld == ICE_FLOW_FIELD_IDX_IPV6_TTL)
980 sib = ICE_FLOW_FIELD_IDX_IPV6_PROT;
981 else if (fld == ICE_FLOW_FIELD_IDX_IPV6_PROT)
982 sib = ICE_FLOW_FIELD_IDX_IPV6_TTL;
983
984 /* If the sibling field is also included, that field's
985 * mask needs to be included.
986 */
987 if (match & BIT(sib))
988 sib_mask = ice_flds_info[sib].mask;
989 break;
990 case ICE_FLOW_FIELD_IDX_IPV4_SA:
991 case ICE_FLOW_FIELD_IDX_IPV4_DA:
992 prot_id = seg == 0 ? ICE_PROT_IPV4_OF_OR_S : ICE_PROT_IPV4_IL;
993 break;
994 case ICE_FLOW_FIELD_IDX_IPV6_SA:
995 case ICE_FLOW_FIELD_IDX_IPV6_DA:
996 prot_id = seg == 0 ? ICE_PROT_IPV6_OF_OR_S : ICE_PROT_IPV6_IL;
997 break;
998 case ICE_FLOW_FIELD_IDX_TCP_SRC_PORT:
999 case ICE_FLOW_FIELD_IDX_TCP_DST_PORT:
1000 case ICE_FLOW_FIELD_IDX_TCP_FLAGS:
1001 prot_id = ICE_PROT_TCP_IL;
1002 break;
1003 case ICE_FLOW_FIELD_IDX_UDP_SRC_PORT:
1004 case ICE_FLOW_FIELD_IDX_UDP_DST_PORT:
1005 prot_id = ICE_PROT_UDP_IL_OR_S;
1006 break;
1007 case ICE_FLOW_FIELD_IDX_SCTP_SRC_PORT:
1008 case ICE_FLOW_FIELD_IDX_SCTP_DST_PORT:
1009 prot_id = ICE_PROT_SCTP_IL;
1010 break;
1011 case ICE_FLOW_FIELD_IDX_GTPC_TEID:
1012 case ICE_FLOW_FIELD_IDX_GTPU_IP_TEID:
1013 case ICE_FLOW_FIELD_IDX_GTPU_UP_TEID:
1014 case ICE_FLOW_FIELD_IDX_GTPU_DWN_TEID:
1015 case ICE_FLOW_FIELD_IDX_GTPU_EH_TEID:
1016 case ICE_FLOW_FIELD_IDX_GTPU_EH_QFI:
1017 /* GTP is accessed through UDP OF protocol */
1018 prot_id = ICE_PROT_UDP_OF;
1019 break;
1020 case ICE_FLOW_FIELD_IDX_PPPOE_SESS_ID:
1021 prot_id = ICE_PROT_PPPOE;
1022 break;
1023 case ICE_FLOW_FIELD_IDX_PFCP_SEID:
1024 prot_id = ICE_PROT_UDP_IL_OR_S;
1025 break;
1026 case ICE_FLOW_FIELD_IDX_L2TPV3_SESS_ID:
1027 prot_id = ICE_PROT_L2TPV3;
1028 break;
1029 case ICE_FLOW_FIELD_IDX_ESP_SPI:
1030 prot_id = ICE_PROT_ESP_F;
1031 break;
1032 case ICE_FLOW_FIELD_IDX_AH_SPI:
1033 prot_id = ICE_PROT_ESP_2;
1034 break;
1035 case ICE_FLOW_FIELD_IDX_NAT_T_ESP_SPI:
1036 prot_id = ICE_PROT_UDP_IL_OR_S;
1037 break;
1038 case ICE_FLOW_FIELD_IDX_ARP_SIP:
1039 case ICE_FLOW_FIELD_IDX_ARP_DIP:
1040 case ICE_FLOW_FIELD_IDX_ARP_SHA:
1041 case ICE_FLOW_FIELD_IDX_ARP_DHA:
1042 case ICE_FLOW_FIELD_IDX_ARP_OP:
1043 prot_id = ICE_PROT_ARP_OF;
1044 break;
1045 case ICE_FLOW_FIELD_IDX_ICMP_TYPE:
1046 case ICE_FLOW_FIELD_IDX_ICMP_CODE:
1047 /* ICMP type and code share the same extraction seq. entry */
1048 prot_id = (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_IPV4) ?
1049 ICE_PROT_ICMP_IL : ICE_PROT_ICMPV6_IL;
1050 sib = fld == ICE_FLOW_FIELD_IDX_ICMP_TYPE ?
1051 ICE_FLOW_FIELD_IDX_ICMP_CODE :
1052 ICE_FLOW_FIELD_IDX_ICMP_TYPE;
1053 break;
1054 case ICE_FLOW_FIELD_IDX_GRE_KEYID:
1055 prot_id = ICE_PROT_GRE_OF;
1056 break;
1057 default:
1058 return -EOPNOTSUPP;
1059 }
1060
1061 /* Each extraction sequence entry is a word in size, and extracts a
1062 * word-aligned offset from a protocol header.
1063 */
1064 ese_bits = ICE_FLOW_FV_EXTRACT_SZ * BITS_PER_BYTE;
1065
1066 flds[fld].xtrct.prot_id = prot_id;
1067 flds[fld].xtrct.off = (ice_flds_info[fld].off / ese_bits) *
1068 ICE_FLOW_FV_EXTRACT_SZ;
1069 flds[fld].xtrct.disp = (u8)(ice_flds_info[fld].off % ese_bits);
1070 flds[fld].xtrct.idx = params->es_cnt;
1071 flds[fld].xtrct.mask = ice_flds_info[fld].mask;
1072
1073 /* Adjust the next field-entry index after accommodating the number of
1074 * entries this field consumes
1075 */
1076 cnt = DIV_ROUND_UP(flds[fld].xtrct.disp + ice_flds_info[fld].size,
1077 ese_bits);
1078
1079 /* Fill in the extraction sequence entries needed for this field */
1080 off = flds[fld].xtrct.off;
1081 mask = flds[fld].xtrct.mask;
1082 for (i = 0; i < cnt; i++) {
1083 /* Only consume an extraction sequence entry if there is no
1084 * sibling field associated with this field or the sibling entry
1085 * already extracts the word shared with this field.
1086 */
1087 if (sib == ICE_FLOW_FIELD_IDX_MAX ||
1088 flds[sib].xtrct.prot_id == ICE_PROT_ID_INVAL ||
1089 flds[sib].xtrct.off != off) {
1090 u8 idx;
1091
1092 /* Make sure the number of extraction sequence required
1093 * does not exceed the block's capability
1094 */
1095 if (params->es_cnt >= fv_words)
1096 return -ENOSPC;
1097
1098 /* some blocks require a reversed field vector layout */
1099 if (hw->blk[params->blk].es.reverse)
1100 idx = fv_words - params->es_cnt - 1;
1101 else
1102 idx = params->es_cnt;
1103
1104 params->es[idx].prot_id = prot_id;
1105 params->es[idx].off = off;
1106 params->mask[idx] = mask | sib_mask;
1107 params->es_cnt++;
1108 }
1109
1110 off += ICE_FLOW_FV_EXTRACT_SZ;
1111 }
1112
1113 return 0;
1114}
1115
1116/**
1117 * ice_flow_xtract_raws - Create extract sequence entries for raw bytes
1118 * @hw: pointer to the HW struct
1119 * @params: information about the flow to be processed
1120 * @seg: index of packet segment whose raw fields are to be extracted
1121 */
1122static int
1123ice_flow_xtract_raws(struct ice_hw *hw, struct ice_flow_prof_params *params,
1124 u8 seg)
1125{
1126 u16 fv_words;
1127 u16 hdrs_sz;
1128 u8 i;
1129
1130 if (!params->prof->segs[seg].raws_cnt)
1131 return 0;
1132
1133 if (params->prof->segs[seg].raws_cnt >
1134 ARRAY_SIZE(params->prof->segs[seg].raws))
1135 return -ENOSPC;
1136
1137 /* Offsets within the segment headers are not supported */
1138 hdrs_sz = ice_flow_calc_seg_sz(params, seg);
1139 if (!hdrs_sz)
1140 return -EINVAL;
1141
1142 fv_words = hw->blk[params->blk].es.fvw;
1143
1144 for (i = 0; i < params->prof->segs[seg].raws_cnt; i++) {
1145 struct ice_flow_seg_fld_raw *raw;
1146 u16 off, cnt, j;
1147
1148 raw = ¶ms->prof->segs[seg].raws[i];
1149
1150 /* Storing extraction information */
1151 raw->info.xtrct.prot_id = ICE_PROT_MAC_OF_OR_S;
1152 raw->info.xtrct.off = (raw->off / ICE_FLOW_FV_EXTRACT_SZ) *
1153 ICE_FLOW_FV_EXTRACT_SZ;
1154 raw->info.xtrct.disp = (raw->off % ICE_FLOW_FV_EXTRACT_SZ) *
1155 BITS_PER_BYTE;
1156 raw->info.xtrct.idx = params->es_cnt;
1157
1158 /* Determine the number of field vector entries this raw field
1159 * consumes.
1160 */
1161 cnt = DIV_ROUND_UP(raw->info.xtrct.disp +
1162 (raw->info.src.last * BITS_PER_BYTE),
1163 (ICE_FLOW_FV_EXTRACT_SZ * BITS_PER_BYTE));
1164 off = raw->info.xtrct.off;
1165 for (j = 0; j < cnt; j++) {
1166 u16 idx;
1167
1168 /* Make sure the number of extraction sequence required
1169 * does not exceed the block's capability
1170 */
1171 if (params->es_cnt >= hw->blk[params->blk].es.count ||
1172 params->es_cnt >= ICE_MAX_FV_WORDS)
1173 return -ENOSPC;
1174
1175 /* some blocks require a reversed field vector layout */
1176 if (hw->blk[params->blk].es.reverse)
1177 idx = fv_words - params->es_cnt - 1;
1178 else
1179 idx = params->es_cnt;
1180
1181 params->es[idx].prot_id = raw->info.xtrct.prot_id;
1182 params->es[idx].off = off;
1183 params->es_cnt++;
1184 off += ICE_FLOW_FV_EXTRACT_SZ;
1185 }
1186 }
1187
1188 return 0;
1189}
1190
1191/**
1192 * ice_flow_create_xtrct_seq - Create an extraction sequence for given segments
1193 * @hw: pointer to the HW struct
1194 * @params: information about the flow to be processed
1195 *
1196 * This function iterates through all matched fields in the given segments, and
1197 * creates an extraction sequence for the fields.
1198 */
1199static int
1200ice_flow_create_xtrct_seq(struct ice_hw *hw,
1201 struct ice_flow_prof_params *params)
1202{
1203 struct ice_flow_prof *prof = params->prof;
1204 int status = 0;
1205 u8 i;
1206
1207 for (i = 0; i < prof->segs_cnt; i++) {
1208 u64 match = params->prof->segs[i].match;
1209 enum ice_flow_field j;
1210
1211 for_each_set_bit(j, (unsigned long *)&match,
1212 ICE_FLOW_FIELD_IDX_MAX) {
1213 status = ice_flow_xtract_fld(hw, params, i, j, match);
1214 if (status)
1215 return status;
1216 clear_bit(j, (unsigned long *)&match);
1217 }
1218
1219 /* Process raw matching bytes */
1220 status = ice_flow_xtract_raws(hw, params, i);
1221 if (status)
1222 return status;
1223 }
1224
1225 return status;
1226}
1227
1228/**
1229 * ice_flow_proc_segs - process all packet segments associated with a profile
1230 * @hw: pointer to the HW struct
1231 * @params: information about the flow to be processed
1232 */
1233static int
1234ice_flow_proc_segs(struct ice_hw *hw, struct ice_flow_prof_params *params)
1235{
1236 int status;
1237
1238 status = ice_flow_proc_seg_hdrs(params);
1239 if (status)
1240 return status;
1241
1242 status = ice_flow_create_xtrct_seq(hw, params);
1243 if (status)
1244 return status;
1245
1246 switch (params->blk) {
1247 case ICE_BLK_FD:
1248 case ICE_BLK_RSS:
1249 status = 0;
1250 break;
1251 default:
1252 return -EOPNOTSUPP;
1253 }
1254
1255 return status;
1256}
1257
1258#define ICE_FLOW_FIND_PROF_CHK_FLDS 0x00000001
1259#define ICE_FLOW_FIND_PROF_CHK_VSI 0x00000002
1260#define ICE_FLOW_FIND_PROF_NOT_CHK_DIR 0x00000004
1261#define ICE_FLOW_FIND_PROF_CHK_SYMM 0x00000008
1262
1263/**
1264 * ice_flow_find_prof_conds - Find a profile matching headers and conditions
1265 * @hw: pointer to the HW struct
1266 * @blk: classification stage
1267 * @dir: flow direction
1268 * @segs: array of one or more packet segments that describe the flow
1269 * @segs_cnt: number of packet segments provided
1270 * @symm: symmetric setting for RSS profiles
1271 * @vsi_handle: software VSI handle to check VSI (ICE_FLOW_FIND_PROF_CHK_VSI)
1272 * @conds: additional conditions to be checked (ICE_FLOW_FIND_PROF_CHK_*)
1273 */
1274static struct ice_flow_prof *
1275ice_flow_find_prof_conds(struct ice_hw *hw, enum ice_block blk,
1276 enum ice_flow_dir dir, struct ice_flow_seg_info *segs,
1277 u8 segs_cnt, bool symm, u16 vsi_handle, u32 conds)
1278{
1279 struct ice_flow_prof *p, *prof = NULL;
1280
1281 mutex_lock(&hw->fl_profs_locks[blk]);
1282 list_for_each_entry(p, &hw->fl_profs[blk], l_entry)
1283 if ((p->dir == dir || conds & ICE_FLOW_FIND_PROF_NOT_CHK_DIR) &&
1284 segs_cnt && segs_cnt == p->segs_cnt) {
1285 u8 i;
1286
1287 /* Check for profile-VSI association if specified */
1288 if ((conds & ICE_FLOW_FIND_PROF_CHK_VSI) &&
1289 ice_is_vsi_valid(hw, vsi_handle) &&
1290 !test_bit(vsi_handle, p->vsis))
1291 continue;
1292
1293 /* Check for symmetric settings */
1294 if ((conds & ICE_FLOW_FIND_PROF_CHK_SYMM) &&
1295 p->symm != symm)
1296 continue;
1297
1298 /* Protocol headers must be checked. Matched fields are
1299 * checked if specified.
1300 */
1301 for (i = 0; i < segs_cnt; i++)
1302 if (segs[i].hdrs != p->segs[i].hdrs ||
1303 ((conds & ICE_FLOW_FIND_PROF_CHK_FLDS) &&
1304 segs[i].match != p->segs[i].match))
1305 break;
1306
1307 /* A match is found if all segments are matched */
1308 if (i == segs_cnt) {
1309 prof = p;
1310 break;
1311 }
1312 }
1313 mutex_unlock(&hw->fl_profs_locks[blk]);
1314
1315 return prof;
1316}
1317
1318/**
1319 * ice_flow_find_prof_id - Look up a profile with given profile ID
1320 * @hw: pointer to the HW struct
1321 * @blk: classification stage
1322 * @prof_id: unique ID to identify this flow profile
1323 */
1324static struct ice_flow_prof *
1325ice_flow_find_prof_id(struct ice_hw *hw, enum ice_block blk, u64 prof_id)
1326{
1327 struct ice_flow_prof *p;
1328
1329 list_for_each_entry(p, &hw->fl_profs[blk], l_entry)
1330 if (p->id == prof_id)
1331 return p;
1332
1333 return NULL;
1334}
1335
1336/**
1337 * ice_flow_rem_entry_sync - Remove a flow entry
1338 * @hw: pointer to the HW struct
1339 * @blk: classification stage
1340 * @entry: flow entry to be removed
1341 */
1342static int
1343ice_flow_rem_entry_sync(struct ice_hw *hw, enum ice_block __always_unused blk,
1344 struct ice_flow_entry *entry)
1345{
1346 if (!entry)
1347 return -EINVAL;
1348
1349 list_del(&entry->l_entry);
1350
1351 devm_kfree(ice_hw_to_dev(hw), entry);
1352
1353 return 0;
1354}
1355
1356/**
1357 * ice_flow_add_prof_sync - Add a flow profile for packet segments and fields
1358 * @hw: pointer to the HW struct
1359 * @blk: classification stage
1360 * @dir: flow direction
1361 * @segs: array of one or more packet segments that describe the flow
1362 * @segs_cnt: number of packet segments provided
1363 * @symm: symmetric setting for RSS profiles
1364 * @prof: stores the returned flow profile added
1365 *
1366 * Assumption: the caller has acquired the lock to the profile list
1367 */
1368static int
1369ice_flow_add_prof_sync(struct ice_hw *hw, enum ice_block blk,
1370 enum ice_flow_dir dir,
1371 struct ice_flow_seg_info *segs, u8 segs_cnt,
1372 bool symm, struct ice_flow_prof **prof)
1373{
1374 struct ice_flow_prof_params *params;
1375 struct ice_prof_id *ids;
1376 int status;
1377 u64 prof_id;
1378 u8 i;
1379
1380 if (!prof)
1381 return -EINVAL;
1382
1383 ids = &hw->blk[blk].prof_id;
1384 prof_id = find_first_zero_bit(ids->id, ids->count);
1385 if (prof_id >= ids->count)
1386 return -ENOSPC;
1387
1388 params = kzalloc(sizeof(*params), GFP_KERNEL);
1389 if (!params)
1390 return -ENOMEM;
1391
1392 params->prof = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*params->prof),
1393 GFP_KERNEL);
1394 if (!params->prof) {
1395 status = -ENOMEM;
1396 goto free_params;
1397 }
1398
1399 /* initialize extraction sequence to all invalid (0xff) */
1400 for (i = 0; i < ICE_MAX_FV_WORDS; i++) {
1401 params->es[i].prot_id = ICE_PROT_INVALID;
1402 params->es[i].off = ICE_FV_OFFSET_INVAL;
1403 }
1404
1405 params->blk = blk;
1406 params->prof->id = prof_id;
1407 params->prof->dir = dir;
1408 params->prof->segs_cnt = segs_cnt;
1409 params->prof->symm = symm;
1410
1411 /* Make a copy of the segments that need to be persistent in the flow
1412 * profile instance
1413 */
1414 for (i = 0; i < segs_cnt; i++)
1415 memcpy(¶ms->prof->segs[i], &segs[i], sizeof(*segs));
1416
1417 status = ice_flow_proc_segs(hw, params);
1418 if (status) {
1419 ice_debug(hw, ICE_DBG_FLOW, "Error processing a flow's packet segments\n");
1420 goto out;
1421 }
1422
1423 /* Add a HW profile for this flow profile */
1424 status = ice_add_prof(hw, blk, prof_id, (u8 *)params->ptypes,
1425 params->attr, params->attr_cnt, params->es,
1426 params->mask, symm, true);
1427 if (status) {
1428 ice_debug(hw, ICE_DBG_FLOW, "Error adding a HW flow profile\n");
1429 goto out;
1430 }
1431
1432 INIT_LIST_HEAD(¶ms->prof->entries);
1433 mutex_init(¶ms->prof->entries_lock);
1434 set_bit(prof_id, ids->id);
1435 *prof = params->prof;
1436
1437out:
1438 if (status)
1439 devm_kfree(ice_hw_to_dev(hw), params->prof);
1440free_params:
1441 kfree(params);
1442
1443 return status;
1444}
1445
1446/**
1447 * ice_flow_rem_prof_sync - remove a flow profile
1448 * @hw: pointer to the hardware structure
1449 * @blk: classification stage
1450 * @prof: pointer to flow profile to remove
1451 *
1452 * Assumption: the caller has acquired the lock to the profile list
1453 */
1454static int
1455ice_flow_rem_prof_sync(struct ice_hw *hw, enum ice_block blk,
1456 struct ice_flow_prof *prof)
1457{
1458 int status;
1459
1460 /* Remove all remaining flow entries before removing the flow profile */
1461 if (!list_empty(&prof->entries)) {
1462 struct ice_flow_entry *e, *t;
1463
1464 mutex_lock(&prof->entries_lock);
1465
1466 list_for_each_entry_safe(e, t, &prof->entries, l_entry) {
1467 status = ice_flow_rem_entry_sync(hw, blk, e);
1468 if (status)
1469 break;
1470 }
1471
1472 mutex_unlock(&prof->entries_lock);
1473 }
1474
1475 /* Remove all hardware profiles associated with this flow profile */
1476 status = ice_rem_prof(hw, blk, prof->id);
1477 if (!status) {
1478 clear_bit(prof->id, hw->blk[blk].prof_id.id);
1479 list_del(&prof->l_entry);
1480 mutex_destroy(&prof->entries_lock);
1481 devm_kfree(ice_hw_to_dev(hw), prof);
1482 }
1483
1484 return status;
1485}
1486
1487/**
1488 * ice_flow_assoc_prof - associate a VSI with a flow profile
1489 * @hw: pointer to the hardware structure
1490 * @blk: classification stage
1491 * @prof: pointer to flow profile
1492 * @vsi_handle: software VSI handle
1493 *
1494 * Assumption: the caller has acquired the lock to the profile list
1495 * and the software VSI handle has been validated
1496 */
1497static int
1498ice_flow_assoc_prof(struct ice_hw *hw, enum ice_block blk,
1499 struct ice_flow_prof *prof, u16 vsi_handle)
1500{
1501 int status = 0;
1502
1503 if (!test_bit(vsi_handle, prof->vsis)) {
1504 status = ice_add_prof_id_flow(hw, blk,
1505 ice_get_hw_vsi_num(hw,
1506 vsi_handle),
1507 prof->id);
1508 if (!status)
1509 set_bit(vsi_handle, prof->vsis);
1510 else
1511 ice_debug(hw, ICE_DBG_FLOW, "HW profile add failed, %d\n",
1512 status);
1513 }
1514
1515 return status;
1516}
1517
1518/**
1519 * ice_flow_disassoc_prof - disassociate a VSI from a flow profile
1520 * @hw: pointer to the hardware structure
1521 * @blk: classification stage
1522 * @prof: pointer to flow profile
1523 * @vsi_handle: software VSI handle
1524 *
1525 * Assumption: the caller has acquired the lock to the profile list
1526 * and the software VSI handle has been validated
1527 */
1528static int
1529ice_flow_disassoc_prof(struct ice_hw *hw, enum ice_block blk,
1530 struct ice_flow_prof *prof, u16 vsi_handle)
1531{
1532 int status = 0;
1533
1534 if (test_bit(vsi_handle, prof->vsis)) {
1535 status = ice_rem_prof_id_flow(hw, blk,
1536 ice_get_hw_vsi_num(hw,
1537 vsi_handle),
1538 prof->id);
1539 if (!status)
1540 clear_bit(vsi_handle, prof->vsis);
1541 else
1542 ice_debug(hw, ICE_DBG_FLOW, "HW profile remove failed, %d\n",
1543 status);
1544 }
1545
1546 return status;
1547}
1548
1549#define FLAG_GTP_EH_PDU_LINK BIT_ULL(13)
1550#define FLAG_GTP_EH_PDU BIT_ULL(14)
1551
1552#define HI_BYTE_IN_WORD GENMASK(15, 8)
1553#define LO_BYTE_IN_WORD GENMASK(7, 0)
1554
1555#define FLAG_GTPU_MSK \
1556 (FLAG_GTP_EH_PDU | FLAG_GTP_EH_PDU_LINK)
1557#define FLAG_GTPU_UP \
1558 (FLAG_GTP_EH_PDU | FLAG_GTP_EH_PDU_LINK)
1559#define FLAG_GTPU_DW FLAG_GTP_EH_PDU
1560
1561/**
1562 * ice_flow_set_parser_prof - Set flow profile based on the parsed profile info
1563 * @hw: pointer to the HW struct
1564 * @dest_vsi: dest VSI
1565 * @fdir_vsi: fdir programming VSI
1566 * @prof: stores parsed profile info from raw flow
1567 * @blk: classification blk
1568 *
1569 * Return: 0 on success or negative errno on failure.
1570 */
1571int
1572ice_flow_set_parser_prof(struct ice_hw *hw, u16 dest_vsi, u16 fdir_vsi,
1573 struct ice_parser_profile *prof, enum ice_block blk)
1574{
1575 u64 id = find_first_bit(prof->ptypes, ICE_FLOW_PTYPE_MAX);
1576 struct ice_flow_prof_params *params __free(kfree);
1577 u8 fv_words = hw->blk[blk].es.fvw;
1578 int status;
1579 int i, idx;
1580
1581 params = kzalloc(sizeof(*params), GFP_KERNEL);
1582 if (!params)
1583 return -ENOMEM;
1584
1585 for (i = 0; i < ICE_MAX_FV_WORDS; i++) {
1586 params->es[i].prot_id = ICE_PROT_INVALID;
1587 params->es[i].off = ICE_FV_OFFSET_INVAL;
1588 }
1589
1590 for (i = 0; i < prof->fv_num; i++) {
1591 if (hw->blk[blk].es.reverse)
1592 idx = fv_words - i - 1;
1593 else
1594 idx = i;
1595 params->es[idx].prot_id = prof->fv[i].proto_id;
1596 params->es[idx].off = prof->fv[i].offset;
1597 params->mask[idx] = (((prof->fv[i].msk) << BITS_PER_BYTE) &
1598 HI_BYTE_IN_WORD) |
1599 (((prof->fv[i].msk) >> BITS_PER_BYTE) &
1600 LO_BYTE_IN_WORD);
1601 }
1602
1603 switch (prof->flags) {
1604 case FLAG_GTPU_DW:
1605 params->attr = ice_attr_gtpu_down;
1606 params->attr_cnt = ARRAY_SIZE(ice_attr_gtpu_down);
1607 break;
1608 case FLAG_GTPU_UP:
1609 params->attr = ice_attr_gtpu_up;
1610 params->attr_cnt = ARRAY_SIZE(ice_attr_gtpu_up);
1611 break;
1612 default:
1613 if (prof->flags_msk & FLAG_GTPU_MSK) {
1614 params->attr = ice_attr_gtpu_session;
1615 params->attr_cnt = ARRAY_SIZE(ice_attr_gtpu_session);
1616 }
1617 break;
1618 }
1619
1620 status = ice_add_prof(hw, blk, id, (u8 *)prof->ptypes,
1621 params->attr, params->attr_cnt,
1622 params->es, params->mask, false, false);
1623 if (status)
1624 return status;
1625
1626 status = ice_flow_assoc_fdir_prof(hw, blk, dest_vsi, fdir_vsi, id);
1627 if (status)
1628 ice_rem_prof(hw, blk, id);
1629
1630 return status;
1631}
1632
1633/**
1634 * ice_flow_add_prof - Add a flow profile for packet segments and matched fields
1635 * @hw: pointer to the HW struct
1636 * @blk: classification stage
1637 * @dir: flow direction
1638 * @segs: array of one or more packet segments that describe the flow
1639 * @segs_cnt: number of packet segments provided
1640 * @symm: symmetric setting for RSS profiles
1641 * @prof: stores the returned flow profile added
1642 */
1643int
1644ice_flow_add_prof(struct ice_hw *hw, enum ice_block blk, enum ice_flow_dir dir,
1645 struct ice_flow_seg_info *segs, u8 segs_cnt,
1646 bool symm, struct ice_flow_prof **prof)
1647{
1648 int status;
1649
1650 if (segs_cnt > ICE_FLOW_SEG_MAX)
1651 return -ENOSPC;
1652
1653 if (!segs_cnt)
1654 return -EINVAL;
1655
1656 if (!segs)
1657 return -EINVAL;
1658
1659 status = ice_flow_val_hdrs(segs, segs_cnt);
1660 if (status)
1661 return status;
1662
1663 mutex_lock(&hw->fl_profs_locks[blk]);
1664
1665 status = ice_flow_add_prof_sync(hw, blk, dir, segs, segs_cnt,
1666 symm, prof);
1667 if (!status)
1668 list_add(&(*prof)->l_entry, &hw->fl_profs[blk]);
1669
1670 mutex_unlock(&hw->fl_profs_locks[blk]);
1671
1672 return status;
1673}
1674
1675/**
1676 * ice_flow_rem_prof - Remove a flow profile and all entries associated with it
1677 * @hw: pointer to the HW struct
1678 * @blk: the block for which the flow profile is to be removed
1679 * @prof_id: unique ID of the flow profile to be removed
1680 */
1681int ice_flow_rem_prof(struct ice_hw *hw, enum ice_block blk, u64 prof_id)
1682{
1683 struct ice_flow_prof *prof;
1684 int status;
1685
1686 mutex_lock(&hw->fl_profs_locks[blk]);
1687
1688 prof = ice_flow_find_prof_id(hw, blk, prof_id);
1689 if (!prof) {
1690 status = -ENOENT;
1691 goto out;
1692 }
1693
1694 /* prof becomes invalid after the call */
1695 status = ice_flow_rem_prof_sync(hw, blk, prof);
1696
1697out:
1698 mutex_unlock(&hw->fl_profs_locks[blk]);
1699
1700 return status;
1701}
1702
1703/**
1704 * ice_flow_add_entry - Add a flow entry
1705 * @hw: pointer to the HW struct
1706 * @blk: classification stage
1707 * @prof_id: ID of the profile to add a new flow entry to
1708 * @entry_id: unique ID to identify this flow entry
1709 * @vsi_handle: software VSI handle for the flow entry
1710 * @prio: priority of the flow entry
1711 * @data: pointer to a data buffer containing flow entry's match values/masks
1712 * @entry_h: pointer to buffer that receives the new flow entry's handle
1713 */
1714int
1715ice_flow_add_entry(struct ice_hw *hw, enum ice_block blk, u64 prof_id,
1716 u64 entry_id, u16 vsi_handle, enum ice_flow_priority prio,
1717 void *data, u64 *entry_h)
1718{
1719 struct ice_flow_entry *e = NULL;
1720 struct ice_flow_prof *prof;
1721 int status;
1722
1723 /* No flow entry data is expected for RSS */
1724 if (!entry_h || (!data && blk != ICE_BLK_RSS))
1725 return -EINVAL;
1726
1727 if (!ice_is_vsi_valid(hw, vsi_handle))
1728 return -EINVAL;
1729
1730 mutex_lock(&hw->fl_profs_locks[blk]);
1731
1732 prof = ice_flow_find_prof_id(hw, blk, prof_id);
1733 if (!prof) {
1734 status = -ENOENT;
1735 } else {
1736 /* Allocate memory for the entry being added and associate
1737 * the VSI to the found flow profile
1738 */
1739 e = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*e), GFP_KERNEL);
1740 if (!e)
1741 status = -ENOMEM;
1742 else
1743 status = ice_flow_assoc_prof(hw, blk, prof, vsi_handle);
1744 }
1745
1746 mutex_unlock(&hw->fl_profs_locks[blk]);
1747 if (status)
1748 goto out;
1749
1750 e->id = entry_id;
1751 e->vsi_handle = vsi_handle;
1752 e->prof = prof;
1753 e->priority = prio;
1754
1755 switch (blk) {
1756 case ICE_BLK_FD:
1757 case ICE_BLK_RSS:
1758 break;
1759 default:
1760 status = -EOPNOTSUPP;
1761 goto out;
1762 }
1763
1764 mutex_lock(&prof->entries_lock);
1765 list_add(&e->l_entry, &prof->entries);
1766 mutex_unlock(&prof->entries_lock);
1767
1768 *entry_h = ICE_FLOW_ENTRY_HNDL(e);
1769
1770out:
1771 if (status)
1772 devm_kfree(ice_hw_to_dev(hw), e);
1773
1774 return status;
1775}
1776
1777/**
1778 * ice_flow_rem_entry - Remove a flow entry
1779 * @hw: pointer to the HW struct
1780 * @blk: classification stage
1781 * @entry_h: handle to the flow entry to be removed
1782 */
1783int ice_flow_rem_entry(struct ice_hw *hw, enum ice_block blk, u64 entry_h)
1784{
1785 struct ice_flow_entry *entry;
1786 struct ice_flow_prof *prof;
1787 int status = 0;
1788
1789 if (entry_h == ICE_FLOW_ENTRY_HANDLE_INVAL)
1790 return -EINVAL;
1791
1792 entry = ICE_FLOW_ENTRY_PTR(entry_h);
1793
1794 /* Retain the pointer to the flow profile as the entry will be freed */
1795 prof = entry->prof;
1796
1797 if (prof) {
1798 mutex_lock(&prof->entries_lock);
1799 status = ice_flow_rem_entry_sync(hw, blk, entry);
1800 mutex_unlock(&prof->entries_lock);
1801 }
1802
1803 return status;
1804}
1805
1806/**
1807 * ice_flow_set_fld_ext - specifies locations of field from entry's input buffer
1808 * @seg: packet segment the field being set belongs to
1809 * @fld: field to be set
1810 * @field_type: type of the field
1811 * @val_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of the value to match from
1812 * entry's input buffer
1813 * @mask_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of mask value from entry's
1814 * input buffer
1815 * @last_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of last/upper value from
1816 * entry's input buffer
1817 *
1818 * This helper function stores information of a field being matched, including
1819 * the type of the field and the locations of the value to match, the mask, and
1820 * the upper-bound value in the start of the input buffer for a flow entry.
1821 * This function should only be used for fixed-size data structures.
1822 *
1823 * This function also opportunistically determines the protocol headers to be
1824 * present based on the fields being set. Some fields cannot be used alone to
1825 * determine the protocol headers present. Sometimes, fields for particular
1826 * protocol headers are not matched. In those cases, the protocol headers
1827 * must be explicitly set.
1828 */
1829static void
1830ice_flow_set_fld_ext(struct ice_flow_seg_info *seg, enum ice_flow_field fld,
1831 enum ice_flow_fld_match_type field_type, u16 val_loc,
1832 u16 mask_loc, u16 last_loc)
1833{
1834 u64 bit = BIT_ULL(fld);
1835
1836 seg->match |= bit;
1837 if (field_type == ICE_FLOW_FLD_TYPE_RANGE)
1838 seg->range |= bit;
1839
1840 seg->fields[fld].type = field_type;
1841 seg->fields[fld].src.val = val_loc;
1842 seg->fields[fld].src.mask = mask_loc;
1843 seg->fields[fld].src.last = last_loc;
1844
1845 ICE_FLOW_SET_HDRS(seg, ice_flds_info[fld].hdr);
1846}
1847
1848/**
1849 * ice_flow_set_fld - specifies locations of field from entry's input buffer
1850 * @seg: packet segment the field being set belongs to
1851 * @fld: field to be set
1852 * @val_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of the value to match from
1853 * entry's input buffer
1854 * @mask_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of mask value from entry's
1855 * input buffer
1856 * @last_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of last/upper value from
1857 * entry's input buffer
1858 * @range: indicate if field being matched is to be in a range
1859 *
1860 * This function specifies the locations, in the form of byte offsets from the
1861 * start of the input buffer for a flow entry, from where the value to match,
1862 * the mask value, and upper value can be extracted. These locations are then
1863 * stored in the flow profile. When adding a flow entry associated with the
1864 * flow profile, these locations will be used to quickly extract the values and
1865 * create the content of a match entry. This function should only be used for
1866 * fixed-size data structures.
1867 */
1868void
1869ice_flow_set_fld(struct ice_flow_seg_info *seg, enum ice_flow_field fld,
1870 u16 val_loc, u16 mask_loc, u16 last_loc, bool range)
1871{
1872 enum ice_flow_fld_match_type t = range ?
1873 ICE_FLOW_FLD_TYPE_RANGE : ICE_FLOW_FLD_TYPE_REG;
1874
1875 ice_flow_set_fld_ext(seg, fld, t, val_loc, mask_loc, last_loc);
1876}
1877
1878/**
1879 * ice_flow_add_fld_raw - sets locations of a raw field from entry's input buf
1880 * @seg: packet segment the field being set belongs to
1881 * @off: offset of the raw field from the beginning of the segment in bytes
1882 * @len: length of the raw pattern to be matched
1883 * @val_loc: location of the value to match from entry's input buffer
1884 * @mask_loc: location of mask value from entry's input buffer
1885 *
1886 * This function specifies the offset of the raw field to be match from the
1887 * beginning of the specified packet segment, and the locations, in the form of
1888 * byte offsets from the start of the input buffer for a flow entry, from where
1889 * the value to match and the mask value to be extracted. These locations are
1890 * then stored in the flow profile. When adding flow entries to the associated
1891 * flow profile, these locations can be used to quickly extract the values to
1892 * create the content of a match entry. This function should only be used for
1893 * fixed-size data structures.
1894 */
1895void
1896ice_flow_add_fld_raw(struct ice_flow_seg_info *seg, u16 off, u8 len,
1897 u16 val_loc, u16 mask_loc)
1898{
1899 if (seg->raws_cnt < ICE_FLOW_SEG_RAW_FLD_MAX) {
1900 seg->raws[seg->raws_cnt].off = off;
1901 seg->raws[seg->raws_cnt].info.type = ICE_FLOW_FLD_TYPE_SIZE;
1902 seg->raws[seg->raws_cnt].info.src.val = val_loc;
1903 seg->raws[seg->raws_cnt].info.src.mask = mask_loc;
1904 /* The "last" field is used to store the length of the field */
1905 seg->raws[seg->raws_cnt].info.src.last = len;
1906 }
1907
1908 /* Overflows of "raws" will be handled as an error condition later in
1909 * the flow when this information is processed.
1910 */
1911 seg->raws_cnt++;
1912}
1913
1914/**
1915 * ice_flow_rem_vsi_prof - remove VSI from flow profile
1916 * @hw: pointer to the hardware structure
1917 * @vsi_handle: software VSI handle
1918 * @prof_id: unique ID to identify this flow profile
1919 *
1920 * This function removes the flow entries associated to the input
1921 * VSI handle and disassociate the VSI from the flow profile.
1922 */
1923int ice_flow_rem_vsi_prof(struct ice_hw *hw, u16 vsi_handle, u64 prof_id)
1924{
1925 struct ice_flow_prof *prof;
1926 int status = 0;
1927
1928 if (!ice_is_vsi_valid(hw, vsi_handle))
1929 return -EINVAL;
1930
1931 /* find flow profile pointer with input package block and profile ID */
1932 prof = ice_flow_find_prof_id(hw, ICE_BLK_FD, prof_id);
1933 if (!prof) {
1934 ice_debug(hw, ICE_DBG_PKG, "Cannot find flow profile id=%llu\n",
1935 prof_id);
1936 return -ENOENT;
1937 }
1938
1939 /* Remove all remaining flow entries before removing the flow profile */
1940 if (!list_empty(&prof->entries)) {
1941 struct ice_flow_entry *e, *t;
1942
1943 mutex_lock(&prof->entries_lock);
1944 list_for_each_entry_safe(e, t, &prof->entries, l_entry) {
1945 if (e->vsi_handle != vsi_handle)
1946 continue;
1947
1948 status = ice_flow_rem_entry_sync(hw, ICE_BLK_FD, e);
1949 if (status)
1950 break;
1951 }
1952 mutex_unlock(&prof->entries_lock);
1953 }
1954 if (status)
1955 return status;
1956
1957 /* disassociate the flow profile from sw VSI handle */
1958 status = ice_flow_disassoc_prof(hw, ICE_BLK_FD, prof, vsi_handle);
1959 if (status)
1960 ice_debug(hw, ICE_DBG_PKG, "ice_flow_disassoc_prof() failed with status=%d\n",
1961 status);
1962 return status;
1963}
1964
1965#define ICE_FLOW_RSS_SEG_HDR_L2_MASKS \
1966 (ICE_FLOW_SEG_HDR_ETH | ICE_FLOW_SEG_HDR_VLAN)
1967
1968#define ICE_FLOW_RSS_SEG_HDR_L3_MASKS \
1969 (ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_IPV6)
1970
1971#define ICE_FLOW_RSS_SEG_HDR_L4_MASKS \
1972 (ICE_FLOW_SEG_HDR_TCP | ICE_FLOW_SEG_HDR_UDP | ICE_FLOW_SEG_HDR_SCTP)
1973
1974#define ICE_FLOW_RSS_SEG_HDR_VAL_MASKS \
1975 (ICE_FLOW_RSS_SEG_HDR_L2_MASKS | \
1976 ICE_FLOW_RSS_SEG_HDR_L3_MASKS | \
1977 ICE_FLOW_RSS_SEG_HDR_L4_MASKS)
1978
1979/**
1980 * ice_flow_set_rss_seg_info - setup packet segments for RSS
1981 * @segs: pointer to the flow field segment(s)
1982 * @seg_cnt: segment count
1983 * @cfg: configure parameters
1984 *
1985 * Helper function to extract fields from hash bitmap and use flow
1986 * header value to set flow field segment for further use in flow
1987 * profile entry or removal.
1988 */
1989static int
1990ice_flow_set_rss_seg_info(struct ice_flow_seg_info *segs, u8 seg_cnt,
1991 const struct ice_rss_hash_cfg *cfg)
1992{
1993 struct ice_flow_seg_info *seg;
1994 u64 val;
1995 u16 i;
1996
1997 /* set inner most segment */
1998 seg = &segs[seg_cnt - 1];
1999
2000 for_each_set_bit(i, (const unsigned long *)&cfg->hash_flds,
2001 (u16)ICE_FLOW_FIELD_IDX_MAX)
2002 ice_flow_set_fld(seg, (enum ice_flow_field)i,
2003 ICE_FLOW_FLD_OFF_INVAL, ICE_FLOW_FLD_OFF_INVAL,
2004 ICE_FLOW_FLD_OFF_INVAL, false);
2005
2006 ICE_FLOW_SET_HDRS(seg, cfg->addl_hdrs);
2007
2008 /* set outer most header */
2009 if (cfg->hdr_type == ICE_RSS_INNER_HEADERS_W_OUTER_IPV4)
2010 segs[ICE_RSS_OUTER_HEADERS].hdrs |= ICE_FLOW_SEG_HDR_IPV4 |
2011 ICE_FLOW_SEG_HDR_IPV_OTHER;
2012 else if (cfg->hdr_type == ICE_RSS_INNER_HEADERS_W_OUTER_IPV6)
2013 segs[ICE_RSS_OUTER_HEADERS].hdrs |= ICE_FLOW_SEG_HDR_IPV6 |
2014 ICE_FLOW_SEG_HDR_IPV_OTHER;
2015
2016 if (seg->hdrs & ~ICE_FLOW_RSS_SEG_HDR_VAL_MASKS &
2017 ~ICE_FLOW_RSS_HDRS_INNER_MASK & ~ICE_FLOW_SEG_HDR_IPV_OTHER)
2018 return -EINVAL;
2019
2020 val = (u64)(seg->hdrs & ICE_FLOW_RSS_SEG_HDR_L3_MASKS);
2021 if (val && !is_power_of_2(val))
2022 return -EIO;
2023
2024 val = (u64)(seg->hdrs & ICE_FLOW_RSS_SEG_HDR_L4_MASKS);
2025 if (val && !is_power_of_2(val))
2026 return -EIO;
2027
2028 return 0;
2029}
2030
2031/**
2032 * ice_rem_vsi_rss_list - remove VSI from RSS list
2033 * @hw: pointer to the hardware structure
2034 * @vsi_handle: software VSI handle
2035 *
2036 * Remove the VSI from all RSS configurations in the list.
2037 */
2038void ice_rem_vsi_rss_list(struct ice_hw *hw, u16 vsi_handle)
2039{
2040 struct ice_rss_cfg *r, *tmp;
2041
2042 if (list_empty(&hw->rss_list_head))
2043 return;
2044
2045 mutex_lock(&hw->rss_locks);
2046 list_for_each_entry_safe(r, tmp, &hw->rss_list_head, l_entry)
2047 if (test_and_clear_bit(vsi_handle, r->vsis))
2048 if (bitmap_empty(r->vsis, ICE_MAX_VSI)) {
2049 list_del(&r->l_entry);
2050 devm_kfree(ice_hw_to_dev(hw), r);
2051 }
2052 mutex_unlock(&hw->rss_locks);
2053}
2054
2055/**
2056 * ice_rem_vsi_rss_cfg - remove RSS configurations associated with VSI
2057 * @hw: pointer to the hardware structure
2058 * @vsi_handle: software VSI handle
2059 *
2060 * This function will iterate through all flow profiles and disassociate
2061 * the VSI from that profile. If the flow profile has no VSIs it will
2062 * be removed.
2063 */
2064int ice_rem_vsi_rss_cfg(struct ice_hw *hw, u16 vsi_handle)
2065{
2066 const enum ice_block blk = ICE_BLK_RSS;
2067 struct ice_flow_prof *p, *t;
2068 int status = 0;
2069
2070 if (!ice_is_vsi_valid(hw, vsi_handle))
2071 return -EINVAL;
2072
2073 if (list_empty(&hw->fl_profs[blk]))
2074 return 0;
2075
2076 mutex_lock(&hw->rss_locks);
2077 list_for_each_entry_safe(p, t, &hw->fl_profs[blk], l_entry)
2078 if (test_bit(vsi_handle, p->vsis)) {
2079 status = ice_flow_disassoc_prof(hw, blk, p, vsi_handle);
2080 if (status)
2081 break;
2082
2083 if (bitmap_empty(p->vsis, ICE_MAX_VSI)) {
2084 status = ice_flow_rem_prof(hw, blk, p->id);
2085 if (status)
2086 break;
2087 }
2088 }
2089 mutex_unlock(&hw->rss_locks);
2090
2091 return status;
2092}
2093
2094/**
2095 * ice_get_rss_hdr_type - get a RSS profile's header type
2096 * @prof: RSS flow profile
2097 */
2098static enum ice_rss_cfg_hdr_type
2099ice_get_rss_hdr_type(struct ice_flow_prof *prof)
2100{
2101 if (prof->segs_cnt == ICE_FLOW_SEG_SINGLE) {
2102 return ICE_RSS_OUTER_HEADERS;
2103 } else if (prof->segs_cnt == ICE_FLOW_SEG_MAX) {
2104 const struct ice_flow_seg_info *s;
2105
2106 s = &prof->segs[ICE_RSS_OUTER_HEADERS];
2107 if (s->hdrs == ICE_FLOW_SEG_HDR_NONE)
2108 return ICE_RSS_INNER_HEADERS;
2109 if (s->hdrs & ICE_FLOW_SEG_HDR_IPV4)
2110 return ICE_RSS_INNER_HEADERS_W_OUTER_IPV4;
2111 if (s->hdrs & ICE_FLOW_SEG_HDR_IPV6)
2112 return ICE_RSS_INNER_HEADERS_W_OUTER_IPV6;
2113 }
2114
2115 return ICE_RSS_ANY_HEADERS;
2116}
2117
2118static bool
2119ice_rss_match_prof(struct ice_rss_cfg *r, struct ice_flow_prof *prof,
2120 enum ice_rss_cfg_hdr_type hdr_type)
2121{
2122 return (r->hash.hdr_type == hdr_type &&
2123 r->hash.hash_flds == prof->segs[prof->segs_cnt - 1].match &&
2124 r->hash.addl_hdrs == prof->segs[prof->segs_cnt - 1].hdrs);
2125}
2126
2127/**
2128 * ice_rem_rss_list - remove RSS configuration from list
2129 * @hw: pointer to the hardware structure
2130 * @vsi_handle: software VSI handle
2131 * @prof: pointer to flow profile
2132 *
2133 * Assumption: lock has already been acquired for RSS list
2134 */
2135static void
2136ice_rem_rss_list(struct ice_hw *hw, u16 vsi_handle, struct ice_flow_prof *prof)
2137{
2138 enum ice_rss_cfg_hdr_type hdr_type;
2139 struct ice_rss_cfg *r, *tmp;
2140
2141 /* Search for RSS hash fields associated to the VSI that match the
2142 * hash configurations associated to the flow profile. If found
2143 * remove from the RSS entry list of the VSI context and delete entry.
2144 */
2145 hdr_type = ice_get_rss_hdr_type(prof);
2146 list_for_each_entry_safe(r, tmp, &hw->rss_list_head, l_entry)
2147 if (ice_rss_match_prof(r, prof, hdr_type)) {
2148 clear_bit(vsi_handle, r->vsis);
2149 if (bitmap_empty(r->vsis, ICE_MAX_VSI)) {
2150 list_del(&r->l_entry);
2151 devm_kfree(ice_hw_to_dev(hw), r);
2152 }
2153 return;
2154 }
2155}
2156
2157/**
2158 * ice_add_rss_list - add RSS configuration to list
2159 * @hw: pointer to the hardware structure
2160 * @vsi_handle: software VSI handle
2161 * @prof: pointer to flow profile
2162 *
2163 * Assumption: lock has already been acquired for RSS list
2164 */
2165static int
2166ice_add_rss_list(struct ice_hw *hw, u16 vsi_handle, struct ice_flow_prof *prof)
2167{
2168 enum ice_rss_cfg_hdr_type hdr_type;
2169 struct ice_rss_cfg *r, *rss_cfg;
2170
2171 hdr_type = ice_get_rss_hdr_type(prof);
2172 list_for_each_entry(r, &hw->rss_list_head, l_entry)
2173 if (ice_rss_match_prof(r, prof, hdr_type)) {
2174 set_bit(vsi_handle, r->vsis);
2175 return 0;
2176 }
2177
2178 rss_cfg = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*rss_cfg),
2179 GFP_KERNEL);
2180 if (!rss_cfg)
2181 return -ENOMEM;
2182
2183 rss_cfg->hash.hash_flds = prof->segs[prof->segs_cnt - 1].match;
2184 rss_cfg->hash.addl_hdrs = prof->segs[prof->segs_cnt - 1].hdrs;
2185 rss_cfg->hash.hdr_type = hdr_type;
2186 rss_cfg->hash.symm = prof->symm;
2187 set_bit(vsi_handle, rss_cfg->vsis);
2188
2189 list_add_tail(&rss_cfg->l_entry, &hw->rss_list_head);
2190
2191 return 0;
2192}
2193
2194/**
2195 * ice_rss_config_xor_word - set the HSYMM registers for one input set word
2196 * @hw: pointer to the hardware structure
2197 * @prof_id: RSS hardware profile id
2198 * @src: the FV index used by the protocol's source field
2199 * @dst: the FV index used by the protocol's destination field
2200 *
2201 * Write to the HSYMM register with the index of @src FV the value of the @dst
2202 * FV index. This will tell the hardware to XOR HSYMM[src] with INSET[dst]
2203 * while calculating the RSS input set.
2204 */
2205static void
2206ice_rss_config_xor_word(struct ice_hw *hw, u8 prof_id, u8 src, u8 dst)
2207{
2208 u32 val, reg, bits_shift;
2209 u8 reg_idx;
2210
2211 reg_idx = src / GLQF_HSYMM_REG_SIZE;
2212 bits_shift = ((src % GLQF_HSYMM_REG_SIZE) << 3);
2213 val = dst | GLQF_HSYMM_ENABLE_BIT;
2214
2215 reg = rd32(hw, GLQF_HSYMM(prof_id, reg_idx));
2216 reg = (reg & ~(0xff << bits_shift)) | (val << bits_shift);
2217 wr32(hw, GLQF_HSYMM(prof_id, reg_idx), reg);
2218}
2219
2220/**
2221 * ice_rss_config_xor - set the symmetric registers for a profile's protocol
2222 * @hw: pointer to the hardware structure
2223 * @prof_id: RSS hardware profile id
2224 * @src: the FV index used by the protocol's source field
2225 * @dst: the FV index used by the protocol's destination field
2226 * @len: length of the source/destination fields in words
2227 */
2228static void
2229ice_rss_config_xor(struct ice_hw *hw, u8 prof_id, u8 src, u8 dst, u8 len)
2230{
2231 int fv_last_word =
2232 ICE_FLOW_SW_FIELD_VECTOR_MAX / ICE_FLOW_FV_EXTRACT_SZ - 1;
2233 int i;
2234
2235 for (i = 0; i < len; i++) {
2236 ice_rss_config_xor_word(hw, prof_id,
2237 /* Yes, field vector in GLQF_HSYMM and
2238 * GLQF_HINSET is inversed!
2239 */
2240 fv_last_word - (src + i),
2241 fv_last_word - (dst + i));
2242 ice_rss_config_xor_word(hw, prof_id,
2243 fv_last_word - (dst + i),
2244 fv_last_word - (src + i));
2245 }
2246}
2247
2248/**
2249 * ice_rss_set_symm - set the symmetric settings for an RSS profile
2250 * @hw: pointer to the hardware structure
2251 * @prof: pointer to flow profile
2252 *
2253 * The symmetric hash will result from XORing the protocol's fields with
2254 * indexes in GLQF_HSYMM and GLQF_HINSET. This function configures the profile's
2255 * GLQF_HSYMM registers.
2256 */
2257static void ice_rss_set_symm(struct ice_hw *hw, struct ice_flow_prof *prof)
2258{
2259 struct ice_prof_map *map;
2260 u8 prof_id, m;
2261
2262 mutex_lock(&hw->blk[ICE_BLK_RSS].es.prof_map_lock);
2263 map = ice_search_prof_id(hw, ICE_BLK_RSS, prof->id);
2264 if (map)
2265 prof_id = map->prof_id;
2266 mutex_unlock(&hw->blk[ICE_BLK_RSS].es.prof_map_lock);
2267
2268 if (!map)
2269 return;
2270
2271 /* clear to default */
2272 for (m = 0; m < GLQF_HSYMM_REG_PER_PROF; m++)
2273 wr32(hw, GLQF_HSYMM(prof_id, m), 0);
2274
2275 if (prof->symm) {
2276 struct ice_flow_seg_xtrct *ipv4_src, *ipv4_dst;
2277 struct ice_flow_seg_xtrct *ipv6_src, *ipv6_dst;
2278 struct ice_flow_seg_xtrct *sctp_src, *sctp_dst;
2279 struct ice_flow_seg_xtrct *tcp_src, *tcp_dst;
2280 struct ice_flow_seg_xtrct *udp_src, *udp_dst;
2281 struct ice_flow_seg_info *seg;
2282
2283 seg = &prof->segs[prof->segs_cnt - 1];
2284
2285 ipv4_src = &seg->fields[ICE_FLOW_FIELD_IDX_IPV4_SA].xtrct;
2286 ipv4_dst = &seg->fields[ICE_FLOW_FIELD_IDX_IPV4_DA].xtrct;
2287
2288 ipv6_src = &seg->fields[ICE_FLOW_FIELD_IDX_IPV6_SA].xtrct;
2289 ipv6_dst = &seg->fields[ICE_FLOW_FIELD_IDX_IPV6_DA].xtrct;
2290
2291 tcp_src = &seg->fields[ICE_FLOW_FIELD_IDX_TCP_SRC_PORT].xtrct;
2292 tcp_dst = &seg->fields[ICE_FLOW_FIELD_IDX_TCP_DST_PORT].xtrct;
2293
2294 udp_src = &seg->fields[ICE_FLOW_FIELD_IDX_UDP_SRC_PORT].xtrct;
2295 udp_dst = &seg->fields[ICE_FLOW_FIELD_IDX_UDP_DST_PORT].xtrct;
2296
2297 sctp_src = &seg->fields[ICE_FLOW_FIELD_IDX_SCTP_SRC_PORT].xtrct;
2298 sctp_dst = &seg->fields[ICE_FLOW_FIELD_IDX_SCTP_DST_PORT].xtrct;
2299
2300 /* xor IPv4 */
2301 if (ipv4_src->prot_id != 0 && ipv4_dst->prot_id != 0)
2302 ice_rss_config_xor(hw, prof_id,
2303 ipv4_src->idx, ipv4_dst->idx, 2);
2304
2305 /* xor IPv6 */
2306 if (ipv6_src->prot_id != 0 && ipv6_dst->prot_id != 0)
2307 ice_rss_config_xor(hw, prof_id,
2308 ipv6_src->idx, ipv6_dst->idx, 8);
2309
2310 /* xor TCP */
2311 if (tcp_src->prot_id != 0 && tcp_dst->prot_id != 0)
2312 ice_rss_config_xor(hw, prof_id,
2313 tcp_src->idx, tcp_dst->idx, 1);
2314
2315 /* xor UDP */
2316 if (udp_src->prot_id != 0 && udp_dst->prot_id != 0)
2317 ice_rss_config_xor(hw, prof_id,
2318 udp_src->idx, udp_dst->idx, 1);
2319
2320 /* xor SCTP */
2321 if (sctp_src->prot_id != 0 && sctp_dst->prot_id != 0)
2322 ice_rss_config_xor(hw, prof_id,
2323 sctp_src->idx, sctp_dst->idx, 1);
2324 }
2325}
2326
2327/**
2328 * ice_add_rss_cfg_sync - add an RSS configuration
2329 * @hw: pointer to the hardware structure
2330 * @vsi_handle: software VSI handle
2331 * @cfg: configure parameters
2332 *
2333 * Assumption: lock has already been acquired for RSS list
2334 */
2335static int
2336ice_add_rss_cfg_sync(struct ice_hw *hw, u16 vsi_handle,
2337 const struct ice_rss_hash_cfg *cfg)
2338{
2339 const enum ice_block blk = ICE_BLK_RSS;
2340 struct ice_flow_prof *prof = NULL;
2341 struct ice_flow_seg_info *segs;
2342 u8 segs_cnt;
2343 int status;
2344
2345 segs_cnt = (cfg->hdr_type == ICE_RSS_OUTER_HEADERS) ?
2346 ICE_FLOW_SEG_SINGLE : ICE_FLOW_SEG_MAX;
2347
2348 segs = kcalloc(segs_cnt, sizeof(*segs), GFP_KERNEL);
2349 if (!segs)
2350 return -ENOMEM;
2351
2352 /* Construct the packet segment info from the hashed fields */
2353 status = ice_flow_set_rss_seg_info(segs, segs_cnt, cfg);
2354 if (status)
2355 goto exit;
2356
2357 /* Search for a flow profile that has matching headers, hash fields,
2358 * symm and has the input VSI associated to it. If found, no further
2359 * operations required and exit.
2360 */
2361 prof = ice_flow_find_prof_conds(hw, blk, ICE_FLOW_RX, segs, segs_cnt,
2362 cfg->symm, vsi_handle,
2363 ICE_FLOW_FIND_PROF_CHK_FLDS |
2364 ICE_FLOW_FIND_PROF_CHK_SYMM |
2365 ICE_FLOW_FIND_PROF_CHK_VSI);
2366 if (prof)
2367 goto exit;
2368
2369 /* Check if a flow profile exists with the same protocol headers and
2370 * associated with the input VSI. If so disassociate the VSI from
2371 * this profile. The VSI will be added to a new profile created with
2372 * the protocol header and new hash field configuration.
2373 */
2374 prof = ice_flow_find_prof_conds(hw, blk, ICE_FLOW_RX, segs, segs_cnt,
2375 cfg->symm, vsi_handle,
2376 ICE_FLOW_FIND_PROF_CHK_VSI);
2377 if (prof) {
2378 status = ice_flow_disassoc_prof(hw, blk, prof, vsi_handle);
2379 if (!status)
2380 ice_rem_rss_list(hw, vsi_handle, prof);
2381 else
2382 goto exit;
2383
2384 /* Remove profile if it has no VSIs associated */
2385 if (bitmap_empty(prof->vsis, ICE_MAX_VSI)) {
2386 status = ice_flow_rem_prof(hw, blk, prof->id);
2387 if (status)
2388 goto exit;
2389 }
2390 }
2391
2392 /* Search for a profile that has the same match fields and symmetric
2393 * setting. If this exists then associate the VSI to this profile.
2394 */
2395 prof = ice_flow_find_prof_conds(hw, blk, ICE_FLOW_RX, segs, segs_cnt,
2396 cfg->symm, vsi_handle,
2397 ICE_FLOW_FIND_PROF_CHK_SYMM |
2398 ICE_FLOW_FIND_PROF_CHK_FLDS);
2399 if (prof) {
2400 status = ice_flow_assoc_prof(hw, blk, prof, vsi_handle);
2401 if (!status)
2402 status = ice_add_rss_list(hw, vsi_handle, prof);
2403 goto exit;
2404 }
2405
2406 /* Create a new flow profile with packet segment information. */
2407 status = ice_flow_add_prof(hw, blk, ICE_FLOW_RX,
2408 segs, segs_cnt, cfg->symm, &prof);
2409 if (status)
2410 goto exit;
2411
2412 prof->symm = cfg->symm;
2413 ice_rss_set_symm(hw, prof);
2414 status = ice_flow_assoc_prof(hw, blk, prof, vsi_handle);
2415 /* If association to a new flow profile failed then this profile can
2416 * be removed.
2417 */
2418 if (status) {
2419 ice_flow_rem_prof(hw, blk, prof->id);
2420 goto exit;
2421 }
2422
2423 status = ice_add_rss_list(hw, vsi_handle, prof);
2424
2425exit:
2426 kfree(segs);
2427 return status;
2428}
2429
2430/**
2431 * ice_add_rss_cfg - add an RSS configuration with specified hashed fields
2432 * @hw: pointer to the hardware structure
2433 * @vsi: VSI to add the RSS configuration to
2434 * @cfg: configure parameters
2435 *
2436 * This function will generate a flow profile based on fields associated with
2437 * the input fields to hash on, the flow type and use the VSI number to add
2438 * a flow entry to the profile.
2439 */
2440int
2441ice_add_rss_cfg(struct ice_hw *hw, struct ice_vsi *vsi,
2442 const struct ice_rss_hash_cfg *cfg)
2443{
2444 struct ice_rss_hash_cfg local_cfg;
2445 u16 vsi_handle;
2446 int status;
2447
2448 if (!vsi)
2449 return -EINVAL;
2450
2451 vsi_handle = vsi->idx;
2452 if (!ice_is_vsi_valid(hw, vsi_handle) ||
2453 !cfg || cfg->hdr_type > ICE_RSS_ANY_HEADERS ||
2454 cfg->hash_flds == ICE_HASH_INVALID)
2455 return -EINVAL;
2456
2457 mutex_lock(&hw->rss_locks);
2458 local_cfg = *cfg;
2459 if (cfg->hdr_type < ICE_RSS_ANY_HEADERS) {
2460 status = ice_add_rss_cfg_sync(hw, vsi_handle, &local_cfg);
2461 } else {
2462 local_cfg.hdr_type = ICE_RSS_OUTER_HEADERS;
2463 status = ice_add_rss_cfg_sync(hw, vsi_handle, &local_cfg);
2464 if (!status) {
2465 local_cfg.hdr_type = ICE_RSS_INNER_HEADERS;
2466 status = ice_add_rss_cfg_sync(hw, vsi_handle,
2467 &local_cfg);
2468 }
2469 }
2470 mutex_unlock(&hw->rss_locks);
2471
2472 return status;
2473}
2474
2475/**
2476 * ice_rem_rss_cfg_sync - remove an existing RSS configuration
2477 * @hw: pointer to the hardware structure
2478 * @vsi_handle: software VSI handle
2479 * @cfg: configure parameters
2480 *
2481 * Assumption: lock has already been acquired for RSS list
2482 */
2483static int
2484ice_rem_rss_cfg_sync(struct ice_hw *hw, u16 vsi_handle,
2485 const struct ice_rss_hash_cfg *cfg)
2486{
2487 const enum ice_block blk = ICE_BLK_RSS;
2488 struct ice_flow_seg_info *segs;
2489 struct ice_flow_prof *prof;
2490 u8 segs_cnt;
2491 int status;
2492
2493 segs_cnt = (cfg->hdr_type == ICE_RSS_OUTER_HEADERS) ?
2494 ICE_FLOW_SEG_SINGLE : ICE_FLOW_SEG_MAX;
2495 segs = kcalloc(segs_cnt, sizeof(*segs), GFP_KERNEL);
2496 if (!segs)
2497 return -ENOMEM;
2498
2499 /* Construct the packet segment info from the hashed fields */
2500 status = ice_flow_set_rss_seg_info(segs, segs_cnt, cfg);
2501 if (status)
2502 goto out;
2503
2504 prof = ice_flow_find_prof_conds(hw, blk, ICE_FLOW_RX, segs, segs_cnt,
2505 cfg->symm, vsi_handle,
2506 ICE_FLOW_FIND_PROF_CHK_FLDS);
2507 if (!prof) {
2508 status = -ENOENT;
2509 goto out;
2510 }
2511
2512 status = ice_flow_disassoc_prof(hw, blk, prof, vsi_handle);
2513 if (status)
2514 goto out;
2515
2516 /* Remove RSS configuration from VSI context before deleting
2517 * the flow profile.
2518 */
2519 ice_rem_rss_list(hw, vsi_handle, prof);
2520
2521 if (bitmap_empty(prof->vsis, ICE_MAX_VSI))
2522 status = ice_flow_rem_prof(hw, blk, prof->id);
2523
2524out:
2525 kfree(segs);
2526 return status;
2527}
2528
2529/**
2530 * ice_rem_rss_cfg - remove an existing RSS config with matching hashed fields
2531 * @hw: pointer to the hardware structure
2532 * @vsi_handle: software VSI handle
2533 * @cfg: configure parameters
2534 *
2535 * This function will lookup the flow profile based on the input
2536 * hash field bitmap, iterate through the profile entry list of
2537 * that profile and find entry associated with input VSI to be
2538 * removed. Calls are made to underlying flow apis which will in
2539 * turn build or update buffers for RSS XLT1 section.
2540 */
2541int
2542ice_rem_rss_cfg(struct ice_hw *hw, u16 vsi_handle,
2543 const struct ice_rss_hash_cfg *cfg)
2544{
2545 struct ice_rss_hash_cfg local_cfg;
2546 int status;
2547
2548 if (!ice_is_vsi_valid(hw, vsi_handle) ||
2549 !cfg || cfg->hdr_type > ICE_RSS_ANY_HEADERS ||
2550 cfg->hash_flds == ICE_HASH_INVALID)
2551 return -EINVAL;
2552
2553 mutex_lock(&hw->rss_locks);
2554 local_cfg = *cfg;
2555 if (cfg->hdr_type < ICE_RSS_ANY_HEADERS) {
2556 status = ice_rem_rss_cfg_sync(hw, vsi_handle, &local_cfg);
2557 } else {
2558 local_cfg.hdr_type = ICE_RSS_OUTER_HEADERS;
2559 status = ice_rem_rss_cfg_sync(hw, vsi_handle, &local_cfg);
2560 if (!status) {
2561 local_cfg.hdr_type = ICE_RSS_INNER_HEADERS;
2562 status = ice_rem_rss_cfg_sync(hw, vsi_handle,
2563 &local_cfg);
2564 }
2565 }
2566 mutex_unlock(&hw->rss_locks);
2567
2568 return status;
2569}
2570
2571/* Mapping of AVF hash bit fields to an L3-L4 hash combination.
2572 * As the ice_flow_avf_hdr_field represent individual bit shifts in a hash,
2573 * convert its values to their appropriate flow L3, L4 values.
2574 */
2575#define ICE_FLOW_AVF_RSS_IPV4_MASKS \
2576 (BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_OTHER) | \
2577 BIT_ULL(ICE_AVF_FLOW_FIELD_FRAG_IPV4))
2578#define ICE_FLOW_AVF_RSS_TCP_IPV4_MASKS \
2579 (BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_TCP_SYN_NO_ACK) | \
2580 BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_TCP))
2581#define ICE_FLOW_AVF_RSS_UDP_IPV4_MASKS \
2582 (BIT_ULL(ICE_AVF_FLOW_FIELD_UNICAST_IPV4_UDP) | \
2583 BIT_ULL(ICE_AVF_FLOW_FIELD_MULTICAST_IPV4_UDP) | \
2584 BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_UDP))
2585#define ICE_FLOW_AVF_RSS_ALL_IPV4_MASKS \
2586 (ICE_FLOW_AVF_RSS_TCP_IPV4_MASKS | ICE_FLOW_AVF_RSS_UDP_IPV4_MASKS | \
2587 ICE_FLOW_AVF_RSS_IPV4_MASKS | BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_SCTP))
2588
2589#define ICE_FLOW_AVF_RSS_IPV6_MASKS \
2590 (BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_OTHER) | \
2591 BIT_ULL(ICE_AVF_FLOW_FIELD_FRAG_IPV6))
2592#define ICE_FLOW_AVF_RSS_UDP_IPV6_MASKS \
2593 (BIT_ULL(ICE_AVF_FLOW_FIELD_UNICAST_IPV6_UDP) | \
2594 BIT_ULL(ICE_AVF_FLOW_FIELD_MULTICAST_IPV6_UDP) | \
2595 BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_UDP))
2596#define ICE_FLOW_AVF_RSS_TCP_IPV6_MASKS \
2597 (BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_TCP_SYN_NO_ACK) | \
2598 BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_TCP))
2599#define ICE_FLOW_AVF_RSS_ALL_IPV6_MASKS \
2600 (ICE_FLOW_AVF_RSS_TCP_IPV6_MASKS | ICE_FLOW_AVF_RSS_UDP_IPV6_MASKS | \
2601 ICE_FLOW_AVF_RSS_IPV6_MASKS | BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_SCTP))
2602
2603/**
2604 * ice_add_avf_rss_cfg - add an RSS configuration for AVF driver
2605 * @hw: pointer to the hardware structure
2606 * @vsi: VF's VSI
2607 * @avf_hash: hash bit fields (ICE_AVF_FLOW_FIELD_*) to configure
2608 *
2609 * This function will take the hash bitmap provided by the AVF driver via a
2610 * message, convert it to ICE-compatible values, and configure RSS flow
2611 * profiles.
2612 */
2613int ice_add_avf_rss_cfg(struct ice_hw *hw, struct ice_vsi *vsi, u64 avf_hash)
2614{
2615 struct ice_rss_hash_cfg hcfg;
2616 u16 vsi_handle;
2617 int status = 0;
2618 u64 hash_flds;
2619
2620 if (!vsi)
2621 return -EINVAL;
2622
2623 vsi_handle = vsi->idx;
2624 if (avf_hash == ICE_AVF_FLOW_FIELD_INVALID ||
2625 !ice_is_vsi_valid(hw, vsi_handle))
2626 return -EINVAL;
2627
2628 /* Make sure no unsupported bits are specified */
2629 if (avf_hash & ~(ICE_FLOW_AVF_RSS_ALL_IPV4_MASKS |
2630 ICE_FLOW_AVF_RSS_ALL_IPV6_MASKS))
2631 return -EIO;
2632
2633 hash_flds = avf_hash;
2634
2635 /* Always create an L3 RSS configuration for any L4 RSS configuration */
2636 if (hash_flds & ICE_FLOW_AVF_RSS_ALL_IPV4_MASKS)
2637 hash_flds |= ICE_FLOW_AVF_RSS_IPV4_MASKS;
2638
2639 if (hash_flds & ICE_FLOW_AVF_RSS_ALL_IPV6_MASKS)
2640 hash_flds |= ICE_FLOW_AVF_RSS_IPV6_MASKS;
2641
2642 /* Create the corresponding RSS configuration for each valid hash bit */
2643 while (hash_flds) {
2644 u64 rss_hash = ICE_HASH_INVALID;
2645
2646 if (hash_flds & ICE_FLOW_AVF_RSS_ALL_IPV4_MASKS) {
2647 if (hash_flds & ICE_FLOW_AVF_RSS_IPV4_MASKS) {
2648 rss_hash = ICE_FLOW_HASH_IPV4;
2649 hash_flds &= ~ICE_FLOW_AVF_RSS_IPV4_MASKS;
2650 } else if (hash_flds &
2651 ICE_FLOW_AVF_RSS_TCP_IPV4_MASKS) {
2652 rss_hash = ICE_FLOW_HASH_IPV4 |
2653 ICE_FLOW_HASH_TCP_PORT;
2654 hash_flds &= ~ICE_FLOW_AVF_RSS_TCP_IPV4_MASKS;
2655 } else if (hash_flds &
2656 ICE_FLOW_AVF_RSS_UDP_IPV4_MASKS) {
2657 rss_hash = ICE_FLOW_HASH_IPV4 |
2658 ICE_FLOW_HASH_UDP_PORT;
2659 hash_flds &= ~ICE_FLOW_AVF_RSS_UDP_IPV4_MASKS;
2660 } else if (hash_flds &
2661 BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_SCTP)) {
2662 rss_hash = ICE_FLOW_HASH_IPV4 |
2663 ICE_FLOW_HASH_SCTP_PORT;
2664 hash_flds &=
2665 ~BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_SCTP);
2666 }
2667 } else if (hash_flds & ICE_FLOW_AVF_RSS_ALL_IPV6_MASKS) {
2668 if (hash_flds & ICE_FLOW_AVF_RSS_IPV6_MASKS) {
2669 rss_hash = ICE_FLOW_HASH_IPV6;
2670 hash_flds &= ~ICE_FLOW_AVF_RSS_IPV6_MASKS;
2671 } else if (hash_flds &
2672 ICE_FLOW_AVF_RSS_TCP_IPV6_MASKS) {
2673 rss_hash = ICE_FLOW_HASH_IPV6 |
2674 ICE_FLOW_HASH_TCP_PORT;
2675 hash_flds &= ~ICE_FLOW_AVF_RSS_TCP_IPV6_MASKS;
2676 } else if (hash_flds &
2677 ICE_FLOW_AVF_RSS_UDP_IPV6_MASKS) {
2678 rss_hash = ICE_FLOW_HASH_IPV6 |
2679 ICE_FLOW_HASH_UDP_PORT;
2680 hash_flds &= ~ICE_FLOW_AVF_RSS_UDP_IPV6_MASKS;
2681 } else if (hash_flds &
2682 BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_SCTP)) {
2683 rss_hash = ICE_FLOW_HASH_IPV6 |
2684 ICE_FLOW_HASH_SCTP_PORT;
2685 hash_flds &=
2686 ~BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_SCTP);
2687 }
2688 }
2689
2690 if (rss_hash == ICE_HASH_INVALID)
2691 return -EIO;
2692
2693 hcfg.addl_hdrs = ICE_FLOW_SEG_HDR_NONE;
2694 hcfg.hash_flds = rss_hash;
2695 hcfg.hdr_type = ICE_RSS_ANY_HEADERS;
2696 hcfg.symm = false;
2697 status = ice_add_rss_cfg(hw, vsi, &hcfg);
2698 if (status)
2699 break;
2700 }
2701
2702 return status;
2703}
2704
2705static bool rss_cfg_symm_valid(u64 hfld)
2706{
2707 return !((!!(hfld & ICE_FLOW_HASH_FLD_IPV4_SA) ^
2708 !!(hfld & ICE_FLOW_HASH_FLD_IPV4_DA)) ||
2709 (!!(hfld & ICE_FLOW_HASH_FLD_IPV6_SA) ^
2710 !!(hfld & ICE_FLOW_HASH_FLD_IPV6_DA)) ||
2711 (!!(hfld & ICE_FLOW_HASH_FLD_TCP_SRC_PORT) ^
2712 !!(hfld & ICE_FLOW_HASH_FLD_TCP_DST_PORT)) ||
2713 (!!(hfld & ICE_FLOW_HASH_FLD_UDP_SRC_PORT) ^
2714 !!(hfld & ICE_FLOW_HASH_FLD_UDP_DST_PORT)) ||
2715 (!!(hfld & ICE_FLOW_HASH_FLD_SCTP_SRC_PORT) ^
2716 !!(hfld & ICE_FLOW_HASH_FLD_SCTP_DST_PORT)));
2717}
2718
2719/**
2720 * ice_set_rss_cfg_symm - set symmtery for all VSI's RSS configurations
2721 * @hw: pointer to the hardware structure
2722 * @vsi: VSI to set/unset Symmetric RSS
2723 * @symm: TRUE to set Symmetric RSS hashing
2724 */
2725int ice_set_rss_cfg_symm(struct ice_hw *hw, struct ice_vsi *vsi, bool symm)
2726{
2727 struct ice_rss_hash_cfg local;
2728 struct ice_rss_cfg *r, *tmp;
2729 u16 vsi_handle = vsi->idx;
2730 int status = 0;
2731
2732 if (!ice_is_vsi_valid(hw, vsi_handle))
2733 return -EINVAL;
2734
2735 mutex_lock(&hw->rss_locks);
2736 list_for_each_entry_safe(r, tmp, &hw->rss_list_head, l_entry) {
2737 if (test_bit(vsi_handle, r->vsis) && r->hash.symm != symm) {
2738 local = r->hash;
2739 local.symm = symm;
2740 if (symm && !rss_cfg_symm_valid(r->hash.hash_flds))
2741 continue;
2742
2743 status = ice_add_rss_cfg_sync(hw, vsi_handle, &local);
2744 if (status)
2745 break;
2746 }
2747 }
2748 mutex_unlock(&hw->rss_locks);
2749
2750 return status;
2751}
2752
2753/**
2754 * ice_replay_rss_cfg - replay RSS configurations associated with VSI
2755 * @hw: pointer to the hardware structure
2756 * @vsi_handle: software VSI handle
2757 */
2758int ice_replay_rss_cfg(struct ice_hw *hw, u16 vsi_handle)
2759{
2760 struct ice_rss_cfg *r;
2761 int status = 0;
2762
2763 if (!ice_is_vsi_valid(hw, vsi_handle))
2764 return -EINVAL;
2765
2766 mutex_lock(&hw->rss_locks);
2767 list_for_each_entry(r, &hw->rss_list_head, l_entry) {
2768 if (test_bit(vsi_handle, r->vsis)) {
2769 status = ice_add_rss_cfg_sync(hw, vsi_handle, &r->hash);
2770 if (status)
2771 break;
2772 }
2773 }
2774 mutex_unlock(&hw->rss_locks);
2775
2776 return status;
2777}
2778
2779/**
2780 * ice_get_rss_cfg - returns hashed fields for the given header types
2781 * @hw: pointer to the hardware structure
2782 * @vsi_handle: software VSI handle
2783 * @hdrs: protocol header type
2784 * @symm: whether the RSS is symmetric (bool, output)
2785 *
2786 * This function will return the match fields of the first instance of flow
2787 * profile having the given header types and containing input VSI
2788 */
2789u64 ice_get_rss_cfg(struct ice_hw *hw, u16 vsi_handle, u32 hdrs, bool *symm)
2790{
2791 u64 rss_hash = ICE_HASH_INVALID;
2792 struct ice_rss_cfg *r;
2793
2794 /* verify if the protocol header is non zero and VSI is valid */
2795 if (hdrs == ICE_FLOW_SEG_HDR_NONE || !ice_is_vsi_valid(hw, vsi_handle))
2796 return ICE_HASH_INVALID;
2797
2798 mutex_lock(&hw->rss_locks);
2799 list_for_each_entry(r, &hw->rss_list_head, l_entry)
2800 if (test_bit(vsi_handle, r->vsis) &&
2801 r->hash.addl_hdrs == hdrs) {
2802 rss_hash = r->hash.hash_flds;
2803 *symm = r->hash.symm;
2804 break;
2805 }
2806 mutex_unlock(&hw->rss_locks);
2807
2808 return rss_hash;
2809}
1// SPDX-License-Identifier: GPL-2.0
2/* Copyright (c) 2019, Intel Corporation. */
3
4#include "ice_common.h"
5#include "ice_flow.h"
6#include <net/gre.h>
7
8/* Describe properties of a protocol header field */
9struct 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 */
14};
15
16#define ICE_FLOW_FLD_INFO(_hdr, _offset_bytes, _size_bytes) { \
17 .hdr = _hdr, \
18 .off = (_offset_bytes) * BITS_PER_BYTE, \
19 .size = (_size_bytes) * BITS_PER_BYTE, \
20 .mask = 0, \
21}
22
23#define ICE_FLOW_FLD_INFO_MSK(_hdr, _offset_bytes, _size_bytes, _mask) { \
24 .hdr = _hdr, \
25 .off = (_offset_bytes) * BITS_PER_BYTE, \
26 .size = (_size_bytes) * BITS_PER_BYTE, \
27 .mask = _mask, \
28}
29
30/* Table containing properties of supported protocol header fields */
31static const
32struct ice_flow_field_info ice_flds_info[ICE_FLOW_FIELD_IDX_MAX] = {
33 /* Ether */
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)),
44 /* IPv4 / IPv6 */
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)),
65 /* Transport */
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),
80 /* ARP */
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)),
91 /* ICMP */
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),
96 /* GRE */
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)),
100 /* GTP */
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),
109 0x3f00),
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)),
114 /* PPPoE */
115 /* ICE_FLOW_FIELD_IDX_PPPOE_SESS_ID */
116 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_PPPOE, 2, sizeof(__be16)),
117 /* PFCP */
118 /* ICE_FLOW_FIELD_IDX_PFCP_SEID */
119 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_PFCP_SESSION, 12, sizeof(__be64)),
120 /* L2TPv3 */
121 /* ICE_FLOW_FIELD_IDX_L2TPV3_SESS_ID */
122 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_L2TPV3, 0, sizeof(__be32)),
123 /* ESP */
124 /* ICE_FLOW_FIELD_IDX_ESP_SPI */
125 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ESP, 0, sizeof(__be32)),
126 /* AH */
127 /* ICE_FLOW_FIELD_IDX_AH_SPI */
128 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_AH, 4, sizeof(__be32)),
129 /* NAT_T_ESP */
130 /* ICE_FLOW_FIELD_IDX_NAT_T_ESP_SPI */
131 ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_NAT_T_ESP, 8, sizeof(__be32)),
132};
133
134/* Bitmaps indicating relevant packet types for a particular protocol header
135 *
136 * Packet types for packets with an Outer/First/Single MAC header
137 */
138static 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,
147};
148
149/* Packet types for packets with an Innermost/Last MAC VLAN header */
150static const u32 ice_ptypes_macvlan_il[] = {
151 0x00000000, 0xBC000000, 0x000001DF, 0xF0000000,
152 0x0000077E, 0x00000000, 0x00000000, 0x00000000,
153 0x00000000, 0x00000000, 0x00000000, 0x00000000,
154 0x00000000, 0x00000000, 0x00000000, 0x00000000,
155 0x00000000, 0x00000000, 0x00000000, 0x00000000,
156 0x00000000, 0x00000000, 0x00000000, 0x00000000,
157 0x00000000, 0x00000000, 0x00000000, 0x00000000,
158 0x00000000, 0x00000000, 0x00000000, 0x00000000,
159};
160
161/* Packet types for packets with an Outer/First/Single IPv4 header, does NOT
162 * include IPv4 other PTYPEs
163 */
164static 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,
173};
174
175/* Packet types for packets with an Outer/First/Single IPv4 header, includes
176 * IPv4 other PTYPEs
177 */
178static 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,
187};
188
189/* Packet types for packets with an Innermost/Last IPv4 header */
190static 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,
199};
200
201/* Packet types for packets with an Outer/First/Single IPv6 header, does NOT
202 * include IPv6 other PTYPEs
203 */
204static 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,
213};
214
215/* Packet types for packets with an Outer/First/Single IPv6 header, includes
216 * IPv6 other PTYPEs
217 */
218static 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,
227};
228
229/* Packet types for packets with an Innermost/Last IPv6 header */
230static 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,
239};
240
241/* Packet types for packets with an Outer/First/Single IPv4 header - no L4 */
242static 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,
251};
252
253/* Packet types for packets with an Outermost/First ARP header */
254static 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,
263};
264
265/* Packet types for packets with an Innermost/Last IPv4 header - no L4 */
266static 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,
275};
276
277/* Packet types for packets with an Outer/First/Single IPv6 header - no L4 */
278static 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,
287};
288
289/* Packet types for packets with an Innermost/Last IPv6 header - no L4 */
290static 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,
299};
300
301/* UDP Packet types for non-tunneled packets or tunneled
302 * packets with inner UDP.
303 */
304static 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,
313};
314
315/* Packet types for packets with an Innermost/Last TCP header */
316static 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,
325};
326
327/* Packet types for packets with an Innermost/Last SCTP header */
328static 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,
337};
338
339/* Packet types for packets with an Outermost/First ICMP header */
340static 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,
349};
350
351/* Packet types for packets with an Innermost/Last ICMP header */
352static 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,
361};
362
363/* Packet types for packets with an Outermost/First GRE header */
364static 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,
373};
374
375/* Packet types for packets with an Innermost/Last MAC header */
376static 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,
385};
386
387/* Packet types for GTPC */
388static 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,
397};
398
399/* Packet types for GTPC with TEID */
400static 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,
409};
410
411/* Packet types for GTPU */
412static 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 },
433};
434
435static 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 },
456};
457
458static 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 },
479};
480
481static 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,
490};
491
492/* Packet types for PPPoE */
493static 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,
502};
503
504/* Packet types for packets with PFCP NODE header */
505static 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,
514};
515
516/* Packet types for packets with PFCP SESSION header */
517static 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,
526};
527
528/* Packet types for L2TPv3 */
529static 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,
538};
539
540/* Packet types for ESP */
541static 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,
550};
551
552/* Packet types for AH */
553static 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,
562};
563
564/* Packet types for packets with NAT_T ESP header */
565static 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,
574};
575
576static 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,
585};
586
587/* Manage parameters and info. used during the creation of a flow profile */
588struct ice_flow_prof_params {
589 enum ice_block blk;
590 u16 entry_length; /* # of bytes formatted entry will require */
591 u8 es_cnt;
592 struct ice_flow_prof *prof;
593
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.
596 */
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;
600 u16 attr_cnt;
601
602 u16 mask[ICE_MAX_FV_WORDS];
603 DECLARE_BITMAP(ptypes, ICE_FLOW_PTYPE_MAX);
604};
605
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)
612
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)
621
622/**
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
626 */
627static int ice_flow_val_hdrs(struct ice_flow_seg_info *segs, u8 segs_cnt)
628{
629 u8 i;
630
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))
635 return -EINVAL;
636
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))
640 return -EINVAL;
641 }
642
643 return 0;
644}
645
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
656
657/**
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
661 */
662static u16 ice_flow_calc_seg_sz(struct ice_flow_prof_params *params, u8 seg)
663{
664 u16 sz;
665
666 /* L2 headers */
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;
669
670 /* L3 headers */
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 */
679 return 0;
680
681 /* L4 headers */
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;
690
691 return sz;
692}
693
694/**
695 * ice_flow_proc_seg_hdrs - process protocol headers present in pkt segments
696 * @params: information about the flow to be processed
697 *
698 * This function identifies the packet types associated with the protocol
699 * headers being present in packet segments of the specified flow profile.
700 */
701static int ice_flow_proc_seg_hdrs(struct ice_flow_prof_params *params)
702{
703 struct ice_flow_prof *prof;
704 u8 i;
705
706 memset(params->ptypes, 0xff, sizeof(params->ptypes));
707
708 prof = params->prof;
709
710 for (i = 0; i < params->prof->segs_cnt; i++) {
711 const unsigned long *src;
712 u32 hdrs;
713
714 hdrs = prof->segs[i].hdrs;
715
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,
720 ICE_FLOW_PTYPE_MAX);
721 }
722
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,
726 ICE_FLOW_PTYPE_MAX);
727 }
728
729 if (!i && hdrs & ICE_FLOW_SEG_HDR_ARP) {
730 bitmap_and(params->ptypes, params->ptypes,
731 (const unsigned long *)ice_ptypes_arp_of,
732 ICE_FLOW_PTYPE_MAX);
733 }
734
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,
740 ICE_FLOW_PTYPE_MAX);
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,
746 ICE_FLOW_PTYPE_MAX);
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,
752 ICE_FLOW_PTYPE_MAX);
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,
757 ICE_FLOW_PTYPE_MAX);
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,
763 ICE_FLOW_PTYPE_MAX);
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,
768 ICE_FLOW_PTYPE_MAX);
769 }
770
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,
774 ICE_FLOW_PTYPE_MAX);
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,
778 ICE_FLOW_PTYPE_MAX);
779 } else {
780 src = (const unsigned long *)ice_ptypes_pppoe;
781 bitmap_andnot(params->ptypes, params->ptypes, src,
782 ICE_FLOW_PTYPE_MAX);
783 }
784
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,
788 ICE_FLOW_PTYPE_MAX);
789 } else if (hdrs & ICE_FLOW_SEG_HDR_TCP) {
790 bitmap_and(params->ptypes, params->ptypes,
791 (const unsigned long *)ice_ptypes_tcp_il,
792 ICE_FLOW_PTYPE_MAX);
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,
796 ICE_FLOW_PTYPE_MAX);
797 }
798
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,
803 ICE_FLOW_PTYPE_MAX);
804 } else if (hdrs & ICE_FLOW_SEG_HDR_GRE) {
805 if (!i) {
806 src = (const unsigned long *)ice_ptypes_gre_of;
807 bitmap_and(params->ptypes, params->ptypes,
808 src, ICE_FLOW_PTYPE_MAX);
809 }
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,
813 ICE_FLOW_PTYPE_MAX);
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,
817 ICE_FLOW_PTYPE_MAX);
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,
821 ICE_FLOW_PTYPE_MAX);
822
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,
829 ICE_FLOW_PTYPE_MAX);
830
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,
837 ICE_FLOW_PTYPE_MAX);
838
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,
845 ICE_FLOW_PTYPE_MAX);
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,
849 ICE_FLOW_PTYPE_MAX);
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,
853 ICE_FLOW_PTYPE_MAX);
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,
857 ICE_FLOW_PTYPE_MAX);
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,
861 ICE_FLOW_PTYPE_MAX);
862 }
863
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;
867 else
868 src = (const unsigned long *)ice_ptypes_pfcp_session;
869
870 bitmap_and(params->ptypes, params->ptypes, src,
871 ICE_FLOW_PTYPE_MAX);
872 } else {
873 src = (const unsigned long *)ice_ptypes_pfcp_node;
874 bitmap_andnot(params->ptypes, params->ptypes, src,
875 ICE_FLOW_PTYPE_MAX);
876
877 src = (const unsigned long *)ice_ptypes_pfcp_session;
878 bitmap_andnot(params->ptypes, params->ptypes, src,
879 ICE_FLOW_PTYPE_MAX);
880 }
881 }
882
883 return 0;
884}
885
886/**
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
893 *
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.
897 */
898static int
899ice_flow_xtract_fld(struct ice_hw *hw, struct ice_flow_prof_params *params,
900 u8 seg, enum ice_flow_field fld, u64 match)
901{
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;
907 u16 sib_mask = 0;
908 u16 mask;
909 u16 off;
910
911 flds = params->prof->segs[seg].fields;
912
913 switch (fld) {
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;
919 break;
920 case ICE_FLOW_FIELD_IDX_ETH_TYPE:
921 prot_id = seg == 0 ? ICE_PROT_ETYPE_OL : ICE_PROT_ETYPE_IL;
922 break;
923 case ICE_FLOW_FIELD_IDX_IPV4_DSCP:
924 prot_id = seg == 0 ? ICE_PROT_IPV4_OF_OR_S : ICE_PROT_IPV4_IL;
925 break;
926 case ICE_FLOW_FIELD_IDX_IPV6_DSCP:
927 prot_id = seg == 0 ? ICE_PROT_IPV6_OF_OR_S : ICE_PROT_IPV6_IL;
928 break;
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;
932
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.
936 */
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;
941
942 /* If the sibling field is also included, that field's
943 * mask needs to be included.
944 */
945 if (match & BIT(sib))
946 sib_mask = ice_flds_info[sib].mask;
947 break;
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;
951
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.
955 */
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;
960
961 /* If the sibling field is also included, that field's
962 * mask needs to be included.
963 */
964 if (match & BIT(sib))
965 sib_mask = ice_flds_info[sib].mask;
966 break;
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;
970 break;
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;
974 break;
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;
979 break;
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;
983 break;
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;
987 break;
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;
996 break;
997 case ICE_FLOW_FIELD_IDX_PPPOE_SESS_ID:
998 prot_id = ICE_PROT_PPPOE;
999 break;
1000 case ICE_FLOW_FIELD_IDX_PFCP_SEID:
1001 prot_id = ICE_PROT_UDP_IL_OR_S;
1002 break;
1003 case ICE_FLOW_FIELD_IDX_L2TPV3_SESS_ID:
1004 prot_id = ICE_PROT_L2TPV3;
1005 break;
1006 case ICE_FLOW_FIELD_IDX_ESP_SPI:
1007 prot_id = ICE_PROT_ESP_F;
1008 break;
1009 case ICE_FLOW_FIELD_IDX_AH_SPI:
1010 prot_id = ICE_PROT_ESP_2;
1011 break;
1012 case ICE_FLOW_FIELD_IDX_NAT_T_ESP_SPI:
1013 prot_id = ICE_PROT_UDP_IL_OR_S;
1014 break;
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;
1021 break;
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;
1030 break;
1031 case ICE_FLOW_FIELD_IDX_GRE_KEYID:
1032 prot_id = ICE_PROT_GRE_OF;
1033 break;
1034 default:
1035 return -EOPNOTSUPP;
1036 }
1037
1038 /* Each extraction sequence entry is a word in size, and extracts a
1039 * word-aligned offset from a protocol header.
1040 */
1041 ese_bits = ICE_FLOW_FV_EXTRACT_SZ * BITS_PER_BYTE;
1042
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;
1049
1050 /* Adjust the next field-entry index after accommodating the number of
1051 * entries this field consumes
1052 */
1053 cnt = DIV_ROUND_UP(flds[fld].xtrct.disp + ice_flds_info[fld].size,
1054 ese_bits);
1055
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.
1063 */
1064 if (sib == ICE_FLOW_FIELD_IDX_MAX ||
1065 flds[sib].xtrct.prot_id == ICE_PROT_ID_INVAL ||
1066 flds[sib].xtrct.off != off) {
1067 u8 idx;
1068
1069 /* Make sure the number of extraction sequence required
1070 * does not exceed the block's capability
1071 */
1072 if (params->es_cnt >= fv_words)
1073 return -ENOSPC;
1074
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;
1078 else
1079 idx = params->es_cnt;
1080
1081 params->es[idx].prot_id = prot_id;
1082 params->es[idx].off = off;
1083 params->mask[idx] = mask | sib_mask;
1084 params->es_cnt++;
1085 }
1086
1087 off += ICE_FLOW_FV_EXTRACT_SZ;
1088 }
1089
1090 return 0;
1091}
1092
1093/**
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
1098 */
1099static int
1100ice_flow_xtract_raws(struct ice_hw *hw, struct ice_flow_prof_params *params,
1101 u8 seg)
1102{
1103 u16 fv_words;
1104 u16 hdrs_sz;
1105 u8 i;
1106
1107 if (!params->prof->segs[seg].raws_cnt)
1108 return 0;
1109
1110 if (params->prof->segs[seg].raws_cnt >
1111 ARRAY_SIZE(params->prof->segs[seg].raws))
1112 return -ENOSPC;
1113
1114 /* Offsets within the segment headers are not supported */
1115 hdrs_sz = ice_flow_calc_seg_sz(params, seg);
1116 if (!hdrs_sz)
1117 return -EINVAL;
1118
1119 fv_words = hw->blk[params->blk].es.fvw;
1120
1121 for (i = 0; i < params->prof->segs[seg].raws_cnt; i++) {
1122 struct ice_flow_seg_fld_raw *raw;
1123 u16 off, cnt, j;
1124
1125 raw = ¶ms->prof->segs[seg].raws[i];
1126
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) *
1132 BITS_PER_BYTE;
1133 raw->info.xtrct.idx = params->es_cnt;
1134
1135 /* Determine the number of field vector entries this raw field
1136 * consumes.
1137 */
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++) {
1143 u16 idx;
1144
1145 /* Make sure the number of extraction sequence required
1146 * does not exceed the block's capability
1147 */
1148 if (params->es_cnt >= hw->blk[params->blk].es.count ||
1149 params->es_cnt >= ICE_MAX_FV_WORDS)
1150 return -ENOSPC;
1151
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;
1155 else
1156 idx = params->es_cnt;
1157
1158 params->es[idx].prot_id = raw->info.xtrct.prot_id;
1159 params->es[idx].off = off;
1160 params->es_cnt++;
1161 off += ICE_FLOW_FV_EXTRACT_SZ;
1162 }
1163 }
1164
1165 return 0;
1166}
1167
1168/**
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
1172 *
1173 * This function iterates through all matched fields in the given segments, and
1174 * creates an extraction sequence for the fields.
1175 */
1176static int
1177ice_flow_create_xtrct_seq(struct ice_hw *hw,
1178 struct ice_flow_prof_params *params)
1179{
1180 struct ice_flow_prof *prof = params->prof;
1181 int status = 0;
1182 u8 i;
1183
1184 for (i = 0; i < prof->segs_cnt; i++) {
1185 u64 match = params->prof->segs[i].match;
1186 enum ice_flow_field j;
1187
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);
1191 if (status)
1192 return status;
1193 clear_bit(j, (unsigned long *)&match);
1194 }
1195
1196 /* Process raw matching bytes */
1197 status = ice_flow_xtract_raws(hw, params, i);
1198 if (status)
1199 return status;
1200 }
1201
1202 return status;
1203}
1204
1205/**
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
1209 */
1210static int
1211ice_flow_proc_segs(struct ice_hw *hw, struct ice_flow_prof_params *params)
1212{
1213 int status;
1214
1215 status = ice_flow_proc_seg_hdrs(params);
1216 if (status)
1217 return status;
1218
1219 status = ice_flow_create_xtrct_seq(hw, params);
1220 if (status)
1221 return status;
1222
1223 switch (params->blk) {
1224 case ICE_BLK_FD:
1225 case ICE_BLK_RSS:
1226 status = 0;
1227 break;
1228 default:
1229 return -EOPNOTSUPP;
1230 }
1231
1232 return status;
1233}
1234
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
1238
1239/**
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_*)
1248 */
1249static struct ice_flow_prof *
1250ice_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)
1253{
1254 struct ice_flow_prof *p, *prof = NULL;
1255
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) {
1260 u8 i;
1261
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))
1266 continue;
1267
1268 /* Protocol headers must be checked. Matched fields are
1269 * checked if specified.
1270 */
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))
1275 break;
1276
1277 /* A match is found if all segments are matched */
1278 if (i == segs_cnt) {
1279 prof = p;
1280 break;
1281 }
1282 }
1283 mutex_unlock(&hw->fl_profs_locks[blk]);
1284
1285 return prof;
1286}
1287
1288/**
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
1293 */
1294static struct ice_flow_prof *
1295ice_flow_find_prof_id(struct ice_hw *hw, enum ice_block blk, u64 prof_id)
1296{
1297 struct ice_flow_prof *p;
1298
1299 list_for_each_entry(p, &hw->fl_profs[blk], l_entry)
1300 if (p->id == prof_id)
1301 return p;
1302
1303 return NULL;
1304}
1305
1306/**
1307 * ice_dealloc_flow_entry - Deallocate flow entry memory
1308 * @hw: pointer to the HW struct
1309 * @entry: flow entry to be removed
1310 */
1311static void
1312ice_dealloc_flow_entry(struct ice_hw *hw, struct ice_flow_entry *entry)
1313{
1314 if (!entry)
1315 return;
1316
1317 if (entry->entry)
1318 devm_kfree(ice_hw_to_dev(hw), entry->entry);
1319
1320 devm_kfree(ice_hw_to_dev(hw), entry);
1321}
1322
1323/**
1324 * ice_flow_rem_entry_sync - Remove a flow entry
1325 * @hw: pointer to the HW struct
1326 * @blk: classification stage
1327 * @entry: flow entry to be removed
1328 */
1329static int
1330ice_flow_rem_entry_sync(struct ice_hw *hw, enum ice_block __always_unused blk,
1331 struct ice_flow_entry *entry)
1332{
1333 if (!entry)
1334 return -EINVAL;
1335
1336 list_del(&entry->l_entry);
1337
1338 ice_dealloc_flow_entry(hw, entry);
1339
1340 return 0;
1341}
1342
1343/**
1344 * ice_flow_add_prof_sync - Add a flow profile for packet segments and fields
1345 * @hw: pointer to the HW struct
1346 * @blk: classification stage
1347 * @dir: flow direction
1348 * @prof_id: unique ID to identify this flow profile
1349 * @segs: array of one or more packet segments that describe the flow
1350 * @segs_cnt: number of packet segments provided
1351 * @prof: stores the returned flow profile added
1352 *
1353 * Assumption: the caller has acquired the lock to the profile list
1354 */
1355static int
1356ice_flow_add_prof_sync(struct ice_hw *hw, enum ice_block blk,
1357 enum ice_flow_dir dir, u64 prof_id,
1358 struct ice_flow_seg_info *segs, u8 segs_cnt,
1359 struct ice_flow_prof **prof)
1360{
1361 struct ice_flow_prof_params *params;
1362 int status;
1363 u8 i;
1364
1365 if (!prof)
1366 return -EINVAL;
1367
1368 params = kzalloc(sizeof(*params), GFP_KERNEL);
1369 if (!params)
1370 return -ENOMEM;
1371
1372 params->prof = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*params->prof),
1373 GFP_KERNEL);
1374 if (!params->prof) {
1375 status = -ENOMEM;
1376 goto free_params;
1377 }
1378
1379 /* initialize extraction sequence to all invalid (0xff) */
1380 for (i = 0; i < ICE_MAX_FV_WORDS; i++) {
1381 params->es[i].prot_id = ICE_PROT_INVALID;
1382 params->es[i].off = ICE_FV_OFFSET_INVAL;
1383 }
1384
1385 params->blk = blk;
1386 params->prof->id = prof_id;
1387 params->prof->dir = dir;
1388 params->prof->segs_cnt = segs_cnt;
1389
1390 /* Make a copy of the segments that need to be persistent in the flow
1391 * profile instance
1392 */
1393 for (i = 0; i < segs_cnt; i++)
1394 memcpy(¶ms->prof->segs[i], &segs[i], sizeof(*segs));
1395
1396 status = ice_flow_proc_segs(hw, params);
1397 if (status) {
1398 ice_debug(hw, ICE_DBG_FLOW, "Error processing a flow's packet segments\n");
1399 goto out;
1400 }
1401
1402 /* Add a HW profile for this flow profile */
1403 status = ice_add_prof(hw, blk, prof_id, (u8 *)params->ptypes,
1404 params->attr, params->attr_cnt, params->es,
1405 params->mask);
1406 if (status) {
1407 ice_debug(hw, ICE_DBG_FLOW, "Error adding a HW flow profile\n");
1408 goto out;
1409 }
1410
1411 INIT_LIST_HEAD(¶ms->prof->entries);
1412 mutex_init(¶ms->prof->entries_lock);
1413 *prof = params->prof;
1414
1415out:
1416 if (status)
1417 devm_kfree(ice_hw_to_dev(hw), params->prof);
1418free_params:
1419 kfree(params);
1420
1421 return status;
1422}
1423
1424/**
1425 * ice_flow_rem_prof_sync - remove a flow profile
1426 * @hw: pointer to the hardware structure
1427 * @blk: classification stage
1428 * @prof: pointer to flow profile to remove
1429 *
1430 * Assumption: the caller has acquired the lock to the profile list
1431 */
1432static int
1433ice_flow_rem_prof_sync(struct ice_hw *hw, enum ice_block blk,
1434 struct ice_flow_prof *prof)
1435{
1436 int status;
1437
1438 /* Remove all remaining flow entries before removing the flow profile */
1439 if (!list_empty(&prof->entries)) {
1440 struct ice_flow_entry *e, *t;
1441
1442 mutex_lock(&prof->entries_lock);
1443
1444 list_for_each_entry_safe(e, t, &prof->entries, l_entry) {
1445 status = ice_flow_rem_entry_sync(hw, blk, e);
1446 if (status)
1447 break;
1448 }
1449
1450 mutex_unlock(&prof->entries_lock);
1451 }
1452
1453 /* Remove all hardware profiles associated with this flow profile */
1454 status = ice_rem_prof(hw, blk, prof->id);
1455 if (!status) {
1456 list_del(&prof->l_entry);
1457 mutex_destroy(&prof->entries_lock);
1458 devm_kfree(ice_hw_to_dev(hw), prof);
1459 }
1460
1461 return status;
1462}
1463
1464/**
1465 * ice_flow_assoc_prof - associate a VSI with a flow profile
1466 * @hw: pointer to the hardware structure
1467 * @blk: classification stage
1468 * @prof: pointer to flow profile
1469 * @vsi_handle: software VSI handle
1470 *
1471 * Assumption: the caller has acquired the lock to the profile list
1472 * and the software VSI handle has been validated
1473 */
1474static int
1475ice_flow_assoc_prof(struct ice_hw *hw, enum ice_block blk,
1476 struct ice_flow_prof *prof, u16 vsi_handle)
1477{
1478 int status = 0;
1479
1480 if (!test_bit(vsi_handle, prof->vsis)) {
1481 status = ice_add_prof_id_flow(hw, blk,
1482 ice_get_hw_vsi_num(hw,
1483 vsi_handle),
1484 prof->id);
1485 if (!status)
1486 set_bit(vsi_handle, prof->vsis);
1487 else
1488 ice_debug(hw, ICE_DBG_FLOW, "HW profile add failed, %d\n",
1489 status);
1490 }
1491
1492 return status;
1493}
1494
1495/**
1496 * ice_flow_disassoc_prof - disassociate a VSI from a flow profile
1497 * @hw: pointer to the hardware structure
1498 * @blk: classification stage
1499 * @prof: pointer to flow profile
1500 * @vsi_handle: software VSI handle
1501 *
1502 * Assumption: the caller has acquired the lock to the profile list
1503 * and the software VSI handle has been validated
1504 */
1505static int
1506ice_flow_disassoc_prof(struct ice_hw *hw, enum ice_block blk,
1507 struct ice_flow_prof *prof, u16 vsi_handle)
1508{
1509 int status = 0;
1510
1511 if (test_bit(vsi_handle, prof->vsis)) {
1512 status = ice_rem_prof_id_flow(hw, blk,
1513 ice_get_hw_vsi_num(hw,
1514 vsi_handle),
1515 prof->id);
1516 if (!status)
1517 clear_bit(vsi_handle, prof->vsis);
1518 else
1519 ice_debug(hw, ICE_DBG_FLOW, "HW profile remove failed, %d\n",
1520 status);
1521 }
1522
1523 return status;
1524}
1525
1526/**
1527 * ice_flow_add_prof - Add a flow profile for packet segments and matched fields
1528 * @hw: pointer to the HW struct
1529 * @blk: classification stage
1530 * @dir: flow direction
1531 * @prof_id: unique ID to identify this flow profile
1532 * @segs: array of one or more packet segments that describe the flow
1533 * @segs_cnt: number of packet segments provided
1534 * @prof: stores the returned flow profile added
1535 */
1536int
1537ice_flow_add_prof(struct ice_hw *hw, enum ice_block blk, enum ice_flow_dir dir,
1538 u64 prof_id, struct ice_flow_seg_info *segs, u8 segs_cnt,
1539 struct ice_flow_prof **prof)
1540{
1541 int status;
1542
1543 if (segs_cnt > ICE_FLOW_SEG_MAX)
1544 return -ENOSPC;
1545
1546 if (!segs_cnt)
1547 return -EINVAL;
1548
1549 if (!segs)
1550 return -EINVAL;
1551
1552 status = ice_flow_val_hdrs(segs, segs_cnt);
1553 if (status)
1554 return status;
1555
1556 mutex_lock(&hw->fl_profs_locks[blk]);
1557
1558 status = ice_flow_add_prof_sync(hw, blk, dir, prof_id, segs, segs_cnt,
1559 prof);
1560 if (!status)
1561 list_add(&(*prof)->l_entry, &hw->fl_profs[blk]);
1562
1563 mutex_unlock(&hw->fl_profs_locks[blk]);
1564
1565 return status;
1566}
1567
1568/**
1569 * ice_flow_rem_prof - Remove a flow profile and all entries associated with it
1570 * @hw: pointer to the HW struct
1571 * @blk: the block for which the flow profile is to be removed
1572 * @prof_id: unique ID of the flow profile to be removed
1573 */
1574int ice_flow_rem_prof(struct ice_hw *hw, enum ice_block blk, u64 prof_id)
1575{
1576 struct ice_flow_prof *prof;
1577 int status;
1578
1579 mutex_lock(&hw->fl_profs_locks[blk]);
1580
1581 prof = ice_flow_find_prof_id(hw, blk, prof_id);
1582 if (!prof) {
1583 status = -ENOENT;
1584 goto out;
1585 }
1586
1587 /* prof becomes invalid after the call */
1588 status = ice_flow_rem_prof_sync(hw, blk, prof);
1589
1590out:
1591 mutex_unlock(&hw->fl_profs_locks[blk]);
1592
1593 return status;
1594}
1595
1596/**
1597 * ice_flow_add_entry - Add a flow entry
1598 * @hw: pointer to the HW struct
1599 * @blk: classification stage
1600 * @prof_id: ID of the profile to add a new flow entry to
1601 * @entry_id: unique ID to identify this flow entry
1602 * @vsi_handle: software VSI handle for the flow entry
1603 * @prio: priority of the flow entry
1604 * @data: pointer to a data buffer containing flow entry's match values/masks
1605 * @entry_h: pointer to buffer that receives the new flow entry's handle
1606 */
1607int
1608ice_flow_add_entry(struct ice_hw *hw, enum ice_block blk, u64 prof_id,
1609 u64 entry_id, u16 vsi_handle, enum ice_flow_priority prio,
1610 void *data, u64 *entry_h)
1611{
1612 struct ice_flow_entry *e = NULL;
1613 struct ice_flow_prof *prof;
1614 int status;
1615
1616 /* No flow entry data is expected for RSS */
1617 if (!entry_h || (!data && blk != ICE_BLK_RSS))
1618 return -EINVAL;
1619
1620 if (!ice_is_vsi_valid(hw, vsi_handle))
1621 return -EINVAL;
1622
1623 mutex_lock(&hw->fl_profs_locks[blk]);
1624
1625 prof = ice_flow_find_prof_id(hw, blk, prof_id);
1626 if (!prof) {
1627 status = -ENOENT;
1628 } else {
1629 /* Allocate memory for the entry being added and associate
1630 * the VSI to the found flow profile
1631 */
1632 e = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*e), GFP_KERNEL);
1633 if (!e)
1634 status = -ENOMEM;
1635 else
1636 status = ice_flow_assoc_prof(hw, blk, prof, vsi_handle);
1637 }
1638
1639 mutex_unlock(&hw->fl_profs_locks[blk]);
1640 if (status)
1641 goto out;
1642
1643 e->id = entry_id;
1644 e->vsi_handle = vsi_handle;
1645 e->prof = prof;
1646 e->priority = prio;
1647
1648 switch (blk) {
1649 case ICE_BLK_FD:
1650 case ICE_BLK_RSS:
1651 break;
1652 default:
1653 status = -EOPNOTSUPP;
1654 goto out;
1655 }
1656
1657 mutex_lock(&prof->entries_lock);
1658 list_add(&e->l_entry, &prof->entries);
1659 mutex_unlock(&prof->entries_lock);
1660
1661 *entry_h = ICE_FLOW_ENTRY_HNDL(e);
1662
1663out:
1664 if (status && e) {
1665 if (e->entry)
1666 devm_kfree(ice_hw_to_dev(hw), e->entry);
1667 devm_kfree(ice_hw_to_dev(hw), e);
1668 }
1669
1670 return status;
1671}
1672
1673/**
1674 * ice_flow_rem_entry - Remove a flow entry
1675 * @hw: pointer to the HW struct
1676 * @blk: classification stage
1677 * @entry_h: handle to the flow entry to be removed
1678 */
1679int ice_flow_rem_entry(struct ice_hw *hw, enum ice_block blk, u64 entry_h)
1680{
1681 struct ice_flow_entry *entry;
1682 struct ice_flow_prof *prof;
1683 int status = 0;
1684
1685 if (entry_h == ICE_FLOW_ENTRY_HANDLE_INVAL)
1686 return -EINVAL;
1687
1688 entry = ICE_FLOW_ENTRY_PTR(entry_h);
1689
1690 /* Retain the pointer to the flow profile as the entry will be freed */
1691 prof = entry->prof;
1692
1693 if (prof) {
1694 mutex_lock(&prof->entries_lock);
1695 status = ice_flow_rem_entry_sync(hw, blk, entry);
1696 mutex_unlock(&prof->entries_lock);
1697 }
1698
1699 return status;
1700}
1701
1702/**
1703 * ice_flow_set_fld_ext - specifies locations of field from entry's input buffer
1704 * @seg: packet segment the field being set belongs to
1705 * @fld: field to be set
1706 * @field_type: type of the field
1707 * @val_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of the value to match from
1708 * entry's input buffer
1709 * @mask_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of mask value from entry's
1710 * input buffer
1711 * @last_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of last/upper value from
1712 * entry's input buffer
1713 *
1714 * This helper function stores information of a field being matched, including
1715 * the type of the field and the locations of the value to match, the mask, and
1716 * the upper-bound value in the start of the input buffer for a flow entry.
1717 * This function should only be used for fixed-size data structures.
1718 *
1719 * This function also opportunistically determines the protocol headers to be
1720 * present based on the fields being set. Some fields cannot be used alone to
1721 * determine the protocol headers present. Sometimes, fields for particular
1722 * protocol headers are not matched. In those cases, the protocol headers
1723 * must be explicitly set.
1724 */
1725static void
1726ice_flow_set_fld_ext(struct ice_flow_seg_info *seg, enum ice_flow_field fld,
1727 enum ice_flow_fld_match_type field_type, u16 val_loc,
1728 u16 mask_loc, u16 last_loc)
1729{
1730 u64 bit = BIT_ULL(fld);
1731
1732 seg->match |= bit;
1733 if (field_type == ICE_FLOW_FLD_TYPE_RANGE)
1734 seg->range |= bit;
1735
1736 seg->fields[fld].type = field_type;
1737 seg->fields[fld].src.val = val_loc;
1738 seg->fields[fld].src.mask = mask_loc;
1739 seg->fields[fld].src.last = last_loc;
1740
1741 ICE_FLOW_SET_HDRS(seg, ice_flds_info[fld].hdr);
1742}
1743
1744/**
1745 * ice_flow_set_fld - specifies locations of field from entry's input buffer
1746 * @seg: packet segment the field being set belongs to
1747 * @fld: field to be set
1748 * @val_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of the value to match from
1749 * entry's input buffer
1750 * @mask_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of mask value from entry's
1751 * input buffer
1752 * @last_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of last/upper value from
1753 * entry's input buffer
1754 * @range: indicate if field being matched is to be in a range
1755 *
1756 * This function specifies the locations, in the form of byte offsets from the
1757 * start of the input buffer for a flow entry, from where the value to match,
1758 * the mask value, and upper value can be extracted. These locations are then
1759 * stored in the flow profile. When adding a flow entry associated with the
1760 * flow profile, these locations will be used to quickly extract the values and
1761 * create the content of a match entry. This function should only be used for
1762 * fixed-size data structures.
1763 */
1764void
1765ice_flow_set_fld(struct ice_flow_seg_info *seg, enum ice_flow_field fld,
1766 u16 val_loc, u16 mask_loc, u16 last_loc, bool range)
1767{
1768 enum ice_flow_fld_match_type t = range ?
1769 ICE_FLOW_FLD_TYPE_RANGE : ICE_FLOW_FLD_TYPE_REG;
1770
1771 ice_flow_set_fld_ext(seg, fld, t, val_loc, mask_loc, last_loc);
1772}
1773
1774/**
1775 * ice_flow_add_fld_raw - sets locations of a raw field from entry's input buf
1776 * @seg: packet segment the field being set belongs to
1777 * @off: offset of the raw field from the beginning of the segment in bytes
1778 * @len: length of the raw pattern to be matched
1779 * @val_loc: location of the value to match from entry's input buffer
1780 * @mask_loc: location of mask value from entry's input buffer
1781 *
1782 * This function specifies the offset of the raw field to be match from the
1783 * beginning of the specified packet segment, and the locations, in the form of
1784 * byte offsets from the start of the input buffer for a flow entry, from where
1785 * the value to match and the mask value to be extracted. These locations are
1786 * then stored in the flow profile. When adding flow entries to the associated
1787 * flow profile, these locations can be used to quickly extract the values to
1788 * create the content of a match entry. This function should only be used for
1789 * fixed-size data structures.
1790 */
1791void
1792ice_flow_add_fld_raw(struct ice_flow_seg_info *seg, u16 off, u8 len,
1793 u16 val_loc, u16 mask_loc)
1794{
1795 if (seg->raws_cnt < ICE_FLOW_SEG_RAW_FLD_MAX) {
1796 seg->raws[seg->raws_cnt].off = off;
1797 seg->raws[seg->raws_cnt].info.type = ICE_FLOW_FLD_TYPE_SIZE;
1798 seg->raws[seg->raws_cnt].info.src.val = val_loc;
1799 seg->raws[seg->raws_cnt].info.src.mask = mask_loc;
1800 /* The "last" field is used to store the length of the field */
1801 seg->raws[seg->raws_cnt].info.src.last = len;
1802 }
1803
1804 /* Overflows of "raws" will be handled as an error condition later in
1805 * the flow when this information is processed.
1806 */
1807 seg->raws_cnt++;
1808}
1809
1810/**
1811 * ice_flow_rem_vsi_prof - remove VSI from flow profile
1812 * @hw: pointer to the hardware structure
1813 * @vsi_handle: software VSI handle
1814 * @prof_id: unique ID to identify this flow profile
1815 *
1816 * This function removes the flow entries associated to the input
1817 * VSI handle and disassociate the VSI from the flow profile.
1818 */
1819int ice_flow_rem_vsi_prof(struct ice_hw *hw, u16 vsi_handle, u64 prof_id)
1820{
1821 struct ice_flow_prof *prof;
1822 int status = 0;
1823
1824 if (!ice_is_vsi_valid(hw, vsi_handle))
1825 return -EINVAL;
1826
1827 /* find flow profile pointer with input package block and profile ID */
1828 prof = ice_flow_find_prof_id(hw, ICE_BLK_FD, prof_id);
1829 if (!prof) {
1830 ice_debug(hw, ICE_DBG_PKG, "Cannot find flow profile id=%llu\n",
1831 prof_id);
1832 return -ENOENT;
1833 }
1834
1835 /* Remove all remaining flow entries before removing the flow profile */
1836 if (!list_empty(&prof->entries)) {
1837 struct ice_flow_entry *e, *t;
1838
1839 mutex_lock(&prof->entries_lock);
1840 list_for_each_entry_safe(e, t, &prof->entries, l_entry) {
1841 if (e->vsi_handle != vsi_handle)
1842 continue;
1843
1844 status = ice_flow_rem_entry_sync(hw, ICE_BLK_FD, e);
1845 if (status)
1846 break;
1847 }
1848 mutex_unlock(&prof->entries_lock);
1849 }
1850 if (status)
1851 return status;
1852
1853 /* disassociate the flow profile from sw VSI handle */
1854 status = ice_flow_disassoc_prof(hw, ICE_BLK_FD, prof, vsi_handle);
1855 if (status)
1856 ice_debug(hw, ICE_DBG_PKG, "ice_flow_disassoc_prof() failed with status=%d\n",
1857 status);
1858 return status;
1859}
1860
1861#define ICE_FLOW_RSS_SEG_HDR_L2_MASKS \
1862 (ICE_FLOW_SEG_HDR_ETH | ICE_FLOW_SEG_HDR_VLAN)
1863
1864#define ICE_FLOW_RSS_SEG_HDR_L3_MASKS \
1865 (ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_IPV6)
1866
1867#define ICE_FLOW_RSS_SEG_HDR_L4_MASKS \
1868 (ICE_FLOW_SEG_HDR_TCP | ICE_FLOW_SEG_HDR_UDP | ICE_FLOW_SEG_HDR_SCTP)
1869
1870#define ICE_FLOW_RSS_SEG_HDR_VAL_MASKS \
1871 (ICE_FLOW_RSS_SEG_HDR_L2_MASKS | \
1872 ICE_FLOW_RSS_SEG_HDR_L3_MASKS | \
1873 ICE_FLOW_RSS_SEG_HDR_L4_MASKS)
1874
1875/**
1876 * ice_flow_set_rss_seg_info - setup packet segments for RSS
1877 * @segs: pointer to the flow field segment(s)
1878 * @hash_fields: fields to be hashed on for the segment(s)
1879 * @flow_hdr: protocol header fields within a packet segment
1880 *
1881 * Helper function to extract fields from hash bitmap and use flow
1882 * header value to set flow field segment for further use in flow
1883 * profile entry or removal.
1884 */
1885static int
1886ice_flow_set_rss_seg_info(struct ice_flow_seg_info *segs, u64 hash_fields,
1887 u32 flow_hdr)
1888{
1889 u64 val;
1890 u8 i;
1891
1892 for_each_set_bit(i, (unsigned long *)&hash_fields,
1893 ICE_FLOW_FIELD_IDX_MAX)
1894 ice_flow_set_fld(segs, (enum ice_flow_field)i,
1895 ICE_FLOW_FLD_OFF_INVAL, ICE_FLOW_FLD_OFF_INVAL,
1896 ICE_FLOW_FLD_OFF_INVAL, false);
1897
1898 ICE_FLOW_SET_HDRS(segs, flow_hdr);
1899
1900 if (segs->hdrs & ~ICE_FLOW_RSS_SEG_HDR_VAL_MASKS &
1901 ~ICE_FLOW_RSS_HDRS_INNER_MASK & ~ICE_FLOW_SEG_HDR_IPV_OTHER)
1902 return -EINVAL;
1903
1904 val = (u64)(segs->hdrs & ICE_FLOW_RSS_SEG_HDR_L3_MASKS);
1905 if (val && !is_power_of_2(val))
1906 return -EIO;
1907
1908 val = (u64)(segs->hdrs & ICE_FLOW_RSS_SEG_HDR_L4_MASKS);
1909 if (val && !is_power_of_2(val))
1910 return -EIO;
1911
1912 return 0;
1913}
1914
1915/**
1916 * ice_rem_vsi_rss_list - remove VSI from RSS list
1917 * @hw: pointer to the hardware structure
1918 * @vsi_handle: software VSI handle
1919 *
1920 * Remove the VSI from all RSS configurations in the list.
1921 */
1922void ice_rem_vsi_rss_list(struct ice_hw *hw, u16 vsi_handle)
1923{
1924 struct ice_rss_cfg *r, *tmp;
1925
1926 if (list_empty(&hw->rss_list_head))
1927 return;
1928
1929 mutex_lock(&hw->rss_locks);
1930 list_for_each_entry_safe(r, tmp, &hw->rss_list_head, l_entry)
1931 if (test_and_clear_bit(vsi_handle, r->vsis))
1932 if (bitmap_empty(r->vsis, ICE_MAX_VSI)) {
1933 list_del(&r->l_entry);
1934 devm_kfree(ice_hw_to_dev(hw), r);
1935 }
1936 mutex_unlock(&hw->rss_locks);
1937}
1938
1939/**
1940 * ice_rem_vsi_rss_cfg - remove RSS configurations associated with VSI
1941 * @hw: pointer to the hardware structure
1942 * @vsi_handle: software VSI handle
1943 *
1944 * This function will iterate through all flow profiles and disassociate
1945 * the VSI from that profile. If the flow profile has no VSIs it will
1946 * be removed.
1947 */
1948int ice_rem_vsi_rss_cfg(struct ice_hw *hw, u16 vsi_handle)
1949{
1950 const enum ice_block blk = ICE_BLK_RSS;
1951 struct ice_flow_prof *p, *t;
1952 int status = 0;
1953
1954 if (!ice_is_vsi_valid(hw, vsi_handle))
1955 return -EINVAL;
1956
1957 if (list_empty(&hw->fl_profs[blk]))
1958 return 0;
1959
1960 mutex_lock(&hw->rss_locks);
1961 list_for_each_entry_safe(p, t, &hw->fl_profs[blk], l_entry)
1962 if (test_bit(vsi_handle, p->vsis)) {
1963 status = ice_flow_disassoc_prof(hw, blk, p, vsi_handle);
1964 if (status)
1965 break;
1966
1967 if (bitmap_empty(p->vsis, ICE_MAX_VSI)) {
1968 status = ice_flow_rem_prof(hw, blk, p->id);
1969 if (status)
1970 break;
1971 }
1972 }
1973 mutex_unlock(&hw->rss_locks);
1974
1975 return status;
1976}
1977
1978/**
1979 * ice_rem_rss_list - remove RSS configuration from list
1980 * @hw: pointer to the hardware structure
1981 * @vsi_handle: software VSI handle
1982 * @prof: pointer to flow profile
1983 *
1984 * Assumption: lock has already been acquired for RSS list
1985 */
1986static void
1987ice_rem_rss_list(struct ice_hw *hw, u16 vsi_handle, struct ice_flow_prof *prof)
1988{
1989 struct ice_rss_cfg *r, *tmp;
1990
1991 /* Search for RSS hash fields associated to the VSI that match the
1992 * hash configurations associated to the flow profile. If found
1993 * remove from the RSS entry list of the VSI context and delete entry.
1994 */
1995 list_for_each_entry_safe(r, tmp, &hw->rss_list_head, l_entry)
1996 if (r->hashed_flds == prof->segs[prof->segs_cnt - 1].match &&
1997 r->packet_hdr == prof->segs[prof->segs_cnt - 1].hdrs) {
1998 clear_bit(vsi_handle, r->vsis);
1999 if (bitmap_empty(r->vsis, ICE_MAX_VSI)) {
2000 list_del(&r->l_entry);
2001 devm_kfree(ice_hw_to_dev(hw), r);
2002 }
2003 return;
2004 }
2005}
2006
2007/**
2008 * ice_add_rss_list - add RSS configuration to list
2009 * @hw: pointer to the hardware structure
2010 * @vsi_handle: software VSI handle
2011 * @prof: pointer to flow profile
2012 *
2013 * Assumption: lock has already been acquired for RSS list
2014 */
2015static int
2016ice_add_rss_list(struct ice_hw *hw, u16 vsi_handle, struct ice_flow_prof *prof)
2017{
2018 struct ice_rss_cfg *r, *rss_cfg;
2019
2020 list_for_each_entry(r, &hw->rss_list_head, l_entry)
2021 if (r->hashed_flds == prof->segs[prof->segs_cnt - 1].match &&
2022 r->packet_hdr == prof->segs[prof->segs_cnt - 1].hdrs) {
2023 set_bit(vsi_handle, r->vsis);
2024 return 0;
2025 }
2026
2027 rss_cfg = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*rss_cfg),
2028 GFP_KERNEL);
2029 if (!rss_cfg)
2030 return -ENOMEM;
2031
2032 rss_cfg->hashed_flds = prof->segs[prof->segs_cnt - 1].match;
2033 rss_cfg->packet_hdr = prof->segs[prof->segs_cnt - 1].hdrs;
2034 set_bit(vsi_handle, rss_cfg->vsis);
2035
2036 list_add_tail(&rss_cfg->l_entry, &hw->rss_list_head);
2037
2038 return 0;
2039}
2040
2041#define ICE_FLOW_PROF_HASH_S 0
2042#define ICE_FLOW_PROF_HASH_M (0xFFFFFFFFULL << ICE_FLOW_PROF_HASH_S)
2043#define ICE_FLOW_PROF_HDR_S 32
2044#define ICE_FLOW_PROF_HDR_M (0x3FFFFFFFULL << ICE_FLOW_PROF_HDR_S)
2045#define ICE_FLOW_PROF_ENCAP_S 63
2046#define ICE_FLOW_PROF_ENCAP_M (BIT_ULL(ICE_FLOW_PROF_ENCAP_S))
2047
2048#define ICE_RSS_OUTER_HEADERS 1
2049#define ICE_RSS_INNER_HEADERS 2
2050
2051/* Flow profile ID format:
2052 * [0:31] - Packet match fields
2053 * [32:62] - Protocol header
2054 * [63] - Encapsulation flag, 0 if non-tunneled, 1 if tunneled
2055 */
2056#define ICE_FLOW_GEN_PROFID(hash, hdr, segs_cnt) \
2057 ((u64)(((u64)(hash) & ICE_FLOW_PROF_HASH_M) | \
2058 (((u64)(hdr) << ICE_FLOW_PROF_HDR_S) & ICE_FLOW_PROF_HDR_M) | \
2059 ((u8)((segs_cnt) - 1) ? ICE_FLOW_PROF_ENCAP_M : 0)))
2060
2061/**
2062 * ice_add_rss_cfg_sync - add an RSS configuration
2063 * @hw: pointer to the hardware structure
2064 * @vsi_handle: software VSI handle
2065 * @hashed_flds: hash bit fields (ICE_FLOW_HASH_*) to configure
2066 * @addl_hdrs: protocol header fields
2067 * @segs_cnt: packet segment count
2068 *
2069 * Assumption: lock has already been acquired for RSS list
2070 */
2071static int
2072ice_add_rss_cfg_sync(struct ice_hw *hw, u16 vsi_handle, u64 hashed_flds,
2073 u32 addl_hdrs, u8 segs_cnt)
2074{
2075 const enum ice_block blk = ICE_BLK_RSS;
2076 struct ice_flow_prof *prof = NULL;
2077 struct ice_flow_seg_info *segs;
2078 int status;
2079
2080 if (!segs_cnt || segs_cnt > ICE_FLOW_SEG_MAX)
2081 return -EINVAL;
2082
2083 segs = kcalloc(segs_cnt, sizeof(*segs), GFP_KERNEL);
2084 if (!segs)
2085 return -ENOMEM;
2086
2087 /* Construct the packet segment info from the hashed fields */
2088 status = ice_flow_set_rss_seg_info(&segs[segs_cnt - 1], hashed_flds,
2089 addl_hdrs);
2090 if (status)
2091 goto exit;
2092
2093 /* Search for a flow profile that has matching headers, hash fields
2094 * and has the input VSI associated to it. If found, no further
2095 * operations required and exit.
2096 */
2097 prof = ice_flow_find_prof_conds(hw, blk, ICE_FLOW_RX, segs, segs_cnt,
2098 vsi_handle,
2099 ICE_FLOW_FIND_PROF_CHK_FLDS |
2100 ICE_FLOW_FIND_PROF_CHK_VSI);
2101 if (prof)
2102 goto exit;
2103
2104 /* Check if a flow profile exists with the same protocol headers and
2105 * associated with the input VSI. If so disassociate the VSI from
2106 * this profile. The VSI will be added to a new profile created with
2107 * the protocol header and new hash field configuration.
2108 */
2109 prof = ice_flow_find_prof_conds(hw, blk, ICE_FLOW_RX, segs, segs_cnt,
2110 vsi_handle, ICE_FLOW_FIND_PROF_CHK_VSI);
2111 if (prof) {
2112 status = ice_flow_disassoc_prof(hw, blk, prof, vsi_handle);
2113 if (!status)
2114 ice_rem_rss_list(hw, vsi_handle, prof);
2115 else
2116 goto exit;
2117
2118 /* Remove profile if it has no VSIs associated */
2119 if (bitmap_empty(prof->vsis, ICE_MAX_VSI)) {
2120 status = ice_flow_rem_prof(hw, blk, prof->id);
2121 if (status)
2122 goto exit;
2123 }
2124 }
2125
2126 /* Search for a profile that has same match fields only. If this
2127 * exists then associate the VSI to this profile.
2128 */
2129 prof = ice_flow_find_prof_conds(hw, blk, ICE_FLOW_RX, segs, segs_cnt,
2130 vsi_handle,
2131 ICE_FLOW_FIND_PROF_CHK_FLDS);
2132 if (prof) {
2133 status = ice_flow_assoc_prof(hw, blk, prof, vsi_handle);
2134 if (!status)
2135 status = ice_add_rss_list(hw, vsi_handle, prof);
2136 goto exit;
2137 }
2138
2139 /* Create a new flow profile with generated profile and packet
2140 * segment information.
2141 */
2142 status = ice_flow_add_prof(hw, blk, ICE_FLOW_RX,
2143 ICE_FLOW_GEN_PROFID(hashed_flds,
2144 segs[segs_cnt - 1].hdrs,
2145 segs_cnt),
2146 segs, segs_cnt, &prof);
2147 if (status)
2148 goto exit;
2149
2150 status = ice_flow_assoc_prof(hw, blk, prof, vsi_handle);
2151 /* If association to a new flow profile failed then this profile can
2152 * be removed.
2153 */
2154 if (status) {
2155 ice_flow_rem_prof(hw, blk, prof->id);
2156 goto exit;
2157 }
2158
2159 status = ice_add_rss_list(hw, vsi_handle, prof);
2160
2161exit:
2162 kfree(segs);
2163 return status;
2164}
2165
2166/**
2167 * ice_add_rss_cfg - add an RSS configuration with specified hashed fields
2168 * @hw: pointer to the hardware structure
2169 * @vsi_handle: software VSI handle
2170 * @hashed_flds: hash bit fields (ICE_FLOW_HASH_*) to configure
2171 * @addl_hdrs: protocol header fields
2172 *
2173 * This function will generate a flow profile based on fields associated with
2174 * the input fields to hash on, the flow type and use the VSI number to add
2175 * a flow entry to the profile.
2176 */
2177int
2178ice_add_rss_cfg(struct ice_hw *hw, u16 vsi_handle, u64 hashed_flds,
2179 u32 addl_hdrs)
2180{
2181 int status;
2182
2183 if (hashed_flds == ICE_HASH_INVALID ||
2184 !ice_is_vsi_valid(hw, vsi_handle))
2185 return -EINVAL;
2186
2187 mutex_lock(&hw->rss_locks);
2188 status = ice_add_rss_cfg_sync(hw, vsi_handle, hashed_flds, addl_hdrs,
2189 ICE_RSS_OUTER_HEADERS);
2190 if (!status)
2191 status = ice_add_rss_cfg_sync(hw, vsi_handle, hashed_flds,
2192 addl_hdrs, ICE_RSS_INNER_HEADERS);
2193 mutex_unlock(&hw->rss_locks);
2194
2195 return status;
2196}
2197
2198/**
2199 * ice_rem_rss_cfg_sync - remove an existing RSS configuration
2200 * @hw: pointer to the hardware structure
2201 * @vsi_handle: software VSI handle
2202 * @hashed_flds: Packet hash types (ICE_FLOW_HASH_*) to remove
2203 * @addl_hdrs: Protocol header fields within a packet segment
2204 * @segs_cnt: packet segment count
2205 *
2206 * Assumption: lock has already been acquired for RSS list
2207 */
2208static int
2209ice_rem_rss_cfg_sync(struct ice_hw *hw, u16 vsi_handle, u64 hashed_flds,
2210 u32 addl_hdrs, u8 segs_cnt)
2211{
2212 const enum ice_block blk = ICE_BLK_RSS;
2213 struct ice_flow_seg_info *segs;
2214 struct ice_flow_prof *prof;
2215 int status;
2216
2217 segs = kcalloc(segs_cnt, sizeof(*segs), GFP_KERNEL);
2218 if (!segs)
2219 return -ENOMEM;
2220
2221 /* Construct the packet segment info from the hashed fields */
2222 status = ice_flow_set_rss_seg_info(&segs[segs_cnt - 1], hashed_flds,
2223 addl_hdrs);
2224 if (status)
2225 goto out;
2226
2227 prof = ice_flow_find_prof_conds(hw, blk, ICE_FLOW_RX, segs, segs_cnt,
2228 vsi_handle,
2229 ICE_FLOW_FIND_PROF_CHK_FLDS);
2230 if (!prof) {
2231 status = -ENOENT;
2232 goto out;
2233 }
2234
2235 status = ice_flow_disassoc_prof(hw, blk, prof, vsi_handle);
2236 if (status)
2237 goto out;
2238
2239 /* Remove RSS configuration from VSI context before deleting
2240 * the flow profile.
2241 */
2242 ice_rem_rss_list(hw, vsi_handle, prof);
2243
2244 if (bitmap_empty(prof->vsis, ICE_MAX_VSI))
2245 status = ice_flow_rem_prof(hw, blk, prof->id);
2246
2247out:
2248 kfree(segs);
2249 return status;
2250}
2251
2252/**
2253 * ice_rem_rss_cfg - remove an existing RSS config with matching hashed fields
2254 * @hw: pointer to the hardware structure
2255 * @vsi_handle: software VSI handle
2256 * @hashed_flds: Packet hash types (ICE_FLOW_HASH_*) to remove
2257 * @addl_hdrs: Protocol header fields within a packet segment
2258 *
2259 * This function will lookup the flow profile based on the input
2260 * hash field bitmap, iterate through the profile entry list of
2261 * that profile and find entry associated with input VSI to be
2262 * removed. Calls are made to underlying flow s which will APIs
2263 * turn build or update buffers for RSS XLT1 section.
2264 */
2265int __maybe_unused
2266ice_rem_rss_cfg(struct ice_hw *hw, u16 vsi_handle, u64 hashed_flds,
2267 u32 addl_hdrs)
2268{
2269 int status;
2270
2271 if (hashed_flds == ICE_HASH_INVALID ||
2272 !ice_is_vsi_valid(hw, vsi_handle))
2273 return -EINVAL;
2274
2275 mutex_lock(&hw->rss_locks);
2276 status = ice_rem_rss_cfg_sync(hw, vsi_handle, hashed_flds, addl_hdrs,
2277 ICE_RSS_OUTER_HEADERS);
2278 if (!status)
2279 status = ice_rem_rss_cfg_sync(hw, vsi_handle, hashed_flds,
2280 addl_hdrs, ICE_RSS_INNER_HEADERS);
2281 mutex_unlock(&hw->rss_locks);
2282
2283 return status;
2284}
2285
2286/* Mapping of AVF hash bit fields to an L3-L4 hash combination.
2287 * As the ice_flow_avf_hdr_field represent individual bit shifts in a hash,
2288 * convert its values to their appropriate flow L3, L4 values.
2289 */
2290#define ICE_FLOW_AVF_RSS_IPV4_MASKS \
2291 (BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_OTHER) | \
2292 BIT_ULL(ICE_AVF_FLOW_FIELD_FRAG_IPV4))
2293#define ICE_FLOW_AVF_RSS_TCP_IPV4_MASKS \
2294 (BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_TCP_SYN_NO_ACK) | \
2295 BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_TCP))
2296#define ICE_FLOW_AVF_RSS_UDP_IPV4_MASKS \
2297 (BIT_ULL(ICE_AVF_FLOW_FIELD_UNICAST_IPV4_UDP) | \
2298 BIT_ULL(ICE_AVF_FLOW_FIELD_MULTICAST_IPV4_UDP) | \
2299 BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_UDP))
2300#define ICE_FLOW_AVF_RSS_ALL_IPV4_MASKS \
2301 (ICE_FLOW_AVF_RSS_TCP_IPV4_MASKS | ICE_FLOW_AVF_RSS_UDP_IPV4_MASKS | \
2302 ICE_FLOW_AVF_RSS_IPV4_MASKS | BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_SCTP))
2303
2304#define ICE_FLOW_AVF_RSS_IPV6_MASKS \
2305 (BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_OTHER) | \
2306 BIT_ULL(ICE_AVF_FLOW_FIELD_FRAG_IPV6))
2307#define ICE_FLOW_AVF_RSS_UDP_IPV6_MASKS \
2308 (BIT_ULL(ICE_AVF_FLOW_FIELD_UNICAST_IPV6_UDP) | \
2309 BIT_ULL(ICE_AVF_FLOW_FIELD_MULTICAST_IPV6_UDP) | \
2310 BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_UDP))
2311#define ICE_FLOW_AVF_RSS_TCP_IPV6_MASKS \
2312 (BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_TCP_SYN_NO_ACK) | \
2313 BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_TCP))
2314#define ICE_FLOW_AVF_RSS_ALL_IPV6_MASKS \
2315 (ICE_FLOW_AVF_RSS_TCP_IPV6_MASKS | ICE_FLOW_AVF_RSS_UDP_IPV6_MASKS | \
2316 ICE_FLOW_AVF_RSS_IPV6_MASKS | BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_SCTP))
2317
2318/**
2319 * ice_add_avf_rss_cfg - add an RSS configuration for AVF driver
2320 * @hw: pointer to the hardware structure
2321 * @vsi_handle: software VSI handle
2322 * @avf_hash: hash bit fields (ICE_AVF_FLOW_FIELD_*) to configure
2323 *
2324 * This function will take the hash bitmap provided by the AVF driver via a
2325 * message, convert it to ICE-compatible values, and configure RSS flow
2326 * profiles.
2327 */
2328int ice_add_avf_rss_cfg(struct ice_hw *hw, u16 vsi_handle, u64 avf_hash)
2329{
2330 int status = 0;
2331 u64 hash_flds;
2332
2333 if (avf_hash == ICE_AVF_FLOW_FIELD_INVALID ||
2334 !ice_is_vsi_valid(hw, vsi_handle))
2335 return -EINVAL;
2336
2337 /* Make sure no unsupported bits are specified */
2338 if (avf_hash & ~(ICE_FLOW_AVF_RSS_ALL_IPV4_MASKS |
2339 ICE_FLOW_AVF_RSS_ALL_IPV6_MASKS))
2340 return -EIO;
2341
2342 hash_flds = avf_hash;
2343
2344 /* Always create an L3 RSS configuration for any L4 RSS configuration */
2345 if (hash_flds & ICE_FLOW_AVF_RSS_ALL_IPV4_MASKS)
2346 hash_flds |= ICE_FLOW_AVF_RSS_IPV4_MASKS;
2347
2348 if (hash_flds & ICE_FLOW_AVF_RSS_ALL_IPV6_MASKS)
2349 hash_flds |= ICE_FLOW_AVF_RSS_IPV6_MASKS;
2350
2351 /* Create the corresponding RSS configuration for each valid hash bit */
2352 while (hash_flds) {
2353 u64 rss_hash = ICE_HASH_INVALID;
2354
2355 if (hash_flds & ICE_FLOW_AVF_RSS_ALL_IPV4_MASKS) {
2356 if (hash_flds & ICE_FLOW_AVF_RSS_IPV4_MASKS) {
2357 rss_hash = ICE_FLOW_HASH_IPV4;
2358 hash_flds &= ~ICE_FLOW_AVF_RSS_IPV4_MASKS;
2359 } else if (hash_flds &
2360 ICE_FLOW_AVF_RSS_TCP_IPV4_MASKS) {
2361 rss_hash = ICE_FLOW_HASH_IPV4 |
2362 ICE_FLOW_HASH_TCP_PORT;
2363 hash_flds &= ~ICE_FLOW_AVF_RSS_TCP_IPV4_MASKS;
2364 } else if (hash_flds &
2365 ICE_FLOW_AVF_RSS_UDP_IPV4_MASKS) {
2366 rss_hash = ICE_FLOW_HASH_IPV4 |
2367 ICE_FLOW_HASH_UDP_PORT;
2368 hash_flds &= ~ICE_FLOW_AVF_RSS_UDP_IPV4_MASKS;
2369 } else if (hash_flds &
2370 BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_SCTP)) {
2371 rss_hash = ICE_FLOW_HASH_IPV4 |
2372 ICE_FLOW_HASH_SCTP_PORT;
2373 hash_flds &=
2374 ~BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_SCTP);
2375 }
2376 } else if (hash_flds & ICE_FLOW_AVF_RSS_ALL_IPV6_MASKS) {
2377 if (hash_flds & ICE_FLOW_AVF_RSS_IPV6_MASKS) {
2378 rss_hash = ICE_FLOW_HASH_IPV6;
2379 hash_flds &= ~ICE_FLOW_AVF_RSS_IPV6_MASKS;
2380 } else if (hash_flds &
2381 ICE_FLOW_AVF_RSS_TCP_IPV6_MASKS) {
2382 rss_hash = ICE_FLOW_HASH_IPV6 |
2383 ICE_FLOW_HASH_TCP_PORT;
2384 hash_flds &= ~ICE_FLOW_AVF_RSS_TCP_IPV6_MASKS;
2385 } else if (hash_flds &
2386 ICE_FLOW_AVF_RSS_UDP_IPV6_MASKS) {
2387 rss_hash = ICE_FLOW_HASH_IPV6 |
2388 ICE_FLOW_HASH_UDP_PORT;
2389 hash_flds &= ~ICE_FLOW_AVF_RSS_UDP_IPV6_MASKS;
2390 } else if (hash_flds &
2391 BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_SCTP)) {
2392 rss_hash = ICE_FLOW_HASH_IPV6 |
2393 ICE_FLOW_HASH_SCTP_PORT;
2394 hash_flds &=
2395 ~BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_SCTP);
2396 }
2397 }
2398
2399 if (rss_hash == ICE_HASH_INVALID)
2400 return -EIO;
2401
2402 status = ice_add_rss_cfg(hw, vsi_handle, rss_hash,
2403 ICE_FLOW_SEG_HDR_NONE);
2404 if (status)
2405 break;
2406 }
2407
2408 return status;
2409}
2410
2411/**
2412 * ice_replay_rss_cfg - replay RSS configurations associated with VSI
2413 * @hw: pointer to the hardware structure
2414 * @vsi_handle: software VSI handle
2415 */
2416int ice_replay_rss_cfg(struct ice_hw *hw, u16 vsi_handle)
2417{
2418 struct ice_rss_cfg *r;
2419 int status = 0;
2420
2421 if (!ice_is_vsi_valid(hw, vsi_handle))
2422 return -EINVAL;
2423
2424 mutex_lock(&hw->rss_locks);
2425 list_for_each_entry(r, &hw->rss_list_head, l_entry) {
2426 if (test_bit(vsi_handle, r->vsis)) {
2427 status = ice_add_rss_cfg_sync(hw, vsi_handle,
2428 r->hashed_flds,
2429 r->packet_hdr,
2430 ICE_RSS_OUTER_HEADERS);
2431 if (status)
2432 break;
2433 status = ice_add_rss_cfg_sync(hw, vsi_handle,
2434 r->hashed_flds,
2435 r->packet_hdr,
2436 ICE_RSS_INNER_HEADERS);
2437 if (status)
2438 break;
2439 }
2440 }
2441 mutex_unlock(&hw->rss_locks);
2442
2443 return status;
2444}
2445
2446/**
2447 * ice_get_rss_cfg - returns hashed fields for the given header types
2448 * @hw: pointer to the hardware structure
2449 * @vsi_handle: software VSI handle
2450 * @hdrs: protocol header type
2451 *
2452 * This function will return the match fields of the first instance of flow
2453 * profile having the given header types and containing input VSI
2454 */
2455u64 ice_get_rss_cfg(struct ice_hw *hw, u16 vsi_handle, u32 hdrs)
2456{
2457 u64 rss_hash = ICE_HASH_INVALID;
2458 struct ice_rss_cfg *r;
2459
2460 /* verify if the protocol header is non zero and VSI is valid */
2461 if (hdrs == ICE_FLOW_SEG_HDR_NONE || !ice_is_vsi_valid(hw, vsi_handle))
2462 return ICE_HASH_INVALID;
2463
2464 mutex_lock(&hw->rss_locks);
2465 list_for_each_entry(r, &hw->rss_list_head, l_entry)
2466 if (test_bit(vsi_handle, r->vsis) &&
2467 r->packet_hdr == hdrs) {
2468 rss_hash = r->hashed_flds;
2469 break;
2470 }
2471 mutex_unlock(&hw->rss_locks);
2472
2473 return rss_hash;
2474}