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 int 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 int 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 int ice_alloc_fd_guar_item(struct ice_hw *hw, u16 *cntr_id, u16 num_fltr)
739 {
740 	return ice_alloc_res_cntr(hw, ICE_AQC_RES_TYPE_FDIR_GUARANTEED_ENTRIES,
741 				  ICE_AQC_RES_TYPE_FLAG_DEDICATED, num_fltr,
742 				  cntr_id);
743 }
744 
745 /**
746  * ice_alloc_fd_shrd_item - allocate resource for flow director shared entries
747  * @hw: pointer to the hardware structure
748  * @cntr_id: returns counter index
749  * @num_fltr: number of filter entries to be allocated
750  */
751 int ice_alloc_fd_shrd_item(struct ice_hw *hw, u16 *cntr_id, u16 num_fltr)
752 {
753 	return ice_alloc_res_cntr(hw, ICE_AQC_RES_TYPE_FDIR_SHARED_ENTRIES,
754 				  ICE_AQC_RES_TYPE_FLAG_DEDICATED, num_fltr,
755 				  cntr_id);
756 }
757 
758 /**
759  * ice_get_fdir_cnt_all - get the number of Flow Director filters
760  * @hw: hardware data structure
761  *
762  * Returns the number of filters available on device
763  */
764 int ice_get_fdir_cnt_all(struct ice_hw *hw)
765 {
766 	return hw->func_caps.fd_fltr_guar + hw->func_caps.fd_fltr_best_effort;
767 }
768 
769 /**
770  * ice_pkt_insert_ipv6_addr - insert a be32 IPv6 address into a memory buffer
771  * @pkt: packet buffer
772  * @offset: offset into buffer
773  * @addr: IPv6 address to convert and insert into pkt at offset
774  */
775 static void ice_pkt_insert_ipv6_addr(u8 *pkt, int offset, __be32 *addr)
776 {
777 	int idx;
778 
779 	for (idx = 0; idx < ICE_IPV6_ADDR_LEN_AS_U32; idx++)
780 		memcpy(pkt + offset + idx * sizeof(*addr), &addr[idx],
781 		       sizeof(*addr));
782 }
783 
784 /**
785  * ice_pkt_insert_u6_qfi - insert a u6 value QFI into a memory buffer for GTPU
786  * @pkt: packet buffer
787  * @offset: offset into buffer
788  * @data: 8 bit value to convert and insert into pkt at offset
789  *
790  * This function is designed for inserting QFI (6 bits) for GTPU.
791  */
792 static void ice_pkt_insert_u6_qfi(u8 *pkt, int offset, u8 data)
793 {
794 	u8 ret;
795 
796 	ret = (data & 0x3F) + (*(pkt + offset) & 0xC0);
797 	memcpy(pkt + offset, &ret, sizeof(ret));
798 }
799 
800 /**
801  * ice_pkt_insert_u8 - insert a u8 value into a memory buffer.
802  * @pkt: packet buffer
803  * @offset: offset into buffer
804  * @data: 8 bit value to convert and insert into pkt at offset
805  */
806 static void ice_pkt_insert_u8(u8 *pkt, int offset, u8 data)
807 {
808 	memcpy(pkt + offset, &data, sizeof(data));
809 }
810 
811 /**
812  * ice_pkt_insert_u8_tc - insert a u8 value into a memory buffer for TC ipv6.
813  * @pkt: packet buffer
814  * @offset: offset into buffer
815  * @data: 8 bit value to convert and insert into pkt at offset
816  *
817  * This function is designed for inserting Traffic Class (TC) for IPv6,
818  * since that TC is not aligned in number of bytes. Here we split it out
819  * into two part and fill each byte with data copy from pkt, then insert
820  * the two bytes data one by one.
821  */
822 static void ice_pkt_insert_u8_tc(u8 *pkt, int offset, u8 data)
823 {
824 	u8 high, low;
825 
826 	high = (data >> 4) + (*(pkt + offset) & 0xF0);
827 	memcpy(pkt + offset, &high, sizeof(high));
828 
829 	low = (*(pkt + offset + 1) & 0x0F) + ((data & 0x0F) << 4);
830 	memcpy(pkt + offset + 1, &low, sizeof(low));
831 }
832 
833 /**
834  * ice_pkt_insert_u16 - insert a be16 value into a memory buffer
835  * @pkt: packet buffer
836  * @offset: offset into buffer
837  * @data: 16 bit value to convert and insert into pkt at offset
838  */
839 static void ice_pkt_insert_u16(u8 *pkt, int offset, __be16 data)
840 {
841 	memcpy(pkt + offset, &data, sizeof(data));
842 }
843 
844 /**
845  * ice_pkt_insert_u32 - insert a be32 value into a memory buffer
846  * @pkt: packet buffer
847  * @offset: offset into buffer
848  * @data: 32 bit value to convert and insert into pkt at offset
849  */
850 static void ice_pkt_insert_u32(u8 *pkt, int offset, __be32 data)
851 {
852 	memcpy(pkt + offset, &data, sizeof(data));
853 }
854 
855 /**
856  * ice_pkt_insert_mac_addr - insert a MAC addr into a memory buffer.
857  * @pkt: packet buffer
858  * @addr: MAC address to convert and insert into pkt at offset
859  */
860 static void ice_pkt_insert_mac_addr(u8 *pkt, u8 *addr)
861 {
862 	ether_addr_copy(pkt, addr);
863 }
864 
865 /**
866  * ice_fdir_get_gen_prgm_pkt - generate a training packet
867  * @hw: pointer to the hardware structure
868  * @input: flow director filter data structure
869  * @pkt: pointer to return filter packet
870  * @frag: generate a fragment packet
871  * @tun: true implies generate a tunnel packet
872  */
873 int
874 ice_fdir_get_gen_prgm_pkt(struct ice_hw *hw, struct ice_fdir_fltr *input,
875 			  u8 *pkt, bool frag, bool tun)
876 {
877 	enum ice_fltr_ptype flow;
878 	u16 tnl_port;
879 	u8 *loc;
880 	u16 idx;
881 
882 	if (input->flow_type == ICE_FLTR_PTYPE_NONF_IPV4_OTHER) {
883 		switch (input->ip.v4.proto) {
884 		case IPPROTO_TCP:
885 			flow = ICE_FLTR_PTYPE_NONF_IPV4_TCP;
886 			break;
887 		case IPPROTO_UDP:
888 			flow = ICE_FLTR_PTYPE_NONF_IPV4_UDP;
889 			break;
890 		case IPPROTO_SCTP:
891 			flow = ICE_FLTR_PTYPE_NONF_IPV4_SCTP;
892 			break;
893 		default:
894 			flow = ICE_FLTR_PTYPE_NONF_IPV4_OTHER;
895 			break;
896 		}
897 	} else if (input->flow_type == ICE_FLTR_PTYPE_NONF_IPV6_OTHER) {
898 		switch (input->ip.v6.proto) {
899 		case IPPROTO_TCP:
900 			flow = ICE_FLTR_PTYPE_NONF_IPV6_TCP;
901 			break;
902 		case IPPROTO_UDP:
903 			flow = ICE_FLTR_PTYPE_NONF_IPV6_UDP;
904 			break;
905 		case IPPROTO_SCTP:
906 			flow = ICE_FLTR_PTYPE_NONF_IPV6_SCTP;
907 			break;
908 		default:
909 			flow = ICE_FLTR_PTYPE_NONF_IPV6_OTHER;
910 			break;
911 		}
912 	} else {
913 		flow = input->flow_type;
914 	}
915 
916 	for (idx = 0; idx < ICE_FDIR_NUM_PKT; idx++)
917 		if (ice_fdir_pkt[idx].flow == flow)
918 			break;
919 	if (idx == ICE_FDIR_NUM_PKT)
920 		return -EINVAL;
921 	if (!tun) {
922 		memcpy(pkt, ice_fdir_pkt[idx].pkt, ice_fdir_pkt[idx].pkt_len);
923 		loc = pkt;
924 	} else {
925 		if (!ice_get_open_tunnel_port(hw, &tnl_port, TNL_ALL))
926 			return -ENOENT;
927 		if (!ice_fdir_pkt[idx].tun_pkt)
928 			return -EINVAL;
929 		memcpy(pkt, ice_fdir_pkt[idx].tun_pkt,
930 		       ice_fdir_pkt[idx].tun_pkt_len);
931 		ice_pkt_insert_u16(pkt, ICE_IPV4_UDP_DST_PORT_OFFSET,
932 				   htons(tnl_port));
933 		loc = &pkt[ICE_FDIR_TUN_PKT_OFF];
934 	}
935 
936 	/* Reverse the src and dst, since the HW expects them to be from Tx
937 	 * perspective. The input from user is from Rx filter perspective.
938 	 */
939 	switch (flow) {
940 	case ICE_FLTR_PTYPE_NONF_IPV4_TCP:
941 		ice_pkt_insert_u32(loc, ICE_IPV4_DST_ADDR_OFFSET,
942 				   input->ip.v4.src_ip);
943 		ice_pkt_insert_u16(loc, ICE_IPV4_TCP_DST_PORT_OFFSET,
944 				   input->ip.v4.src_port);
945 		ice_pkt_insert_u32(loc, ICE_IPV4_SRC_ADDR_OFFSET,
946 				   input->ip.v4.dst_ip);
947 		ice_pkt_insert_u16(loc, ICE_IPV4_TCP_SRC_PORT_OFFSET,
948 				   input->ip.v4.dst_port);
949 		ice_pkt_insert_u8(loc, ICE_IPV4_TOS_OFFSET, input->ip.v4.tos);
950 		ice_pkt_insert_u8(loc, ICE_IPV4_TTL_OFFSET, input->ip.v4.ttl);
951 		ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac);
952 		if (frag)
953 			loc[20] = ICE_FDIR_IPV4_PKT_FLAG_MF;
954 		break;
955 	case ICE_FLTR_PTYPE_NONF_IPV4_UDP:
956 		ice_pkt_insert_u32(loc, ICE_IPV4_DST_ADDR_OFFSET,
957 				   input->ip.v4.src_ip);
958 		ice_pkt_insert_u16(loc, ICE_IPV4_UDP_DST_PORT_OFFSET,
959 				   input->ip.v4.src_port);
960 		ice_pkt_insert_u32(loc, ICE_IPV4_SRC_ADDR_OFFSET,
961 				   input->ip.v4.dst_ip);
962 		ice_pkt_insert_u16(loc, ICE_IPV4_UDP_SRC_PORT_OFFSET,
963 				   input->ip.v4.dst_port);
964 		ice_pkt_insert_u8(loc, ICE_IPV4_TOS_OFFSET, input->ip.v4.tos);
965 		ice_pkt_insert_u8(loc, ICE_IPV4_TTL_OFFSET, input->ip.v4.ttl);
966 		ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac);
967 		ice_pkt_insert_mac_addr(loc + ETH_ALEN,
968 					input->ext_data.src_mac);
969 		break;
970 	case ICE_FLTR_PTYPE_NONF_IPV4_SCTP:
971 		ice_pkt_insert_u32(loc, ICE_IPV4_DST_ADDR_OFFSET,
972 				   input->ip.v4.src_ip);
973 		ice_pkt_insert_u16(loc, ICE_IPV4_SCTP_DST_PORT_OFFSET,
974 				   input->ip.v4.src_port);
975 		ice_pkt_insert_u32(loc, ICE_IPV4_SRC_ADDR_OFFSET,
976 				   input->ip.v4.dst_ip);
977 		ice_pkt_insert_u16(loc, ICE_IPV4_SCTP_SRC_PORT_OFFSET,
978 				   input->ip.v4.dst_port);
979 		ice_pkt_insert_u8(loc, ICE_IPV4_TOS_OFFSET, input->ip.v4.tos);
980 		ice_pkt_insert_u8(loc, ICE_IPV4_TTL_OFFSET, input->ip.v4.ttl);
981 		ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac);
982 		break;
983 	case ICE_FLTR_PTYPE_NONF_IPV4_OTHER:
984 		ice_pkt_insert_u32(loc, ICE_IPV4_DST_ADDR_OFFSET,
985 				   input->ip.v4.src_ip);
986 		ice_pkt_insert_u32(loc, ICE_IPV4_SRC_ADDR_OFFSET,
987 				   input->ip.v4.dst_ip);
988 		ice_pkt_insert_u8(loc, ICE_IPV4_TOS_OFFSET, input->ip.v4.tos);
989 		ice_pkt_insert_u8(loc, ICE_IPV4_TTL_OFFSET, input->ip.v4.ttl);
990 		ice_pkt_insert_u8(loc, ICE_IPV4_PROTO_OFFSET,
991 				  input->ip.v4.proto);
992 		ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac);
993 		break;
994 	case ICE_FLTR_PTYPE_NONF_IPV4_GTPU_IPV4_UDP:
995 	case ICE_FLTR_PTYPE_NONF_IPV4_GTPU_IPV4_TCP:
996 	case ICE_FLTR_PTYPE_NONF_IPV4_GTPU_IPV4_ICMP:
997 	case ICE_FLTR_PTYPE_NONF_IPV4_GTPU_IPV4_OTHER:
998 		ice_pkt_insert_u32(loc, ICE_IPV4_DST_ADDR_OFFSET,
999 				   input->ip.v4.src_ip);
1000 		ice_pkt_insert_u32(loc, ICE_IPV4_SRC_ADDR_OFFSET,
1001 				   input->ip.v4.dst_ip);
1002 		ice_pkt_insert_u32(loc, ICE_IPV4_GTPU_TEID_OFFSET,
1003 				   input->gtpu_data.teid);
1004 		ice_pkt_insert_u6_qfi(loc, ICE_IPV4_GTPU_QFI_OFFSET,
1005 				      input->gtpu_data.qfi);
1006 		break;
1007 	case ICE_FLTR_PTYPE_NONF_IPV4_L2TPV3:
1008 		ice_pkt_insert_u32(loc, ICE_IPV4_L2TPV3_SESS_ID_OFFSET,
1009 				   input->l2tpv3_data.session_id);
1010 		break;
1011 	case ICE_FLTR_PTYPE_NONF_IPV6_L2TPV3:
1012 		ice_pkt_insert_u32(loc, ICE_IPV6_L2TPV3_SESS_ID_OFFSET,
1013 				   input->l2tpv3_data.session_id);
1014 		break;
1015 	case ICE_FLTR_PTYPE_NONF_IPV4_ESP:
1016 		ice_pkt_insert_u32(loc, ICE_IPV4_ESP_SPI_OFFSET,
1017 				   input->ip.v4.sec_parm_idx);
1018 		break;
1019 	case ICE_FLTR_PTYPE_NONF_IPV6_ESP:
1020 		ice_pkt_insert_u32(loc, ICE_IPV6_ESP_SPI_OFFSET,
1021 				   input->ip.v6.sec_parm_idx);
1022 		break;
1023 	case ICE_FLTR_PTYPE_NONF_IPV4_AH:
1024 		ice_pkt_insert_u32(loc, ICE_IPV4_AH_SPI_OFFSET,
1025 				   input->ip.v4.sec_parm_idx);
1026 		break;
1027 	case ICE_FLTR_PTYPE_NONF_IPV6_AH:
1028 		ice_pkt_insert_u32(loc, ICE_IPV6_AH_SPI_OFFSET,
1029 				   input->ip.v6.sec_parm_idx);
1030 		break;
1031 	case ICE_FLTR_PTYPE_NONF_IPV4_NAT_T_ESP:
1032 		ice_pkt_insert_u32(loc, ICE_IPV4_DST_ADDR_OFFSET,
1033 				   input->ip.v4.src_ip);
1034 		ice_pkt_insert_u32(loc, ICE_IPV4_SRC_ADDR_OFFSET,
1035 				   input->ip.v4.dst_ip);
1036 		ice_pkt_insert_u32(loc, ICE_IPV4_NAT_T_ESP_SPI_OFFSET,
1037 				   input->ip.v4.sec_parm_idx);
1038 		break;
1039 	case ICE_FLTR_PTYPE_NONF_IPV6_NAT_T_ESP:
1040 		ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_DST_ADDR_OFFSET,
1041 					 input->ip.v6.src_ip);
1042 		ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_SRC_ADDR_OFFSET,
1043 					 input->ip.v6.dst_ip);
1044 		ice_pkt_insert_u32(loc, ICE_IPV6_NAT_T_ESP_SPI_OFFSET,
1045 				   input->ip.v6.sec_parm_idx);
1046 		break;
1047 	case ICE_FLTR_PTYPE_NONF_IPV4_PFCP_NODE:
1048 	case ICE_FLTR_PTYPE_NONF_IPV4_PFCP_SESSION:
1049 		ice_pkt_insert_u16(loc, ICE_IPV4_UDP_SRC_PORT_OFFSET,
1050 				   input->ip.v4.dst_port);
1051 		break;
1052 	case ICE_FLTR_PTYPE_NONF_IPV6_PFCP_NODE:
1053 	case ICE_FLTR_PTYPE_NONF_IPV6_PFCP_SESSION:
1054 		ice_pkt_insert_u16(loc, ICE_IPV6_UDP_SRC_PORT_OFFSET,
1055 				   input->ip.v6.dst_port);
1056 		break;
1057 	case ICE_FLTR_PTYPE_NON_IP_L2:
1058 		ice_pkt_insert_u16(loc, ICE_MAC_ETHTYPE_OFFSET,
1059 				   input->ext_data.ether_type);
1060 		break;
1061 	case ICE_FLTR_PTYPE_NONF_IPV6_TCP:
1062 		ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_DST_ADDR_OFFSET,
1063 					 input->ip.v6.src_ip);
1064 		ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_SRC_ADDR_OFFSET,
1065 					 input->ip.v6.dst_ip);
1066 		ice_pkt_insert_u16(loc, ICE_IPV6_TCP_DST_PORT_OFFSET,
1067 				   input->ip.v6.src_port);
1068 		ice_pkt_insert_u16(loc, ICE_IPV6_TCP_SRC_PORT_OFFSET,
1069 				   input->ip.v6.dst_port);
1070 		ice_pkt_insert_u8_tc(loc, ICE_IPV6_TC_OFFSET, input->ip.v6.tc);
1071 		ice_pkt_insert_u8(loc, ICE_IPV6_HLIM_OFFSET, input->ip.v6.hlim);
1072 		ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac);
1073 		break;
1074 	case ICE_FLTR_PTYPE_NONF_IPV6_UDP:
1075 		ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_DST_ADDR_OFFSET,
1076 					 input->ip.v6.src_ip);
1077 		ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_SRC_ADDR_OFFSET,
1078 					 input->ip.v6.dst_ip);
1079 		ice_pkt_insert_u16(loc, ICE_IPV6_UDP_DST_PORT_OFFSET,
1080 				   input->ip.v6.src_port);
1081 		ice_pkt_insert_u16(loc, ICE_IPV6_UDP_SRC_PORT_OFFSET,
1082 				   input->ip.v6.dst_port);
1083 		ice_pkt_insert_u8_tc(loc, ICE_IPV6_TC_OFFSET, input->ip.v6.tc);
1084 		ice_pkt_insert_u8(loc, ICE_IPV6_HLIM_OFFSET, input->ip.v6.hlim);
1085 		ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac);
1086 		break;
1087 	case ICE_FLTR_PTYPE_NONF_IPV6_SCTP:
1088 		ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_DST_ADDR_OFFSET,
1089 					 input->ip.v6.src_ip);
1090 		ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_SRC_ADDR_OFFSET,
1091 					 input->ip.v6.dst_ip);
1092 		ice_pkt_insert_u16(loc, ICE_IPV6_SCTP_DST_PORT_OFFSET,
1093 				   input->ip.v6.src_port);
1094 		ice_pkt_insert_u16(loc, ICE_IPV6_SCTP_SRC_PORT_OFFSET,
1095 				   input->ip.v6.dst_port);
1096 		ice_pkt_insert_u8_tc(loc, ICE_IPV6_TC_OFFSET, input->ip.v6.tc);
1097 		ice_pkt_insert_u8(loc, ICE_IPV6_HLIM_OFFSET, input->ip.v6.hlim);
1098 		ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac);
1099 		break;
1100 	case ICE_FLTR_PTYPE_NONF_IPV6_OTHER:
1101 		ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_DST_ADDR_OFFSET,
1102 					 input->ip.v6.src_ip);
1103 		ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_SRC_ADDR_OFFSET,
1104 					 input->ip.v6.dst_ip);
1105 		ice_pkt_insert_u8_tc(loc, ICE_IPV6_TC_OFFSET, input->ip.v6.tc);
1106 		ice_pkt_insert_u8(loc, ICE_IPV6_HLIM_OFFSET, input->ip.v6.hlim);
1107 		ice_pkt_insert_u8(loc, ICE_IPV6_PROTO_OFFSET,
1108 				  input->ip.v6.proto);
1109 		ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac);
1110 		break;
1111 	default:
1112 		return -EINVAL;
1113 	}
1114 
1115 	if (input->flex_fltr)
1116 		ice_pkt_insert_u16(loc, input->flex_offset, input->flex_word);
1117 
1118 	return 0;
1119 }
1120 
1121 /**
1122  * ice_fdir_has_frag - does flow type have 2 ptypes
1123  * @flow: flow ptype
1124  *
1125  * returns true is there is a fragment packet for this ptype
1126  */
1127 bool ice_fdir_has_frag(enum ice_fltr_ptype flow)
1128 {
1129 	if (flow == ICE_FLTR_PTYPE_NONF_IPV4_OTHER)
1130 		return true;
1131 	else
1132 		return false;
1133 }
1134 
1135 /**
1136  * ice_fdir_find_fltr_by_idx - find filter with idx
1137  * @hw: pointer to hardware structure
1138  * @fltr_idx: index to find.
1139  *
1140  * Returns pointer to filter if found or null
1141  */
1142 struct ice_fdir_fltr *
1143 ice_fdir_find_fltr_by_idx(struct ice_hw *hw, u32 fltr_idx)
1144 {
1145 	struct ice_fdir_fltr *rule;
1146 
1147 	list_for_each_entry(rule, &hw->fdir_list_head, fltr_node) {
1148 		/* rule ID found in the list */
1149 		if (fltr_idx == rule->fltr_id)
1150 			return rule;
1151 		if (fltr_idx < rule->fltr_id)
1152 			break;
1153 	}
1154 	return NULL;
1155 }
1156 
1157 /**
1158  * ice_fdir_list_add_fltr - add a new node to the flow director filter list
1159  * @hw: hardware structure
1160  * @fltr: filter node to add to structure
1161  */
1162 void ice_fdir_list_add_fltr(struct ice_hw *hw, struct ice_fdir_fltr *fltr)
1163 {
1164 	struct ice_fdir_fltr *rule, *parent = NULL;
1165 
1166 	list_for_each_entry(rule, &hw->fdir_list_head, fltr_node) {
1167 		/* rule ID found or pass its spot in the list */
1168 		if (rule->fltr_id >= fltr->fltr_id)
1169 			break;
1170 		parent = rule;
1171 	}
1172 
1173 	if (parent)
1174 		list_add(&fltr->fltr_node, &parent->fltr_node);
1175 	else
1176 		list_add(&fltr->fltr_node, &hw->fdir_list_head);
1177 }
1178 
1179 /**
1180  * ice_fdir_update_cntrs - increment / decrement filter counter
1181  * @hw: pointer to hardware structure
1182  * @flow: filter flow type
1183  * @add: true implies filters added
1184  */
1185 void
1186 ice_fdir_update_cntrs(struct ice_hw *hw, enum ice_fltr_ptype flow, bool add)
1187 {
1188 	int incr;
1189 
1190 	incr = add ? 1 : -1;
1191 	hw->fdir_active_fltr += incr;
1192 
1193 	if (flow == ICE_FLTR_PTYPE_NONF_NONE || flow >= ICE_FLTR_PTYPE_MAX)
1194 		ice_debug(hw, ICE_DBG_SW, "Unknown filter type %d\n", flow);
1195 	else
1196 		hw->fdir_fltr_cnt[flow] += incr;
1197 }
1198 
1199 /**
1200  * ice_cmp_ipv6_addr - compare 2 IP v6 addresses
1201  * @a: IP v6 address
1202  * @b: IP v6 address
1203  *
1204  * Returns 0 on equal, returns non-0 if different
1205  */
1206 static int ice_cmp_ipv6_addr(__be32 *a, __be32 *b)
1207 {
1208 	return memcmp(a, b, 4 * sizeof(__be32));
1209 }
1210 
1211 /**
1212  * ice_fdir_comp_rules - compare 2 filters
1213  * @a: a Flow Director filter data structure
1214  * @b: a Flow Director filter data structure
1215  * @v6: bool true if v6 filter
1216  *
1217  * Returns true if the filters match
1218  */
1219 static bool
1220 ice_fdir_comp_rules(struct ice_fdir_fltr *a,  struct ice_fdir_fltr *b, bool v6)
1221 {
1222 	enum ice_fltr_ptype flow_type = a->flow_type;
1223 
1224 	/* The calling function already checks that the two filters have the
1225 	 * same flow_type.
1226 	 */
1227 	if (!v6) {
1228 		if (flow_type == ICE_FLTR_PTYPE_NONF_IPV4_TCP ||
1229 		    flow_type == ICE_FLTR_PTYPE_NONF_IPV4_UDP ||
1230 		    flow_type == ICE_FLTR_PTYPE_NONF_IPV4_SCTP) {
1231 			if (a->ip.v4.dst_ip == b->ip.v4.dst_ip &&
1232 			    a->ip.v4.src_ip == b->ip.v4.src_ip &&
1233 			    a->ip.v4.dst_port == b->ip.v4.dst_port &&
1234 			    a->ip.v4.src_port == b->ip.v4.src_port)
1235 				return true;
1236 		} else if (flow_type == ICE_FLTR_PTYPE_NONF_IPV4_OTHER) {
1237 			if (a->ip.v4.dst_ip == b->ip.v4.dst_ip &&
1238 			    a->ip.v4.src_ip == b->ip.v4.src_ip &&
1239 			    a->ip.v4.l4_header == b->ip.v4.l4_header &&
1240 			    a->ip.v4.proto == b->ip.v4.proto &&
1241 			    a->ip.v4.ip_ver == b->ip.v4.ip_ver &&
1242 			    a->ip.v4.tos == b->ip.v4.tos)
1243 				return true;
1244 		}
1245 	} else {
1246 		if (flow_type == ICE_FLTR_PTYPE_NONF_IPV6_UDP ||
1247 		    flow_type == ICE_FLTR_PTYPE_NONF_IPV6_TCP ||
1248 		    flow_type == ICE_FLTR_PTYPE_NONF_IPV6_SCTP) {
1249 			if (a->ip.v6.dst_port == b->ip.v6.dst_port &&
1250 			    a->ip.v6.src_port == b->ip.v6.src_port &&
1251 			    !ice_cmp_ipv6_addr(a->ip.v6.dst_ip,
1252 					       b->ip.v6.dst_ip) &&
1253 			    !ice_cmp_ipv6_addr(a->ip.v6.src_ip,
1254 					       b->ip.v6.src_ip))
1255 				return true;
1256 		} else if (flow_type == ICE_FLTR_PTYPE_NONF_IPV6_OTHER) {
1257 			if (a->ip.v6.dst_port == b->ip.v6.dst_port &&
1258 			    a->ip.v6.src_port == b->ip.v6.src_port)
1259 				return true;
1260 		}
1261 	}
1262 
1263 	return false;
1264 }
1265 
1266 /**
1267  * ice_fdir_is_dup_fltr - test if filter is already in list for PF
1268  * @hw: hardware data structure
1269  * @input: Flow Director filter data structure
1270  *
1271  * Returns true if the filter is found in the list
1272  */
1273 bool ice_fdir_is_dup_fltr(struct ice_hw *hw, struct ice_fdir_fltr *input)
1274 {
1275 	struct ice_fdir_fltr *rule;
1276 	bool ret = false;
1277 
1278 	list_for_each_entry(rule, &hw->fdir_list_head, fltr_node) {
1279 		enum ice_fltr_ptype flow_type;
1280 
1281 		if (rule->flow_type != input->flow_type)
1282 			continue;
1283 
1284 		flow_type = input->flow_type;
1285 		if (flow_type == ICE_FLTR_PTYPE_NONF_IPV4_TCP ||
1286 		    flow_type == ICE_FLTR_PTYPE_NONF_IPV4_UDP ||
1287 		    flow_type == ICE_FLTR_PTYPE_NONF_IPV4_SCTP ||
1288 		    flow_type == ICE_FLTR_PTYPE_NONF_IPV4_OTHER)
1289 			ret = ice_fdir_comp_rules(rule, input, false);
1290 		else
1291 			ret = ice_fdir_comp_rules(rule, input, true);
1292 		if (ret) {
1293 			if (rule->fltr_id == input->fltr_id &&
1294 			    rule->q_index != input->q_index)
1295 				ret = false;
1296 			else
1297 				break;
1298 		}
1299 	}
1300 
1301 	return ret;
1302 }
1303