xref: /dpdk/drivers/net/ice/base/ice_fdir.c (revision 2c7845a7)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2001-2019
3  */
4 
5 #include "ice_common.h"
6 #include "ice_fdir.h"
7 
8 /* These are training packet headers used to program flow director filters. */
9 static const u8 ice_fdir_tcpv4_pkt[] = {
10 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11 	0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00,
12 	0x00, 0x28, 0x00, 0x01, 0x00, 0x00, 0x40, 0x06,
13 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
14 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
15 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00,
16 	0x20, 0x00, 0x00, 0x00, 0x00, 0x00
17 };
18 
19 static const u8 ice_fdir_udpv4_pkt[] = {
20 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
21 	0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00,
22 	0x00, 0x1C, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11,
23 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
24 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
25 	0x00, 0x00,
26 };
27 
28 static const u8 ice_fdir_sctpv4_pkt[] = {
29 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
30 	0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00,
31 	0x00, 0x20, 0x00, 0x00, 0x40, 0x00, 0x40, 0x84,
32 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
33 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
34 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
35 };
36 
37 static const u8 ice_fdir_ipv4_pkt[] = {
38 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
39 	0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00,
40 	0x00, 0x14, 0x00, 0x00, 0x40, 0x00, 0x40, 0x10,
41 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
42 	0x00, 0x00
43 };
44 
45 static const u8 ice_fdir_udp4_gtpu4_pkt[] = {
46 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
47 	0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00,
48 	0x00, 0x4c, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11,
49 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
50 	0x00, 0x00, 0x08, 0x68, 0x08, 0x68, 0x00, 0x00,
51 	0x00, 0x00, 0x34, 0xff, 0x00, 0x28, 0x00, 0x00,
52 	0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x02, 0x00,
53 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x00,
54 	0x00, 0x1c, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11,
55 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
56 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
57 	0x00, 0x00,
58 };
59 
60 static const u8 ice_fdir_tcp4_gtpu4_pkt[] = {
61 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
62 	0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00,
63 	0x00, 0x58, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11,
64 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
65 	0x00, 0x00, 0x08, 0x68, 0x08, 0x68, 0x00, 0x00,
66 	0x00, 0x00, 0x34, 0xff, 0x00, 0x28, 0x00, 0x00,
67 	0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x02, 0x00,
68 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x00,
69 	0x00, 0x28, 0x00, 0x00, 0x40, 0x00, 0x40, 0x06,
70 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
71 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
72 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
73 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
74 };
75 
76 static const u8 ice_fdir_icmp4_gtpu4_pkt[] = {
77 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
78 	0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00,
79 	0x00, 0x4c, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11,
80 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
81 	0x00, 0x00, 0x08, 0x68, 0x08, 0x68, 0x00, 0x00,
82 	0x00, 0x00, 0x34, 0xff, 0x00, 0x28, 0x00, 0x00,
83 	0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x02, 0x00,
84 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x00,
85 	0x00, 0x1c, 0x00, 0x00, 0x40, 0x00, 0x40, 0x01,
86 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
87 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
88 	0x00, 0x00,
89 };
90 
91 static const u8 ice_fdir_ipv4_gtpu4_pkt[] = {
92 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
93 	0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00,
94 	0x00, 0x44, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11,
95 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
96 	0x00, 0x00, 0x08, 0x68, 0x08, 0x68, 0x00, 0x00,
97 	0x00, 0x00, 0x34, 0xff, 0x00, 0x28, 0x00, 0x00,
98 	0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x02, 0x00,
99 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x00,
100 	0x00, 0x14, 0x00, 0x00, 0x40, 0x00, 0x40, 0x00,
101 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
102 	0x00, 0x00,
103 };
104 
105 static const u8 ice_fdir_tcpv6_pkt[] = {
106 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
107 	0x00, 0x00, 0x00, 0x00, 0x86, 0xDD, 0x60, 0x00,
108 	0x00, 0x00, 0x00, 0x14, 0x06, 0x40, 0x00, 0x00,
109 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
110 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
111 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
112 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
113 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
114 	0x00, 0x00, 0x50, 0x00, 0x20, 0x00, 0x00, 0x00,
115 	0x00, 0x00,
116 };
117 
118 static const u8 ice_fdir_udpv6_pkt[] = {
119 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
120 	0x00, 0x00, 0x00, 0x00, 0x86, 0xDD, 0x60, 0x00,
121 	0x00, 0x00, 0x00, 0x08, 0x11, 0x40, 0x00, 0x00,
122 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
123 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
124 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
125 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
126 	0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
127 };
128 
129 static const u8 ice_fdir_sctpv6_pkt[] = {
130 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
131 	0x00, 0x00, 0x00, 0x00, 0x86, 0xDD, 0x60, 0x00,
132 	0x00, 0x00, 0x00, 0x0C, 0x84, 0x40, 0x00, 0x00,
133 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
134 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
135 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
136 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
137 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
138 	0x00, 0x00,
139 };
140 
141 static const u8 ice_fdir_ipv6_pkt[] = {
142 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
143 	0x00, 0x00, 0x00, 0x00, 0x86, 0xDD, 0x60, 0x00,
144 	0x00, 0x00, 0x00, 0x00, 0x3B, 0x40, 0x00, 0x00,
145 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
146 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
147 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
148 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
149 };
150 
151 static const u8 ice_fdir_tcp4_tun_pkt[] = {
152 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
153 	0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00,
154 	0x00, 0x5a, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11,
155 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
156 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
157 	0x00, 0x00, 0x04, 0x00, 0x00, 0x03, 0x00, 0x00,
158 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
159 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
160 	0x45, 0x00, 0x00, 0x28, 0x00, 0x00, 0x40, 0x00,
161 	0x40, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
162 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
163 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
164 	0x50, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00,
165 };
166 
167 static const u8 ice_fdir_udp4_tun_pkt[] = {
168 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
169 	0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00,
170 	0x00, 0x4e, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11,
171 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
172 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
173 	0x00, 0x00, 0x04, 0x00, 0x00, 0x03, 0x00, 0x00,
174 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
175 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
176 	0x45, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x40, 0x00,
177 	0x40, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
178 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
179 	0x00, 0x00, 0x00, 0x00,
180 };
181 
182 static const u8 ice_fdir_sctp4_tun_pkt[] = {
183 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
184 	0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00,
185 	0x00, 0x52, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11,
186 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
187 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
188 	0x00, 0x00, 0x04, 0x00, 0x00, 0x03, 0x00, 0x00,
189 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
190 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
191 	0x45, 0x00, 0x00, 0x20, 0x00, 0x01, 0x00, 0x00,
192 	0x40, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
193 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
194 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
195 };
196 
197 static const u8 ice_fdir_ip4_tun_pkt[] = {
198 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
199 	0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00,
200 	0x00, 0x46, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11,
201 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
202 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
203 	0x00, 0x00, 0x04, 0x00, 0x00, 0x03, 0x00, 0x00,
204 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
205 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
206 	0x45, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00,
207 	0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
208 	0x00, 0x00, 0x00, 0x00,
209 };
210 
211 static const u8 ice_fdir_tcp6_tun_pkt[] = {
212 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
213 	0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00,
214 	0x00, 0x6e, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11,
215 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
216 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
217 	0x00, 0x00, 0x04, 0x00, 0x00, 0x03, 0x00, 0x00,
218 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
219 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0xdd,
220 	0x60, 0x00, 0x00, 0x00, 0x00, 0x14, 0x06, 0x40,
221 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
222 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
223 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
224 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
225 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
226 	0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x20, 0x00,
227 	0x00, 0x00, 0x00, 0x00,
228 };
229 
230 static const u8 ice_fdir_udp6_tun_pkt[] = {
231 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
232 	0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00,
233 	0x00, 0x62, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11,
234 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
235 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
236 	0x00, 0x00, 0x04, 0x00, 0x00, 0x03, 0x00, 0x00,
237 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
238 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0xdd,
239 	0x60, 0x00, 0x00, 0x00, 0x00, 0x08, 0x11, 0x40,
240 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
241 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
242 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
243 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
244 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
245 };
246 
247 static const u8 ice_fdir_sctp6_tun_pkt[] = {
248 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
249 	0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00,
250 	0x00, 0x66, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11,
251 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
252 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
253 	0x00, 0x00, 0x04, 0x00, 0x00, 0x03, 0x00, 0x00,
254 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
255 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0xdd,
256 	0x60, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x84, 0x40,
257 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
258 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
259 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
260 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
261 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
262 	0x00, 0x00, 0x00, 0x00,
263 };
264 
265 static const u8 ice_fdir_ip6_tun_pkt[] = {
266 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
267 	0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00,
268 	0x00, 0x5a, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11,
269 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
270 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
271 	0x00, 0x00, 0x04, 0x00, 0x00, 0x03, 0x00, 0x00,
272 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
273 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0xdd,
274 	0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3b, 0x40,
275 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
276 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
277 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
278 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
279 };
280 
281 /* Flow Director no-op training packet table */
282 static const struct ice_fdir_base_pkt ice_fdir_pkt[] = {
283 	{
284 		ICE_FLTR_PTYPE_NONF_IPV4_TCP,
285 		sizeof(ice_fdir_tcpv4_pkt), ice_fdir_tcpv4_pkt,
286 		sizeof(ice_fdir_tcp4_tun_pkt), ice_fdir_tcp4_tun_pkt,
287 	},
288 	{
289 		ICE_FLTR_PTYPE_NONF_IPV4_UDP,
290 		sizeof(ice_fdir_udpv4_pkt), ice_fdir_udpv4_pkt,
291 		sizeof(ice_fdir_udp4_tun_pkt), ice_fdir_udp4_tun_pkt,
292 	},
293 	{
294 		ICE_FLTR_PTYPE_NONF_IPV4_SCTP,
295 		sizeof(ice_fdir_sctpv4_pkt), ice_fdir_sctpv4_pkt,
296 		sizeof(ice_fdir_sctp4_tun_pkt), ice_fdir_sctp4_tun_pkt,
297 	},
298 	{
299 		ICE_FLTR_PTYPE_NONF_IPV4_OTHER,
300 		sizeof(ice_fdir_ipv4_pkt), ice_fdir_ipv4_pkt,
301 		sizeof(ice_fdir_ip4_tun_pkt), ice_fdir_ip4_tun_pkt,
302 	},
303 	{
304 		ICE_FLTR_PTYPE_NONF_IPV4_GTPU_IPV4_UDP,
305 		sizeof(ice_fdir_udp4_gtpu4_pkt),
306 		ice_fdir_udp4_gtpu4_pkt,
307 		sizeof(ice_fdir_udp4_gtpu4_pkt),
308 		ice_fdir_udp4_gtpu4_pkt,
309 	},
310 	{
311 		ICE_FLTR_PTYPE_NONF_IPV4_GTPU_IPV4_TCP,
312 		sizeof(ice_fdir_tcp4_gtpu4_pkt),
313 		ice_fdir_tcp4_gtpu4_pkt,
314 		sizeof(ice_fdir_tcp4_gtpu4_pkt),
315 		ice_fdir_tcp4_gtpu4_pkt,
316 	},
317 	{
318 		ICE_FLTR_PTYPE_NONF_IPV4_GTPU_IPV4_ICMP,
319 		sizeof(ice_fdir_icmp4_gtpu4_pkt),
320 		ice_fdir_icmp4_gtpu4_pkt,
321 		sizeof(ice_fdir_icmp4_gtpu4_pkt),
322 		ice_fdir_icmp4_gtpu4_pkt,
323 	},
324 	{
325 		ICE_FLTR_PTYPE_NONF_IPV4_GTPU_IPV4_OTHER,
326 		sizeof(ice_fdir_ipv4_gtpu4_pkt),
327 		ice_fdir_ipv4_gtpu4_pkt,
328 		sizeof(ice_fdir_ipv4_gtpu4_pkt),
329 		ice_fdir_ipv4_gtpu4_pkt,
330 	},
331 	{
332 		ICE_FLTR_PTYPE_NONF_IPV6_TCP,
333 		sizeof(ice_fdir_tcpv6_pkt), ice_fdir_tcpv6_pkt,
334 		sizeof(ice_fdir_tcp6_tun_pkt), ice_fdir_tcp6_tun_pkt,
335 	},
336 	{
337 		ICE_FLTR_PTYPE_NONF_IPV6_UDP,
338 		sizeof(ice_fdir_udpv6_pkt), ice_fdir_udpv6_pkt,
339 		sizeof(ice_fdir_udp6_tun_pkt), ice_fdir_udp6_tun_pkt,
340 	},
341 	{
342 		ICE_FLTR_PTYPE_NONF_IPV6_SCTP,
343 		sizeof(ice_fdir_sctpv6_pkt), ice_fdir_sctpv6_pkt,
344 		sizeof(ice_fdir_sctp6_tun_pkt), ice_fdir_sctp6_tun_pkt,
345 	},
346 	{
347 		ICE_FLTR_PTYPE_NONF_IPV6_OTHER,
348 		sizeof(ice_fdir_ipv6_pkt), ice_fdir_ipv6_pkt,
349 		sizeof(ice_fdir_ip6_tun_pkt), ice_fdir_ip6_tun_pkt,
350 	},
351 };
352 
353 #define ICE_FDIR_NUM_PKT ARRAY_SIZE(ice_fdir_pkt)
354 
355 /* Flow Direcotr (FD) filter program descriptor Context */
356 static const struct ice_ctx_ele ice_fd_fltr_desc_ctx_info[] = {
357 					   /* Field		Width	LSB */
358 	ICE_CTX_STORE(ice_fd_fltr_desc_ctx, qindex,		11,	0),
359 	ICE_CTX_STORE(ice_fd_fltr_desc_ctx, comp_q,		1,	11),
360 	ICE_CTX_STORE(ice_fd_fltr_desc_ctx, comp_report,	2,	12),
361 	ICE_CTX_STORE(ice_fd_fltr_desc_ctx, fd_space,		2,	14),
362 	ICE_CTX_STORE(ice_fd_fltr_desc_ctx, cnt_index,		13,	16),
363 	ICE_CTX_STORE(ice_fd_fltr_desc_ctx, cnt_ena,		2,	29),
364 	ICE_CTX_STORE(ice_fd_fltr_desc_ctx, evict_ena,		1,	31),
365 	ICE_CTX_STORE(ice_fd_fltr_desc_ctx, toq,		3,	32),
366 	ICE_CTX_STORE(ice_fd_fltr_desc_ctx, toq_prio,		3,	35),
367 	ICE_CTX_STORE(ice_fd_fltr_desc_ctx, dpu_recipe,		2,	38),
368 	ICE_CTX_STORE(ice_fd_fltr_desc_ctx, drop,		1,	40),
369 	ICE_CTX_STORE(ice_fd_fltr_desc_ctx, flex_prio,		3,	41),
370 	ICE_CTX_STORE(ice_fd_fltr_desc_ctx, flex_mdid,		4,	44),
371 	ICE_CTX_STORE(ice_fd_fltr_desc_ctx, flex_val,		16,	48),
372 	ICE_CTX_STORE(ice_fd_fltr_desc_ctx, dtype,		4,	64),
373 	ICE_CTX_STORE(ice_fd_fltr_desc_ctx, pcmd,		1,	68),
374 	ICE_CTX_STORE(ice_fd_fltr_desc_ctx, desc_prof_prio,	3,	69),
375 	ICE_CTX_STORE(ice_fd_fltr_desc_ctx, desc_prof,		6,	72),
376 	ICE_CTX_STORE(ice_fd_fltr_desc_ctx, fd_vsi,		10,	78),
377 	ICE_CTX_STORE(ice_fd_fltr_desc_ctx, swap,		1,	88),
378 	ICE_CTX_STORE(ice_fd_fltr_desc_ctx, fdid_prio,		3,	89),
379 	ICE_CTX_STORE(ice_fd_fltr_desc_ctx, fdid_mdid,		4,	92),
380 	ICE_CTX_STORE(ice_fd_fltr_desc_ctx, fdid,		32,	96),
381 	{ 0 }
382 };
383 
384 /**
385  * ice_set_dflt_val_fd_desc
386  * @fd_fltr_ctx: pointer to fd filter descriptor
387  */
388 void
389 ice_set_dflt_val_fd_desc(struct ice_fd_fltr_desc_ctx *fd_fltr_ctx)
390 {
391 	fd_fltr_ctx->comp_q = ICE_FXD_FLTR_QW0_COMP_Q_ZERO;
392 	fd_fltr_ctx->comp_report = ICE_FXD_FLTR_QW0_COMP_REPORT_SW_FAIL;
393 	fd_fltr_ctx->fd_space = ICE_FXD_FLTR_QW0_FD_SPACE_GUAR_BEST;
394 	fd_fltr_ctx->cnt_ena = ICE_FXD_FLTR_QW0_STAT_ENA_PKTS;
395 	fd_fltr_ctx->evict_ena = ICE_FXD_FLTR_QW0_EVICT_ENA_TRUE;
396 	fd_fltr_ctx->toq = ICE_FXD_FLTR_QW0_TO_Q_EQUALS_QINDEX;
397 	fd_fltr_ctx->toq_prio = ICE_FXD_FLTR_QW0_TO_Q_PRIO1;
398 	fd_fltr_ctx->dpu_recipe = ICE_FXD_FLTR_QW0_DPU_RECIPE_DFLT;
399 	fd_fltr_ctx->drop = ICE_FXD_FLTR_QW0_DROP_NO;
400 	fd_fltr_ctx->flex_prio = ICE_FXD_FLTR_QW0_FLEX_PRI_NONE;
401 	fd_fltr_ctx->flex_mdid = ICE_FXD_FLTR_QW0_FLEX_MDID0;
402 	fd_fltr_ctx->flex_val = ICE_FXD_FLTR_QW0_FLEX_VAL0;
403 	fd_fltr_ctx->dtype = ICE_TX_DESC_DTYPE_FLTR_PROG;
404 	fd_fltr_ctx->desc_prof_prio = ICE_FXD_FLTR_QW1_PROF_PRIO_ZERO;
405 	fd_fltr_ctx->desc_prof = ICE_FXD_FLTR_QW1_PROF_ZERO;
406 	fd_fltr_ctx->swap = ICE_FXD_FLTR_QW1_SWAP_SET;
407 	fd_fltr_ctx->fdid_prio = ICE_FXD_FLTR_QW1_FDID_PRI_ONE;
408 	fd_fltr_ctx->fdid_mdid = ICE_FXD_FLTR_QW1_FDID_MDID_FD;
409 	fd_fltr_ctx->fdid = ICE_FXD_FLTR_QW1_FDID_ZERO;
410 }
411 
412 /**
413  * ice_fdir_get_prgm_desc - set a fdir descriptor from a fdir filter struct
414  * @hw: pointer to the hardware structure
415  * @input: filter
416  * @fdesc: filter descriptor
417  * @add: if add is true, this is an add operation, false implies delete
418  */
419 void
420 ice_fdir_get_prgm_desc(struct ice_hw *hw, struct ice_fdir_fltr *input,
421 		       struct ice_fltr_desc *fdesc, bool add)
422 {
423 	struct ice_fd_fltr_desc_ctx fdir_fltr_ctx = { 0 };
424 
425 	/* set default context info */
426 	ice_set_dflt_val_fd_desc(&fdir_fltr_ctx);
427 
428 	/* change sideband filtering values */
429 	fdir_fltr_ctx.fdid = input->fltr_id;
430 	if (input->dest_ctl == ICE_FLTR_PRGM_DESC_DEST_DROP_PKT) {
431 		fdir_fltr_ctx.drop = ICE_FXD_FLTR_QW0_DROP_YES;
432 		fdir_fltr_ctx.qindex = 0;
433 	} else {
434 		if (input->dest_ctl ==
435 		    ICE_FLTR_PRGM_DESC_DEST_DIRECT_PKT_QGROUP)
436 			fdir_fltr_ctx.toq = input->q_region;
437 		fdir_fltr_ctx.drop = ICE_FXD_FLTR_QW0_DROP_NO;
438 		fdir_fltr_ctx.qindex = input->q_index;
439 	}
440 	fdir_fltr_ctx.cnt_ena = input->cnt_ena;
441 	fdir_fltr_ctx.cnt_index = input->cnt_index;
442 	fdir_fltr_ctx.fd_vsi = ice_get_hw_vsi_num(hw, input->dest_vsi);
443 	fdir_fltr_ctx.evict_ena = ICE_FXD_FLTR_QW0_EVICT_ENA_FALSE;
444 	fdir_fltr_ctx.toq_prio = 3;
445 	fdir_fltr_ctx.pcmd = (add) ? ICE_FXD_FLTR_QW1_PCMD_ADD :
446 		ICE_FXD_FLTR_QW1_PCMD_REMOVE;
447 	fdir_fltr_ctx.swap = ICE_FXD_FLTR_QW1_SWAP_NOT_SET;
448 	fdir_fltr_ctx.comp_q = ICE_FXD_FLTR_QW0_COMP_Q_ZERO;
449 	fdir_fltr_ctx.comp_report = ICE_FXD_FLTR_QW0_COMP_REPORT_SW;
450 	fdir_fltr_ctx.fdid_prio = 3;
451 	fdir_fltr_ctx.desc_prof = 1;
452 	fdir_fltr_ctx.desc_prof_prio = 3;
453 	ice_set_fd_desc_val(&fdir_fltr_ctx, fdesc);
454 }
455 
456 /**
457  * ice_set_fd_desc_val
458  * @fd_fltr_ctx: pointer to fd filter descriptor context
459  * @fdir_desc: populated with fd filter descriptor values
460  */
461 void
462 ice_set_fd_desc_val(struct ice_fd_fltr_desc_ctx *fd_fltr_ctx,
463 		    struct ice_fltr_desc *fdir_desc)
464 {
465 	u64 ctx_buf[2] = { 0 };
466 
467 	ice_set_ctx((u8 *)fd_fltr_ctx, (u8 *)ctx_buf,
468 		    ice_fd_fltr_desc_ctx_info);
469 	fdir_desc->qidx_compq_space_stat = CPU_TO_LE64(ctx_buf[0]);
470 	fdir_desc->dtype_cmd_vsi_fdid = CPU_TO_LE64(ctx_buf[1]);
471 }
472 
473 /**
474  * ice_alloc_fd_res_cntr - obtain counter resource for FD type
475  * @hw: pointer to the hardware structure
476  * @cntr_id: returns counter index
477  */
478 enum ice_status ice_alloc_fd_res_cntr(struct ice_hw *hw, u16 *cntr_id)
479 {
480 	return ice_alloc_res_cntr(hw, ICE_AQC_RES_TYPE_FDIR_COUNTER_BLOCK,
481 				  ICE_AQC_RES_TYPE_FLAG_DEDICATED, 1, cntr_id);
482 }
483 
484 /**
485  * ice_free_fd_res_cntr - Free counter resource for FD type
486  * @hw: pointer to the hardware structure
487  * @cntr_id: counter index to be freed
488  */
489 enum ice_status ice_free_fd_res_cntr(struct ice_hw *hw, u16 cntr_id)
490 {
491 	return ice_free_res_cntr(hw, ICE_AQC_RES_TYPE_FDIR_COUNTER_BLOCK,
492 				 ICE_AQC_RES_TYPE_FLAG_DEDICATED, 1, cntr_id);
493 }
494 
495 /**
496  * ice_alloc_fd_guar_item - allocate resource for FD guaranteed entries
497  * @hw: pointer to the hardware structure
498  * @cntr_id: returns counter index
499  * @num_fltr: number of filter entries to be allocated
500  */
501 enum ice_status
502 ice_alloc_fd_guar_item(struct ice_hw *hw, u16 *cntr_id, u16 num_fltr)
503 {
504 	return ice_alloc_res_cntr(hw, ICE_AQC_RES_TYPE_FDIR_GUARANTEED_ENTRIES,
505 				  ICE_AQC_RES_TYPE_FLAG_DEDICATED, num_fltr,
506 				  cntr_id);
507 }
508 
509 /**
510  * ice_free_fd_guar_item - Free flow director guaranteed entries
511  * @hw: pointer to the hardware structure
512  * @cntr_id: counter index that needs to be freed
513  * @num_fltr: number of filters to be freed
514  */
515 enum ice_status
516 ice_free_fd_guar_item(struct ice_hw *hw, u16 cntr_id, u16 num_fltr)
517 {
518 	return ice_free_res_cntr(hw, ICE_AQC_RES_TYPE_FDIR_GUARANTEED_ENTRIES,
519 				 ICE_AQC_RES_TYPE_FLAG_DEDICATED, num_fltr,
520 				 cntr_id);
521 }
522 
523 /**
524  * ice_alloc_fd_shrd_item - allocate resource for flow director shared entries
525  * @hw: pointer to the hardware structure
526  * @cntr_id: returns counter index
527  * @num_fltr: number of filter entries to be allocated
528  */
529 enum ice_status
530 ice_alloc_fd_shrd_item(struct ice_hw *hw, u16 *cntr_id, u16 num_fltr)
531 {
532 	return ice_alloc_res_cntr(hw, ICE_AQC_RES_TYPE_FDIR_SHARED_ENTRIES,
533 				  ICE_AQC_RES_TYPE_FLAG_DEDICATED, num_fltr,
534 				  cntr_id);
535 }
536 
537 /**
538  * ice_free_fd_shrd_item - Free flow director shared entries
539  * @hw: pointer to the hardware structure
540  * @cntr_id: counter index that needs to be freed
541  * @num_fltr: number of filters to be freed
542  */
543 enum ice_status
544 ice_free_fd_shrd_item(struct ice_hw *hw, u16 cntr_id, u16 num_fltr)
545 {
546 	return ice_free_res_cntr(hw, ICE_AQC_RES_TYPE_FDIR_SHARED_ENTRIES,
547 				 ICE_AQC_RES_TYPE_FLAG_DEDICATED, num_fltr,
548 				 cntr_id);
549 }
550 
551 /**
552  * ice_get_fdir_cnt_all - get the number of Flow Director filters
553  * @hw: hardware data structure
554  *
555  * Returns the number of filters available on device
556  */
557 int ice_get_fdir_cnt_all(struct ice_hw *hw)
558 {
559 	return hw->func_caps.fd_fltr_guar +
560 	       hw->func_caps.fd_fltr_best_effort;
561 }
562 
563 /**
564  * ice_pkt_insert_ipv6_addr - insert a be32 IPv6 address into a memory buffer.
565  * @pkt: packet buffer
566  * @offset: offset into buffer
567  * @addr: IPv6 address to convert and insert into pkt at offset
568  */
569 static void ice_pkt_insert_ipv6_addr(u8 *pkt, int offset, __be32 *addr)
570 {
571 	int idx;
572 
573 	for (idx = 0; idx < ICE_IPV6_ADDR_LEN_AS_U32; idx++)
574 		ice_memcpy(pkt + offset + idx * sizeof(*addr), &addr[idx],
575 			   sizeof(*addr), ICE_NONDMA_TO_NONDMA);
576 }
577 
578 /**
579  * ice_pkt_insert_u6_qfi - insert a u6 value qfi into a memory buffer for gtpu
580  * @pkt: packet buffer
581  * @offset: offset into buffer
582  * @data: 8 bit value to convert and insert into pkt at offset
583  *
584  * This function is designed for inserting qfi (6 bits) for gtpu.
585  */
586 static void ice_pkt_insert_u6_qfi(u8 *pkt, int offset, u8 data)
587 {
588 	u8 ret;
589 
590 	ret = (data & 0x3F) + (*(pkt + offset) & 0xC0);
591 	ice_memcpy(pkt + offset, &ret, sizeof(ret), ICE_NONDMA_TO_NONDMA);
592 }
593 
594 /**
595  * ice_pkt_insert_u8 - insert a u8 value into a memory buffer.
596  * @pkt: packet buffer
597  * @offset: offset into buffer
598  * @data: 8 bit value to convert and insert into pkt at offset
599  */
600 static void ice_pkt_insert_u8(u8 *pkt, int offset, u8 data)
601 {
602 	ice_memcpy(pkt + offset, &data, sizeof(data), ICE_NONDMA_TO_NONDMA);
603 }
604 
605 /**
606  * ice_pkt_insert_u8_tc - insert a u8 value into a memory buffer for tc ipv6.
607  * @pkt: packet buffer
608  * @offset: offset into buffer
609  * @data: 8 bit value to convert and insert into pkt at offset
610  *
611  * This function is designed for inserting Traffic Class (tc) for IPv6,
612  * since that tc is not aligned in number of bytes. Here we split it out
613  * into two part and fill each byte with data copy from pkt, then insert
614  * the two bytes data one by one.
615  */
616 static void ice_pkt_insert_u8_tc(u8 *pkt, int offset, u8 data)
617 {
618 	u8 high, low;
619 
620 	high = (data >> 4) + (*(pkt + offset) & 0xF0);
621 	ice_memcpy(pkt + offset, &high, sizeof(high), ICE_NONDMA_TO_NONDMA);
622 
623 	low = (*(pkt + offset + 1) & 0x0F) + ((data & 0x0F) << 4);
624 	ice_memcpy(pkt + offset + 1, &low, sizeof(low), ICE_NONDMA_TO_NONDMA);
625 }
626 
627 /**
628  * ice_pkt_insert_u16 - insert a be16 value into a memory buffer.
629  * @pkt: packet buffer
630  * @offset: offset into buffer
631  * @data: 16 bit value to convert and insert into pkt at offset
632  */
633 static void ice_pkt_insert_u16(u8 *pkt, int offset, __be16 data)
634 {
635 	ice_memcpy(pkt + offset, &data, sizeof(data), ICE_NONDMA_TO_NONDMA);
636 }
637 
638 /**
639  * ice_pkt_insert_u32 - insert a be32 value into a memory buffer.
640  * @pkt: packet buffer
641  * @offset: offset into buffer
642  * @data: 32 bit value to convert and insert into pkt at offset
643  */
644 static void ice_pkt_insert_u32(u8 *pkt, int offset, __be32 data)
645 {
646 	ice_memcpy(pkt + offset, &data, sizeof(data), ICE_NONDMA_TO_NONDMA);
647 }
648 
649 /**
650  * ice_pkt_insert_mac_addr - insert a MAC addr into a memory buffer.
651  * @pkt: packet buffer
652  * @offset: offset into buffer
653  * @addr: MAC address to convert and insert into pkt at offset
654  */
655 static void ice_pkt_insert_mac_addr(u8 *pkt, u8 *addr)
656 {
657 	ice_memcpy(pkt, addr, ETH_ALEN, ICE_NONDMA_TO_NONDMA);
658 }
659 
660 /**
661  * ice_fdir_get_gen_prgm_pkt - generate a training packet
662  * @hw: pointer to the hardware structure
663  * @input: flow director filter data structure
664  * @pkt: pointer to return filter packet
665  * @frag: generate a fragment packet
666  * @tun: true implies generate a tunnel packet
667  */
668 enum ice_status
669 ice_fdir_get_gen_prgm_pkt(struct ice_hw *hw, struct ice_fdir_fltr *input,
670 			  u8 *pkt, bool frag, bool tun)
671 {
672 	enum ice_fltr_ptype flow;
673 	u16 tnl_port;
674 	u8 *loc;
675 	u16 idx;
676 
677 	if (input->flow_type == ICE_FLTR_PTYPE_NONF_IPV4_OTHER) {
678 		switch (input->ip.v4.proto) {
679 		case ICE_IP_PROTO_TCP:
680 			flow = ICE_FLTR_PTYPE_NONF_IPV4_TCP;
681 			break;
682 		case ICE_IP_PROTO_UDP:
683 			flow = ICE_FLTR_PTYPE_NONF_IPV4_UDP;
684 			break;
685 		case ICE_IP_PROTO_SCTP:
686 			flow = ICE_FLTR_PTYPE_NONF_IPV4_SCTP;
687 			break;
688 		default:
689 			flow = ICE_FLTR_PTYPE_NONF_IPV4_OTHER;
690 			break;
691 		}
692 	} else if (input->flow_type == ICE_FLTR_PTYPE_NONF_IPV6_OTHER) {
693 		switch (input->ip.v6.proto) {
694 		case ICE_IP_PROTO_TCP:
695 			flow = ICE_FLTR_PTYPE_NONF_IPV6_TCP;
696 			break;
697 		case ICE_IP_PROTO_UDP:
698 			flow = ICE_FLTR_PTYPE_NONF_IPV6_UDP;
699 			break;
700 		case ICE_IP_PROTO_SCTP:
701 			flow = ICE_FLTR_PTYPE_NONF_IPV6_SCTP;
702 			break;
703 		default:
704 			flow = ICE_FLTR_PTYPE_NONF_IPV6_OTHER;
705 			break;
706 		}
707 	} else {
708 		flow = input->flow_type;
709 	}
710 
711 	for (idx = 0; idx < ICE_FDIR_NUM_PKT; idx++)
712 		if (ice_fdir_pkt[idx].flow == flow)
713 			break;
714 	if (idx == ICE_FDIR_NUM_PKT)
715 		return ICE_ERR_PARAM;
716 	if (!tun) {
717 		ice_memcpy(pkt, ice_fdir_pkt[idx].pkt,
718 			   ice_fdir_pkt[idx].pkt_len, ICE_NONDMA_TO_NONDMA);
719 		loc = pkt;
720 	} else {
721 		if (!ice_get_open_tunnel_port(hw, TNL_ALL, &tnl_port))
722 			return ICE_ERR_DOES_NOT_EXIST;
723 		if (!ice_fdir_pkt[idx].tun_pkt)
724 			return ICE_ERR_PARAM;
725 		ice_memcpy(pkt, ice_fdir_pkt[idx].tun_pkt,
726 			   ice_fdir_pkt[idx].tun_pkt_len, ICE_NONDMA_TO_NONDMA);
727 		ice_pkt_insert_u16(pkt, ICE_IPV4_UDP_DST_PORT_OFFSET,
728 				   HTONS(tnl_port));
729 		loc = &pkt[ICE_FDIR_TUN_PKT_OFF];
730 	}
731 
732 	switch (flow) {
733 	case ICE_FLTR_PTYPE_NONF_IPV4_TCP:
734 		ice_pkt_insert_u32(loc, ICE_IPV4_DST_ADDR_OFFSET,
735 				   input->ip.v4.dst_ip);
736 		ice_pkt_insert_u16(loc, ICE_IPV4_TCP_DST_PORT_OFFSET,
737 				   input->ip.v4.dst_port);
738 		ice_pkt_insert_u32(loc, ICE_IPV4_SRC_ADDR_OFFSET,
739 				   input->ip.v4.src_ip);
740 		ice_pkt_insert_u16(loc, ICE_IPV4_TCP_SRC_PORT_OFFSET,
741 				   input->ip.v4.src_port);
742 		ice_pkt_insert_u8(loc, ICE_IPV4_TOS_OFFSET, input->ip.v4.tos);
743 		ice_pkt_insert_u8(loc, ICE_IPV4_TTL_OFFSET, input->ip.v4.ttl);
744 		ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac);
745 		if (frag)
746 			loc[20] = ICE_FDIR_IPV4_PKT_FLAG_DF;
747 		break;
748 	case ICE_FLTR_PTYPE_NONF_IPV4_UDP:
749 		ice_pkt_insert_u32(loc, ICE_IPV4_DST_ADDR_OFFSET,
750 				   input->ip.v4.dst_ip);
751 		ice_pkt_insert_u16(loc, ICE_IPV4_UDP_DST_PORT_OFFSET,
752 				   input->ip.v4.dst_port);
753 		ice_pkt_insert_u32(loc, ICE_IPV4_SRC_ADDR_OFFSET,
754 				   input->ip.v4.src_ip);
755 		ice_pkt_insert_u16(loc, ICE_IPV4_UDP_SRC_PORT_OFFSET,
756 				   input->ip.v4.src_port);
757 		ice_pkt_insert_u8(loc, ICE_IPV4_TOS_OFFSET, input->ip.v4.tos);
758 		ice_pkt_insert_u8(loc, ICE_IPV4_TTL_OFFSET, input->ip.v4.ttl);
759 		ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac);
760 		break;
761 	case ICE_FLTR_PTYPE_NONF_IPV4_SCTP:
762 		ice_pkt_insert_u32(loc, ICE_IPV4_DST_ADDR_OFFSET,
763 				   input->ip.v4.dst_ip);
764 		ice_pkt_insert_u16(loc, ICE_IPV4_SCTP_DST_PORT_OFFSET,
765 				   input->ip.v4.dst_port);
766 		ice_pkt_insert_u32(loc, ICE_IPV4_SRC_ADDR_OFFSET,
767 				   input->ip.v4.src_ip);
768 		ice_pkt_insert_u16(loc, ICE_IPV4_SCTP_SRC_PORT_OFFSET,
769 				   input->ip.v4.src_port);
770 		ice_pkt_insert_u8(loc, ICE_IPV4_TOS_OFFSET, input->ip.v4.tos);
771 		ice_pkt_insert_u8(loc, ICE_IPV4_TTL_OFFSET, input->ip.v4.ttl);
772 		ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac);
773 		break;
774 	case ICE_FLTR_PTYPE_NONF_IPV4_OTHER:
775 		ice_pkt_insert_u32(loc, ICE_IPV4_DST_ADDR_OFFSET,
776 				   input->ip.v4.dst_ip);
777 		ice_pkt_insert_u32(loc, ICE_IPV4_SRC_ADDR_OFFSET,
778 				   input->ip.v4.src_ip);
779 		ice_pkt_insert_u8(loc, ICE_IPV4_TOS_OFFSET, input->ip.v4.tos);
780 		ice_pkt_insert_u8(loc, ICE_IPV4_TTL_OFFSET, input->ip.v4.ttl);
781 		ice_pkt_insert_u8(loc, ICE_IPV4_PROTO_OFFSET,
782 				  input->ip.v4.proto);
783 		ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac);
784 		break;
785 	case ICE_FLTR_PTYPE_NONF_IPV4_GTPU_IPV4_UDP:
786 	case ICE_FLTR_PTYPE_NONF_IPV4_GTPU_IPV4_TCP:
787 	case ICE_FLTR_PTYPE_NONF_IPV4_GTPU_IPV4_ICMP:
788 	case ICE_FLTR_PTYPE_NONF_IPV4_GTPU_IPV4_OTHER:
789 		ice_pkt_insert_u6_qfi(loc, ICE_IPV4_GTPU_QFI_OFFSET,
790 				      input->gtpu_data.qfi);
791 		break;
792 	case ICE_FLTR_PTYPE_NONF_IPV6_TCP:
793 		ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_DST_ADDR_OFFSET,
794 					 input->ip.v6.dst_ip);
795 		ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_SRC_ADDR_OFFSET,
796 					 input->ip.v6.src_ip);
797 		ice_pkt_insert_u16(loc, ICE_IPV6_TCP_DST_PORT_OFFSET,
798 				   input->ip.v6.dst_port);
799 		ice_pkt_insert_u16(loc, ICE_IPV6_TCP_SRC_PORT_OFFSET,
800 				   input->ip.v6.src_port);
801 		ice_pkt_insert_u8_tc(loc, ICE_IPV6_TC_OFFSET, input->ip.v6.tc);
802 		ice_pkt_insert_u8(loc, ICE_IPV6_HLIM_OFFSET, input->ip.v6.hlim);
803 		ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac);
804 		break;
805 	case ICE_FLTR_PTYPE_NONF_IPV6_UDP:
806 		ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_DST_ADDR_OFFSET,
807 					 input->ip.v6.dst_ip);
808 		ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_SRC_ADDR_OFFSET,
809 					 input->ip.v6.src_ip);
810 		ice_pkt_insert_u16(loc, ICE_IPV6_UDP_DST_PORT_OFFSET,
811 				   input->ip.v6.dst_port);
812 		ice_pkt_insert_u16(loc, ICE_IPV6_UDP_SRC_PORT_OFFSET,
813 				   input->ip.v6.src_port);
814 		ice_pkt_insert_u8_tc(loc, ICE_IPV6_TC_OFFSET, input->ip.v6.tc);
815 		ice_pkt_insert_u8(loc, ICE_IPV6_HLIM_OFFSET, input->ip.v6.hlim);
816 		ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac);
817 		break;
818 	case ICE_FLTR_PTYPE_NONF_IPV6_SCTP:
819 		ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_DST_ADDR_OFFSET,
820 					 input->ip.v6.dst_ip);
821 		ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_SRC_ADDR_OFFSET,
822 					 input->ip.v6.src_ip);
823 		ice_pkt_insert_u16(loc, ICE_IPV6_SCTP_DST_PORT_OFFSET,
824 				   input->ip.v6.dst_port);
825 		ice_pkt_insert_u16(loc, ICE_IPV6_SCTP_SRC_PORT_OFFSET,
826 				   input->ip.v6.src_port);
827 		ice_pkt_insert_u8_tc(loc, ICE_IPV6_TC_OFFSET, input->ip.v6.tc);
828 		ice_pkt_insert_u8(loc, ICE_IPV6_HLIM_OFFSET, input->ip.v6.hlim);
829 		ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac);
830 		break;
831 	case ICE_FLTR_PTYPE_NONF_IPV6_OTHER:
832 		ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_DST_ADDR_OFFSET,
833 					 input->ip.v6.dst_ip);
834 		ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_SRC_ADDR_OFFSET,
835 					 input->ip.v6.src_ip);
836 		ice_pkt_insert_u8_tc(loc, ICE_IPV6_TC_OFFSET, input->ip.v6.tc);
837 		ice_pkt_insert_u8(loc, ICE_IPV6_HLIM_OFFSET, input->ip.v6.hlim);
838 		ice_pkt_insert_u8(loc, ICE_IPV6_PROTO_OFFSET,
839 				  input->ip.v6.proto);
840 		ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac);
841 		break;
842 	default:
843 		return ICE_ERR_PARAM;
844 	}
845 
846 	if (input->flex_fltr)
847 		ice_pkt_insert_u16(loc, input->flex_offset, input->flex_word);
848 
849 	return ICE_SUCCESS;
850 }
851 
852 /**
853  * ice_fdir_get_prgm_pkt - generate a training packet
854  * @input: flow director filter data structure
855  * @pkt: pointer to return filter packet
856  * @frag: generate a fragment packet
857  */
858 enum ice_status
859 ice_fdir_get_prgm_pkt(struct ice_fdir_fltr *input, u8 *pkt, bool frag)
860 {
861 	return ice_fdir_get_gen_prgm_pkt(NULL, input, pkt, frag, false);
862 }
863 
864 /**
865  * ice_fdir_has_frag - does flow type have 2 ptypes
866  * @flow: flow ptype
867  *
868  * returns true is there is a fragment packet for this ptype
869  */
870 bool ice_fdir_has_frag(enum ice_fltr_ptype flow)
871 {
872 	if (flow == ICE_FLTR_PTYPE_NONF_IPV4_OTHER)
873 		return true;
874 	else
875 		return false;
876 }
877 
878 /**
879  * ice_fdir_find_by_idx - find filter with idx
880  * @hw: pointer to hardware structure
881  * @fltr_idx: index to find.
882  *
883  * Returns pointer to filter if found or null
884  */
885 struct ice_fdir_fltr *
886 ice_fdir_find_fltr_by_idx(struct ice_hw *hw, u32 fltr_idx)
887 {
888 	struct ice_fdir_fltr *rule = NULL;
889 
890 	LIST_FOR_EACH_ENTRY(rule, &hw->fdir_list_head, ice_fdir_fltr,
891 			    fltr_node) {
892 		/* rule ID found in the list */
893 		if (fltr_idx == rule->fltr_id)
894 			return rule;
895 		if (fltr_idx < rule->fltr_id)
896 			break;
897 	}
898 	return NULL;
899 }
900 
901 /**
902  * ice_fdir_list_add_fltr - add a new node to the flow director filter list
903  * @hw: hardware structure
904  * @fltr: filter node to add to structure
905  */
906 void ice_fdir_list_add_fltr(struct ice_hw *hw, struct ice_fdir_fltr *fltr)
907 {
908 	struct ice_fdir_fltr *rule, *parent = NULL;
909 
910 	LIST_FOR_EACH_ENTRY(rule, &hw->fdir_list_head, ice_fdir_fltr,
911 			    fltr_node) {
912 		/* rule ID found or pass its spot in the list */
913 		if (rule->fltr_id >= fltr->fltr_id)
914 			break;
915 		parent = rule;
916 	}
917 
918 	if (parent)
919 		LIST_ADD_AFTER(&fltr->fltr_node, &parent->fltr_node);
920 	else
921 		LIST_ADD(&fltr->fltr_node, &hw->fdir_list_head);
922 }
923 
924 /**
925  * ice_fdir_update_cntrs - increment / decrement filter counter
926  * @hw: pointer to hardware structure
927  * @flow: filter flow type
928  * @add: true implies filters added
929  */
930 void
931 ice_fdir_update_cntrs(struct ice_hw *hw, enum ice_fltr_ptype flow, bool add)
932 {
933 	int incr;
934 
935 	incr = (add) ? 1 : -1;
936 	hw->fdir_active_fltr += incr;
937 	if (flow == ICE_FLTR_PTYPE_NONF_NONE || flow >= ICE_FLTR_PTYPE_MAX)
938 		ice_debug(hw, ICE_DBG_SW, "Unknown filter type %d\n", flow);
939 	else
940 		hw->fdir_fltr_cnt[flow] += incr;
941 }
942 
943 /**
944  * ice_cmp_ipv6_addr - compare 2 IP v6 addresses
945  * @a: IP v6 address
946  * @b: IP v6 address
947  *
948  * Returns 0 on equal, returns non-0 if different
949  */
950 static int ice_cmp_ipv6_addr(__be32 *a, __be32 *b)
951 {
952 	return memcmp(a, b, 4 * sizeof(__be32));
953 }
954 
955 /**
956  * ice_fdir_comp_ipv6_rules - compare 2 filters
957  * @a: a Flow Director filter data structure
958  * @b: a Flow Director filter data structure
959  * @v6: bool true if v6 filter
960  *
961  * Returns true if the filters match
962  */
963 static bool
964 ice_fdir_comp_rules(struct ice_fdir_fltr *a,  struct ice_fdir_fltr *b, bool v6)
965 {
966 	enum ice_fltr_ptype flow_type = a->flow_type;
967 
968 	/* The calling function already checks that the two filters have the
969 	 * same flow_type.
970 	 */
971 	if (!v6) {
972 		if (flow_type == ICE_FLTR_PTYPE_NONF_IPV4_TCP ||
973 		    flow_type == ICE_FLTR_PTYPE_NONF_IPV4_UDP ||
974 		    flow_type == ICE_FLTR_PTYPE_NONF_IPV4_SCTP) {
975 			if (a->ip.v4.dst_ip == b->ip.v4.dst_ip &&
976 			    a->ip.v4.src_ip == b->ip.v4.src_ip &&
977 			    a->ip.v4.dst_port == b->ip.v4.dst_port &&
978 			    a->ip.v4.src_port == b->ip.v4.src_port)
979 				return true;
980 		} else if (flow_type == ICE_FLTR_PTYPE_NONF_IPV4_OTHER) {
981 			if (a->ip.v4.dst_ip == b->ip.v4.dst_ip &&
982 			    a->ip.v4.src_ip == b->ip.v4.src_ip &&
983 			    a->ip.v4.l4_header == b->ip.v4.l4_header &&
984 			    a->ip.v4.proto == b->ip.v4.proto &&
985 			    a->ip.v4.ip_ver == b->ip.v4.ip_ver &&
986 			    a->ip.v4.tos == b->ip.v4.tos)
987 				return true;
988 		}
989 	} else {
990 		if (flow_type == ICE_FLTR_PTYPE_NONF_IPV6_UDP ||
991 		    flow_type == ICE_FLTR_PTYPE_NONF_IPV6_TCP ||
992 		    flow_type == ICE_FLTR_PTYPE_NONF_IPV6_SCTP) {
993 			if (a->ip.v6.dst_port == b->ip.v6.dst_port &&
994 			    a->ip.v6.src_port == b->ip.v6.src_port &&
995 			    !ice_cmp_ipv6_addr(a->ip.v6.dst_ip,
996 					       b->ip.v6.dst_ip) &&
997 			    !ice_cmp_ipv6_addr(a->ip.v6.src_ip,
998 					       b->ip.v6.src_ip))
999 				return true;
1000 		} else if (flow_type == ICE_FLTR_PTYPE_NONF_IPV6_OTHER) {
1001 			if (a->ip.v6.dst_port == b->ip.v6.dst_port &&
1002 			    a->ip.v6.src_port == b->ip.v6.src_port)
1003 				return true;
1004 		}
1005 	}
1006 
1007 	return false;
1008 }
1009 
1010 /**
1011  * ice_fdir_is_dup_fltr - test if filter is already in list for PF
1012  * @hw: hardware data structure
1013  * @input: Flow Director filter data structure
1014  *
1015  * Returns true if the filter is found in the list
1016  */
1017 bool ice_fdir_is_dup_fltr(struct ice_hw *hw, struct ice_fdir_fltr *input)
1018 {
1019 	enum ice_fltr_ptype flow_type;
1020 	struct ice_fdir_fltr *rule;
1021 	bool ret = false;
1022 
1023 	rule = NULL;
1024 
1025 	LIST_FOR_EACH_ENTRY(rule, &hw->fdir_list_head, ice_fdir_fltr,
1026 			    fltr_node) {
1027 		if (rule->flow_type == input->flow_type) {
1028 			flow_type = input->flow_type;
1029 			if (flow_type == ICE_FLTR_PTYPE_NONF_IPV4_TCP ||
1030 			    flow_type == ICE_FLTR_PTYPE_NONF_IPV4_UDP ||
1031 			    flow_type == ICE_FLTR_PTYPE_NONF_IPV4_SCTP ||
1032 			    flow_type == ICE_FLTR_PTYPE_NONF_IPV4_OTHER)
1033 				ret = ice_fdir_comp_rules(rule, input, false);
1034 			else
1035 				ret = ice_fdir_comp_rules(rule, input, true);
1036 			if (ret) {
1037 				if (rule->fltr_id == input->fltr_id &&
1038 				    rule->q_index != input->q_index)
1039 					ret = false;
1040 				else
1041 					break;
1042 			}
1043 		}
1044 	}
1045 
1046 	return ret;
1047 }
1048 
1049 /**
1050  * ice_clear_vsi_fd_table - admin command to clear FD table for a VSI
1051  * @hw: hardware data structure
1052  * @vsi_num: vsi_num (HW VSI num)
1053  *
1054  * Clears FD table entries by issuing admin command (direct, 0x0B06)
1055  * Must to pass valid vsi_num as returned by "AddVSI".
1056  */
1057 enum ice_status ice_clear_vsi_fd_table(struct ice_hw *hw, u16 vsi_num)
1058 {
1059 	struct ice_aqc_clear_fd_table *cmd;
1060 	struct ice_aq_desc desc;
1061 
1062 	cmd = &desc.params.clear_fd_table;
1063 	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_clear_fd_table);
1064 	cmd->clear_type = CL_FD_VM_VF_TYPE_VSI_IDX;
1065 
1066 	cmd->vsi_index = CPU_TO_LE16(vsi_num);
1067 	return ice_aq_send_cmd(hw, &desc, NULL, 0, NULL);
1068 }
1069 
1070 /**
1071  * ice_clear_pf_fd_table - admin command to clear FD table for PF
1072  * @hw: hardware data structure
1073  *
1074  * Clears FD table entries for a PF by issuing admin command (direct, 0x0B06)
1075  */
1076 enum ice_status ice_clear_pf_fd_table(struct ice_hw *hw)
1077 {
1078 	struct ice_aqc_clear_fd_table *cmd;
1079 	struct ice_aq_desc desc;
1080 
1081 	cmd = &desc.params.clear_fd_table;
1082 	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_clear_fd_table);
1083 	cmd->clear_type = CL_FD_VM_VF_TYPE_PF_IDX;
1084 	/* vsi_index must be 0 to clear FD table for a PF */
1085 	cmd->vsi_index = CPU_TO_LE16(0);
1086 
1087 	return ice_aq_send_cmd(hw, &desc, NULL, 0, NULL);
1088 }
1089