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