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