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