GNU Linux-libre 5.10.215-gnu1
[releases.git] / drivers / net / ethernet / intel / ice / ice_fdir.c
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  */
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
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
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  */
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  */
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
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
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  */
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  */
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  */
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  */
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
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  */
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 *
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  */
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
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  */
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
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  */
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 }