1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2001-2020 Intel Corporation
5 #include "ice_common.h"
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
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,
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,
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,
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,
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,
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,
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,
105 static const u8 ice_fdir_non_ip_l2_pkt[] = {
106 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
107 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
108 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
111 static const u8 ice_fdir_tcpv6_pkt[] = {
112 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
113 0x00, 0x00, 0x00, 0x00, 0x86, 0xDD, 0x60, 0x00,
114 0x00, 0x00, 0x00, 0x14, 0x06, 0x40, 0x00, 0x00,
115 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 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, 0x50, 0x00, 0x20, 0x00, 0x00, 0x00,
124 static const u8 ice_fdir_udpv6_pkt[] = {
125 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
126 0x00, 0x00, 0x00, 0x00, 0x86, 0xDD, 0x60, 0x00,
127 0x00, 0x00, 0x00, 0x08, 0x11, 0x40, 0x00, 0x00,
128 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
129 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
130 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
131 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
132 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
135 static const u8 ice_fdir_sctpv6_pkt[] = {
136 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
137 0x00, 0x00, 0x00, 0x00, 0x86, 0xDD, 0x60, 0x00,
138 0x00, 0x00, 0x00, 0x0C, 0x84, 0x40, 0x00, 0x00,
139 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
140 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
141 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
142 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
143 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
147 static const u8 ice_fdir_ipv6_pkt[] = {
148 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
149 0x00, 0x00, 0x00, 0x00, 0x86, 0xDD, 0x60, 0x00,
150 0x00, 0x00, 0x00, 0x00, 0x3B, 0x40, 0x00, 0x00,
151 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
152 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
153 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
154 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
157 static const u8 ice_fdir_tcp4_tun_pkt[] = {
158 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
159 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00,
160 0x00, 0x5a, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11,
161 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
162 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
163 0x00, 0x00, 0x04, 0x00, 0x00, 0x03, 0x00, 0x00,
164 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
165 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
166 0x45, 0x00, 0x00, 0x28, 0x00, 0x00, 0x40, 0x00,
167 0x40, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
168 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
169 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
170 0x50, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00,
173 static const u8 ice_fdir_udp4_tun_pkt[] = {
174 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
175 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00,
176 0x00, 0x4e, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11,
177 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
178 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
179 0x00, 0x00, 0x04, 0x00, 0x00, 0x03, 0x00, 0x00,
180 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
181 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
182 0x45, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x40, 0x00,
183 0x40, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
184 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
185 0x00, 0x00, 0x00, 0x00,
188 static const u8 ice_fdir_sctp4_tun_pkt[] = {
189 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
190 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00,
191 0x00, 0x52, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11,
192 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
193 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
194 0x00, 0x00, 0x04, 0x00, 0x00, 0x03, 0x00, 0x00,
195 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
196 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
197 0x45, 0x00, 0x00, 0x20, 0x00, 0x01, 0x00, 0x00,
198 0x40, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
199 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
200 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
203 static const u8 ice_fdir_ip4_tun_pkt[] = {
204 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
205 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00,
206 0x00, 0x46, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11,
207 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
208 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
209 0x00, 0x00, 0x04, 0x00, 0x00, 0x03, 0x00, 0x00,
210 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
211 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
212 0x45, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00,
213 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
214 0x00, 0x00, 0x00, 0x00,
217 static const u8 ice_fdir_tcp6_tun_pkt[] = {
218 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
219 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00,
220 0x00, 0x6e, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11,
221 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
222 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
223 0x00, 0x00, 0x04, 0x00, 0x00, 0x03, 0x00, 0x00,
224 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
225 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0xdd,
226 0x60, 0x00, 0x00, 0x00, 0x00, 0x14, 0x06, 0x40,
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, 0x00, 0x00,
230 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
231 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
232 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x20, 0x00,
233 0x00, 0x00, 0x00, 0x00,
236 static const u8 ice_fdir_udp6_tun_pkt[] = {
237 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
238 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00,
239 0x00, 0x62, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11,
240 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
241 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
242 0x00, 0x00, 0x04, 0x00, 0x00, 0x03, 0x00, 0x00,
243 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
244 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0xdd,
245 0x60, 0x00, 0x00, 0x00, 0x00, 0x08, 0x11, 0x40,
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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
253 static const u8 ice_fdir_sctp6_tun_pkt[] = {
254 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
255 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00,
256 0x00, 0x66, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11,
257 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
258 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
259 0x00, 0x00, 0x04, 0x00, 0x00, 0x03, 0x00, 0x00,
260 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
261 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0xdd,
262 0x60, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x84, 0x40,
263 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
264 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
265 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
266 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
267 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
268 0x00, 0x00, 0x00, 0x00,
271 static const u8 ice_fdir_ip6_tun_pkt[] = {
272 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
273 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00,
274 0x00, 0x5a, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11,
275 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
276 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
277 0x00, 0x00, 0x04, 0x00, 0x00, 0x03, 0x00, 0x00,
278 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
279 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0xdd,
280 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3b, 0x40,
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, 0x00, 0x00,
287 /* Flow Director no-op training packet table */
288 static const struct ice_fdir_base_pkt ice_fdir_pkt[] = {
290 ICE_FLTR_PTYPE_NONF_IPV4_TCP,
291 sizeof(ice_fdir_tcpv4_pkt), ice_fdir_tcpv4_pkt,
292 sizeof(ice_fdir_tcp4_tun_pkt), ice_fdir_tcp4_tun_pkt,
295 ICE_FLTR_PTYPE_NONF_IPV4_UDP,
296 sizeof(ice_fdir_udpv4_pkt), ice_fdir_udpv4_pkt,
297 sizeof(ice_fdir_udp4_tun_pkt), ice_fdir_udp4_tun_pkt,
300 ICE_FLTR_PTYPE_NONF_IPV4_SCTP,
301 sizeof(ice_fdir_sctpv4_pkt), ice_fdir_sctpv4_pkt,
302 sizeof(ice_fdir_sctp4_tun_pkt), ice_fdir_sctp4_tun_pkt,
305 ICE_FLTR_PTYPE_NONF_IPV4_OTHER,
306 sizeof(ice_fdir_ipv4_pkt), ice_fdir_ipv4_pkt,
307 sizeof(ice_fdir_ip4_tun_pkt), ice_fdir_ip4_tun_pkt,
310 ICE_FLTR_PTYPE_NONF_IPV4_GTPU_IPV4_UDP,
311 sizeof(ice_fdir_udp4_gtpu4_pkt),
312 ice_fdir_udp4_gtpu4_pkt,
313 sizeof(ice_fdir_udp4_gtpu4_pkt),
314 ice_fdir_udp4_gtpu4_pkt,
317 ICE_FLTR_PTYPE_NONF_IPV4_GTPU_IPV4_TCP,
318 sizeof(ice_fdir_tcp4_gtpu4_pkt),
319 ice_fdir_tcp4_gtpu4_pkt,
320 sizeof(ice_fdir_tcp4_gtpu4_pkt),
321 ice_fdir_tcp4_gtpu4_pkt,
324 ICE_FLTR_PTYPE_NONF_IPV4_GTPU_IPV4_ICMP,
325 sizeof(ice_fdir_icmp4_gtpu4_pkt),
326 ice_fdir_icmp4_gtpu4_pkt,
327 sizeof(ice_fdir_icmp4_gtpu4_pkt),
328 ice_fdir_icmp4_gtpu4_pkt,
331 ICE_FLTR_PTYPE_NONF_IPV4_GTPU_IPV4_OTHER,
332 sizeof(ice_fdir_ipv4_gtpu4_pkt),
333 ice_fdir_ipv4_gtpu4_pkt,
334 sizeof(ice_fdir_ipv4_gtpu4_pkt),
335 ice_fdir_ipv4_gtpu4_pkt,
338 ICE_FLTR_PTYPE_NON_IP_L2,
339 sizeof(ice_fdir_non_ip_l2_pkt), ice_fdir_non_ip_l2_pkt,
340 sizeof(ice_fdir_non_ip_l2_pkt), ice_fdir_non_ip_l2_pkt,
343 ICE_FLTR_PTYPE_NONF_IPV6_TCP,
344 sizeof(ice_fdir_tcpv6_pkt), ice_fdir_tcpv6_pkt,
345 sizeof(ice_fdir_tcp6_tun_pkt), ice_fdir_tcp6_tun_pkt,
348 ICE_FLTR_PTYPE_NONF_IPV6_UDP,
349 sizeof(ice_fdir_udpv6_pkt), ice_fdir_udpv6_pkt,
350 sizeof(ice_fdir_udp6_tun_pkt), ice_fdir_udp6_tun_pkt,
353 ICE_FLTR_PTYPE_NONF_IPV6_SCTP,
354 sizeof(ice_fdir_sctpv6_pkt), ice_fdir_sctpv6_pkt,
355 sizeof(ice_fdir_sctp6_tun_pkt), ice_fdir_sctp6_tun_pkt,
358 ICE_FLTR_PTYPE_NONF_IPV6_OTHER,
359 sizeof(ice_fdir_ipv6_pkt), ice_fdir_ipv6_pkt,
360 sizeof(ice_fdir_ip6_tun_pkt), ice_fdir_ip6_tun_pkt,
364 #define ICE_FDIR_NUM_PKT ARRAY_SIZE(ice_fdir_pkt)
367 * ice_set_dflt_val_fd_desc
368 * @fd_fltr_ctx: pointer to fd filter descriptor
371 ice_set_dflt_val_fd_desc(struct ice_fd_fltr_desc_ctx *fd_fltr_ctx)
373 fd_fltr_ctx->comp_q = ICE_FXD_FLTR_QW0_COMP_Q_ZERO;
374 fd_fltr_ctx->comp_report = ICE_FXD_FLTR_QW0_COMP_REPORT_SW_FAIL;
375 fd_fltr_ctx->fd_space = ICE_FXD_FLTR_QW0_FD_SPACE_GUAR_BEST;
376 fd_fltr_ctx->cnt_ena = ICE_FXD_FLTR_QW0_STAT_ENA_PKTS;
377 fd_fltr_ctx->evict_ena = ICE_FXD_FLTR_QW0_EVICT_ENA_TRUE;
378 fd_fltr_ctx->toq = ICE_FXD_FLTR_QW0_TO_Q_EQUALS_QINDEX;
379 fd_fltr_ctx->toq_prio = ICE_FXD_FLTR_QW0_TO_Q_PRIO1;
380 fd_fltr_ctx->dpu_recipe = ICE_FXD_FLTR_QW0_DPU_RECIPE_DFLT;
381 fd_fltr_ctx->drop = ICE_FXD_FLTR_QW0_DROP_NO;
382 fd_fltr_ctx->flex_prio = ICE_FXD_FLTR_QW0_FLEX_PRI_NONE;
383 fd_fltr_ctx->flex_mdid = ICE_FXD_FLTR_QW0_FLEX_MDID0;
384 fd_fltr_ctx->flex_val = ICE_FXD_FLTR_QW0_FLEX_VAL0;
385 fd_fltr_ctx->dtype = ICE_TX_DESC_DTYPE_FLTR_PROG;
386 fd_fltr_ctx->desc_prof_prio = ICE_FXD_FLTR_QW1_PROF_PRIO_ZERO;
387 fd_fltr_ctx->desc_prof = ICE_FXD_FLTR_QW1_PROF_ZERO;
388 fd_fltr_ctx->swap = ICE_FXD_FLTR_QW1_SWAP_SET;
389 fd_fltr_ctx->fdid_prio = ICE_FXD_FLTR_QW1_FDID_PRI_ONE;
390 fd_fltr_ctx->fdid_mdid = ICE_FXD_FLTR_QW1_FDID_MDID_FD;
391 fd_fltr_ctx->fdid = ICE_FXD_FLTR_QW1_FDID_ZERO;
395 * ice_set_fd_desc_val
396 * @ctx: pointer to fd filter descriptor context
397 * @fdir_desc: populated with fd filter descriptor values
400 ice_set_fd_desc_val(struct ice_fd_fltr_desc_ctx *ctx,
401 struct ice_fltr_desc *fdir_desc)
405 /* prep QW0 of FD filter programming desc */
406 qword = ((u64)ctx->qindex << ICE_FXD_FLTR_QW0_QINDEX_S) &
407 ICE_FXD_FLTR_QW0_QINDEX_M;
408 qword |= ((u64)ctx->comp_q << ICE_FXD_FLTR_QW0_COMP_Q_S) &
409 ICE_FXD_FLTR_QW0_COMP_Q_M;
410 qword |= ((u64)ctx->comp_report << ICE_FXD_FLTR_QW0_COMP_REPORT_S) &
411 ICE_FXD_FLTR_QW0_COMP_REPORT_M;
412 qword |= ((u64)ctx->fd_space << ICE_FXD_FLTR_QW0_FD_SPACE_S) &
413 ICE_FXD_FLTR_QW0_FD_SPACE_M;
414 qword |= ((u64)ctx->cnt_index << ICE_FXD_FLTR_QW0_STAT_CNT_S) &
415 ICE_FXD_FLTR_QW0_STAT_CNT_M;
416 qword |= ((u64)ctx->cnt_ena << ICE_FXD_FLTR_QW0_STAT_ENA_S) &
417 ICE_FXD_FLTR_QW0_STAT_ENA_M;
418 qword |= ((u64)ctx->evict_ena << ICE_FXD_FLTR_QW0_EVICT_ENA_S) &
419 ICE_FXD_FLTR_QW0_EVICT_ENA_M;
420 qword |= ((u64)ctx->toq << ICE_FXD_FLTR_QW0_TO_Q_S) &
421 ICE_FXD_FLTR_QW0_TO_Q_M;
422 qword |= ((u64)ctx->toq_prio << ICE_FXD_FLTR_QW0_TO_Q_PRI_S) &
423 ICE_FXD_FLTR_QW0_TO_Q_PRI_M;
424 qword |= ((u64)ctx->dpu_recipe << ICE_FXD_FLTR_QW0_DPU_RECIPE_S) &
425 ICE_FXD_FLTR_QW0_DPU_RECIPE_M;
426 qword |= ((u64)ctx->drop << ICE_FXD_FLTR_QW0_DROP_S) &
427 ICE_FXD_FLTR_QW0_DROP_M;
428 qword |= ((u64)ctx->flex_prio << ICE_FXD_FLTR_QW0_FLEX_PRI_S) &
429 ICE_FXD_FLTR_QW0_FLEX_PRI_M;
430 qword |= ((u64)ctx->flex_mdid << ICE_FXD_FLTR_QW0_FLEX_MDID_S) &
431 ICE_FXD_FLTR_QW0_FLEX_MDID_M;
432 qword |= ((u64)ctx->flex_val << ICE_FXD_FLTR_QW0_FLEX_VAL_S) &
433 ICE_FXD_FLTR_QW0_FLEX_VAL_M;
434 fdir_desc->qidx_compq_space_stat = CPU_TO_LE64(qword);
436 /* prep QW1 of FD filter programming desc */
437 qword = ((u64)ctx->dtype << ICE_FXD_FLTR_QW1_DTYPE_S) &
438 ICE_FXD_FLTR_QW1_DTYPE_M;
439 qword |= ((u64)ctx->pcmd << ICE_FXD_FLTR_QW1_PCMD_S) &
440 ICE_FXD_FLTR_QW1_PCMD_M;
441 qword |= ((u64)ctx->desc_prof_prio << ICE_FXD_FLTR_QW1_PROF_PRI_S) &
442 ICE_FXD_FLTR_QW1_PROF_PRI_M;
443 qword |= ((u64)ctx->desc_prof << ICE_FXD_FLTR_QW1_PROF_S) &
444 ICE_FXD_FLTR_QW1_PROF_M;
445 qword |= ((u64)ctx->fd_vsi << ICE_FXD_FLTR_QW1_FD_VSI_S) &
446 ICE_FXD_FLTR_QW1_FD_VSI_M;
447 qword |= ((u64)ctx->swap << ICE_FXD_FLTR_QW1_SWAP_S) &
448 ICE_FXD_FLTR_QW1_SWAP_M;
449 qword |= ((u64)ctx->fdid_prio << ICE_FXD_FLTR_QW1_FDID_PRI_S) &
450 ICE_FXD_FLTR_QW1_FDID_PRI_M;
451 qword |= ((u64)ctx->fdid_mdid << ICE_FXD_FLTR_QW1_FDID_MDID_S) &
452 ICE_FXD_FLTR_QW1_FDID_MDID_M;
453 qword |= ((u64)ctx->fdid << ICE_FXD_FLTR_QW1_FDID_S) &
454 ICE_FXD_FLTR_QW1_FDID_M;
455 fdir_desc->dtype_cmd_vsi_fdid = CPU_TO_LE64(qword);
459 * ice_fdir_get_prgm_desc - set a fdir descriptor from a fdir filter struct
460 * @hw: pointer to the hardware structure
462 * @fdesc: filter descriptor
463 * @add: if add is true, this is an add operation, false implies delete
466 ice_fdir_get_prgm_desc(struct ice_hw *hw, struct ice_fdir_fltr *input,
467 struct ice_fltr_desc *fdesc, bool add)
469 struct ice_fd_fltr_desc_ctx fdir_fltr_ctx = { 0 };
471 /* set default context info */
472 ice_set_dflt_val_fd_desc(&fdir_fltr_ctx);
474 /* change sideband filtering values */
475 fdir_fltr_ctx.fdid = input->fltr_id;
476 if (input->dest_ctl == ICE_FLTR_PRGM_DESC_DEST_DROP_PKT) {
477 fdir_fltr_ctx.drop = ICE_FXD_FLTR_QW0_DROP_YES;
478 fdir_fltr_ctx.qindex = 0;
479 } else if (input->dest_ctl ==
480 ICE_FLTR_PRGM_DESC_DEST_DIRECT_PKT_OTHER) {
481 fdir_fltr_ctx.drop = ICE_FXD_FLTR_QW0_DROP_NO;
482 fdir_fltr_ctx.qindex = 0;
484 if (input->dest_ctl ==
485 ICE_FLTR_PRGM_DESC_DEST_DIRECT_PKT_QGROUP)
486 fdir_fltr_ctx.toq = input->q_region;
487 fdir_fltr_ctx.drop = ICE_FXD_FLTR_QW0_DROP_NO;
488 fdir_fltr_ctx.qindex = input->q_index;
490 fdir_fltr_ctx.cnt_ena = input->cnt_ena;
491 fdir_fltr_ctx.cnt_index = input->cnt_index;
492 fdir_fltr_ctx.fd_vsi = ice_get_hw_vsi_num(hw, input->dest_vsi);
493 fdir_fltr_ctx.evict_ena = ICE_FXD_FLTR_QW0_EVICT_ENA_FALSE;
494 if (input->dest_ctl == ICE_FLTR_PRGM_DESC_DEST_DIRECT_PKT_OTHER)
495 fdir_fltr_ctx.toq_prio = 0;
497 fdir_fltr_ctx.toq_prio = 3;
498 fdir_fltr_ctx.pcmd = (add) ? ICE_FXD_FLTR_QW1_PCMD_ADD :
499 ICE_FXD_FLTR_QW1_PCMD_REMOVE;
500 fdir_fltr_ctx.swap = ICE_FXD_FLTR_QW1_SWAP_NOT_SET;
501 fdir_fltr_ctx.comp_q = ICE_FXD_FLTR_QW0_COMP_Q_ZERO;
502 fdir_fltr_ctx.comp_report = ICE_FXD_FLTR_QW0_COMP_REPORT_SW;
503 fdir_fltr_ctx.fdid_prio = input->fdid_prio;
504 fdir_fltr_ctx.desc_prof = 1;
505 fdir_fltr_ctx.desc_prof_prio = 3;
506 ice_set_fd_desc_val(&fdir_fltr_ctx, fdesc);
510 * ice_alloc_fd_res_cntr - obtain counter resource for FD type
511 * @hw: pointer to the hardware structure
512 * @cntr_id: returns counter index
514 enum ice_status ice_alloc_fd_res_cntr(struct ice_hw *hw, u16 *cntr_id)
516 return ice_alloc_res_cntr(hw, ICE_AQC_RES_TYPE_FDIR_COUNTER_BLOCK,
517 ICE_AQC_RES_TYPE_FLAG_DEDICATED, 1, cntr_id);
521 * ice_free_fd_res_cntr - Free counter resource for FD type
522 * @hw: pointer to the hardware structure
523 * @cntr_id: counter index to be freed
525 enum ice_status ice_free_fd_res_cntr(struct ice_hw *hw, u16 cntr_id)
527 return ice_free_res_cntr(hw, ICE_AQC_RES_TYPE_FDIR_COUNTER_BLOCK,
528 ICE_AQC_RES_TYPE_FLAG_DEDICATED, 1, cntr_id);
532 * ice_alloc_fd_guar_item - allocate resource for FD guaranteed entries
533 * @hw: pointer to the hardware structure
534 * @cntr_id: returns counter index
535 * @num_fltr: number of filter entries to be allocated
538 ice_alloc_fd_guar_item(struct ice_hw *hw, u16 *cntr_id, u16 num_fltr)
540 return ice_alloc_res_cntr(hw, ICE_AQC_RES_TYPE_FDIR_GUARANTEED_ENTRIES,
541 ICE_AQC_RES_TYPE_FLAG_DEDICATED, num_fltr,
546 * ice_free_fd_guar_item - Free flow director guaranteed entries
547 * @hw: pointer to the hardware structure
548 * @cntr_id: counter index that needs to be freed
549 * @num_fltr: number of filters to be freed
552 ice_free_fd_guar_item(struct ice_hw *hw, u16 cntr_id, u16 num_fltr)
554 return ice_free_res_cntr(hw, ICE_AQC_RES_TYPE_FDIR_GUARANTEED_ENTRIES,
555 ICE_AQC_RES_TYPE_FLAG_DEDICATED, num_fltr,
560 * ice_alloc_fd_shrd_item - allocate resource for flow director shared entries
561 * @hw: pointer to the hardware structure
562 * @cntr_id: returns counter index
563 * @num_fltr: number of filter entries to be allocated
566 ice_alloc_fd_shrd_item(struct ice_hw *hw, u16 *cntr_id, u16 num_fltr)
568 return ice_alloc_res_cntr(hw, ICE_AQC_RES_TYPE_FDIR_SHARED_ENTRIES,
569 ICE_AQC_RES_TYPE_FLAG_DEDICATED, num_fltr,
574 * ice_free_fd_shrd_item - Free flow director shared entries
575 * @hw: pointer to the hardware structure
576 * @cntr_id: counter index that needs to be freed
577 * @num_fltr: number of filters to be freed
580 ice_free_fd_shrd_item(struct ice_hw *hw, u16 cntr_id, u16 num_fltr)
582 return ice_free_res_cntr(hw, ICE_AQC_RES_TYPE_FDIR_SHARED_ENTRIES,
583 ICE_AQC_RES_TYPE_FLAG_DEDICATED, num_fltr,
588 * ice_get_fdir_cnt_all - get the number of Flow Director filters
589 * @hw: hardware data structure
591 * Returns the number of filters available on device
593 int ice_get_fdir_cnt_all(struct ice_hw *hw)
595 return hw->func_caps.fd_fltr_guar + hw->func_caps.fd_fltr_best_effort;
599 * ice_pkt_insert_ipv6_addr - insert a be32 IPv6 address into a memory buffer.
600 * @pkt: packet buffer
601 * @offset: offset into buffer
602 * @addr: IPv6 address to convert and insert into pkt at offset
604 static void ice_pkt_insert_ipv6_addr(u8 *pkt, int offset, __be32 *addr)
608 for (idx = 0; idx < ICE_IPV6_ADDR_LEN_AS_U32; idx++)
609 ice_memcpy(pkt + offset + idx * sizeof(*addr), &addr[idx],
610 sizeof(*addr), ICE_NONDMA_TO_NONDMA);
614 * ice_pkt_insert_u6_qfi - insert a u6 value qfi into a memory buffer for gtpu
615 * @pkt: packet buffer
616 * @offset: offset into buffer
617 * @data: 8 bit value to convert and insert into pkt at offset
619 * This function is designed for inserting qfi (6 bits) for gtpu.
621 static void ice_pkt_insert_u6_qfi(u8 *pkt, int offset, u8 data)
625 ret = (data & 0x3F) + (*(pkt + offset) & 0xC0);
626 ice_memcpy(pkt + offset, &ret, sizeof(ret), ICE_NONDMA_TO_NONDMA);
630 * ice_pkt_insert_u8 - insert a u8 value into a memory buffer.
631 * @pkt: packet buffer
632 * @offset: offset into buffer
633 * @data: 8 bit value to convert and insert into pkt at offset
635 static void ice_pkt_insert_u8(u8 *pkt, int offset, u8 data)
637 ice_memcpy(pkt + offset, &data, sizeof(data), ICE_NONDMA_TO_NONDMA);
641 * ice_pkt_insert_u8_tc - insert a u8 value into a memory buffer for TC ipv6.
642 * @pkt: packet buffer
643 * @offset: offset into buffer
644 * @data: 8 bit value to convert and insert into pkt at offset
646 * This function is designed for inserting Traffic Class (TC) for IPv6,
647 * since that TC is not aligned in number of bytes. Here we split it out
648 * into two part and fill each byte with data copy from pkt, then insert
649 * the two bytes data one by one.
651 static void ice_pkt_insert_u8_tc(u8 *pkt, int offset, u8 data)
655 high = (data >> 4) + (*(pkt + offset) & 0xF0);
656 ice_memcpy(pkt + offset, &high, sizeof(high), ICE_NONDMA_TO_NONDMA);
658 low = (*(pkt + offset + 1) & 0x0F) + ((data & 0x0F) << 4);
659 ice_memcpy(pkt + offset + 1, &low, sizeof(low), ICE_NONDMA_TO_NONDMA);
663 * ice_pkt_insert_u16 - insert a be16 value into a memory buffer.
664 * @pkt: packet buffer
665 * @offset: offset into buffer
666 * @data: 16 bit value to convert and insert into pkt at offset
668 static void ice_pkt_insert_u16(u8 *pkt, int offset, __be16 data)
670 ice_memcpy(pkt + offset, &data, sizeof(data), ICE_NONDMA_TO_NONDMA);
674 * ice_pkt_insert_u32 - insert a be32 value into a memory buffer.
675 * @pkt: packet buffer
676 * @offset: offset into buffer
677 * @data: 32 bit value to convert and insert into pkt at offset
679 static void ice_pkt_insert_u32(u8 *pkt, int offset, __be32 data)
681 ice_memcpy(pkt + offset, &data, sizeof(data), ICE_NONDMA_TO_NONDMA);
685 * ice_pkt_insert_mac_addr - insert a MAC addr into a memory buffer.
686 * @pkt: packet buffer
687 * @offset: offset into buffer
688 * @addr: MAC address to convert and insert into pkt at offset
690 static void ice_pkt_insert_mac_addr(u8 *pkt, u8 *addr)
692 ice_memcpy(pkt, addr, ETH_ALEN, ICE_NONDMA_TO_NONDMA);
696 * ice_fdir_get_gen_prgm_pkt - generate a training packet
697 * @hw: pointer to the hardware structure
698 * @input: flow director filter data structure
699 * @pkt: pointer to return filter packet
700 * @frag: generate a fragment packet
701 * @tun: true implies generate a tunnel packet
704 ice_fdir_get_gen_prgm_pkt(struct ice_hw *hw, struct ice_fdir_fltr *input,
705 u8 *pkt, bool frag, bool tun)
707 enum ice_fltr_ptype flow;
712 if (input->flow_type == ICE_FLTR_PTYPE_NONF_IPV4_OTHER) {
713 switch (input->ip.v4.proto) {
714 case ICE_IP_PROTO_TCP:
715 flow = ICE_FLTR_PTYPE_NONF_IPV4_TCP;
717 case ICE_IP_PROTO_UDP:
718 flow = ICE_FLTR_PTYPE_NONF_IPV4_UDP;
720 case ICE_IP_PROTO_SCTP:
721 flow = ICE_FLTR_PTYPE_NONF_IPV4_SCTP;
724 flow = ICE_FLTR_PTYPE_NONF_IPV4_OTHER;
727 } else if (input->flow_type == ICE_FLTR_PTYPE_NONF_IPV6_OTHER) {
728 switch (input->ip.v6.proto) {
729 case ICE_IP_PROTO_TCP:
730 flow = ICE_FLTR_PTYPE_NONF_IPV6_TCP;
732 case ICE_IP_PROTO_UDP:
733 flow = ICE_FLTR_PTYPE_NONF_IPV6_UDP;
735 case ICE_IP_PROTO_SCTP:
736 flow = ICE_FLTR_PTYPE_NONF_IPV6_SCTP;
739 flow = ICE_FLTR_PTYPE_NONF_IPV6_OTHER;
743 flow = input->flow_type;
746 for (idx = 0; idx < ICE_FDIR_NUM_PKT; idx++)
747 if (ice_fdir_pkt[idx].flow == flow)
749 if (idx == ICE_FDIR_NUM_PKT)
750 return ICE_ERR_PARAM;
752 ice_memcpy(pkt, ice_fdir_pkt[idx].pkt,
753 ice_fdir_pkt[idx].pkt_len, ICE_NONDMA_TO_NONDMA);
756 if (!ice_get_open_tunnel_port(hw, TNL_ALL, &tnl_port))
757 return ICE_ERR_DOES_NOT_EXIST;
758 if (!ice_fdir_pkt[idx].tun_pkt)
759 return ICE_ERR_PARAM;
760 ice_memcpy(pkt, ice_fdir_pkt[idx].tun_pkt,
761 ice_fdir_pkt[idx].tun_pkt_len, ICE_NONDMA_TO_NONDMA);
762 ice_pkt_insert_u16(pkt, ICE_IPV4_UDP_DST_PORT_OFFSET,
764 loc = &pkt[ICE_FDIR_TUN_PKT_OFF];
767 /* Reverse the src and dst, since the HW expects them to be from Tx
768 * perspective. The input from user is from Rx filter perspective.
771 case ICE_FLTR_PTYPE_NONF_IPV4_TCP:
772 ice_pkt_insert_u32(loc, ICE_IPV4_DST_ADDR_OFFSET,
773 input->ip.v4.src_ip);
774 ice_pkt_insert_u16(loc, ICE_IPV4_TCP_DST_PORT_OFFSET,
775 input->ip.v4.src_port);
776 ice_pkt_insert_u32(loc, ICE_IPV4_SRC_ADDR_OFFSET,
777 input->ip.v4.dst_ip);
778 ice_pkt_insert_u16(loc, ICE_IPV4_TCP_SRC_PORT_OFFSET,
779 input->ip.v4.dst_port);
780 ice_pkt_insert_u8(loc, ICE_IPV4_TOS_OFFSET, input->ip.v4.tos);
781 ice_pkt_insert_u8(loc, ICE_IPV4_TTL_OFFSET, input->ip.v4.ttl);
782 ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac);
784 loc[20] = ICE_FDIR_IPV4_PKT_FLAG_DF;
786 case ICE_FLTR_PTYPE_NONF_IPV4_UDP:
787 ice_pkt_insert_u32(loc, ICE_IPV4_DST_ADDR_OFFSET,
788 input->ip.v4.src_ip);
789 ice_pkt_insert_u16(loc, ICE_IPV4_UDP_DST_PORT_OFFSET,
790 input->ip.v4.src_port);
791 ice_pkt_insert_u32(loc, ICE_IPV4_SRC_ADDR_OFFSET,
792 input->ip.v4.dst_ip);
793 ice_pkt_insert_u16(loc, ICE_IPV4_UDP_SRC_PORT_OFFSET,
794 input->ip.v4.dst_port);
795 ice_pkt_insert_u8(loc, ICE_IPV4_TOS_OFFSET, input->ip.v4.tos);
796 ice_pkt_insert_u8(loc, ICE_IPV4_TTL_OFFSET, input->ip.v4.ttl);
797 ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac);
799 case ICE_FLTR_PTYPE_NONF_IPV4_SCTP:
800 ice_pkt_insert_u32(loc, ICE_IPV4_DST_ADDR_OFFSET,
801 input->ip.v4.src_ip);
802 ice_pkt_insert_u16(loc, ICE_IPV4_SCTP_DST_PORT_OFFSET,
803 input->ip.v4.src_port);
804 ice_pkt_insert_u32(loc, ICE_IPV4_SRC_ADDR_OFFSET,
805 input->ip.v4.dst_ip);
806 ice_pkt_insert_u16(loc, ICE_IPV4_SCTP_SRC_PORT_OFFSET,
807 input->ip.v4.dst_port);
808 ice_pkt_insert_u8(loc, ICE_IPV4_TOS_OFFSET, input->ip.v4.tos);
809 ice_pkt_insert_u8(loc, ICE_IPV4_TTL_OFFSET, input->ip.v4.ttl);
810 ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac);
812 case ICE_FLTR_PTYPE_NONF_IPV4_OTHER:
813 ice_pkt_insert_u32(loc, ICE_IPV4_DST_ADDR_OFFSET,
814 input->ip.v4.src_ip);
815 ice_pkt_insert_u32(loc, ICE_IPV4_SRC_ADDR_OFFSET,
816 input->ip.v4.dst_ip);
817 ice_pkt_insert_u8(loc, ICE_IPV4_TOS_OFFSET, input->ip.v4.tos);
818 ice_pkt_insert_u8(loc, ICE_IPV4_TTL_OFFSET, input->ip.v4.ttl);
819 ice_pkt_insert_u8(loc, ICE_IPV4_PROTO_OFFSET,
821 ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac);
823 case ICE_FLTR_PTYPE_NONF_IPV4_GTPU_IPV4_UDP:
824 case ICE_FLTR_PTYPE_NONF_IPV4_GTPU_IPV4_TCP:
825 case ICE_FLTR_PTYPE_NONF_IPV4_GTPU_IPV4_ICMP:
826 case ICE_FLTR_PTYPE_NONF_IPV4_GTPU_IPV4_OTHER:
827 ice_pkt_insert_u32(loc, ICE_IPV4_SRC_ADDR_OFFSET,
828 input->ip.v4.src_ip);
829 ice_pkt_insert_u32(loc, ICE_IPV4_DST_ADDR_OFFSET,
830 input->ip.v4.dst_ip);
831 ice_pkt_insert_u32(loc, ICE_IPV4_GTPU_TEID_OFFSET,
832 input->gtpu_data.teid);
833 ice_pkt_insert_u6_qfi(loc, ICE_IPV4_GTPU_QFI_OFFSET,
834 input->gtpu_data.qfi);
836 case ICE_FLTR_PTYPE_NON_IP_L2:
837 ice_pkt_insert_u16(loc, ICE_MAC_ETHTYPE_OFFSET,
838 input->ext_data.ether_type);
840 case ICE_FLTR_PTYPE_NONF_IPV6_TCP:
841 ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_DST_ADDR_OFFSET,
842 input->ip.v6.src_ip);
843 ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_SRC_ADDR_OFFSET,
844 input->ip.v6.dst_ip);
845 ice_pkt_insert_u16(loc, ICE_IPV6_TCP_DST_PORT_OFFSET,
846 input->ip.v6.src_port);
847 ice_pkt_insert_u16(loc, ICE_IPV6_TCP_SRC_PORT_OFFSET,
848 input->ip.v6.dst_port);
849 ice_pkt_insert_u8_tc(loc, ICE_IPV6_TC_OFFSET, input->ip.v6.tc);
850 ice_pkt_insert_u8(loc, ICE_IPV6_HLIM_OFFSET, input->ip.v6.hlim);
851 ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac);
853 case ICE_FLTR_PTYPE_NONF_IPV6_UDP:
854 ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_DST_ADDR_OFFSET,
855 input->ip.v6.src_ip);
856 ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_SRC_ADDR_OFFSET,
857 input->ip.v6.dst_ip);
858 ice_pkt_insert_u16(loc, ICE_IPV6_UDP_DST_PORT_OFFSET,
859 input->ip.v6.src_port);
860 ice_pkt_insert_u16(loc, ICE_IPV6_UDP_SRC_PORT_OFFSET,
861 input->ip.v6.dst_port);
862 ice_pkt_insert_u8_tc(loc, ICE_IPV6_TC_OFFSET, input->ip.v6.tc);
863 ice_pkt_insert_u8(loc, ICE_IPV6_HLIM_OFFSET, input->ip.v6.hlim);
864 ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac);
866 case ICE_FLTR_PTYPE_NONF_IPV6_SCTP:
867 ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_DST_ADDR_OFFSET,
868 input->ip.v6.src_ip);
869 ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_SRC_ADDR_OFFSET,
870 input->ip.v6.dst_ip);
871 ice_pkt_insert_u16(loc, ICE_IPV6_SCTP_DST_PORT_OFFSET,
872 input->ip.v6.src_port);
873 ice_pkt_insert_u16(loc, ICE_IPV6_SCTP_SRC_PORT_OFFSET,
874 input->ip.v6.dst_port);
875 ice_pkt_insert_u8_tc(loc, ICE_IPV6_TC_OFFSET, input->ip.v6.tc);
876 ice_pkt_insert_u8(loc, ICE_IPV6_HLIM_OFFSET, input->ip.v6.hlim);
877 ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac);
879 case ICE_FLTR_PTYPE_NONF_IPV6_OTHER:
880 ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_DST_ADDR_OFFSET,
881 input->ip.v6.src_ip);
882 ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_SRC_ADDR_OFFSET,
883 input->ip.v6.dst_ip);
884 ice_pkt_insert_u8_tc(loc, ICE_IPV6_TC_OFFSET, input->ip.v6.tc);
885 ice_pkt_insert_u8(loc, ICE_IPV6_HLIM_OFFSET, input->ip.v6.hlim);
886 ice_pkt_insert_u8(loc, ICE_IPV6_PROTO_OFFSET,
888 ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac);
891 return ICE_ERR_PARAM;
894 if (input->flex_fltr)
895 ice_pkt_insert_u16(loc, input->flex_offset, input->flex_word);
901 * ice_fdir_get_prgm_pkt - generate a training packet
902 * @input: flow director filter data structure
903 * @pkt: pointer to return filter packet
904 * @frag: generate a fragment packet
907 ice_fdir_get_prgm_pkt(struct ice_fdir_fltr *input, u8 *pkt, bool frag)
909 return ice_fdir_get_gen_prgm_pkt(NULL, input, pkt, frag, false);
913 * ice_fdir_has_frag - does flow type have 2 ptypes
916 * returns true is there is a fragment packet for this ptype
918 bool ice_fdir_has_frag(enum ice_fltr_ptype flow)
920 if (flow == ICE_FLTR_PTYPE_NONF_IPV4_OTHER)
927 * ice_fdir_find_by_idx - find filter with idx
928 * @hw: pointer to hardware structure
929 * @fltr_idx: index to find.
931 * Returns pointer to filter if found or null
933 struct ice_fdir_fltr *
934 ice_fdir_find_fltr_by_idx(struct ice_hw *hw, u32 fltr_idx)
936 struct ice_fdir_fltr *rule;
938 LIST_FOR_EACH_ENTRY(rule, &hw->fdir_list_head, ice_fdir_fltr,
940 /* rule ID found in the list */
941 if (fltr_idx == rule->fltr_id)
943 if (fltr_idx < rule->fltr_id)
950 * ice_fdir_list_add_fltr - add a new node to the flow director filter list
951 * @hw: hardware structure
952 * @fltr: filter node to add to structure
954 void ice_fdir_list_add_fltr(struct ice_hw *hw, struct ice_fdir_fltr *fltr)
956 struct ice_fdir_fltr *rule, *parent = NULL;
958 LIST_FOR_EACH_ENTRY(rule, &hw->fdir_list_head, ice_fdir_fltr,
960 /* rule ID found or pass its spot in the list */
961 if (rule->fltr_id >= fltr->fltr_id)
967 LIST_ADD_AFTER(&fltr->fltr_node, &parent->fltr_node);
969 LIST_ADD(&fltr->fltr_node, &hw->fdir_list_head);
973 * ice_fdir_update_cntrs - increment / decrement filter counter
974 * @hw: pointer to hardware structure
975 * @flow: filter flow type
976 * @acl_fltr: true indicates an ACL filter
977 * @add: true implies filters added
980 ice_fdir_update_cntrs(struct ice_hw *hw, enum ice_fltr_ptype flow,
981 bool acl_fltr, bool add)
986 hw->fdir_active_fltr += incr;
987 if (flow == ICE_FLTR_PTYPE_NONF_NONE || flow >= ICE_FLTR_PTYPE_MAX) {
988 ice_debug(hw, ICE_DBG_SW, "Unknown filter type %d\n", flow);
991 hw->acl_fltr_cnt[flow] += incr;
993 hw->fdir_fltr_cnt[flow] += incr;
998 * ice_cmp_ipv6_addr - compare 2 IP v6 addresses
1002 * Returns 0 on equal, returns non-0 if different
1004 static int ice_cmp_ipv6_addr(__be32 *a, __be32 *b)
1006 return memcmp(a, b, 4 * sizeof(__be32));
1010 * ice_fdir_comp_rules - compare 2 filters
1011 * @a: a Flow Director filter data structure
1012 * @b: a Flow Director filter data structure
1013 * @v6: bool true if v6 filter
1015 * Returns true if the filters match
1018 ice_fdir_comp_rules(struct ice_fdir_fltr *a, struct ice_fdir_fltr *b, bool v6)
1020 enum ice_fltr_ptype flow_type = a->flow_type;
1022 /* The calling function already checks that the two filters have the
1026 if (flow_type == ICE_FLTR_PTYPE_NONF_IPV4_TCP ||
1027 flow_type == ICE_FLTR_PTYPE_NONF_IPV4_UDP ||
1028 flow_type == ICE_FLTR_PTYPE_NONF_IPV4_SCTP) {
1029 if (a->ip.v4.dst_ip == b->ip.v4.dst_ip &&
1030 a->ip.v4.src_ip == b->ip.v4.src_ip &&
1031 a->ip.v4.dst_port == b->ip.v4.dst_port &&
1032 a->ip.v4.src_port == b->ip.v4.src_port)
1034 } else if (flow_type == ICE_FLTR_PTYPE_NONF_IPV4_OTHER) {
1035 if (a->ip.v4.dst_ip == b->ip.v4.dst_ip &&
1036 a->ip.v4.src_ip == b->ip.v4.src_ip &&
1037 a->ip.v4.l4_header == b->ip.v4.l4_header &&
1038 a->ip.v4.proto == b->ip.v4.proto &&
1039 a->ip.v4.ip_ver == b->ip.v4.ip_ver &&
1040 a->ip.v4.tos == b->ip.v4.tos)
1044 if (flow_type == ICE_FLTR_PTYPE_NONF_IPV6_UDP ||
1045 flow_type == ICE_FLTR_PTYPE_NONF_IPV6_TCP ||
1046 flow_type == ICE_FLTR_PTYPE_NONF_IPV6_SCTP) {
1047 if (a->ip.v6.dst_port == b->ip.v6.dst_port &&
1048 a->ip.v6.src_port == b->ip.v6.src_port &&
1049 !ice_cmp_ipv6_addr(a->ip.v6.dst_ip,
1051 !ice_cmp_ipv6_addr(a->ip.v6.src_ip,
1054 } else if (flow_type == ICE_FLTR_PTYPE_NONF_IPV6_OTHER) {
1055 if (a->ip.v6.dst_port == b->ip.v6.dst_port &&
1056 a->ip.v6.src_port == b->ip.v6.src_port)
1065 * ice_fdir_is_dup_fltr - test if filter is already in list for PF
1066 * @hw: hardware data structure
1067 * @input: Flow Director filter data structure
1069 * Returns true if the filter is found in the list
1071 bool ice_fdir_is_dup_fltr(struct ice_hw *hw, struct ice_fdir_fltr *input)
1073 struct ice_fdir_fltr *rule;
1076 LIST_FOR_EACH_ENTRY(rule, &hw->fdir_list_head, ice_fdir_fltr,
1078 enum ice_fltr_ptype flow_type;
1080 if (rule->flow_type != input->flow_type)
1083 flow_type = input->flow_type;
1084 if (flow_type == ICE_FLTR_PTYPE_NONF_IPV4_TCP ||
1085 flow_type == ICE_FLTR_PTYPE_NONF_IPV4_UDP ||
1086 flow_type == ICE_FLTR_PTYPE_NONF_IPV4_SCTP ||
1087 flow_type == ICE_FLTR_PTYPE_NONF_IPV4_OTHER)
1088 ret = ice_fdir_comp_rules(rule, input, false);
1090 ret = ice_fdir_comp_rules(rule, input, true);
1092 if (rule->fltr_id == input->fltr_id &&
1093 rule->q_index != input->q_index)
1104 * ice_clear_vsi_fd_table - admin command to clear FD table for a VSI
1105 * @hw: hardware data structure
1106 * @vsi_num: vsi_num (HW VSI num)
1108 * Clears FD table entries by issuing admin command (direct, 0x0B06)
1109 * Must to pass valid vsi_num as returned by "AddVSI".
1111 enum ice_status ice_clear_vsi_fd_table(struct ice_hw *hw, u16 vsi_num)
1113 struct ice_aqc_clear_fd_table *cmd;
1114 struct ice_aq_desc desc;
1116 cmd = &desc.params.clear_fd_table;
1117 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_clear_fd_table);
1118 cmd->clear_type = CL_FD_VM_VF_TYPE_VSI_IDX;
1120 cmd->vsi_index = CPU_TO_LE16(vsi_num);
1121 return ice_aq_send_cmd(hw, &desc, NULL, 0, NULL);
1125 * ice_clear_pf_fd_table - admin command to clear FD table for PF
1126 * @hw: hardware data structure
1128 * Clears FD table entries for a PF by issuing admin command (direct, 0x0B06)
1130 enum ice_status ice_clear_pf_fd_table(struct ice_hw *hw)
1132 struct ice_aqc_clear_fd_table *cmd;
1133 struct ice_aq_desc desc;
1135 cmd = &desc.params.clear_fd_table;
1136 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_clear_fd_table);
1137 cmd->clear_type = CL_FD_VM_VF_TYPE_PF_IDX;
1138 /* vsi_index must be 0 to clear FD table for a PF */
1139 cmd->vsi_index = CPU_TO_LE16(0);
1141 return ice_aq_send_cmd(hw, &desc, NULL, 0, NULL);