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