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