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