net/ice/base: refactor flow director filter swap
[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         /* Reverse the src and dst, since the HW expects them to be from Tx
768          * perspective. The input from user is from Rx filter perspective.
769          */
770         switch (flow) {
771         case ICE_FLTR_PTYPE_NONF_IPV4_TCP:
772                 ice_pkt_insert_u32(loc, ICE_IPV4_DST_ADDR_OFFSET,
773                                    input->ip.v4.src_ip);
774                 ice_pkt_insert_u16(loc, ICE_IPV4_TCP_DST_PORT_OFFSET,
775                                    input->ip.v4.src_port);
776                 ice_pkt_insert_u32(loc, ICE_IPV4_SRC_ADDR_OFFSET,
777                                    input->ip.v4.dst_ip);
778                 ice_pkt_insert_u16(loc, ICE_IPV4_TCP_SRC_PORT_OFFSET,
779                                    input->ip.v4.dst_port);
780                 ice_pkt_insert_u8(loc, ICE_IPV4_TOS_OFFSET, input->ip.v4.tos);
781                 ice_pkt_insert_u8(loc, ICE_IPV4_TTL_OFFSET, input->ip.v4.ttl);
782                 ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac);
783                 if (frag)
784                         loc[20] = ICE_FDIR_IPV4_PKT_FLAG_DF;
785                 break;
786         case ICE_FLTR_PTYPE_NONF_IPV4_UDP:
787                 ice_pkt_insert_u32(loc, ICE_IPV4_DST_ADDR_OFFSET,
788                                    input->ip.v4.src_ip);
789                 ice_pkt_insert_u16(loc, ICE_IPV4_UDP_DST_PORT_OFFSET,
790                                    input->ip.v4.src_port);
791                 ice_pkt_insert_u32(loc, ICE_IPV4_SRC_ADDR_OFFSET,
792                                    input->ip.v4.dst_ip);
793                 ice_pkt_insert_u16(loc, ICE_IPV4_UDP_SRC_PORT_OFFSET,
794                                    input->ip.v4.dst_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_SCTP:
800                 ice_pkt_insert_u32(loc, ICE_IPV4_DST_ADDR_OFFSET,
801                                    input->ip.v4.src_ip);
802                 ice_pkt_insert_u16(loc, ICE_IPV4_SCTP_DST_PORT_OFFSET,
803                                    input->ip.v4.src_port);
804                 ice_pkt_insert_u32(loc, ICE_IPV4_SRC_ADDR_OFFSET,
805                                    input->ip.v4.dst_ip);
806                 ice_pkt_insert_u16(loc, ICE_IPV4_SCTP_SRC_PORT_OFFSET,
807                                    input->ip.v4.dst_port);
808                 ice_pkt_insert_u8(loc, ICE_IPV4_TOS_OFFSET, input->ip.v4.tos);
809                 ice_pkt_insert_u8(loc, ICE_IPV4_TTL_OFFSET, input->ip.v4.ttl);
810                 ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac);
811                 break;
812         case ICE_FLTR_PTYPE_NONF_IPV4_OTHER:
813                 ice_pkt_insert_u32(loc, ICE_IPV4_DST_ADDR_OFFSET,
814                                    input->ip.v4.src_ip);
815                 ice_pkt_insert_u32(loc, ICE_IPV4_SRC_ADDR_OFFSET,
816                                    input->ip.v4.dst_ip);
817                 ice_pkt_insert_u8(loc, ICE_IPV4_TOS_OFFSET, input->ip.v4.tos);
818                 ice_pkt_insert_u8(loc, ICE_IPV4_TTL_OFFSET, input->ip.v4.ttl);
819                 ice_pkt_insert_u8(loc, ICE_IPV4_PROTO_OFFSET,
820                                   input->ip.v4.proto);
821                 ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac);
822                 break;
823         case ICE_FLTR_PTYPE_NONF_IPV4_GTPU_IPV4_UDP:
824         case ICE_FLTR_PTYPE_NONF_IPV4_GTPU_IPV4_TCP:
825         case ICE_FLTR_PTYPE_NONF_IPV4_GTPU_IPV4_ICMP:
826         case ICE_FLTR_PTYPE_NONF_IPV4_GTPU_IPV4_OTHER:
827                 ice_pkt_insert_u32(loc, ICE_IPV4_SRC_ADDR_OFFSET,
828                                         input->ip.v4.src_ip);
829                 ice_pkt_insert_u32(loc, ICE_IPV4_DST_ADDR_OFFSET,
830                                         input->ip.v4.dst_ip);
831                 ice_pkt_insert_u32(loc, ICE_IPV4_GTPU_TEID_OFFSET,
832                                    input->gtpu_data.teid);
833                 ice_pkt_insert_u6_qfi(loc, ICE_IPV4_GTPU_QFI_OFFSET,
834                                       input->gtpu_data.qfi);
835                 break;
836         case ICE_FLTR_PTYPE_NON_IP_L2:
837                 ice_pkt_insert_u16(loc, ICE_MAC_ETHTYPE_OFFSET,
838                                    input->ext_data.ether_type);
839                 break;
840         case ICE_FLTR_PTYPE_NONF_IPV6_TCP:
841                 ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_DST_ADDR_OFFSET,
842                                          input->ip.v6.src_ip);
843                 ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_SRC_ADDR_OFFSET,
844                                          input->ip.v6.dst_ip);
845                 ice_pkt_insert_u16(loc, ICE_IPV6_TCP_DST_PORT_OFFSET,
846                                    input->ip.v6.src_port);
847                 ice_pkt_insert_u16(loc, ICE_IPV6_TCP_SRC_PORT_OFFSET,
848                                    input->ip.v6.dst_port);
849                 ice_pkt_insert_u8_tc(loc, ICE_IPV6_TC_OFFSET, input->ip.v6.tc);
850                 ice_pkt_insert_u8(loc, ICE_IPV6_HLIM_OFFSET, input->ip.v6.hlim);
851                 ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac);
852                 break;
853         case ICE_FLTR_PTYPE_NONF_IPV6_UDP:
854                 ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_DST_ADDR_OFFSET,
855                                          input->ip.v6.src_ip);
856                 ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_SRC_ADDR_OFFSET,
857                                          input->ip.v6.dst_ip);
858                 ice_pkt_insert_u16(loc, ICE_IPV6_UDP_DST_PORT_OFFSET,
859                                    input->ip.v6.src_port);
860                 ice_pkt_insert_u16(loc, ICE_IPV6_UDP_SRC_PORT_OFFSET,
861                                    input->ip.v6.dst_port);
862                 ice_pkt_insert_u8_tc(loc, ICE_IPV6_TC_OFFSET, input->ip.v6.tc);
863                 ice_pkt_insert_u8(loc, ICE_IPV6_HLIM_OFFSET, input->ip.v6.hlim);
864                 ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac);
865                 break;
866         case ICE_FLTR_PTYPE_NONF_IPV6_SCTP:
867                 ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_DST_ADDR_OFFSET,
868                                          input->ip.v6.src_ip);
869                 ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_SRC_ADDR_OFFSET,
870                                          input->ip.v6.dst_ip);
871                 ice_pkt_insert_u16(loc, ICE_IPV6_SCTP_DST_PORT_OFFSET,
872                                    input->ip.v6.src_port);
873                 ice_pkt_insert_u16(loc, ICE_IPV6_SCTP_SRC_PORT_OFFSET,
874                                    input->ip.v6.dst_port);
875                 ice_pkt_insert_u8_tc(loc, ICE_IPV6_TC_OFFSET, input->ip.v6.tc);
876                 ice_pkt_insert_u8(loc, ICE_IPV6_HLIM_OFFSET, input->ip.v6.hlim);
877                 ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac);
878                 break;
879         case ICE_FLTR_PTYPE_NONF_IPV6_OTHER:
880                 ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_DST_ADDR_OFFSET,
881                                          input->ip.v6.src_ip);
882                 ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_SRC_ADDR_OFFSET,
883                                          input->ip.v6.dst_ip);
884                 ice_pkt_insert_u8_tc(loc, ICE_IPV6_TC_OFFSET, input->ip.v6.tc);
885                 ice_pkt_insert_u8(loc, ICE_IPV6_HLIM_OFFSET, input->ip.v6.hlim);
886                 ice_pkt_insert_u8(loc, ICE_IPV6_PROTO_OFFSET,
887                                   input->ip.v6.proto);
888                 ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac);
889                 break;
890         default:
891                 return ICE_ERR_PARAM;
892         }
893
894         if (input->flex_fltr)
895                 ice_pkt_insert_u16(loc, input->flex_offset, input->flex_word);
896
897         return ICE_SUCCESS;
898 }
899
900 /**
901  * ice_fdir_get_prgm_pkt - generate a training packet
902  * @input: flow director filter data structure
903  * @pkt: pointer to return filter packet
904  * @frag: generate a fragment packet
905  */
906 enum ice_status
907 ice_fdir_get_prgm_pkt(struct ice_fdir_fltr *input, u8 *pkt, bool frag)
908 {
909         return ice_fdir_get_gen_prgm_pkt(NULL, input, pkt, frag, false);
910 }
911
912 /**
913  * ice_fdir_has_frag - does flow type have 2 ptypes
914  * @flow: flow ptype
915  *
916  * returns true is there is a fragment packet for this ptype
917  */
918 bool ice_fdir_has_frag(enum ice_fltr_ptype flow)
919 {
920         if (flow == ICE_FLTR_PTYPE_NONF_IPV4_OTHER)
921                 return true;
922         else
923                 return false;
924 }
925
926 /**
927  * ice_fdir_find_by_idx - find filter with idx
928  * @hw: pointer to hardware structure
929  * @fltr_idx: index to find.
930  *
931  * Returns pointer to filter if found or null
932  */
933 struct ice_fdir_fltr *
934 ice_fdir_find_fltr_by_idx(struct ice_hw *hw, u32 fltr_idx)
935 {
936         struct ice_fdir_fltr *rule;
937
938         LIST_FOR_EACH_ENTRY(rule, &hw->fdir_list_head, ice_fdir_fltr,
939                             fltr_node) {
940                 /* rule ID found in the list */
941                 if (fltr_idx == rule->fltr_id)
942                         return rule;
943                 if (fltr_idx < rule->fltr_id)
944                         break;
945         }
946         return NULL;
947 }
948
949 /**
950  * ice_fdir_list_add_fltr - add a new node to the flow director filter list
951  * @hw: hardware structure
952  * @fltr: filter node to add to structure
953  */
954 void ice_fdir_list_add_fltr(struct ice_hw *hw, struct ice_fdir_fltr *fltr)
955 {
956         struct ice_fdir_fltr *rule, *parent = NULL;
957
958         LIST_FOR_EACH_ENTRY(rule, &hw->fdir_list_head, ice_fdir_fltr,
959                             fltr_node) {
960                 /* rule ID found or pass its spot in the list */
961                 if (rule->fltr_id >= fltr->fltr_id)
962                         break;
963                 parent = rule;
964         }
965
966         if (parent)
967                 LIST_ADD_AFTER(&fltr->fltr_node, &parent->fltr_node);
968         else
969                 LIST_ADD(&fltr->fltr_node, &hw->fdir_list_head);
970 }
971
972 /**
973  * ice_fdir_update_cntrs - increment / decrement filter counter
974  * @hw: pointer to hardware structure
975  * @flow: filter flow type
976  * @acl_fltr: true indicates an ACL filter
977  * @add: true implies filters added
978  */
979 void
980 ice_fdir_update_cntrs(struct ice_hw *hw, enum ice_fltr_ptype flow,
981                       bool acl_fltr, bool add)
982 {
983         int incr;
984
985         incr = add ? 1 : -1;
986         hw->fdir_active_fltr += incr;
987         if (flow == ICE_FLTR_PTYPE_NONF_NONE || flow >= ICE_FLTR_PTYPE_MAX) {
988                 ice_debug(hw, ICE_DBG_SW, "Unknown filter type %d\n", flow);
989         } else {
990                 if (acl_fltr)
991                         hw->acl_fltr_cnt[flow] += incr;
992                 else
993                         hw->fdir_fltr_cnt[flow] += incr;
994         }
995 }
996
997 /**
998  * ice_cmp_ipv6_addr - compare 2 IP v6 addresses
999  * @a: IP v6 address
1000  * @b: IP v6 address
1001  *
1002  * Returns 0 on equal, returns non-0 if different
1003  */
1004 static int ice_cmp_ipv6_addr(__be32 *a, __be32 *b)
1005 {
1006         return memcmp(a, b, 4 * sizeof(__be32));
1007 }
1008
1009 /**
1010  * ice_fdir_comp_rules - compare 2 filters
1011  * @a: a Flow Director filter data structure
1012  * @b: a Flow Director filter data structure
1013  * @v6: bool true if v6 filter
1014  *
1015  * Returns true if the filters match
1016  */
1017 static bool
1018 ice_fdir_comp_rules(struct ice_fdir_fltr *a,  struct ice_fdir_fltr *b, bool v6)
1019 {
1020         enum ice_fltr_ptype flow_type = a->flow_type;
1021
1022         /* The calling function already checks that the two filters have the
1023          * same flow_type.
1024          */
1025         if (!v6) {
1026                 if (flow_type == ICE_FLTR_PTYPE_NONF_IPV4_TCP ||
1027                     flow_type == ICE_FLTR_PTYPE_NONF_IPV4_UDP ||
1028                     flow_type == ICE_FLTR_PTYPE_NONF_IPV4_SCTP) {
1029                         if (a->ip.v4.dst_ip == b->ip.v4.dst_ip &&
1030                             a->ip.v4.src_ip == b->ip.v4.src_ip &&
1031                             a->ip.v4.dst_port == b->ip.v4.dst_port &&
1032                             a->ip.v4.src_port == b->ip.v4.src_port)
1033                                 return true;
1034                 } else if (flow_type == ICE_FLTR_PTYPE_NONF_IPV4_OTHER) {
1035                         if (a->ip.v4.dst_ip == b->ip.v4.dst_ip &&
1036                             a->ip.v4.src_ip == b->ip.v4.src_ip &&
1037                             a->ip.v4.l4_header == b->ip.v4.l4_header &&
1038                             a->ip.v4.proto == b->ip.v4.proto &&
1039                             a->ip.v4.ip_ver == b->ip.v4.ip_ver &&
1040                             a->ip.v4.tos == b->ip.v4.tos)
1041                                 return true;
1042                 }
1043         } else {
1044                 if (flow_type == ICE_FLTR_PTYPE_NONF_IPV6_UDP ||
1045                     flow_type == ICE_FLTR_PTYPE_NONF_IPV6_TCP ||
1046                     flow_type == ICE_FLTR_PTYPE_NONF_IPV6_SCTP) {
1047                         if (a->ip.v6.dst_port == b->ip.v6.dst_port &&
1048                             a->ip.v6.src_port == b->ip.v6.src_port &&
1049                             !ice_cmp_ipv6_addr(a->ip.v6.dst_ip,
1050                                                b->ip.v6.dst_ip) &&
1051                             !ice_cmp_ipv6_addr(a->ip.v6.src_ip,
1052                                                b->ip.v6.src_ip))
1053                                 return true;
1054                 } else if (flow_type == ICE_FLTR_PTYPE_NONF_IPV6_OTHER) {
1055                         if (a->ip.v6.dst_port == b->ip.v6.dst_port &&
1056                             a->ip.v6.src_port == b->ip.v6.src_port)
1057                                 return true;
1058                 }
1059         }
1060
1061         return false;
1062 }
1063
1064 /**
1065  * ice_fdir_is_dup_fltr - test if filter is already in list for PF
1066  * @hw: hardware data structure
1067  * @input: Flow Director filter data structure
1068  *
1069  * Returns true if the filter is found in the list
1070  */
1071 bool ice_fdir_is_dup_fltr(struct ice_hw *hw, struct ice_fdir_fltr *input)
1072 {
1073         struct ice_fdir_fltr *rule;
1074         bool ret = false;
1075
1076         LIST_FOR_EACH_ENTRY(rule, &hw->fdir_list_head, ice_fdir_fltr,
1077                             fltr_node) {
1078                 enum ice_fltr_ptype flow_type;
1079
1080                 if (rule->flow_type != input->flow_type)
1081                         continue;
1082
1083                 flow_type = input->flow_type;
1084                 if (flow_type == ICE_FLTR_PTYPE_NONF_IPV4_TCP ||
1085                     flow_type == ICE_FLTR_PTYPE_NONF_IPV4_UDP ||
1086                     flow_type == ICE_FLTR_PTYPE_NONF_IPV4_SCTP ||
1087                     flow_type == ICE_FLTR_PTYPE_NONF_IPV4_OTHER)
1088                         ret = ice_fdir_comp_rules(rule, input, false);
1089                 else
1090                         ret = ice_fdir_comp_rules(rule, input, true);
1091                 if (ret) {
1092                         if (rule->fltr_id == input->fltr_id &&
1093                             rule->q_index != input->q_index)
1094                                 ret = false;
1095                         else
1096                                 break;
1097                 }
1098         }
1099
1100         return ret;
1101 }
1102
1103 /**
1104  * ice_clear_vsi_fd_table - admin command to clear FD table for a VSI
1105  * @hw: hardware data structure
1106  * @vsi_num: vsi_num (HW VSI num)
1107  *
1108  * Clears FD table entries by issuing admin command (direct, 0x0B06)
1109  * Must to pass valid vsi_num as returned by "AddVSI".
1110  */
1111 enum ice_status ice_clear_vsi_fd_table(struct ice_hw *hw, u16 vsi_num)
1112 {
1113         struct ice_aqc_clear_fd_table *cmd;
1114         struct ice_aq_desc desc;
1115
1116         cmd = &desc.params.clear_fd_table;
1117         ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_clear_fd_table);
1118         cmd->clear_type = CL_FD_VM_VF_TYPE_VSI_IDX;
1119
1120         cmd->vsi_index = CPU_TO_LE16(vsi_num);
1121         return ice_aq_send_cmd(hw, &desc, NULL, 0, NULL);
1122 }
1123
1124 /**
1125  * ice_clear_pf_fd_table - admin command to clear FD table for PF
1126  * @hw: hardware data structure
1127  *
1128  * Clears FD table entries for a PF by issuing admin command (direct, 0x0B06)
1129  */
1130 enum ice_status ice_clear_pf_fd_table(struct ice_hw *hw)
1131 {
1132         struct ice_aqc_clear_fd_table *cmd;
1133         struct ice_aq_desc desc;
1134
1135         cmd = &desc.params.clear_fd_table;
1136         ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_clear_fd_table);
1137         cmd->clear_type = CL_FD_VM_VF_TYPE_PF_IDX;
1138         /* vsi_index must be 0 to clear FD table for a PF */
1139         cmd->vsi_index = CPU_TO_LE16(0);
1140
1141         return ice_aq_send_cmd(hw, &desc, NULL, 0, NULL);
1142 }