1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (C) 2018-2020, Intel Corporation. */
3
4 #include "ice_common.h"
5
6 /* These are training packet headers used to program flow director filters. */
7 static const u8 ice_fdir_tcpv4_pkt[] = {
8 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00,
10 0x00, 0x28, 0x00, 0x01, 0x00, 0x00, 0x40, 0x06,
11 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
12 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
13 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00,
14 0x20, 0x00, 0x00, 0x00, 0x00, 0x00
15 };
16
17 static const u8 ice_fdir_udpv4_pkt[] = {
18 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
19 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00,
20 0x00, 0x1C, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11,
21 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
22 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
23 0x00, 0x00,
24 };
25
26 static const u8 ice_fdir_sctpv4_pkt[] = {
27 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
28 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00,
29 0x00, 0x20, 0x00, 0x00, 0x40, 0x00, 0x40, 0x84,
30 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
31 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
32 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
33 };
34
35 static const u8 ice_fdir_ipv4_pkt[] = {
36 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
37 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00,
38 0x00, 0x14, 0x00, 0x00, 0x40, 0x00, 0x40, 0x10,
39 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
40 0x00, 0x00
41 };
42
43 static const u8 ice_fdir_tcpv6_pkt[] = {
44 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
45 0x00, 0x00, 0x00, 0x00, 0x86, 0xDD, 0x60, 0x00,
46 0x00, 0x00, 0x00, 0x14, 0x06, 0x40, 0x00, 0x00,
47 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
48 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
49 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
50 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
51 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
52 0x00, 0x00, 0x50, 0x00, 0x20, 0x00, 0x00, 0x00,
53 0x00, 0x00,
54 };
55
56 static const u8 ice_fdir_udpv6_pkt[] = {
57 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
58 0x00, 0x00, 0x00, 0x00, 0x86, 0xDD, 0x60, 0x00,
59 0x00, 0x00, 0x00, 0x08, 0x11, 0x40, 0x00, 0x00,
60 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
61 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
62 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
63 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
64 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
65 };
66
67 static const u8 ice_fdir_sctpv6_pkt[] = {
68 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
69 0x00, 0x00, 0x00, 0x00, 0x86, 0xDD, 0x60, 0x00,
70 0x00, 0x00, 0x00, 0x0C, 0x84, 0x40, 0x00, 0x00,
71 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
72 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
73 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
74 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
75 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
76 0x00, 0x00,
77 };
78
79 static const u8 ice_fdir_ipv6_pkt[] = {
80 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
81 0x00, 0x00, 0x00, 0x00, 0x86, 0xDD, 0x60, 0x00,
82 0x00, 0x00, 0x00, 0x00, 0x3B, 0x40, 0x00, 0x00,
83 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
84 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
85 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
86 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
87 };
88
89 static const u8 ice_fdir_tcp4_tun_pkt[] = {
90 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
91 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00,
92 0x00, 0x5a, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11,
93 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
94 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
95 0x00, 0x00, 0x04, 0x00, 0x00, 0x03, 0x00, 0x00,
96 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
97 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
98 0x45, 0x00, 0x00, 0x28, 0x00, 0x00, 0x40, 0x00,
99 0x40, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
100 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
101 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
102 0x50, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00,
103 };
104
105 static const u8 ice_fdir_udp4_tun_pkt[] = {
106 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
107 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00,
108 0x00, 0x4e, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11,
109 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
110 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
111 0x00, 0x00, 0x04, 0x00, 0x00, 0x03, 0x00, 0x00,
112 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
113 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
114 0x45, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x40, 0x00,
115 0x40, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
116 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
117 0x00, 0x00, 0x00, 0x00,
118 };
119
120 static const u8 ice_fdir_sctp4_tun_pkt[] = {
121 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
122 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00,
123 0x00, 0x52, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11,
124 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
125 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
126 0x00, 0x00, 0x04, 0x00, 0x00, 0x03, 0x00, 0x00,
127 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
128 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
129 0x45, 0x00, 0x00, 0x20, 0x00, 0x01, 0x00, 0x00,
130 0x40, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
131 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
132 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
133 };
134
135 static const u8 ice_fdir_ip4_tun_pkt[] = {
136 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
137 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00,
138 0x00, 0x46, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11,
139 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
140 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
141 0x00, 0x00, 0x04, 0x00, 0x00, 0x03, 0x00, 0x00,
142 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
143 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
144 0x45, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00,
145 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
146 0x00, 0x00, 0x00, 0x00,
147 };
148
149 static const u8 ice_fdir_tcp6_tun_pkt[] = {
150 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
151 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00,
152 0x00, 0x6e, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11,
153 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
154 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
155 0x00, 0x00, 0x04, 0x00, 0x00, 0x03, 0x00, 0x00,
156 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
157 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0xdd,
158 0x60, 0x00, 0x00, 0x00, 0x00, 0x14, 0x06, 0x40,
159 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
160 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
161 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
162 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
163 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
164 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x20, 0x00,
165 0x00, 0x00, 0x00, 0x00,
166 };
167
168 static const u8 ice_fdir_udp6_tun_pkt[] = {
169 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
170 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00,
171 0x00, 0x62, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11,
172 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
173 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
174 0x00, 0x00, 0x04, 0x00, 0x00, 0x03, 0x00, 0x00,
175 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
176 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0xdd,
177 0x60, 0x00, 0x00, 0x00, 0x00, 0x08, 0x11, 0x40,
178 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
179 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
180 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
181 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
182 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
183 };
184
185 static const u8 ice_fdir_sctp6_tun_pkt[] = {
186 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
187 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00,
188 0x00, 0x66, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11,
189 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
190 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
191 0x00, 0x00, 0x04, 0x00, 0x00, 0x03, 0x00, 0x00,
192 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
193 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0xdd,
194 0x60, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x84, 0x40,
195 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
196 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
197 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
198 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
199 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
200 0x00, 0x00, 0x00, 0x00,
201 };
202
203 static const u8 ice_fdir_ip6_tun_pkt[] = {
204 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
205 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00,
206 0x00, 0x5a, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11,
207 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
208 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
209 0x00, 0x00, 0x04, 0x00, 0x00, 0x03, 0x00, 0x00,
210 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
211 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0xdd,
212 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3b, 0x40,
213 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
214 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
215 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
216 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
217 };
218
219 /* Flow Director no-op training packet table */
220 static const struct ice_fdir_base_pkt ice_fdir_pkt[] = {
221 {
222 ICE_FLTR_PTYPE_NONF_IPV4_TCP,
223 sizeof(ice_fdir_tcpv4_pkt), ice_fdir_tcpv4_pkt,
224 sizeof(ice_fdir_tcp4_tun_pkt), ice_fdir_tcp4_tun_pkt,
225 },
226 {
227 ICE_FLTR_PTYPE_NONF_IPV4_UDP,
228 sizeof(ice_fdir_udpv4_pkt), ice_fdir_udpv4_pkt,
229 sizeof(ice_fdir_udp4_tun_pkt), ice_fdir_udp4_tun_pkt,
230 },
231 {
232 ICE_FLTR_PTYPE_NONF_IPV4_SCTP,
233 sizeof(ice_fdir_sctpv4_pkt), ice_fdir_sctpv4_pkt,
234 sizeof(ice_fdir_sctp4_tun_pkt), ice_fdir_sctp4_tun_pkt,
235 },
236 {
237 ICE_FLTR_PTYPE_NONF_IPV4_OTHER,
238 sizeof(ice_fdir_ipv4_pkt), ice_fdir_ipv4_pkt,
239 sizeof(ice_fdir_ip4_tun_pkt), ice_fdir_ip4_tun_pkt,
240 },
241 {
242 ICE_FLTR_PTYPE_NONF_IPV6_TCP,
243 sizeof(ice_fdir_tcpv6_pkt), ice_fdir_tcpv6_pkt,
244 sizeof(ice_fdir_tcp6_tun_pkt), ice_fdir_tcp6_tun_pkt,
245 },
246 {
247 ICE_FLTR_PTYPE_NONF_IPV6_UDP,
248 sizeof(ice_fdir_udpv6_pkt), ice_fdir_udpv6_pkt,
249 sizeof(ice_fdir_udp6_tun_pkt), ice_fdir_udp6_tun_pkt,
250 },
251 {
252 ICE_FLTR_PTYPE_NONF_IPV6_SCTP,
253 sizeof(ice_fdir_sctpv6_pkt), ice_fdir_sctpv6_pkt,
254 sizeof(ice_fdir_sctp6_tun_pkt), ice_fdir_sctp6_tun_pkt,
255 },
256 {
257 ICE_FLTR_PTYPE_NONF_IPV6_OTHER,
258 sizeof(ice_fdir_ipv6_pkt), ice_fdir_ipv6_pkt,
259 sizeof(ice_fdir_ip6_tun_pkt), ice_fdir_ip6_tun_pkt,
260 },
261 };
262
263 #define ICE_FDIR_NUM_PKT ARRAY_SIZE(ice_fdir_pkt)
264
265 /**
266 * ice_set_dflt_val_fd_desc
267 * @fd_fltr_ctx: pointer to fd filter descriptor
268 */
ice_set_dflt_val_fd_desc(struct ice_fd_fltr_desc_ctx * fd_fltr_ctx)269 static void ice_set_dflt_val_fd_desc(struct ice_fd_fltr_desc_ctx *fd_fltr_ctx)
270 {
271 fd_fltr_ctx->comp_q = ICE_FXD_FLTR_QW0_COMP_Q_ZERO;
272 fd_fltr_ctx->comp_report = ICE_FXD_FLTR_QW0_COMP_REPORT_SW_FAIL;
273 fd_fltr_ctx->fd_space = ICE_FXD_FLTR_QW0_FD_SPACE_GUAR_BEST;
274 fd_fltr_ctx->cnt_ena = ICE_FXD_FLTR_QW0_STAT_ENA_PKTS;
275 fd_fltr_ctx->evict_ena = ICE_FXD_FLTR_QW0_EVICT_ENA_TRUE;
276 fd_fltr_ctx->toq = ICE_FXD_FLTR_QW0_TO_Q_EQUALS_QINDEX;
277 fd_fltr_ctx->toq_prio = ICE_FXD_FLTR_QW0_TO_Q_PRIO1;
278 fd_fltr_ctx->dpu_recipe = ICE_FXD_FLTR_QW0_DPU_RECIPE_DFLT;
279 fd_fltr_ctx->drop = ICE_FXD_FLTR_QW0_DROP_NO;
280 fd_fltr_ctx->flex_prio = ICE_FXD_FLTR_QW0_FLEX_PRI_NONE;
281 fd_fltr_ctx->flex_mdid = ICE_FXD_FLTR_QW0_FLEX_MDID0;
282 fd_fltr_ctx->flex_val = ICE_FXD_FLTR_QW0_FLEX_VAL0;
283 fd_fltr_ctx->dtype = ICE_TX_DESC_DTYPE_FLTR_PROG;
284 fd_fltr_ctx->desc_prof_prio = ICE_FXD_FLTR_QW1_PROF_PRIO_ZERO;
285 fd_fltr_ctx->desc_prof = ICE_FXD_FLTR_QW1_PROF_ZERO;
286 fd_fltr_ctx->swap = ICE_FXD_FLTR_QW1_SWAP_SET;
287 fd_fltr_ctx->fdid_prio = ICE_FXD_FLTR_QW1_FDID_PRI_ONE;
288 fd_fltr_ctx->fdid_mdid = ICE_FXD_FLTR_QW1_FDID_MDID_FD;
289 fd_fltr_ctx->fdid = ICE_FXD_FLTR_QW1_FDID_ZERO;
290 }
291
292 /**
293 * ice_set_fd_desc_val
294 * @ctx: pointer to fd filter descriptor context
295 * @fdir_desc: populated with fd filter descriptor values
296 */
297 static void
ice_set_fd_desc_val(struct ice_fd_fltr_desc_ctx * ctx,struct ice_fltr_desc * fdir_desc)298 ice_set_fd_desc_val(struct ice_fd_fltr_desc_ctx *ctx,
299 struct ice_fltr_desc *fdir_desc)
300 {
301 u64 qword;
302
303 /* prep QW0 of FD filter programming desc */
304 qword = ((u64)ctx->qindex << ICE_FXD_FLTR_QW0_QINDEX_S) &
305 ICE_FXD_FLTR_QW0_QINDEX_M;
306 qword |= ((u64)ctx->comp_q << ICE_FXD_FLTR_QW0_COMP_Q_S) &
307 ICE_FXD_FLTR_QW0_COMP_Q_M;
308 qword |= ((u64)ctx->comp_report << ICE_FXD_FLTR_QW0_COMP_REPORT_S) &
309 ICE_FXD_FLTR_QW0_COMP_REPORT_M;
310 qword |= ((u64)ctx->fd_space << ICE_FXD_FLTR_QW0_FD_SPACE_S) &
311 ICE_FXD_FLTR_QW0_FD_SPACE_M;
312 qword |= ((u64)ctx->cnt_index << ICE_FXD_FLTR_QW0_STAT_CNT_S) &
313 ICE_FXD_FLTR_QW0_STAT_CNT_M;
314 qword |= ((u64)ctx->cnt_ena << ICE_FXD_FLTR_QW0_STAT_ENA_S) &
315 ICE_FXD_FLTR_QW0_STAT_ENA_M;
316 qword |= ((u64)ctx->evict_ena << ICE_FXD_FLTR_QW0_EVICT_ENA_S) &
317 ICE_FXD_FLTR_QW0_EVICT_ENA_M;
318 qword |= ((u64)ctx->toq << ICE_FXD_FLTR_QW0_TO_Q_S) &
319 ICE_FXD_FLTR_QW0_TO_Q_M;
320 qword |= ((u64)ctx->toq_prio << ICE_FXD_FLTR_QW0_TO_Q_PRI_S) &
321 ICE_FXD_FLTR_QW0_TO_Q_PRI_M;
322 qword |= ((u64)ctx->dpu_recipe << ICE_FXD_FLTR_QW0_DPU_RECIPE_S) &
323 ICE_FXD_FLTR_QW0_DPU_RECIPE_M;
324 qword |= ((u64)ctx->drop << ICE_FXD_FLTR_QW0_DROP_S) &
325 ICE_FXD_FLTR_QW0_DROP_M;
326 qword |= ((u64)ctx->flex_prio << ICE_FXD_FLTR_QW0_FLEX_PRI_S) &
327 ICE_FXD_FLTR_QW0_FLEX_PRI_M;
328 qword |= ((u64)ctx->flex_mdid << ICE_FXD_FLTR_QW0_FLEX_MDID_S) &
329 ICE_FXD_FLTR_QW0_FLEX_MDID_M;
330 qword |= ((u64)ctx->flex_val << ICE_FXD_FLTR_QW0_FLEX_VAL_S) &
331 ICE_FXD_FLTR_QW0_FLEX_VAL_M;
332 fdir_desc->qidx_compq_space_stat = cpu_to_le64(qword);
333
334 /* prep QW1 of FD filter programming desc */
335 qword = ((u64)ctx->dtype << ICE_FXD_FLTR_QW1_DTYPE_S) &
336 ICE_FXD_FLTR_QW1_DTYPE_M;
337 qword |= ((u64)ctx->pcmd << ICE_FXD_FLTR_QW1_PCMD_S) &
338 ICE_FXD_FLTR_QW1_PCMD_M;
339 qword |= ((u64)ctx->desc_prof_prio << ICE_FXD_FLTR_QW1_PROF_PRI_S) &
340 ICE_FXD_FLTR_QW1_PROF_PRI_M;
341 qword |= ((u64)ctx->desc_prof << ICE_FXD_FLTR_QW1_PROF_S) &
342 ICE_FXD_FLTR_QW1_PROF_M;
343 qword |= ((u64)ctx->fd_vsi << ICE_FXD_FLTR_QW1_FD_VSI_S) &
344 ICE_FXD_FLTR_QW1_FD_VSI_M;
345 qword |= ((u64)ctx->swap << ICE_FXD_FLTR_QW1_SWAP_S) &
346 ICE_FXD_FLTR_QW1_SWAP_M;
347 qword |= ((u64)ctx->fdid_prio << ICE_FXD_FLTR_QW1_FDID_PRI_S) &
348 ICE_FXD_FLTR_QW1_FDID_PRI_M;
349 qword |= ((u64)ctx->fdid_mdid << ICE_FXD_FLTR_QW1_FDID_MDID_S) &
350 ICE_FXD_FLTR_QW1_FDID_MDID_M;
351 qword |= ((u64)ctx->fdid << ICE_FXD_FLTR_QW1_FDID_S) &
352 ICE_FXD_FLTR_QW1_FDID_M;
353 fdir_desc->dtype_cmd_vsi_fdid = cpu_to_le64(qword);
354 }
355
356 /**
357 * ice_fdir_get_prgm_desc - set a fdir descriptor from a fdir filter struct
358 * @hw: pointer to the hardware structure
359 * @input: filter
360 * @fdesc: filter descriptor
361 * @add: if add is true, this is an add operation, false implies delete
362 */
363 void
ice_fdir_get_prgm_desc(struct ice_hw * hw,struct ice_fdir_fltr * input,struct ice_fltr_desc * fdesc,bool add)364 ice_fdir_get_prgm_desc(struct ice_hw *hw, struct ice_fdir_fltr *input,
365 struct ice_fltr_desc *fdesc, bool add)
366 {
367 struct ice_fd_fltr_desc_ctx fdir_fltr_ctx = { 0 };
368
369 /* set default context info */
370 ice_set_dflt_val_fd_desc(&fdir_fltr_ctx);
371
372 /* change sideband filtering values */
373 fdir_fltr_ctx.fdid = input->fltr_id;
374 if (input->dest_ctl == ICE_FLTR_PRGM_DESC_DEST_DROP_PKT) {
375 fdir_fltr_ctx.drop = ICE_FXD_FLTR_QW0_DROP_YES;
376 fdir_fltr_ctx.qindex = 0;
377 } else {
378 fdir_fltr_ctx.drop = ICE_FXD_FLTR_QW0_DROP_NO;
379 fdir_fltr_ctx.qindex = input->q_index;
380 }
381 fdir_fltr_ctx.cnt_ena = ICE_FXD_FLTR_QW0_STAT_ENA_PKTS;
382 fdir_fltr_ctx.cnt_index = input->cnt_index;
383 fdir_fltr_ctx.fd_vsi = ice_get_hw_vsi_num(hw, input->dest_vsi);
384 fdir_fltr_ctx.evict_ena = ICE_FXD_FLTR_QW0_EVICT_ENA_FALSE;
385 fdir_fltr_ctx.toq_prio = 3;
386 fdir_fltr_ctx.pcmd = add ? ICE_FXD_FLTR_QW1_PCMD_ADD :
387 ICE_FXD_FLTR_QW1_PCMD_REMOVE;
388 fdir_fltr_ctx.swap = ICE_FXD_FLTR_QW1_SWAP_NOT_SET;
389 fdir_fltr_ctx.comp_q = ICE_FXD_FLTR_QW0_COMP_Q_ZERO;
390 fdir_fltr_ctx.comp_report = ICE_FXD_FLTR_QW0_COMP_REPORT_SW_FAIL;
391 fdir_fltr_ctx.fdid_prio = 3;
392 fdir_fltr_ctx.desc_prof = 1;
393 fdir_fltr_ctx.desc_prof_prio = 3;
394 ice_set_fd_desc_val(&fdir_fltr_ctx, fdesc);
395 }
396
397 /**
398 * ice_alloc_fd_res_cntr - obtain counter resource for FD type
399 * @hw: pointer to the hardware structure
400 * @cntr_id: returns counter index
401 */
ice_alloc_fd_res_cntr(struct ice_hw * hw,u16 * cntr_id)402 enum ice_status ice_alloc_fd_res_cntr(struct ice_hw *hw, u16 *cntr_id)
403 {
404 return ice_alloc_res_cntr(hw, ICE_AQC_RES_TYPE_FDIR_COUNTER_BLOCK,
405 ICE_AQC_RES_TYPE_FLAG_DEDICATED, 1, cntr_id);
406 }
407
408 /**
409 * ice_free_fd_res_cntr - Free counter resource for FD type
410 * @hw: pointer to the hardware structure
411 * @cntr_id: counter index to be freed
412 */
ice_free_fd_res_cntr(struct ice_hw * hw,u16 cntr_id)413 enum ice_status ice_free_fd_res_cntr(struct ice_hw *hw, u16 cntr_id)
414 {
415 return ice_free_res_cntr(hw, ICE_AQC_RES_TYPE_FDIR_COUNTER_BLOCK,
416 ICE_AQC_RES_TYPE_FLAG_DEDICATED, 1, cntr_id);
417 }
418
419 /**
420 * ice_alloc_fd_guar_item - allocate resource for FD guaranteed entries
421 * @hw: pointer to the hardware structure
422 * @cntr_id: returns counter index
423 * @num_fltr: number of filter entries to be allocated
424 */
425 enum ice_status
ice_alloc_fd_guar_item(struct ice_hw * hw,u16 * cntr_id,u16 num_fltr)426 ice_alloc_fd_guar_item(struct ice_hw *hw, u16 *cntr_id, u16 num_fltr)
427 {
428 return ice_alloc_res_cntr(hw, ICE_AQC_RES_TYPE_FDIR_GUARANTEED_ENTRIES,
429 ICE_AQC_RES_TYPE_FLAG_DEDICATED, num_fltr,
430 cntr_id);
431 }
432
433 /**
434 * ice_alloc_fd_shrd_item - allocate resource for flow director shared entries
435 * @hw: pointer to the hardware structure
436 * @cntr_id: returns counter index
437 * @num_fltr: number of filter entries to be allocated
438 */
439 enum ice_status
ice_alloc_fd_shrd_item(struct ice_hw * hw,u16 * cntr_id,u16 num_fltr)440 ice_alloc_fd_shrd_item(struct ice_hw *hw, u16 *cntr_id, u16 num_fltr)
441 {
442 return ice_alloc_res_cntr(hw, ICE_AQC_RES_TYPE_FDIR_SHARED_ENTRIES,
443 ICE_AQC_RES_TYPE_FLAG_DEDICATED, num_fltr,
444 cntr_id);
445 }
446
447 /**
448 * ice_get_fdir_cnt_all - get the number of Flow Director filters
449 * @hw: hardware data structure
450 *
451 * Returns the number of filters available on device
452 */
ice_get_fdir_cnt_all(struct ice_hw * hw)453 int ice_get_fdir_cnt_all(struct ice_hw *hw)
454 {
455 return hw->func_caps.fd_fltr_guar + hw->func_caps.fd_fltr_best_effort;
456 }
457
458 /**
459 * ice_pkt_insert_ipv6_addr - insert a be32 IPv6 address into a memory buffer
460 * @pkt: packet buffer
461 * @offset: offset into buffer
462 * @addr: IPv6 address to convert and insert into pkt at offset
463 */
ice_pkt_insert_ipv6_addr(u8 * pkt,int offset,__be32 * addr)464 static void ice_pkt_insert_ipv6_addr(u8 *pkt, int offset, __be32 *addr)
465 {
466 int idx;
467
468 for (idx = 0; idx < ICE_IPV6_ADDR_LEN_AS_U32; idx++)
469 memcpy(pkt + offset + idx * sizeof(*addr), &addr[idx],
470 sizeof(*addr));
471 }
472
473 /**
474 * ice_pkt_insert_u16 - insert a be16 value into a memory buffer
475 * @pkt: packet buffer
476 * @offset: offset into buffer
477 * @data: 16 bit value to convert and insert into pkt at offset
478 */
ice_pkt_insert_u16(u8 * pkt,int offset,__be16 data)479 static void ice_pkt_insert_u16(u8 *pkt, int offset, __be16 data)
480 {
481 memcpy(pkt + offset, &data, sizeof(data));
482 }
483
484 /**
485 * ice_pkt_insert_u32 - insert a be32 value into a memory buffer
486 * @pkt: packet buffer
487 * @offset: offset into buffer
488 * @data: 32 bit value to convert and insert into pkt at offset
489 */
ice_pkt_insert_u32(u8 * pkt,int offset,__be32 data)490 static void ice_pkt_insert_u32(u8 *pkt, int offset, __be32 data)
491 {
492 memcpy(pkt + offset, &data, sizeof(data));
493 }
494
495 /**
496 * ice_fdir_get_gen_prgm_pkt - generate a training packet
497 * @hw: pointer to the hardware structure
498 * @input: flow director filter data structure
499 * @pkt: pointer to return filter packet
500 * @frag: generate a fragment packet
501 * @tun: true implies generate a tunnel packet
502 */
503 enum ice_status
ice_fdir_get_gen_prgm_pkt(struct ice_hw * hw,struct ice_fdir_fltr * input,u8 * pkt,bool frag,bool tun)504 ice_fdir_get_gen_prgm_pkt(struct ice_hw *hw, struct ice_fdir_fltr *input,
505 u8 *pkt, bool frag, bool tun)
506 {
507 enum ice_fltr_ptype flow;
508 u16 tnl_port;
509 u8 *loc;
510 u16 idx;
511
512 if (input->flow_type == ICE_FLTR_PTYPE_NONF_IPV4_OTHER) {
513 switch (input->ip.v4.proto) {
514 case IPPROTO_TCP:
515 flow = ICE_FLTR_PTYPE_NONF_IPV4_TCP;
516 break;
517 case IPPROTO_UDP:
518 flow = ICE_FLTR_PTYPE_NONF_IPV4_UDP;
519 break;
520 case IPPROTO_SCTP:
521 flow = ICE_FLTR_PTYPE_NONF_IPV4_SCTP;
522 break;
523 case IPPROTO_IP:
524 flow = ICE_FLTR_PTYPE_NONF_IPV4_OTHER;
525 break;
526 default:
527 return ICE_ERR_PARAM;
528 }
529 } else if (input->flow_type == ICE_FLTR_PTYPE_NONF_IPV6_OTHER) {
530 switch (input->ip.v6.proto) {
531 case IPPROTO_TCP:
532 flow = ICE_FLTR_PTYPE_NONF_IPV6_TCP;
533 break;
534 case IPPROTO_UDP:
535 flow = ICE_FLTR_PTYPE_NONF_IPV6_UDP;
536 break;
537 case IPPROTO_SCTP:
538 flow = ICE_FLTR_PTYPE_NONF_IPV6_SCTP;
539 break;
540 case IPPROTO_IP:
541 flow = ICE_FLTR_PTYPE_NONF_IPV6_OTHER;
542 break;
543 default:
544 return ICE_ERR_PARAM;
545 }
546 } else {
547 flow = input->flow_type;
548 }
549
550 for (idx = 0; idx < ICE_FDIR_NUM_PKT; idx++)
551 if (ice_fdir_pkt[idx].flow == flow)
552 break;
553 if (idx == ICE_FDIR_NUM_PKT)
554 return ICE_ERR_PARAM;
555 if (!tun) {
556 memcpy(pkt, ice_fdir_pkt[idx].pkt, ice_fdir_pkt[idx].pkt_len);
557 loc = pkt;
558 } else {
559 if (!ice_get_open_tunnel_port(hw, &tnl_port))
560 return ICE_ERR_DOES_NOT_EXIST;
561 if (!ice_fdir_pkt[idx].tun_pkt)
562 return ICE_ERR_PARAM;
563 memcpy(pkt, ice_fdir_pkt[idx].tun_pkt,
564 ice_fdir_pkt[idx].tun_pkt_len);
565 ice_pkt_insert_u16(pkt, ICE_IPV4_UDP_DST_PORT_OFFSET,
566 htons(tnl_port));
567 loc = &pkt[ICE_FDIR_TUN_PKT_OFF];
568 }
569
570 /* Reverse the src and dst, since the HW expects them to be from Tx
571 * perspective. The input from user is from Rx filter perspective.
572 */
573 switch (flow) {
574 case ICE_FLTR_PTYPE_NONF_IPV4_TCP:
575 ice_pkt_insert_u32(loc, ICE_IPV4_DST_ADDR_OFFSET,
576 input->ip.v4.src_ip);
577 ice_pkt_insert_u16(loc, ICE_IPV4_TCP_DST_PORT_OFFSET,
578 input->ip.v4.src_port);
579 ice_pkt_insert_u32(loc, ICE_IPV4_SRC_ADDR_OFFSET,
580 input->ip.v4.dst_ip);
581 ice_pkt_insert_u16(loc, ICE_IPV4_TCP_SRC_PORT_OFFSET,
582 input->ip.v4.dst_port);
583 if (frag)
584 loc[20] = ICE_FDIR_IPV4_PKT_FLAG_DF;
585 break;
586 case ICE_FLTR_PTYPE_NONF_IPV4_UDP:
587 ice_pkt_insert_u32(loc, ICE_IPV4_DST_ADDR_OFFSET,
588 input->ip.v4.src_ip);
589 ice_pkt_insert_u16(loc, ICE_IPV4_UDP_DST_PORT_OFFSET,
590 input->ip.v4.src_port);
591 ice_pkt_insert_u32(loc, ICE_IPV4_SRC_ADDR_OFFSET,
592 input->ip.v4.dst_ip);
593 ice_pkt_insert_u16(loc, ICE_IPV4_UDP_SRC_PORT_OFFSET,
594 input->ip.v4.dst_port);
595 break;
596 case ICE_FLTR_PTYPE_NONF_IPV4_SCTP:
597 ice_pkt_insert_u32(loc, ICE_IPV4_DST_ADDR_OFFSET,
598 input->ip.v4.src_ip);
599 ice_pkt_insert_u16(loc, ICE_IPV4_SCTP_DST_PORT_OFFSET,
600 input->ip.v4.src_port);
601 ice_pkt_insert_u32(loc, ICE_IPV4_SRC_ADDR_OFFSET,
602 input->ip.v4.dst_ip);
603 ice_pkt_insert_u16(loc, ICE_IPV4_SCTP_SRC_PORT_OFFSET,
604 input->ip.v4.dst_port);
605 break;
606 case ICE_FLTR_PTYPE_NONF_IPV4_OTHER:
607 ice_pkt_insert_u32(loc, ICE_IPV4_DST_ADDR_OFFSET,
608 input->ip.v4.src_ip);
609 ice_pkt_insert_u32(loc, ICE_IPV4_SRC_ADDR_OFFSET,
610 input->ip.v4.dst_ip);
611 ice_pkt_insert_u16(loc, ICE_IPV4_PROTO_OFFSET, 0);
612 break;
613 case ICE_FLTR_PTYPE_NONF_IPV6_TCP:
614 ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_DST_ADDR_OFFSET,
615 input->ip.v6.src_ip);
616 ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_SRC_ADDR_OFFSET,
617 input->ip.v6.dst_ip);
618 ice_pkt_insert_u16(loc, ICE_IPV6_TCP_DST_PORT_OFFSET,
619 input->ip.v6.src_port);
620 ice_pkt_insert_u16(loc, ICE_IPV6_TCP_SRC_PORT_OFFSET,
621 input->ip.v6.dst_port);
622 break;
623 case ICE_FLTR_PTYPE_NONF_IPV6_UDP:
624 ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_DST_ADDR_OFFSET,
625 input->ip.v6.src_ip);
626 ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_SRC_ADDR_OFFSET,
627 input->ip.v6.dst_ip);
628 ice_pkt_insert_u16(loc, ICE_IPV6_UDP_DST_PORT_OFFSET,
629 input->ip.v6.src_port);
630 ice_pkt_insert_u16(loc, ICE_IPV6_UDP_SRC_PORT_OFFSET,
631 input->ip.v6.dst_port);
632 break;
633 case ICE_FLTR_PTYPE_NONF_IPV6_SCTP:
634 ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_DST_ADDR_OFFSET,
635 input->ip.v6.src_ip);
636 ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_SRC_ADDR_OFFSET,
637 input->ip.v6.dst_ip);
638 ice_pkt_insert_u16(loc, ICE_IPV6_SCTP_DST_PORT_OFFSET,
639 input->ip.v6.src_port);
640 ice_pkt_insert_u16(loc, ICE_IPV6_SCTP_SRC_PORT_OFFSET,
641 input->ip.v6.dst_port);
642 break;
643 case ICE_FLTR_PTYPE_NONF_IPV6_OTHER:
644 ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_DST_ADDR_OFFSET,
645 input->ip.v6.src_ip);
646 ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_SRC_ADDR_OFFSET,
647 input->ip.v6.dst_ip);
648 break;
649 default:
650 return ICE_ERR_PARAM;
651 }
652
653 if (input->flex_fltr)
654 ice_pkt_insert_u16(loc, input->flex_offset, input->flex_word);
655
656 return 0;
657 }
658
659 /**
660 * ice_fdir_has_frag - does flow type have 2 ptypes
661 * @flow: flow ptype
662 *
663 * returns true is there is a fragment packet for this ptype
664 */
ice_fdir_has_frag(enum ice_fltr_ptype flow)665 bool ice_fdir_has_frag(enum ice_fltr_ptype flow)
666 {
667 if (flow == ICE_FLTR_PTYPE_NONF_IPV4_OTHER)
668 return true;
669 else
670 return false;
671 }
672
673 /**
674 * ice_fdir_find_by_idx - find filter with idx
675 * @hw: pointer to hardware structure
676 * @fltr_idx: index to find.
677 *
678 * Returns pointer to filter if found or null
679 */
680 struct ice_fdir_fltr *
ice_fdir_find_fltr_by_idx(struct ice_hw * hw,u32 fltr_idx)681 ice_fdir_find_fltr_by_idx(struct ice_hw *hw, u32 fltr_idx)
682 {
683 struct ice_fdir_fltr *rule;
684
685 list_for_each_entry(rule, &hw->fdir_list_head, fltr_node) {
686 /* rule ID found in the list */
687 if (fltr_idx == rule->fltr_id)
688 return rule;
689 if (fltr_idx < rule->fltr_id)
690 break;
691 }
692 return NULL;
693 }
694
695 /**
696 * ice_fdir_list_add_fltr - add a new node to the flow director filter list
697 * @hw: hardware structure
698 * @fltr: filter node to add to structure
699 */
ice_fdir_list_add_fltr(struct ice_hw * hw,struct ice_fdir_fltr * fltr)700 void ice_fdir_list_add_fltr(struct ice_hw *hw, struct ice_fdir_fltr *fltr)
701 {
702 struct ice_fdir_fltr *rule, *parent = NULL;
703
704 list_for_each_entry(rule, &hw->fdir_list_head, fltr_node) {
705 /* rule ID found or pass its spot in the list */
706 if (rule->fltr_id >= fltr->fltr_id)
707 break;
708 parent = rule;
709 }
710
711 if (parent)
712 list_add(&fltr->fltr_node, &parent->fltr_node);
713 else
714 list_add(&fltr->fltr_node, &hw->fdir_list_head);
715 }
716
717 /**
718 * ice_fdir_update_cntrs - increment / decrement filter counter
719 * @hw: pointer to hardware structure
720 * @flow: filter flow type
721 * @add: true implies filters added
722 */
723 void
ice_fdir_update_cntrs(struct ice_hw * hw,enum ice_fltr_ptype flow,bool add)724 ice_fdir_update_cntrs(struct ice_hw *hw, enum ice_fltr_ptype flow, bool add)
725 {
726 int incr;
727
728 incr = add ? 1 : -1;
729 hw->fdir_active_fltr += incr;
730
731 if (flow == ICE_FLTR_PTYPE_NONF_NONE || flow >= ICE_FLTR_PTYPE_MAX)
732 ice_debug(hw, ICE_DBG_SW, "Unknown filter type %d\n", flow);
733 else
734 hw->fdir_fltr_cnt[flow] += incr;
735 }
736
737 /**
738 * ice_cmp_ipv6_addr - compare 2 IP v6 addresses
739 * @a: IP v6 address
740 * @b: IP v6 address
741 *
742 * Returns 0 on equal, returns non-0 if different
743 */
ice_cmp_ipv6_addr(__be32 * a,__be32 * b)744 static int ice_cmp_ipv6_addr(__be32 *a, __be32 *b)
745 {
746 return memcmp(a, b, 4 * sizeof(__be32));
747 }
748
749 /**
750 * ice_fdir_comp_rules - compare 2 filters
751 * @a: a Flow Director filter data structure
752 * @b: a Flow Director filter data structure
753 * @v6: bool true if v6 filter
754 *
755 * Returns true if the filters match
756 */
757 static bool
ice_fdir_comp_rules(struct ice_fdir_fltr * a,struct ice_fdir_fltr * b,bool v6)758 ice_fdir_comp_rules(struct ice_fdir_fltr *a, struct ice_fdir_fltr *b, bool v6)
759 {
760 enum ice_fltr_ptype flow_type = a->flow_type;
761
762 /* The calling function already checks that the two filters have the
763 * same flow_type.
764 */
765 if (!v6) {
766 if (flow_type == ICE_FLTR_PTYPE_NONF_IPV4_TCP ||
767 flow_type == ICE_FLTR_PTYPE_NONF_IPV4_UDP ||
768 flow_type == ICE_FLTR_PTYPE_NONF_IPV4_SCTP) {
769 if (a->ip.v4.dst_ip == b->ip.v4.dst_ip &&
770 a->ip.v4.src_ip == b->ip.v4.src_ip &&
771 a->ip.v4.dst_port == b->ip.v4.dst_port &&
772 a->ip.v4.src_port == b->ip.v4.src_port)
773 return true;
774 } else if (flow_type == ICE_FLTR_PTYPE_NONF_IPV4_OTHER) {
775 if (a->ip.v4.dst_ip == b->ip.v4.dst_ip &&
776 a->ip.v4.src_ip == b->ip.v4.src_ip &&
777 a->ip.v4.l4_header == b->ip.v4.l4_header &&
778 a->ip.v4.proto == b->ip.v4.proto &&
779 a->ip.v4.ip_ver == b->ip.v4.ip_ver &&
780 a->ip.v4.tos == b->ip.v4.tos)
781 return true;
782 }
783 } else {
784 if (flow_type == ICE_FLTR_PTYPE_NONF_IPV6_UDP ||
785 flow_type == ICE_FLTR_PTYPE_NONF_IPV6_TCP ||
786 flow_type == ICE_FLTR_PTYPE_NONF_IPV6_SCTP) {
787 if (a->ip.v6.dst_port == b->ip.v6.dst_port &&
788 a->ip.v6.src_port == b->ip.v6.src_port &&
789 !ice_cmp_ipv6_addr(a->ip.v6.dst_ip,
790 b->ip.v6.dst_ip) &&
791 !ice_cmp_ipv6_addr(a->ip.v6.src_ip,
792 b->ip.v6.src_ip))
793 return true;
794 } else if (flow_type == ICE_FLTR_PTYPE_NONF_IPV6_OTHER) {
795 if (a->ip.v6.dst_port == b->ip.v6.dst_port &&
796 a->ip.v6.src_port == b->ip.v6.src_port)
797 return true;
798 }
799 }
800
801 return false;
802 }
803
804 /**
805 * ice_fdir_is_dup_fltr - test if filter is already in list for PF
806 * @hw: hardware data structure
807 * @input: Flow Director filter data structure
808 *
809 * Returns true if the filter is found in the list
810 */
ice_fdir_is_dup_fltr(struct ice_hw * hw,struct ice_fdir_fltr * input)811 bool ice_fdir_is_dup_fltr(struct ice_hw *hw, struct ice_fdir_fltr *input)
812 {
813 struct ice_fdir_fltr *rule;
814 bool ret = false;
815
816 list_for_each_entry(rule, &hw->fdir_list_head, fltr_node) {
817 enum ice_fltr_ptype flow_type;
818
819 if (rule->flow_type != input->flow_type)
820 continue;
821
822 flow_type = input->flow_type;
823 if (flow_type == ICE_FLTR_PTYPE_NONF_IPV4_TCP ||
824 flow_type == ICE_FLTR_PTYPE_NONF_IPV4_UDP ||
825 flow_type == ICE_FLTR_PTYPE_NONF_IPV4_SCTP ||
826 flow_type == ICE_FLTR_PTYPE_NONF_IPV4_OTHER)
827 ret = ice_fdir_comp_rules(rule, input, false);
828 else
829 ret = ice_fdir_comp_rules(rule, input, true);
830 if (ret) {
831 if (rule->fltr_id == input->fltr_id &&
832 rule->q_index != input->q_index)
833 ret = false;
834 else
835 break;
836 }
837 }
838
839 return ret;
840 }
841