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