20d64f8612d63e79df23ecfe95975b2a2336fbc6
[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 /**
356  * ice_set_dflt_val_fd_desc
357  * @fd_fltr_ctx: pointer to fd filter descriptor
358  */
359 void
360 ice_set_dflt_val_fd_desc(struct ice_fd_fltr_desc_ctx *fd_fltr_ctx)
361 {
362         fd_fltr_ctx->comp_q = ICE_FXD_FLTR_QW0_COMP_Q_ZERO;
363         fd_fltr_ctx->comp_report = ICE_FXD_FLTR_QW0_COMP_REPORT_SW_FAIL;
364         fd_fltr_ctx->fd_space = ICE_FXD_FLTR_QW0_FD_SPACE_GUAR_BEST;
365         fd_fltr_ctx->cnt_ena = ICE_FXD_FLTR_QW0_STAT_ENA_PKTS;
366         fd_fltr_ctx->evict_ena = ICE_FXD_FLTR_QW0_EVICT_ENA_TRUE;
367         fd_fltr_ctx->toq = ICE_FXD_FLTR_QW0_TO_Q_EQUALS_QINDEX;
368         fd_fltr_ctx->toq_prio = ICE_FXD_FLTR_QW0_TO_Q_PRIO1;
369         fd_fltr_ctx->dpu_recipe = ICE_FXD_FLTR_QW0_DPU_RECIPE_DFLT;
370         fd_fltr_ctx->drop = ICE_FXD_FLTR_QW0_DROP_NO;
371         fd_fltr_ctx->flex_prio = ICE_FXD_FLTR_QW0_FLEX_PRI_NONE;
372         fd_fltr_ctx->flex_mdid = ICE_FXD_FLTR_QW0_FLEX_MDID0;
373         fd_fltr_ctx->flex_val = ICE_FXD_FLTR_QW0_FLEX_VAL0;
374         fd_fltr_ctx->dtype = ICE_TX_DESC_DTYPE_FLTR_PROG;
375         fd_fltr_ctx->desc_prof_prio = ICE_FXD_FLTR_QW1_PROF_PRIO_ZERO;
376         fd_fltr_ctx->desc_prof = ICE_FXD_FLTR_QW1_PROF_ZERO;
377         fd_fltr_ctx->swap = ICE_FXD_FLTR_QW1_SWAP_SET;
378         fd_fltr_ctx->fdid_prio = ICE_FXD_FLTR_QW1_FDID_PRI_ONE;
379         fd_fltr_ctx->fdid_mdid = ICE_FXD_FLTR_QW1_FDID_MDID_FD;
380         fd_fltr_ctx->fdid = ICE_FXD_FLTR_QW1_FDID_ZERO;
381 }
382
383 /**
384  * ice_fdir_get_prgm_desc - set a fdir descriptor from a fdir filter struct
385  * @hw: pointer to the hardware structure
386  * @input: filter
387  * @fdesc: filter descriptor
388  * @add: if add is true, this is an add operation, false implies delete
389  */
390 void
391 ice_fdir_get_prgm_desc(struct ice_hw *hw, struct ice_fdir_fltr *input,
392                        struct ice_fltr_desc *fdesc, bool add)
393 {
394         struct ice_fd_fltr_desc_ctx fdir_fltr_ctx = { 0 };
395
396         /* set default context info */
397         ice_set_dflt_val_fd_desc(&fdir_fltr_ctx);
398
399         /* change sideband filtering values */
400         fdir_fltr_ctx.fdid = input->fltr_id;
401         if (input->dest_ctl == ICE_FLTR_PRGM_DESC_DEST_DROP_PKT) {
402                 fdir_fltr_ctx.drop = ICE_FXD_FLTR_QW0_DROP_YES;
403                 fdir_fltr_ctx.qindex = 0;
404         } else {
405                 if (input->dest_ctl ==
406                     ICE_FLTR_PRGM_DESC_DEST_DIRECT_PKT_QGROUP)
407                         fdir_fltr_ctx.toq = input->q_region;
408                 fdir_fltr_ctx.drop = ICE_FXD_FLTR_QW0_DROP_NO;
409                 fdir_fltr_ctx.qindex = input->q_index;
410         }
411         fdir_fltr_ctx.cnt_ena = input->cnt_ena;
412         fdir_fltr_ctx.cnt_index = input->cnt_index;
413         fdir_fltr_ctx.fd_vsi = ice_get_hw_vsi_num(hw, input->dest_vsi);
414         fdir_fltr_ctx.evict_ena = ICE_FXD_FLTR_QW0_EVICT_ENA_FALSE;
415         fdir_fltr_ctx.toq_prio = 3;
416         fdir_fltr_ctx.pcmd = (add) ? ICE_FXD_FLTR_QW1_PCMD_ADD :
417                 ICE_FXD_FLTR_QW1_PCMD_REMOVE;
418         fdir_fltr_ctx.swap = ICE_FXD_FLTR_QW1_SWAP_NOT_SET;
419         fdir_fltr_ctx.comp_q = ICE_FXD_FLTR_QW0_COMP_Q_ZERO;
420         fdir_fltr_ctx.comp_report = ICE_FXD_FLTR_QW0_COMP_REPORT_SW;
421         fdir_fltr_ctx.fdid_prio = input->fdid_prio;
422         fdir_fltr_ctx.desc_prof = 1;
423         fdir_fltr_ctx.desc_prof_prio = 3;
424         ice_set_fd_desc_val(&fdir_fltr_ctx, fdesc);
425 }
426
427 /**
428  * ice_set_fd_desc_val
429  * @ctx: pointer to fd filter descriptor context
430  * @fdir_desc: populated with fd filter descriptor values
431  */
432 void
433 ice_set_fd_desc_val(struct ice_fd_fltr_desc_ctx *ctx,
434                     struct ice_fltr_desc *fdir_desc)
435 {
436         u64 qword;
437
438         /* prep QW0 of FD filter programming desc */
439         qword = ((u64)ctx->qindex << ICE_FXD_FLTR_QW0_QINDEX_S) &
440                 ICE_FXD_FLTR_QW0_QINDEX_M;
441         qword |= ((u64)ctx->comp_q << ICE_FXD_FLTR_QW0_COMP_Q_S) &
442                  ICE_FXD_FLTR_QW0_COMP_Q_M;
443         qword |= ((u64)ctx->comp_report << ICE_FXD_FLTR_QW0_COMP_REPORT_S) &
444                  ICE_FXD_FLTR_QW0_COMP_REPORT_M;
445         qword |= ((u64)ctx->fd_space << ICE_FXD_FLTR_QW0_FD_SPACE_S) &
446                  ICE_FXD_FLTR_QW0_FD_SPACE_M;
447         qword |= ((u64)ctx->cnt_index << ICE_FXD_FLTR_QW0_STAT_CNT_S) &
448                  ICE_FXD_FLTR_QW0_STAT_CNT_M;
449         qword |= ((u64)ctx->cnt_ena << ICE_FXD_FLTR_QW0_STAT_ENA_S) &
450                  ICE_FXD_FLTR_QW0_STAT_ENA_M;
451         qword |= ((u64)ctx->evict_ena << ICE_FXD_FLTR_QW0_EVICT_ENA_S) &
452                  ICE_FXD_FLTR_QW0_EVICT_ENA_M;
453         qword |= ((u64)ctx->toq << ICE_FXD_FLTR_QW0_TO_Q_S) &
454                  ICE_FXD_FLTR_QW0_TO_Q_M;
455         qword |= ((u64)ctx->toq_prio << ICE_FXD_FLTR_QW0_TO_Q_PRI_S) &
456                  ICE_FXD_FLTR_QW0_TO_Q_PRI_M;
457         qword |= ((u64)ctx->dpu_recipe << ICE_FXD_FLTR_QW0_DPU_RECIPE_S) &
458                  ICE_FXD_FLTR_QW0_DPU_RECIPE_M;
459         qword |= ((u64)ctx->drop << ICE_FXD_FLTR_QW0_DROP_S) &
460                  ICE_FXD_FLTR_QW0_DROP_M;
461         qword |= ((u64)ctx->flex_prio << ICE_FXD_FLTR_QW0_FLEX_PRI_S) &
462                  ICE_FXD_FLTR_QW0_FLEX_PRI_M;
463         qword |= ((u64)ctx->flex_mdid << ICE_FXD_FLTR_QW0_FLEX_MDID_S) &
464                  ICE_FXD_FLTR_QW0_FLEX_MDID_M;
465         qword |= ((u64)ctx->flex_val << ICE_FXD_FLTR_QW0_FLEX_VAL_S) &
466                  ICE_FXD_FLTR_QW0_FLEX_VAL_M;
467         fdir_desc->qidx_compq_space_stat = CPU_TO_LE64(qword);
468
469         /* prep QW1 of FD filter programming desc */
470         qword = ((u64)ctx->dtype << ICE_FXD_FLTR_QW1_DTYPE_S) &
471                 ICE_FXD_FLTR_QW1_DTYPE_M;
472         qword |= ((u64)ctx->pcmd << ICE_FXD_FLTR_QW1_PCMD_S) &
473                  ICE_FXD_FLTR_QW1_PCMD_M;
474         qword |= ((u64)ctx->desc_prof_prio << ICE_FXD_FLTR_QW1_PROF_PRI_S) &
475                  ICE_FXD_FLTR_QW1_PROF_PRI_M;
476         qword |= ((u64)ctx->desc_prof << ICE_FXD_FLTR_QW1_PROF_S) &
477                  ICE_FXD_FLTR_QW1_PROF_M;
478         qword |= ((u64)ctx->fd_vsi << ICE_FXD_FLTR_QW1_FD_VSI_S) &
479                  ICE_FXD_FLTR_QW1_FD_VSI_M;
480         qword |= ((u64)ctx->swap << ICE_FXD_FLTR_QW1_SWAP_S) &
481                  ICE_FXD_FLTR_QW1_SWAP_M;
482         qword |= ((u64)ctx->fdid_prio << ICE_FXD_FLTR_QW1_FDID_PRI_S) &
483                  ICE_FXD_FLTR_QW1_FDID_PRI_M;
484         qword |= ((u64)ctx->fdid_mdid << ICE_FXD_FLTR_QW1_FDID_MDID_S) &
485                  ICE_FXD_FLTR_QW1_FDID_MDID_M;
486         qword |= ((u64)ctx->fdid << ICE_FXD_FLTR_QW1_FDID_S) &
487                  ICE_FXD_FLTR_QW1_FDID_M;
488         fdir_desc->dtype_cmd_vsi_fdid = CPU_TO_LE64(qword);
489 }
490
491 /**
492  * ice_alloc_fd_res_cntr - obtain counter resource for FD type
493  * @hw: pointer to the hardware structure
494  * @cntr_id: returns counter index
495  */
496 enum ice_status ice_alloc_fd_res_cntr(struct ice_hw *hw, u16 *cntr_id)
497 {
498         return ice_alloc_res_cntr(hw, ICE_AQC_RES_TYPE_FDIR_COUNTER_BLOCK,
499                                   ICE_AQC_RES_TYPE_FLAG_DEDICATED, 1, cntr_id);
500 }
501
502 /**
503  * ice_free_fd_res_cntr - Free counter resource for FD type
504  * @hw: pointer to the hardware structure
505  * @cntr_id: counter index to be freed
506  */
507 enum ice_status ice_free_fd_res_cntr(struct ice_hw *hw, u16 cntr_id)
508 {
509         return ice_free_res_cntr(hw, ICE_AQC_RES_TYPE_FDIR_COUNTER_BLOCK,
510                                  ICE_AQC_RES_TYPE_FLAG_DEDICATED, 1, cntr_id);
511 }
512
513 /**
514  * ice_alloc_fd_guar_item - allocate resource for FD guaranteed entries
515  * @hw: pointer to the hardware structure
516  * @cntr_id: returns counter index
517  * @num_fltr: number of filter entries to be allocated
518  */
519 enum ice_status
520 ice_alloc_fd_guar_item(struct ice_hw *hw, u16 *cntr_id, u16 num_fltr)
521 {
522         return ice_alloc_res_cntr(hw, ICE_AQC_RES_TYPE_FDIR_GUARANTEED_ENTRIES,
523                                   ICE_AQC_RES_TYPE_FLAG_DEDICATED, num_fltr,
524                                   cntr_id);
525 }
526
527 /**
528  * ice_free_fd_guar_item - Free flow director guaranteed entries
529  * @hw: pointer to the hardware structure
530  * @cntr_id: counter index that needs to be freed
531  * @num_fltr: number of filters to be freed
532  */
533 enum ice_status
534 ice_free_fd_guar_item(struct ice_hw *hw, u16 cntr_id, u16 num_fltr)
535 {
536         return ice_free_res_cntr(hw, ICE_AQC_RES_TYPE_FDIR_GUARANTEED_ENTRIES,
537                                  ICE_AQC_RES_TYPE_FLAG_DEDICATED, num_fltr,
538                                  cntr_id);
539 }
540
541 /**
542  * ice_alloc_fd_shrd_item - allocate resource for flow director shared entries
543  * @hw: pointer to the hardware structure
544  * @cntr_id: returns counter index
545  * @num_fltr: number of filter entries to be allocated
546  */
547 enum ice_status
548 ice_alloc_fd_shrd_item(struct ice_hw *hw, u16 *cntr_id, u16 num_fltr)
549 {
550         return ice_alloc_res_cntr(hw, ICE_AQC_RES_TYPE_FDIR_SHARED_ENTRIES,
551                                   ICE_AQC_RES_TYPE_FLAG_DEDICATED, num_fltr,
552                                   cntr_id);
553 }
554
555 /**
556  * ice_free_fd_shrd_item - Free flow director shared entries
557  * @hw: pointer to the hardware structure
558  * @cntr_id: counter index that needs to be freed
559  * @num_fltr: number of filters to be freed
560  */
561 enum ice_status
562 ice_free_fd_shrd_item(struct ice_hw *hw, u16 cntr_id, u16 num_fltr)
563 {
564         return ice_free_res_cntr(hw, ICE_AQC_RES_TYPE_FDIR_SHARED_ENTRIES,
565                                  ICE_AQC_RES_TYPE_FLAG_DEDICATED, num_fltr,
566                                  cntr_id);
567 }
568
569 /**
570  * ice_get_fdir_cnt_all - get the number of Flow Director filters
571  * @hw: hardware data structure
572  *
573  * Returns the number of filters available on device
574  */
575 int ice_get_fdir_cnt_all(struct ice_hw *hw)
576 {
577         return hw->func_caps.fd_fltr_guar +
578                hw->func_caps.fd_fltr_best_effort;
579 }
580
581 /**
582  * ice_pkt_insert_ipv6_addr - insert a be32 IPv6 address into a memory buffer.
583  * @pkt: packet buffer
584  * @offset: offset into buffer
585  * @addr: IPv6 address to convert and insert into pkt at offset
586  */
587 static void ice_pkt_insert_ipv6_addr(u8 *pkt, int offset, __be32 *addr)
588 {
589         int idx;
590
591         for (idx = 0; idx < ICE_IPV6_ADDR_LEN_AS_U32; idx++)
592                 ice_memcpy(pkt + offset + idx * sizeof(*addr), &addr[idx],
593                            sizeof(*addr), ICE_NONDMA_TO_NONDMA);
594 }
595
596 /**
597  * ice_pkt_insert_u6_qfi - insert a u6 value qfi into a memory buffer for gtpu
598  * @pkt: packet buffer
599  * @offset: offset into buffer
600  * @data: 8 bit value to convert and insert into pkt at offset
601  *
602  * This function is designed for inserting qfi (6 bits) for gtpu.
603  */
604 static void ice_pkt_insert_u6_qfi(u8 *pkt, int offset, u8 data)
605 {
606         u8 ret;
607
608         ret = (data & 0x3F) + (*(pkt + offset) & 0xC0);
609         ice_memcpy(pkt + offset, &ret, sizeof(ret), ICE_NONDMA_TO_NONDMA);
610 }
611
612 /**
613  * ice_pkt_insert_u8 - insert a u8 value into a memory buffer.
614  * @pkt: packet buffer
615  * @offset: offset into buffer
616  * @data: 8 bit value to convert and insert into pkt at offset
617  */
618 static void ice_pkt_insert_u8(u8 *pkt, int offset, u8 data)
619 {
620         ice_memcpy(pkt + offset, &data, sizeof(data), ICE_NONDMA_TO_NONDMA);
621 }
622
623 /**
624  * ice_pkt_insert_u8_tc - insert a u8 value into a memory buffer for tc ipv6.
625  * @pkt: packet buffer
626  * @offset: offset into buffer
627  * @data: 8 bit value to convert and insert into pkt at offset
628  *
629  * This function is designed for inserting Traffic Class (tc) for IPv6,
630  * since that tc is not aligned in number of bytes. Here we split it out
631  * into two part and fill each byte with data copy from pkt, then insert
632  * the two bytes data one by one.
633  */
634 static void ice_pkt_insert_u8_tc(u8 *pkt, int offset, u8 data)
635 {
636         u8 high, low;
637
638         high = (data >> 4) + (*(pkt + offset) & 0xF0);
639         ice_memcpy(pkt + offset, &high, sizeof(high), ICE_NONDMA_TO_NONDMA);
640
641         low = (*(pkt + offset + 1) & 0x0F) + ((data & 0x0F) << 4);
642         ice_memcpy(pkt + offset + 1, &low, sizeof(low), ICE_NONDMA_TO_NONDMA);
643 }
644
645 /**
646  * ice_pkt_insert_u16 - insert a be16 value into a memory buffer.
647  * @pkt: packet buffer
648  * @offset: offset into buffer
649  * @data: 16 bit value to convert and insert into pkt at offset
650  */
651 static void ice_pkt_insert_u16(u8 *pkt, int offset, __be16 data)
652 {
653         ice_memcpy(pkt + offset, &data, sizeof(data), ICE_NONDMA_TO_NONDMA);
654 }
655
656 /**
657  * ice_pkt_insert_u32 - insert a be32 value into a memory buffer.
658  * @pkt: packet buffer
659  * @offset: offset into buffer
660  * @data: 32 bit value to convert and insert into pkt at offset
661  */
662 static void ice_pkt_insert_u32(u8 *pkt, int offset, __be32 data)
663 {
664         ice_memcpy(pkt + offset, &data, sizeof(data), ICE_NONDMA_TO_NONDMA);
665 }
666
667 /**
668  * ice_pkt_insert_mac_addr - insert a MAC addr into a memory buffer.
669  * @pkt: packet buffer
670  * @offset: offset into buffer
671  * @addr: MAC address to convert and insert into pkt at offset
672  */
673 static void ice_pkt_insert_mac_addr(u8 *pkt, u8 *addr)
674 {
675         ice_memcpy(pkt, addr, ETH_ALEN, ICE_NONDMA_TO_NONDMA);
676 }
677
678 /**
679  * ice_fdir_get_gen_prgm_pkt - generate a training packet
680  * @hw: pointer to the hardware structure
681  * @input: flow director filter data structure
682  * @pkt: pointer to return filter packet
683  * @frag: generate a fragment packet
684  * @tun: true implies generate a tunnel packet
685  */
686 enum ice_status
687 ice_fdir_get_gen_prgm_pkt(struct ice_hw *hw, struct ice_fdir_fltr *input,
688                           u8 *pkt, bool frag, bool tun)
689 {
690         enum ice_fltr_ptype flow;
691         u16 tnl_port;
692         u8 *loc;
693         u16 idx;
694
695         if (input->flow_type == ICE_FLTR_PTYPE_NONF_IPV4_OTHER) {
696                 switch (input->ip.v4.proto) {
697                 case ICE_IP_PROTO_TCP:
698                         flow = ICE_FLTR_PTYPE_NONF_IPV4_TCP;
699                         break;
700                 case ICE_IP_PROTO_UDP:
701                         flow = ICE_FLTR_PTYPE_NONF_IPV4_UDP;
702                         break;
703                 case ICE_IP_PROTO_SCTP:
704                         flow = ICE_FLTR_PTYPE_NONF_IPV4_SCTP;
705                         break;
706                 default:
707                         flow = ICE_FLTR_PTYPE_NONF_IPV4_OTHER;
708                         break;
709                 }
710         } else if (input->flow_type == ICE_FLTR_PTYPE_NONF_IPV6_OTHER) {
711                 switch (input->ip.v6.proto) {
712                 case ICE_IP_PROTO_TCP:
713                         flow = ICE_FLTR_PTYPE_NONF_IPV6_TCP;
714                         break;
715                 case ICE_IP_PROTO_UDP:
716                         flow = ICE_FLTR_PTYPE_NONF_IPV6_UDP;
717                         break;
718                 case ICE_IP_PROTO_SCTP:
719                         flow = ICE_FLTR_PTYPE_NONF_IPV6_SCTP;
720                         break;
721                 default:
722                         flow = ICE_FLTR_PTYPE_NONF_IPV6_OTHER;
723                         break;
724                 }
725         } else {
726                 flow = input->flow_type;
727         }
728
729         for (idx = 0; idx < ICE_FDIR_NUM_PKT; idx++)
730                 if (ice_fdir_pkt[idx].flow == flow)
731                         break;
732         if (idx == ICE_FDIR_NUM_PKT)
733                 return ICE_ERR_PARAM;
734         if (!tun) {
735                 ice_memcpy(pkt, ice_fdir_pkt[idx].pkt,
736                            ice_fdir_pkt[idx].pkt_len, ICE_NONDMA_TO_NONDMA);
737                 loc = pkt;
738         } else {
739                 if (!ice_get_open_tunnel_port(hw, TNL_ALL, &tnl_port))
740                         return ICE_ERR_DOES_NOT_EXIST;
741                 if (!ice_fdir_pkt[idx].tun_pkt)
742                         return ICE_ERR_PARAM;
743                 ice_memcpy(pkt, ice_fdir_pkt[idx].tun_pkt,
744                            ice_fdir_pkt[idx].tun_pkt_len, ICE_NONDMA_TO_NONDMA);
745                 ice_pkt_insert_u16(pkt, ICE_IPV4_UDP_DST_PORT_OFFSET,
746                                    HTONS(tnl_port));
747                 loc = &pkt[ICE_FDIR_TUN_PKT_OFF];
748         }
749
750         switch (flow) {
751         case ICE_FLTR_PTYPE_NONF_IPV4_TCP:
752                 ice_pkt_insert_u32(loc, ICE_IPV4_DST_ADDR_OFFSET,
753                                    input->ip.v4.dst_ip);
754                 ice_pkt_insert_u16(loc, ICE_IPV4_TCP_DST_PORT_OFFSET,
755                                    input->ip.v4.dst_port);
756                 ice_pkt_insert_u32(loc, ICE_IPV4_SRC_ADDR_OFFSET,
757                                    input->ip.v4.src_ip);
758                 ice_pkt_insert_u16(loc, ICE_IPV4_TCP_SRC_PORT_OFFSET,
759                                    input->ip.v4.src_port);
760                 ice_pkt_insert_u8(loc, ICE_IPV4_TOS_OFFSET, input->ip.v4.tos);
761                 ice_pkt_insert_u8(loc, ICE_IPV4_TTL_OFFSET, input->ip.v4.ttl);
762                 ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac);
763                 if (frag)
764                         loc[20] = ICE_FDIR_IPV4_PKT_FLAG_DF;
765                 break;
766         case ICE_FLTR_PTYPE_NONF_IPV4_UDP:
767                 ice_pkt_insert_u32(loc, ICE_IPV4_DST_ADDR_OFFSET,
768                                    input->ip.v4.dst_ip);
769                 ice_pkt_insert_u16(loc, ICE_IPV4_UDP_DST_PORT_OFFSET,
770                                    input->ip.v4.dst_port);
771                 ice_pkt_insert_u32(loc, ICE_IPV4_SRC_ADDR_OFFSET,
772                                    input->ip.v4.src_ip);
773                 ice_pkt_insert_u16(loc, ICE_IPV4_UDP_SRC_PORT_OFFSET,
774                                    input->ip.v4.src_port);
775                 ice_pkt_insert_u8(loc, ICE_IPV4_TOS_OFFSET, input->ip.v4.tos);
776                 ice_pkt_insert_u8(loc, ICE_IPV4_TTL_OFFSET, input->ip.v4.ttl);
777                 ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac);
778                 break;
779         case ICE_FLTR_PTYPE_NONF_IPV4_SCTP:
780                 ice_pkt_insert_u32(loc, ICE_IPV4_DST_ADDR_OFFSET,
781                                    input->ip.v4.dst_ip);
782                 ice_pkt_insert_u16(loc, ICE_IPV4_SCTP_DST_PORT_OFFSET,
783                                    input->ip.v4.dst_port);
784                 ice_pkt_insert_u32(loc, ICE_IPV4_SRC_ADDR_OFFSET,
785                                    input->ip.v4.src_ip);
786                 ice_pkt_insert_u16(loc, ICE_IPV4_SCTP_SRC_PORT_OFFSET,
787                                    input->ip.v4.src_port);
788                 ice_pkt_insert_u8(loc, ICE_IPV4_TOS_OFFSET, input->ip.v4.tos);
789                 ice_pkt_insert_u8(loc, ICE_IPV4_TTL_OFFSET, input->ip.v4.ttl);
790                 ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac);
791                 break;
792         case ICE_FLTR_PTYPE_NONF_IPV4_OTHER:
793                 ice_pkt_insert_u32(loc, ICE_IPV4_DST_ADDR_OFFSET,
794                                    input->ip.v4.dst_ip);
795                 ice_pkt_insert_u32(loc, ICE_IPV4_SRC_ADDR_OFFSET,
796                                    input->ip.v4.src_ip);
797                 ice_pkt_insert_u8(loc, ICE_IPV4_TOS_OFFSET, input->ip.v4.tos);
798                 ice_pkt_insert_u8(loc, ICE_IPV4_TTL_OFFSET, input->ip.v4.ttl);
799                 ice_pkt_insert_u8(loc, ICE_IPV4_PROTO_OFFSET,
800                                   input->ip.v4.proto);
801                 ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac);
802                 break;
803         case ICE_FLTR_PTYPE_NONF_IPV4_GTPU_IPV4_UDP:
804         case ICE_FLTR_PTYPE_NONF_IPV4_GTPU_IPV4_TCP:
805         case ICE_FLTR_PTYPE_NONF_IPV4_GTPU_IPV4_ICMP:
806         case ICE_FLTR_PTYPE_NONF_IPV4_GTPU_IPV4_OTHER:
807                 ice_pkt_insert_u32(loc, ICE_IPV4_GTPU_TEID_OFFSET,
808                                    input->gtpu_data.teid);
809                 ice_pkt_insert_u6_qfi(loc, ICE_IPV4_GTPU_QFI_OFFSET,
810                                       input->gtpu_data.qfi);
811                 break;
812         case ICE_FLTR_PTYPE_NONF_IPV6_TCP:
813                 ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_DST_ADDR_OFFSET,
814                                          input->ip.v6.dst_ip);
815                 ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_SRC_ADDR_OFFSET,
816                                          input->ip.v6.src_ip);
817                 ice_pkt_insert_u16(loc, ICE_IPV6_TCP_DST_PORT_OFFSET,
818                                    input->ip.v6.dst_port);
819                 ice_pkt_insert_u16(loc, ICE_IPV6_TCP_SRC_PORT_OFFSET,
820                                    input->ip.v6.src_port);
821                 ice_pkt_insert_u8_tc(loc, ICE_IPV6_TC_OFFSET, input->ip.v6.tc);
822                 ice_pkt_insert_u8(loc, ICE_IPV6_HLIM_OFFSET, input->ip.v6.hlim);
823                 ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac);
824                 break;
825         case ICE_FLTR_PTYPE_NONF_IPV6_UDP:
826                 ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_DST_ADDR_OFFSET,
827                                          input->ip.v6.dst_ip);
828                 ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_SRC_ADDR_OFFSET,
829                                          input->ip.v6.src_ip);
830                 ice_pkt_insert_u16(loc, ICE_IPV6_UDP_DST_PORT_OFFSET,
831                                    input->ip.v6.dst_port);
832                 ice_pkt_insert_u16(loc, ICE_IPV6_UDP_SRC_PORT_OFFSET,
833                                    input->ip.v6.src_port);
834                 ice_pkt_insert_u8_tc(loc, ICE_IPV6_TC_OFFSET, input->ip.v6.tc);
835                 ice_pkt_insert_u8(loc, ICE_IPV6_HLIM_OFFSET, input->ip.v6.hlim);
836                 ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac);
837                 break;
838         case ICE_FLTR_PTYPE_NONF_IPV6_SCTP:
839                 ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_DST_ADDR_OFFSET,
840                                          input->ip.v6.dst_ip);
841                 ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_SRC_ADDR_OFFSET,
842                                          input->ip.v6.src_ip);
843                 ice_pkt_insert_u16(loc, ICE_IPV6_SCTP_DST_PORT_OFFSET,
844                                    input->ip.v6.dst_port);
845                 ice_pkt_insert_u16(loc, ICE_IPV6_SCTP_SRC_PORT_OFFSET,
846                                    input->ip.v6.src_port);
847                 ice_pkt_insert_u8_tc(loc, ICE_IPV6_TC_OFFSET, input->ip.v6.tc);
848                 ice_pkt_insert_u8(loc, ICE_IPV6_HLIM_OFFSET, input->ip.v6.hlim);
849                 ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac);
850                 break;
851         case ICE_FLTR_PTYPE_NONF_IPV6_OTHER:
852                 ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_DST_ADDR_OFFSET,
853                                          input->ip.v6.dst_ip);
854                 ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_SRC_ADDR_OFFSET,
855                                          input->ip.v6.src_ip);
856                 ice_pkt_insert_u8_tc(loc, ICE_IPV6_TC_OFFSET, input->ip.v6.tc);
857                 ice_pkt_insert_u8(loc, ICE_IPV6_HLIM_OFFSET, input->ip.v6.hlim);
858                 ice_pkt_insert_u8(loc, ICE_IPV6_PROTO_OFFSET,
859                                   input->ip.v6.proto);
860                 ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac);
861                 break;
862         default:
863                 return ICE_ERR_PARAM;
864         }
865
866         if (input->flex_fltr)
867                 ice_pkt_insert_u16(loc, input->flex_offset, input->flex_word);
868
869         return ICE_SUCCESS;
870 }
871
872 /**
873  * ice_fdir_get_prgm_pkt - generate a training packet
874  * @input: flow director filter data structure
875  * @pkt: pointer to return filter packet
876  * @frag: generate a fragment packet
877  */
878 enum ice_status
879 ice_fdir_get_prgm_pkt(struct ice_fdir_fltr *input, u8 *pkt, bool frag)
880 {
881         return ice_fdir_get_gen_prgm_pkt(NULL, input, pkt, frag, false);
882 }
883
884 /**
885  * ice_fdir_has_frag - does flow type have 2 ptypes
886  * @flow: flow ptype
887  *
888  * returns true is there is a fragment packet for this ptype
889  */
890 bool ice_fdir_has_frag(enum ice_fltr_ptype flow)
891 {
892         if (flow == ICE_FLTR_PTYPE_NONF_IPV4_OTHER)
893                 return true;
894         else
895                 return false;
896 }
897
898 /**
899  * ice_fdir_find_by_idx - find filter with idx
900  * @hw: pointer to hardware structure
901  * @fltr_idx: index to find.
902  *
903  * Returns pointer to filter if found or null
904  */
905 struct ice_fdir_fltr *
906 ice_fdir_find_fltr_by_idx(struct ice_hw *hw, u32 fltr_idx)
907 {
908         struct ice_fdir_fltr *rule = NULL;
909
910         LIST_FOR_EACH_ENTRY(rule, &hw->fdir_list_head, ice_fdir_fltr,
911                             fltr_node) {
912                 /* rule ID found in the list */
913                 if (fltr_idx == rule->fltr_id)
914                         return rule;
915                 if (fltr_idx < rule->fltr_id)
916                         break;
917         }
918         return NULL;
919 }
920
921 /**
922  * ice_fdir_list_add_fltr - add a new node to the flow director filter list
923  * @hw: hardware structure
924  * @fltr: filter node to add to structure
925  */
926 void ice_fdir_list_add_fltr(struct ice_hw *hw, struct ice_fdir_fltr *fltr)
927 {
928         struct ice_fdir_fltr *rule, *parent = NULL;
929
930         LIST_FOR_EACH_ENTRY(rule, &hw->fdir_list_head, ice_fdir_fltr,
931                             fltr_node) {
932                 /* rule ID found or pass its spot in the list */
933                 if (rule->fltr_id >= fltr->fltr_id)
934                         break;
935                 parent = rule;
936         }
937
938         if (parent)
939                 LIST_ADD_AFTER(&fltr->fltr_node, &parent->fltr_node);
940         else
941                 LIST_ADD(&fltr->fltr_node, &hw->fdir_list_head);
942 }
943
944 /**
945  * ice_fdir_update_cntrs - increment / decrement filter counter
946  * @hw: pointer to hardware structure
947  * @flow: filter flow type
948  * @add: true implies filters added
949  */
950 void
951 ice_fdir_update_cntrs(struct ice_hw *hw, enum ice_fltr_ptype flow, bool add)
952 {
953         int incr;
954
955         incr = (add) ? 1 : -1;
956         hw->fdir_active_fltr += incr;
957         if (flow == ICE_FLTR_PTYPE_NONF_NONE || flow >= ICE_FLTR_PTYPE_MAX)
958                 ice_debug(hw, ICE_DBG_SW, "Unknown filter type %d\n", flow);
959         else
960                 hw->fdir_fltr_cnt[flow] += incr;
961 }
962
963 /**
964  * ice_cmp_ipv6_addr - compare 2 IP v6 addresses
965  * @a: IP v6 address
966  * @b: IP v6 address
967  *
968  * Returns 0 on equal, returns non-0 if different
969  */
970 static int ice_cmp_ipv6_addr(__be32 *a, __be32 *b)
971 {
972         return memcmp(a, b, 4 * sizeof(__be32));
973 }
974
975 /**
976  * ice_fdir_comp_ipv6_rules - compare 2 filters
977  * @a: a Flow Director filter data structure
978  * @b: a Flow Director filter data structure
979  * @v6: bool true if v6 filter
980  *
981  * Returns true if the filters match
982  */
983 static bool
984 ice_fdir_comp_rules(struct ice_fdir_fltr *a,  struct ice_fdir_fltr *b, bool v6)
985 {
986         enum ice_fltr_ptype flow_type = a->flow_type;
987
988         /* The calling function already checks that the two filters have the
989          * same flow_type.
990          */
991         if (!v6) {
992                 if (flow_type == ICE_FLTR_PTYPE_NONF_IPV4_TCP ||
993                     flow_type == ICE_FLTR_PTYPE_NONF_IPV4_UDP ||
994                     flow_type == ICE_FLTR_PTYPE_NONF_IPV4_SCTP) {
995                         if (a->ip.v4.dst_ip == b->ip.v4.dst_ip &&
996                             a->ip.v4.src_ip == b->ip.v4.src_ip &&
997                             a->ip.v4.dst_port == b->ip.v4.dst_port &&
998                             a->ip.v4.src_port == b->ip.v4.src_port)
999                                 return true;
1000                 } else if (flow_type == ICE_FLTR_PTYPE_NONF_IPV4_OTHER) {
1001                         if (a->ip.v4.dst_ip == b->ip.v4.dst_ip &&
1002                             a->ip.v4.src_ip == b->ip.v4.src_ip &&
1003                             a->ip.v4.l4_header == b->ip.v4.l4_header &&
1004                             a->ip.v4.proto == b->ip.v4.proto &&
1005                             a->ip.v4.ip_ver == b->ip.v4.ip_ver &&
1006                             a->ip.v4.tos == b->ip.v4.tos)
1007                                 return true;
1008                 }
1009         } else {
1010                 if (flow_type == ICE_FLTR_PTYPE_NONF_IPV6_UDP ||
1011                     flow_type == ICE_FLTR_PTYPE_NONF_IPV6_TCP ||
1012                     flow_type == ICE_FLTR_PTYPE_NONF_IPV6_SCTP) {
1013                         if (a->ip.v6.dst_port == b->ip.v6.dst_port &&
1014                             a->ip.v6.src_port == b->ip.v6.src_port &&
1015                             !ice_cmp_ipv6_addr(a->ip.v6.dst_ip,
1016                                                b->ip.v6.dst_ip) &&
1017                             !ice_cmp_ipv6_addr(a->ip.v6.src_ip,
1018                                                b->ip.v6.src_ip))
1019                                 return true;
1020                 } else if (flow_type == ICE_FLTR_PTYPE_NONF_IPV6_OTHER) {
1021                         if (a->ip.v6.dst_port == b->ip.v6.dst_port &&
1022                             a->ip.v6.src_port == b->ip.v6.src_port)
1023                                 return true;
1024                 }
1025         }
1026
1027         return false;
1028 }
1029
1030 /**
1031  * ice_fdir_is_dup_fltr - test if filter is already in list for PF
1032  * @hw: hardware data structure
1033  * @input: Flow Director filter data structure
1034  *
1035  * Returns true if the filter is found in the list
1036  */
1037 bool ice_fdir_is_dup_fltr(struct ice_hw *hw, struct ice_fdir_fltr *input)
1038 {
1039         enum ice_fltr_ptype flow_type;
1040         struct ice_fdir_fltr *rule;
1041         bool ret = false;
1042
1043         rule = NULL;
1044
1045         LIST_FOR_EACH_ENTRY(rule, &hw->fdir_list_head, ice_fdir_fltr,
1046                             fltr_node) {
1047                 if (rule->flow_type == input->flow_type) {
1048                         flow_type = input->flow_type;
1049                         if (flow_type == ICE_FLTR_PTYPE_NONF_IPV4_TCP ||
1050                             flow_type == ICE_FLTR_PTYPE_NONF_IPV4_UDP ||
1051                             flow_type == ICE_FLTR_PTYPE_NONF_IPV4_SCTP ||
1052                             flow_type == ICE_FLTR_PTYPE_NONF_IPV4_OTHER)
1053                                 ret = ice_fdir_comp_rules(rule, input, false);
1054                         else
1055                                 ret = ice_fdir_comp_rules(rule, input, true);
1056                         if (ret) {
1057                                 if (rule->fltr_id == input->fltr_id &&
1058                                     rule->q_index != input->q_index)
1059                                         ret = false;
1060                                 else
1061                                         break;
1062                         }
1063                 }
1064         }
1065
1066         return ret;
1067 }
1068
1069 /**
1070  * ice_clear_vsi_fd_table - admin command to clear FD table for a VSI
1071  * @hw: hardware data structure
1072  * @vsi_num: vsi_num (HW VSI num)
1073  *
1074  * Clears FD table entries by issuing admin command (direct, 0x0B06)
1075  * Must to pass valid vsi_num as returned by "AddVSI".
1076  */
1077 enum ice_status ice_clear_vsi_fd_table(struct ice_hw *hw, u16 vsi_num)
1078 {
1079         struct ice_aqc_clear_fd_table *cmd;
1080         struct ice_aq_desc desc;
1081
1082         cmd = &desc.params.clear_fd_table;
1083         ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_clear_fd_table);
1084         cmd->clear_type = CL_FD_VM_VF_TYPE_VSI_IDX;
1085
1086         cmd->vsi_index = CPU_TO_LE16(vsi_num);
1087         return ice_aq_send_cmd(hw, &desc, NULL, 0, NULL);
1088 }
1089
1090 /**
1091  * ice_clear_pf_fd_table - admin command to clear FD table for PF
1092  * @hw: hardware data structure
1093  *
1094  * Clears FD table entries for a PF by issuing admin command (direct, 0x0B06)
1095  */
1096 enum ice_status ice_clear_pf_fd_table(struct ice_hw *hw)
1097 {
1098         struct ice_aqc_clear_fd_table *cmd;
1099         struct ice_aq_desc desc;
1100
1101         cmd = &desc.params.clear_fd_table;
1102         ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_clear_fd_table);
1103         cmd->clear_type = CL_FD_VM_VF_TYPE_PF_IDX;
1104         /* vsi_index must be 0 to clear FD table for a PF */
1105         cmd->vsi_index = CPU_TO_LE16(0);
1106
1107         return ice_aq_send_cmd(hw, &desc, NULL, 0, NULL);
1108 }