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