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