xref: /linux/drivers/net/ethernet/intel/ice/ice_fdir.c (revision 97ef3b7f4fdf8ad6818aa2c8201c3b72cc635e16)
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 = ((u64)ctx->qindex << ICE_FXD_FLTR_QW0_QINDEX_S) &
608 		ICE_FXD_FLTR_QW0_QINDEX_M;
609 	qword |= ((u64)ctx->comp_q << ICE_FXD_FLTR_QW0_COMP_Q_S) &
610 		 ICE_FXD_FLTR_QW0_COMP_Q_M;
611 	qword |= ((u64)ctx->comp_report << ICE_FXD_FLTR_QW0_COMP_REPORT_S) &
612 		 ICE_FXD_FLTR_QW0_COMP_REPORT_M;
613 	qword |= ((u64)ctx->fd_space << ICE_FXD_FLTR_QW0_FD_SPACE_S) &
614 		 ICE_FXD_FLTR_QW0_FD_SPACE_M;
615 	qword |= ((u64)ctx->cnt_index << ICE_FXD_FLTR_QW0_STAT_CNT_S) &
616 		 ICE_FXD_FLTR_QW0_STAT_CNT_M;
617 	qword |= ((u64)ctx->cnt_ena << ICE_FXD_FLTR_QW0_STAT_ENA_S) &
618 		 ICE_FXD_FLTR_QW0_STAT_ENA_M;
619 	qword |= ((u64)ctx->evict_ena << ICE_FXD_FLTR_QW0_EVICT_ENA_S) &
620 		 ICE_FXD_FLTR_QW0_EVICT_ENA_M;
621 	qword |= ((u64)ctx->toq << ICE_FXD_FLTR_QW0_TO_Q_S) &
622 		 ICE_FXD_FLTR_QW0_TO_Q_M;
623 	qword |= ((u64)ctx->toq_prio << ICE_FXD_FLTR_QW0_TO_Q_PRI_S) &
624 		 ICE_FXD_FLTR_QW0_TO_Q_PRI_M;
625 	qword |= ((u64)ctx->dpu_recipe << ICE_FXD_FLTR_QW0_DPU_RECIPE_S) &
626 		 ICE_FXD_FLTR_QW0_DPU_RECIPE_M;
627 	qword |= ((u64)ctx->drop << ICE_FXD_FLTR_QW0_DROP_S) &
628 		 ICE_FXD_FLTR_QW0_DROP_M;
629 	qword |= ((u64)ctx->flex_prio << ICE_FXD_FLTR_QW0_FLEX_PRI_S) &
630 		 ICE_FXD_FLTR_QW0_FLEX_PRI_M;
631 	qword |= ((u64)ctx->flex_mdid << ICE_FXD_FLTR_QW0_FLEX_MDID_S) &
632 		 ICE_FXD_FLTR_QW0_FLEX_MDID_M;
633 	qword |= ((u64)ctx->flex_val << ICE_FXD_FLTR_QW0_FLEX_VAL_S) &
634 		 ICE_FXD_FLTR_QW0_FLEX_VAL_M;
635 	fdir_desc->qidx_compq_space_stat = cpu_to_le64(qword);
636 
637 	/* prep QW1 of FD filter programming desc */
638 	qword = ((u64)ctx->dtype << ICE_FXD_FLTR_QW1_DTYPE_S) &
639 		ICE_FXD_FLTR_QW1_DTYPE_M;
640 	qword |= ((u64)ctx->pcmd << ICE_FXD_FLTR_QW1_PCMD_S) &
641 		 ICE_FXD_FLTR_QW1_PCMD_M;
642 	qword |= ((u64)ctx->desc_prof_prio << ICE_FXD_FLTR_QW1_PROF_PRI_S) &
643 		 ICE_FXD_FLTR_QW1_PROF_PRI_M;
644 	qword |= ((u64)ctx->desc_prof << ICE_FXD_FLTR_QW1_PROF_S) &
645 		 ICE_FXD_FLTR_QW1_PROF_M;
646 	qword |= ((u64)ctx->fd_vsi << ICE_FXD_FLTR_QW1_FD_VSI_S) &
647 		 ICE_FXD_FLTR_QW1_FD_VSI_M;
648 	qword |= ((u64)ctx->swap << ICE_FXD_FLTR_QW1_SWAP_S) &
649 		 ICE_FXD_FLTR_QW1_SWAP_M;
650 	qword |= ((u64)ctx->fdid_prio << ICE_FXD_FLTR_QW1_FDID_PRI_S) &
651 		 ICE_FXD_FLTR_QW1_FDID_PRI_M;
652 	qword |= ((u64)ctx->fdid_mdid << ICE_FXD_FLTR_QW1_FDID_MDID_S) &
653 		 ICE_FXD_FLTR_QW1_FDID_MDID_M;
654 	qword |= ((u64)ctx->fdid << ICE_FXD_FLTR_QW1_FDID_S) &
655 		 ICE_FXD_FLTR_QW1_FDID_M;
656 	fdir_desc->dtype_cmd_vsi_fdid = cpu_to_le64(qword);
657 }
658 
659 /**
660  * ice_fdir_get_prgm_desc - set a fdir descriptor from a fdir filter struct
661  * @hw: pointer to the hardware structure
662  * @input: filter
663  * @fdesc: filter descriptor
664  * @add: if add is true, this is an add operation, false implies delete
665  */
666 void
667 ice_fdir_get_prgm_desc(struct ice_hw *hw, struct ice_fdir_fltr *input,
668 		       struct ice_fltr_desc *fdesc, bool add)
669 {
670 	struct ice_fd_fltr_desc_ctx fdir_fltr_ctx = { 0 };
671 
672 	/* set default context info */
673 	ice_set_dflt_val_fd_desc(&fdir_fltr_ctx);
674 
675 	/* change sideband filtering values */
676 	fdir_fltr_ctx.fdid = input->fltr_id;
677 	if (input->dest_ctl == ICE_FLTR_PRGM_DESC_DEST_DROP_PKT) {
678 		fdir_fltr_ctx.drop = ICE_FXD_FLTR_QW0_DROP_YES;
679 		fdir_fltr_ctx.qindex = 0;
680 	} else if (input->dest_ctl ==
681 		   ICE_FLTR_PRGM_DESC_DEST_DIRECT_PKT_OTHER) {
682 		fdir_fltr_ctx.drop = ICE_FXD_FLTR_QW0_DROP_NO;
683 		fdir_fltr_ctx.qindex = 0;
684 	} else {
685 		if (input->dest_ctl ==
686 		    ICE_FLTR_PRGM_DESC_DEST_DIRECT_PKT_QGROUP)
687 			fdir_fltr_ctx.toq = input->q_region;
688 		fdir_fltr_ctx.drop = ICE_FXD_FLTR_QW0_DROP_NO;
689 		fdir_fltr_ctx.qindex = input->q_index;
690 	}
691 	fdir_fltr_ctx.cnt_ena = input->cnt_ena;
692 	fdir_fltr_ctx.cnt_index = input->cnt_index;
693 	fdir_fltr_ctx.fd_vsi = ice_get_hw_vsi_num(hw, input->dest_vsi);
694 	fdir_fltr_ctx.evict_ena = ICE_FXD_FLTR_QW0_EVICT_ENA_FALSE;
695 	if (input->dest_ctl == ICE_FLTR_PRGM_DESC_DEST_DIRECT_PKT_OTHER)
696 		fdir_fltr_ctx.toq_prio = 0;
697 	else
698 		fdir_fltr_ctx.toq_prio = 3;
699 	fdir_fltr_ctx.pcmd = add ? ICE_FXD_FLTR_QW1_PCMD_ADD :
700 		ICE_FXD_FLTR_QW1_PCMD_REMOVE;
701 	fdir_fltr_ctx.swap = ICE_FXD_FLTR_QW1_SWAP_NOT_SET;
702 	fdir_fltr_ctx.comp_q = ICE_FXD_FLTR_QW0_COMP_Q_ZERO;
703 	fdir_fltr_ctx.comp_report = input->comp_report;
704 	fdir_fltr_ctx.fdid_prio = input->fdid_prio;
705 	fdir_fltr_ctx.desc_prof = 1;
706 	fdir_fltr_ctx.desc_prof_prio = 3;
707 	ice_set_fd_desc_val(&fdir_fltr_ctx, fdesc);
708 }
709 
710 /**
711  * ice_alloc_fd_res_cntr - obtain counter resource for FD type
712  * @hw: pointer to the hardware structure
713  * @cntr_id: returns counter index
714  */
715 enum ice_status ice_alloc_fd_res_cntr(struct ice_hw *hw, u16 *cntr_id)
716 {
717 	return ice_alloc_res_cntr(hw, ICE_AQC_RES_TYPE_FDIR_COUNTER_BLOCK,
718 				  ICE_AQC_RES_TYPE_FLAG_DEDICATED, 1, cntr_id);
719 }
720 
721 /**
722  * ice_free_fd_res_cntr - Free counter resource for FD type
723  * @hw: pointer to the hardware structure
724  * @cntr_id: counter index to be freed
725  */
726 enum ice_status ice_free_fd_res_cntr(struct ice_hw *hw, u16 cntr_id)
727 {
728 	return ice_free_res_cntr(hw, ICE_AQC_RES_TYPE_FDIR_COUNTER_BLOCK,
729 				 ICE_AQC_RES_TYPE_FLAG_DEDICATED, 1, cntr_id);
730 }
731 
732 /**
733  * ice_alloc_fd_guar_item - allocate resource for FD guaranteed entries
734  * @hw: pointer to the hardware structure
735  * @cntr_id: returns counter index
736  * @num_fltr: number of filter entries to be allocated
737  */
738 enum ice_status
739 ice_alloc_fd_guar_item(struct ice_hw *hw, u16 *cntr_id, u16 num_fltr)
740 {
741 	return ice_alloc_res_cntr(hw, ICE_AQC_RES_TYPE_FDIR_GUARANTEED_ENTRIES,
742 				  ICE_AQC_RES_TYPE_FLAG_DEDICATED, num_fltr,
743 				  cntr_id);
744 }
745 
746 /**
747  * ice_alloc_fd_shrd_item - allocate resource for flow director shared entries
748  * @hw: pointer to the hardware structure
749  * @cntr_id: returns counter index
750  * @num_fltr: number of filter entries to be allocated
751  */
752 enum ice_status
753 ice_alloc_fd_shrd_item(struct ice_hw *hw, u16 *cntr_id, u16 num_fltr)
754 {
755 	return ice_alloc_res_cntr(hw, ICE_AQC_RES_TYPE_FDIR_SHARED_ENTRIES,
756 				  ICE_AQC_RES_TYPE_FLAG_DEDICATED, num_fltr,
757 				  cntr_id);
758 }
759 
760 /**
761  * ice_get_fdir_cnt_all - get the number of Flow Director filters
762  * @hw: hardware data structure
763  *
764  * Returns the number of filters available on device
765  */
766 int ice_get_fdir_cnt_all(struct ice_hw *hw)
767 {
768 	return hw->func_caps.fd_fltr_guar + hw->func_caps.fd_fltr_best_effort;
769 }
770 
771 /**
772  * ice_pkt_insert_ipv6_addr - insert a be32 IPv6 address into a memory buffer
773  * @pkt: packet buffer
774  * @offset: offset into buffer
775  * @addr: IPv6 address to convert and insert into pkt at offset
776  */
777 static void ice_pkt_insert_ipv6_addr(u8 *pkt, int offset, __be32 *addr)
778 {
779 	int idx;
780 
781 	for (idx = 0; idx < ICE_IPV6_ADDR_LEN_AS_U32; idx++)
782 		memcpy(pkt + offset + idx * sizeof(*addr), &addr[idx],
783 		       sizeof(*addr));
784 }
785 
786 /**
787  * ice_pkt_insert_u6_qfi - insert a u6 value QFI into a memory buffer for GTPU
788  * @pkt: packet buffer
789  * @offset: offset into buffer
790  * @data: 8 bit value to convert and insert into pkt at offset
791  *
792  * This function is designed for inserting QFI (6 bits) for GTPU.
793  */
794 static void ice_pkt_insert_u6_qfi(u8 *pkt, int offset, u8 data)
795 {
796 	u8 ret;
797 
798 	ret = (data & 0x3F) + (*(pkt + offset) & 0xC0);
799 	memcpy(pkt + offset, &ret, sizeof(ret));
800 }
801 
802 /**
803  * ice_pkt_insert_u8 - insert a u8 value into a memory buffer.
804  * @pkt: packet buffer
805  * @offset: offset into buffer
806  * @data: 8 bit value to convert and insert into pkt at offset
807  */
808 static void ice_pkt_insert_u8(u8 *pkt, int offset, u8 data)
809 {
810 	memcpy(pkt + offset, &data, sizeof(data));
811 }
812 
813 /**
814  * ice_pkt_insert_u8_tc - insert a u8 value into a memory buffer for TC ipv6.
815  * @pkt: packet buffer
816  * @offset: offset into buffer
817  * @data: 8 bit value to convert and insert into pkt at offset
818  *
819  * This function is designed for inserting Traffic Class (TC) for IPv6,
820  * since that TC is not aligned in number of bytes. Here we split it out
821  * into two part and fill each byte with data copy from pkt, then insert
822  * the two bytes data one by one.
823  */
824 static void ice_pkt_insert_u8_tc(u8 *pkt, int offset, u8 data)
825 {
826 	u8 high, low;
827 
828 	high = (data >> 4) + (*(pkt + offset) & 0xF0);
829 	memcpy(pkt + offset, &high, sizeof(high));
830 
831 	low = (*(pkt + offset + 1) & 0x0F) + ((data & 0x0F) << 4);
832 	memcpy(pkt + offset + 1, &low, sizeof(low));
833 }
834 
835 /**
836  * ice_pkt_insert_u16 - insert a be16 value into a memory buffer
837  * @pkt: packet buffer
838  * @offset: offset into buffer
839  * @data: 16 bit value to convert and insert into pkt at offset
840  */
841 static void ice_pkt_insert_u16(u8 *pkt, int offset, __be16 data)
842 {
843 	memcpy(pkt + offset, &data, sizeof(data));
844 }
845 
846 /**
847  * ice_pkt_insert_u32 - insert a be32 value into a memory buffer
848  * @pkt: packet buffer
849  * @offset: offset into buffer
850  * @data: 32 bit value to convert and insert into pkt at offset
851  */
852 static void ice_pkt_insert_u32(u8 *pkt, int offset, __be32 data)
853 {
854 	memcpy(pkt + offset, &data, sizeof(data));
855 }
856 
857 /**
858  * ice_pkt_insert_mac_addr - insert a MAC addr into a memory buffer.
859  * @pkt: packet buffer
860  * @addr: MAC address to convert and insert into pkt at offset
861  */
862 static void ice_pkt_insert_mac_addr(u8 *pkt, u8 *addr)
863 {
864 	ether_addr_copy(pkt, addr);
865 }
866 
867 /**
868  * ice_fdir_get_gen_prgm_pkt - generate a training packet
869  * @hw: pointer to the hardware structure
870  * @input: flow director filter data structure
871  * @pkt: pointer to return filter packet
872  * @frag: generate a fragment packet
873  * @tun: true implies generate a tunnel packet
874  */
875 enum ice_status
876 ice_fdir_get_gen_prgm_pkt(struct ice_hw *hw, struct ice_fdir_fltr *input,
877 			  u8 *pkt, bool frag, bool tun)
878 {
879 	enum ice_fltr_ptype flow;
880 	u16 tnl_port;
881 	u8 *loc;
882 	u16 idx;
883 
884 	if (input->flow_type == ICE_FLTR_PTYPE_NONF_IPV4_OTHER) {
885 		switch (input->ip.v4.proto) {
886 		case IPPROTO_TCP:
887 			flow = ICE_FLTR_PTYPE_NONF_IPV4_TCP;
888 			break;
889 		case IPPROTO_UDP:
890 			flow = ICE_FLTR_PTYPE_NONF_IPV4_UDP;
891 			break;
892 		case IPPROTO_SCTP:
893 			flow = ICE_FLTR_PTYPE_NONF_IPV4_SCTP;
894 			break;
895 		default:
896 			flow = ICE_FLTR_PTYPE_NONF_IPV4_OTHER;
897 			break;
898 		}
899 	} else if (input->flow_type == ICE_FLTR_PTYPE_NONF_IPV6_OTHER) {
900 		switch (input->ip.v6.proto) {
901 		case IPPROTO_TCP:
902 			flow = ICE_FLTR_PTYPE_NONF_IPV6_TCP;
903 			break;
904 		case IPPROTO_UDP:
905 			flow = ICE_FLTR_PTYPE_NONF_IPV6_UDP;
906 			break;
907 		case IPPROTO_SCTP:
908 			flow = ICE_FLTR_PTYPE_NONF_IPV6_SCTP;
909 			break;
910 		default:
911 			flow = ICE_FLTR_PTYPE_NONF_IPV6_OTHER;
912 			break;
913 		}
914 	} else {
915 		flow = input->flow_type;
916 	}
917 
918 	for (idx = 0; idx < ICE_FDIR_NUM_PKT; idx++)
919 		if (ice_fdir_pkt[idx].flow == flow)
920 			break;
921 	if (idx == ICE_FDIR_NUM_PKT)
922 		return ICE_ERR_PARAM;
923 	if (!tun) {
924 		memcpy(pkt, ice_fdir_pkt[idx].pkt, ice_fdir_pkt[idx].pkt_len);
925 		loc = pkt;
926 	} else {
927 		if (!ice_get_open_tunnel_port(hw, &tnl_port))
928 			return ICE_ERR_DOES_NOT_EXIST;
929 		if (!ice_fdir_pkt[idx].tun_pkt)
930 			return ICE_ERR_PARAM;
931 		memcpy(pkt, ice_fdir_pkt[idx].tun_pkt,
932 		       ice_fdir_pkt[idx].tun_pkt_len);
933 		ice_pkt_insert_u16(pkt, ICE_IPV4_UDP_DST_PORT_OFFSET,
934 				   htons(tnl_port));
935 		loc = &pkt[ICE_FDIR_TUN_PKT_OFF];
936 	}
937 
938 	/* Reverse the src and dst, since the HW expects them to be from Tx
939 	 * perspective. The input from user is from Rx filter perspective.
940 	 */
941 	switch (flow) {
942 	case ICE_FLTR_PTYPE_NONF_IPV4_TCP:
943 		ice_pkt_insert_u32(loc, ICE_IPV4_DST_ADDR_OFFSET,
944 				   input->ip.v4.src_ip);
945 		ice_pkt_insert_u16(loc, ICE_IPV4_TCP_DST_PORT_OFFSET,
946 				   input->ip.v4.src_port);
947 		ice_pkt_insert_u32(loc, ICE_IPV4_SRC_ADDR_OFFSET,
948 				   input->ip.v4.dst_ip);
949 		ice_pkt_insert_u16(loc, ICE_IPV4_TCP_SRC_PORT_OFFSET,
950 				   input->ip.v4.dst_port);
951 		ice_pkt_insert_u8(loc, ICE_IPV4_TOS_OFFSET, input->ip.v4.tos);
952 		ice_pkt_insert_u8(loc, ICE_IPV4_TTL_OFFSET, input->ip.v4.ttl);
953 		ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac);
954 		if (frag)
955 			loc[20] = ICE_FDIR_IPV4_PKT_FLAG_DF;
956 		break;
957 	case ICE_FLTR_PTYPE_NONF_IPV4_UDP:
958 		ice_pkt_insert_u32(loc, ICE_IPV4_DST_ADDR_OFFSET,
959 				   input->ip.v4.src_ip);
960 		ice_pkt_insert_u16(loc, ICE_IPV4_UDP_DST_PORT_OFFSET,
961 				   input->ip.v4.src_port);
962 		ice_pkt_insert_u32(loc, ICE_IPV4_SRC_ADDR_OFFSET,
963 				   input->ip.v4.dst_ip);
964 		ice_pkt_insert_u16(loc, ICE_IPV4_UDP_SRC_PORT_OFFSET,
965 				   input->ip.v4.dst_port);
966 		ice_pkt_insert_u8(loc, ICE_IPV4_TOS_OFFSET, input->ip.v4.tos);
967 		ice_pkt_insert_u8(loc, ICE_IPV4_TTL_OFFSET, input->ip.v4.ttl);
968 		ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac);
969 		ice_pkt_insert_mac_addr(loc + ETH_ALEN,
970 					input->ext_data.src_mac);
971 		break;
972 	case ICE_FLTR_PTYPE_NONF_IPV4_SCTP:
973 		ice_pkt_insert_u32(loc, ICE_IPV4_DST_ADDR_OFFSET,
974 				   input->ip.v4.src_ip);
975 		ice_pkt_insert_u16(loc, ICE_IPV4_SCTP_DST_PORT_OFFSET,
976 				   input->ip.v4.src_port);
977 		ice_pkt_insert_u32(loc, ICE_IPV4_SRC_ADDR_OFFSET,
978 				   input->ip.v4.dst_ip);
979 		ice_pkt_insert_u16(loc, ICE_IPV4_SCTP_SRC_PORT_OFFSET,
980 				   input->ip.v4.dst_port);
981 		ice_pkt_insert_u8(loc, ICE_IPV4_TOS_OFFSET, input->ip.v4.tos);
982 		ice_pkt_insert_u8(loc, ICE_IPV4_TTL_OFFSET, input->ip.v4.ttl);
983 		ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac);
984 		break;
985 	case ICE_FLTR_PTYPE_NONF_IPV4_OTHER:
986 		ice_pkt_insert_u32(loc, ICE_IPV4_DST_ADDR_OFFSET,
987 				   input->ip.v4.src_ip);
988 		ice_pkt_insert_u32(loc, ICE_IPV4_SRC_ADDR_OFFSET,
989 				   input->ip.v4.dst_ip);
990 		ice_pkt_insert_u8(loc, ICE_IPV4_TOS_OFFSET, input->ip.v4.tos);
991 		ice_pkt_insert_u8(loc, ICE_IPV4_TTL_OFFSET, input->ip.v4.ttl);
992 		ice_pkt_insert_u8(loc, ICE_IPV4_PROTO_OFFSET,
993 				  input->ip.v4.proto);
994 		ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac);
995 		break;
996 	case ICE_FLTR_PTYPE_NONF_IPV4_GTPU_IPV4_UDP:
997 	case ICE_FLTR_PTYPE_NONF_IPV4_GTPU_IPV4_TCP:
998 	case ICE_FLTR_PTYPE_NONF_IPV4_GTPU_IPV4_ICMP:
999 	case ICE_FLTR_PTYPE_NONF_IPV4_GTPU_IPV4_OTHER:
1000 		ice_pkt_insert_u32(loc, ICE_IPV4_DST_ADDR_OFFSET,
1001 				   input->ip.v4.src_ip);
1002 		ice_pkt_insert_u32(loc, ICE_IPV4_SRC_ADDR_OFFSET,
1003 				   input->ip.v4.dst_ip);
1004 		ice_pkt_insert_u32(loc, ICE_IPV4_GTPU_TEID_OFFSET,
1005 				   input->gtpu_data.teid);
1006 		ice_pkt_insert_u6_qfi(loc, ICE_IPV4_GTPU_QFI_OFFSET,
1007 				      input->gtpu_data.qfi);
1008 		break;
1009 	case ICE_FLTR_PTYPE_NONF_IPV4_L2TPV3:
1010 		ice_pkt_insert_u32(loc, ICE_IPV4_L2TPV3_SESS_ID_OFFSET,
1011 				   input->l2tpv3_data.session_id);
1012 		break;
1013 	case ICE_FLTR_PTYPE_NONF_IPV6_L2TPV3:
1014 		ice_pkt_insert_u32(loc, ICE_IPV6_L2TPV3_SESS_ID_OFFSET,
1015 				   input->l2tpv3_data.session_id);
1016 		break;
1017 	case ICE_FLTR_PTYPE_NONF_IPV4_ESP:
1018 		ice_pkt_insert_u32(loc, ICE_IPV4_ESP_SPI_OFFSET,
1019 				   input->ip.v4.sec_parm_idx);
1020 		break;
1021 	case ICE_FLTR_PTYPE_NONF_IPV6_ESP:
1022 		ice_pkt_insert_u32(loc, ICE_IPV6_ESP_SPI_OFFSET,
1023 				   input->ip.v6.sec_parm_idx);
1024 		break;
1025 	case ICE_FLTR_PTYPE_NONF_IPV4_AH:
1026 		ice_pkt_insert_u32(loc, ICE_IPV4_AH_SPI_OFFSET,
1027 				   input->ip.v4.sec_parm_idx);
1028 		break;
1029 	case ICE_FLTR_PTYPE_NONF_IPV6_AH:
1030 		ice_pkt_insert_u32(loc, ICE_IPV6_AH_SPI_OFFSET,
1031 				   input->ip.v6.sec_parm_idx);
1032 		break;
1033 	case ICE_FLTR_PTYPE_NONF_IPV4_NAT_T_ESP:
1034 		ice_pkt_insert_u32(loc, ICE_IPV4_DST_ADDR_OFFSET,
1035 				   input->ip.v4.src_ip);
1036 		ice_pkt_insert_u32(loc, ICE_IPV4_SRC_ADDR_OFFSET,
1037 				   input->ip.v4.dst_ip);
1038 		ice_pkt_insert_u32(loc, ICE_IPV4_NAT_T_ESP_SPI_OFFSET,
1039 				   input->ip.v4.sec_parm_idx);
1040 		break;
1041 	case ICE_FLTR_PTYPE_NONF_IPV6_NAT_T_ESP:
1042 		ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_DST_ADDR_OFFSET,
1043 					 input->ip.v6.src_ip);
1044 		ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_SRC_ADDR_OFFSET,
1045 					 input->ip.v6.dst_ip);
1046 		ice_pkt_insert_u32(loc, ICE_IPV6_NAT_T_ESP_SPI_OFFSET,
1047 				   input->ip.v6.sec_parm_idx);
1048 		break;
1049 	case ICE_FLTR_PTYPE_NONF_IPV4_PFCP_NODE:
1050 	case ICE_FLTR_PTYPE_NONF_IPV4_PFCP_SESSION:
1051 		ice_pkt_insert_u16(loc, ICE_IPV4_UDP_SRC_PORT_OFFSET,
1052 				   input->ip.v4.dst_port);
1053 		break;
1054 	case ICE_FLTR_PTYPE_NONF_IPV6_PFCP_NODE:
1055 	case ICE_FLTR_PTYPE_NONF_IPV6_PFCP_SESSION:
1056 		ice_pkt_insert_u16(loc, ICE_IPV6_UDP_SRC_PORT_OFFSET,
1057 				   input->ip.v6.dst_port);
1058 		break;
1059 	case ICE_FLTR_PTYPE_NON_IP_L2:
1060 		ice_pkt_insert_u16(loc, ICE_MAC_ETHTYPE_OFFSET,
1061 				   input->ext_data.ether_type);
1062 		break;
1063 	case ICE_FLTR_PTYPE_NONF_IPV6_TCP:
1064 		ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_DST_ADDR_OFFSET,
1065 					 input->ip.v6.src_ip);
1066 		ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_SRC_ADDR_OFFSET,
1067 					 input->ip.v6.dst_ip);
1068 		ice_pkt_insert_u16(loc, ICE_IPV6_TCP_DST_PORT_OFFSET,
1069 				   input->ip.v6.src_port);
1070 		ice_pkt_insert_u16(loc, ICE_IPV6_TCP_SRC_PORT_OFFSET,
1071 				   input->ip.v6.dst_port);
1072 		ice_pkt_insert_u8_tc(loc, ICE_IPV6_TC_OFFSET, input->ip.v6.tc);
1073 		ice_pkt_insert_u8(loc, ICE_IPV6_HLIM_OFFSET, input->ip.v6.hlim);
1074 		ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac);
1075 		break;
1076 	case ICE_FLTR_PTYPE_NONF_IPV6_UDP:
1077 		ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_DST_ADDR_OFFSET,
1078 					 input->ip.v6.src_ip);
1079 		ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_SRC_ADDR_OFFSET,
1080 					 input->ip.v6.dst_ip);
1081 		ice_pkt_insert_u16(loc, ICE_IPV6_UDP_DST_PORT_OFFSET,
1082 				   input->ip.v6.src_port);
1083 		ice_pkt_insert_u16(loc, ICE_IPV6_UDP_SRC_PORT_OFFSET,
1084 				   input->ip.v6.dst_port);
1085 		ice_pkt_insert_u8_tc(loc, ICE_IPV6_TC_OFFSET, input->ip.v6.tc);
1086 		ice_pkt_insert_u8(loc, ICE_IPV6_HLIM_OFFSET, input->ip.v6.hlim);
1087 		ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac);
1088 		break;
1089 	case ICE_FLTR_PTYPE_NONF_IPV6_SCTP:
1090 		ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_DST_ADDR_OFFSET,
1091 					 input->ip.v6.src_ip);
1092 		ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_SRC_ADDR_OFFSET,
1093 					 input->ip.v6.dst_ip);
1094 		ice_pkt_insert_u16(loc, ICE_IPV6_SCTP_DST_PORT_OFFSET,
1095 				   input->ip.v6.src_port);
1096 		ice_pkt_insert_u16(loc, ICE_IPV6_SCTP_SRC_PORT_OFFSET,
1097 				   input->ip.v6.dst_port);
1098 		ice_pkt_insert_u8_tc(loc, ICE_IPV6_TC_OFFSET, input->ip.v6.tc);
1099 		ice_pkt_insert_u8(loc, ICE_IPV6_HLIM_OFFSET, input->ip.v6.hlim);
1100 		ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac);
1101 		break;
1102 	case ICE_FLTR_PTYPE_NONF_IPV6_OTHER:
1103 		ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_DST_ADDR_OFFSET,
1104 					 input->ip.v6.src_ip);
1105 		ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_SRC_ADDR_OFFSET,
1106 					 input->ip.v6.dst_ip);
1107 		ice_pkt_insert_u8_tc(loc, ICE_IPV6_TC_OFFSET, input->ip.v6.tc);
1108 		ice_pkt_insert_u8(loc, ICE_IPV6_HLIM_OFFSET, input->ip.v6.hlim);
1109 		ice_pkt_insert_u8(loc, ICE_IPV6_PROTO_OFFSET,
1110 				  input->ip.v6.proto);
1111 		ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac);
1112 		break;
1113 	default:
1114 		return ICE_ERR_PARAM;
1115 	}
1116 
1117 	if (input->flex_fltr)
1118 		ice_pkt_insert_u16(loc, input->flex_offset, input->flex_word);
1119 
1120 	return 0;
1121 }
1122 
1123 /**
1124  * ice_fdir_has_frag - does flow type have 2 ptypes
1125  * @flow: flow ptype
1126  *
1127  * returns true is there is a fragment packet for this ptype
1128  */
1129 bool ice_fdir_has_frag(enum ice_fltr_ptype flow)
1130 {
1131 	if (flow == ICE_FLTR_PTYPE_NONF_IPV4_OTHER)
1132 		return true;
1133 	else
1134 		return false;
1135 }
1136 
1137 /**
1138  * ice_fdir_find_fltr_by_idx - find filter with idx
1139  * @hw: pointer to hardware structure
1140  * @fltr_idx: index to find.
1141  *
1142  * Returns pointer to filter if found or null
1143  */
1144 struct ice_fdir_fltr *
1145 ice_fdir_find_fltr_by_idx(struct ice_hw *hw, u32 fltr_idx)
1146 {
1147 	struct ice_fdir_fltr *rule;
1148 
1149 	list_for_each_entry(rule, &hw->fdir_list_head, fltr_node) {
1150 		/* rule ID found in the list */
1151 		if (fltr_idx == rule->fltr_id)
1152 			return rule;
1153 		if (fltr_idx < rule->fltr_id)
1154 			break;
1155 	}
1156 	return NULL;
1157 }
1158 
1159 /**
1160  * ice_fdir_list_add_fltr - add a new node to the flow director filter list
1161  * @hw: hardware structure
1162  * @fltr: filter node to add to structure
1163  */
1164 void ice_fdir_list_add_fltr(struct ice_hw *hw, struct ice_fdir_fltr *fltr)
1165 {
1166 	struct ice_fdir_fltr *rule, *parent = NULL;
1167 
1168 	list_for_each_entry(rule, &hw->fdir_list_head, fltr_node) {
1169 		/* rule ID found or pass its spot in the list */
1170 		if (rule->fltr_id >= fltr->fltr_id)
1171 			break;
1172 		parent = rule;
1173 	}
1174 
1175 	if (parent)
1176 		list_add(&fltr->fltr_node, &parent->fltr_node);
1177 	else
1178 		list_add(&fltr->fltr_node, &hw->fdir_list_head);
1179 }
1180 
1181 /**
1182  * ice_fdir_update_cntrs - increment / decrement filter counter
1183  * @hw: pointer to hardware structure
1184  * @flow: filter flow type
1185  * @add: true implies filters added
1186  */
1187 void
1188 ice_fdir_update_cntrs(struct ice_hw *hw, enum ice_fltr_ptype flow, bool add)
1189 {
1190 	int incr;
1191 
1192 	incr = add ? 1 : -1;
1193 	hw->fdir_active_fltr += incr;
1194 
1195 	if (flow == ICE_FLTR_PTYPE_NONF_NONE || flow >= ICE_FLTR_PTYPE_MAX)
1196 		ice_debug(hw, ICE_DBG_SW, "Unknown filter type %d\n", flow);
1197 	else
1198 		hw->fdir_fltr_cnt[flow] += incr;
1199 }
1200 
1201 /**
1202  * ice_cmp_ipv6_addr - compare 2 IP v6 addresses
1203  * @a: IP v6 address
1204  * @b: IP v6 address
1205  *
1206  * Returns 0 on equal, returns non-0 if different
1207  */
1208 static int ice_cmp_ipv6_addr(__be32 *a, __be32 *b)
1209 {
1210 	return memcmp(a, b, 4 * sizeof(__be32));
1211 }
1212 
1213 /**
1214  * ice_fdir_comp_rules - compare 2 filters
1215  * @a: a Flow Director filter data structure
1216  * @b: a Flow Director filter data structure
1217  * @v6: bool true if v6 filter
1218  *
1219  * Returns true if the filters match
1220  */
1221 static bool
1222 ice_fdir_comp_rules(struct ice_fdir_fltr *a,  struct ice_fdir_fltr *b, bool v6)
1223 {
1224 	enum ice_fltr_ptype flow_type = a->flow_type;
1225 
1226 	/* The calling function already checks that the two filters have the
1227 	 * same flow_type.
1228 	 */
1229 	if (!v6) {
1230 		if (flow_type == ICE_FLTR_PTYPE_NONF_IPV4_TCP ||
1231 		    flow_type == ICE_FLTR_PTYPE_NONF_IPV4_UDP ||
1232 		    flow_type == 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 		} else if (flow_type == ICE_FLTR_PTYPE_NONF_IPV4_OTHER) {
1239 			if (a->ip.v4.dst_ip == b->ip.v4.dst_ip &&
1240 			    a->ip.v4.src_ip == b->ip.v4.src_ip &&
1241 			    a->ip.v4.l4_header == b->ip.v4.l4_header &&
1242 			    a->ip.v4.proto == b->ip.v4.proto &&
1243 			    a->ip.v4.ip_ver == b->ip.v4.ip_ver &&
1244 			    a->ip.v4.tos == b->ip.v4.tos)
1245 				return true;
1246 		}
1247 	} else {
1248 		if (flow_type == ICE_FLTR_PTYPE_NONF_IPV6_UDP ||
1249 		    flow_type == ICE_FLTR_PTYPE_NONF_IPV6_TCP ||
1250 		    flow_type == 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 		} else if (flow_type == ICE_FLTR_PTYPE_NONF_IPV6_OTHER) {
1259 			if (a->ip.v6.dst_port == b->ip.v6.dst_port &&
1260 			    a->ip.v6.src_port == b->ip.v6.src_port)
1261 				return true;
1262 		}
1263 	}
1264 
1265 	return false;
1266 }
1267 
1268 /**
1269  * ice_fdir_is_dup_fltr - test if filter is already in list for PF
1270  * @hw: hardware data structure
1271  * @input: Flow Director filter data structure
1272  *
1273  * Returns true if the filter is found in the list
1274  */
1275 bool ice_fdir_is_dup_fltr(struct ice_hw *hw, struct ice_fdir_fltr *input)
1276 {
1277 	struct ice_fdir_fltr *rule;
1278 	bool ret = false;
1279 
1280 	list_for_each_entry(rule, &hw->fdir_list_head, fltr_node) {
1281 		enum ice_fltr_ptype flow_type;
1282 
1283 		if (rule->flow_type != input->flow_type)
1284 			continue;
1285 
1286 		flow_type = input->flow_type;
1287 		if (flow_type == ICE_FLTR_PTYPE_NONF_IPV4_TCP ||
1288 		    flow_type == ICE_FLTR_PTYPE_NONF_IPV4_UDP ||
1289 		    flow_type == ICE_FLTR_PTYPE_NONF_IPV4_SCTP ||
1290 		    flow_type == ICE_FLTR_PTYPE_NONF_IPV4_OTHER)
1291 			ret = ice_fdir_comp_rules(rule, input, false);
1292 		else
1293 			ret = ice_fdir_comp_rules(rule, input, true);
1294 		if (ret) {
1295 			if (rule->fltr_id == input->fltr_id &&
1296 			    rule->q_index != input->q_index)
1297 				ret = false;
1298 			else
1299 				break;
1300 		}
1301 	}
1302 
1303 	return ret;
1304 }
1305