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