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