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