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