]> git.proxmox.com Git - ceph.git/blame - ceph/src/spdk/dpdk/drivers/net/ice/base/ice_fdir.c
update source to Ceph Pacific 16.2.2
[ceph.git] / ceph / src / spdk / dpdk / drivers / net / ice / base / ice_fdir.c
CommitLineData
9f95a23c 1/* SPDX-License-Identifier: BSD-3-Clause
f67539c2 2 * Copyright(c) 2001-2020 Intel Corporation
9f95a23c
TL
3 */
4
5#include "ice_common.h"
6#include "ice_fdir.h"
7
f67539c2 8/* These are training packet headers used to program flow director filters. */
9f95a23c
TL
9static 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
19static 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
28static 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
37static 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
f67539c2
TL
45static 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
60static 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
76static 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
91static 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
9f95a23c
TL
105static 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
118static 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
129static 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
141static 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
f67539c2
TL
151static 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
167static 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
182static 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
197static 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
211static 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
230static 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
247static 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
265static 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 */
9f95a23c
TL
282static const struct ice_fdir_base_pkt ice_fdir_pkt[] = {
283 {
284 ICE_FLTR_PTYPE_NONF_IPV4_TCP,
f67539c2
TL
285 sizeof(ice_fdir_tcpv4_pkt), ice_fdir_tcpv4_pkt,
286 sizeof(ice_fdir_tcp4_tun_pkt), ice_fdir_tcp4_tun_pkt,
9f95a23c
TL
287 },
288 {
289 ICE_FLTR_PTYPE_NONF_IPV4_UDP,
f67539c2
TL
290 sizeof(ice_fdir_udpv4_pkt), ice_fdir_udpv4_pkt,
291 sizeof(ice_fdir_udp4_tun_pkt), ice_fdir_udp4_tun_pkt,
9f95a23c
TL
292 },
293 {
294 ICE_FLTR_PTYPE_NONF_IPV4_SCTP,
f67539c2
TL
295 sizeof(ice_fdir_sctpv4_pkt), ice_fdir_sctpv4_pkt,
296 sizeof(ice_fdir_sctp4_tun_pkt), ice_fdir_sctp4_tun_pkt,
9f95a23c
TL
297 },
298 {
299 ICE_FLTR_PTYPE_NONF_IPV4_OTHER,
f67539c2
TL
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,
9f95a23c
TL
330 },
331 {
332 ICE_FLTR_PTYPE_NONF_IPV6_TCP,
f67539c2
TL
333 sizeof(ice_fdir_tcpv6_pkt), ice_fdir_tcpv6_pkt,
334 sizeof(ice_fdir_tcp6_tun_pkt), ice_fdir_tcp6_tun_pkt,
9f95a23c
TL
335 },
336 {
337 ICE_FLTR_PTYPE_NONF_IPV6_UDP,
f67539c2
TL
338 sizeof(ice_fdir_udpv6_pkt), ice_fdir_udpv6_pkt,
339 sizeof(ice_fdir_udp6_tun_pkt), ice_fdir_udp6_tun_pkt,
9f95a23c
TL
340 },
341 {
342 ICE_FLTR_PTYPE_NONF_IPV6_SCTP,
f67539c2
TL
343 sizeof(ice_fdir_sctpv6_pkt), ice_fdir_sctpv6_pkt,
344 sizeof(ice_fdir_sctp6_tun_pkt), ice_fdir_sctp6_tun_pkt,
9f95a23c
TL
345 },
346 {
347 ICE_FLTR_PTYPE_NONF_IPV6_OTHER,
f67539c2
TL
348 sizeof(ice_fdir_ipv6_pkt), ice_fdir_ipv6_pkt,
349 sizeof(ice_fdir_ip6_tun_pkt), ice_fdir_ip6_tun_pkt,
9f95a23c
TL
350 },
351};
352
353#define ICE_FDIR_NUM_PKT ARRAY_SIZE(ice_fdir_pkt)
354
9f95a23c
TL
355/**
356 * ice_set_dflt_val_fd_desc
357 * @fd_fltr_ctx: pointer to fd filter descriptor
358 */
359void
360ice_set_dflt_val_fd_desc(struct ice_fd_fltr_desc_ctx *fd_fltr_ctx)
361{
362 fd_fltr_ctx->comp_q = ICE_FXD_FLTR_QW0_COMP_Q_ZERO;
363 fd_fltr_ctx->comp_report = ICE_FXD_FLTR_QW0_COMP_REPORT_SW_FAIL;
364 fd_fltr_ctx->fd_space = ICE_FXD_FLTR_QW0_FD_SPACE_GUAR_BEST;
365 fd_fltr_ctx->cnt_ena = ICE_FXD_FLTR_QW0_STAT_ENA_PKTS;
366 fd_fltr_ctx->evict_ena = ICE_FXD_FLTR_QW0_EVICT_ENA_TRUE;
367 fd_fltr_ctx->toq = ICE_FXD_FLTR_QW0_TO_Q_EQUALS_QINDEX;
368 fd_fltr_ctx->toq_prio = ICE_FXD_FLTR_QW0_TO_Q_PRIO1;
369 fd_fltr_ctx->dpu_recipe = ICE_FXD_FLTR_QW0_DPU_RECIPE_DFLT;
370 fd_fltr_ctx->drop = ICE_FXD_FLTR_QW0_DROP_NO;
371 fd_fltr_ctx->flex_prio = ICE_FXD_FLTR_QW0_FLEX_PRI_NONE;
372 fd_fltr_ctx->flex_mdid = ICE_FXD_FLTR_QW0_FLEX_MDID0;
373 fd_fltr_ctx->flex_val = ICE_FXD_FLTR_QW0_FLEX_VAL0;
374 fd_fltr_ctx->dtype = ICE_TX_DESC_DTYPE_FLTR_PROG;
375 fd_fltr_ctx->desc_prof_prio = ICE_FXD_FLTR_QW1_PROF_PRIO_ZERO;
376 fd_fltr_ctx->desc_prof = ICE_FXD_FLTR_QW1_PROF_ZERO;
377 fd_fltr_ctx->swap = ICE_FXD_FLTR_QW1_SWAP_SET;
f67539c2 378 fd_fltr_ctx->fdid_prio = ICE_FXD_FLTR_QW1_FDID_PRI_ONE;
9f95a23c
TL
379 fd_fltr_ctx->fdid_mdid = ICE_FXD_FLTR_QW1_FDID_MDID_FD;
380 fd_fltr_ctx->fdid = ICE_FXD_FLTR_QW1_FDID_ZERO;
381}
382
f67539c2
TL
383/**
384 * ice_set_fd_desc_val
385 * @ctx: pointer to fd filter descriptor context
386 * @fdir_desc: populated with fd filter descriptor values
387 */
388static void
389ice_set_fd_desc_val(struct ice_fd_fltr_desc_ctx *ctx,
390 struct ice_fltr_desc *fdir_desc)
391{
392 u64 qword;
393
394 /* prep QW0 of FD filter programming desc */
395 qword = ((u64)ctx->qindex << ICE_FXD_FLTR_QW0_QINDEX_S) &
396 ICE_FXD_FLTR_QW0_QINDEX_M;
397 qword |= ((u64)ctx->comp_q << ICE_FXD_FLTR_QW0_COMP_Q_S) &
398 ICE_FXD_FLTR_QW0_COMP_Q_M;
399 qword |= ((u64)ctx->comp_report << ICE_FXD_FLTR_QW0_COMP_REPORT_S) &
400 ICE_FXD_FLTR_QW0_COMP_REPORT_M;
401 qword |= ((u64)ctx->fd_space << ICE_FXD_FLTR_QW0_FD_SPACE_S) &
402 ICE_FXD_FLTR_QW0_FD_SPACE_M;
403 qword |= ((u64)ctx->cnt_index << ICE_FXD_FLTR_QW0_STAT_CNT_S) &
404 ICE_FXD_FLTR_QW0_STAT_CNT_M;
405 qword |= ((u64)ctx->cnt_ena << ICE_FXD_FLTR_QW0_STAT_ENA_S) &
406 ICE_FXD_FLTR_QW0_STAT_ENA_M;
407 qword |= ((u64)ctx->evict_ena << ICE_FXD_FLTR_QW0_EVICT_ENA_S) &
408 ICE_FXD_FLTR_QW0_EVICT_ENA_M;
409 qword |= ((u64)ctx->toq << ICE_FXD_FLTR_QW0_TO_Q_S) &
410 ICE_FXD_FLTR_QW0_TO_Q_M;
411 qword |= ((u64)ctx->toq_prio << ICE_FXD_FLTR_QW0_TO_Q_PRI_S) &
412 ICE_FXD_FLTR_QW0_TO_Q_PRI_M;
413 qword |= ((u64)ctx->dpu_recipe << ICE_FXD_FLTR_QW0_DPU_RECIPE_S) &
414 ICE_FXD_FLTR_QW0_DPU_RECIPE_M;
415 qword |= ((u64)ctx->drop << ICE_FXD_FLTR_QW0_DROP_S) &
416 ICE_FXD_FLTR_QW0_DROP_M;
417 qword |= ((u64)ctx->flex_prio << ICE_FXD_FLTR_QW0_FLEX_PRI_S) &
418 ICE_FXD_FLTR_QW0_FLEX_PRI_M;
419 qword |= ((u64)ctx->flex_mdid << ICE_FXD_FLTR_QW0_FLEX_MDID_S) &
420 ICE_FXD_FLTR_QW0_FLEX_MDID_M;
421 qword |= ((u64)ctx->flex_val << ICE_FXD_FLTR_QW0_FLEX_VAL_S) &
422 ICE_FXD_FLTR_QW0_FLEX_VAL_M;
423 fdir_desc->qidx_compq_space_stat = CPU_TO_LE64(qword);
424
425 /* prep QW1 of FD filter programming desc */
426 qword = ((u64)ctx->dtype << ICE_FXD_FLTR_QW1_DTYPE_S) &
427 ICE_FXD_FLTR_QW1_DTYPE_M;
428 qword |= ((u64)ctx->pcmd << ICE_FXD_FLTR_QW1_PCMD_S) &
429 ICE_FXD_FLTR_QW1_PCMD_M;
430 qword |= ((u64)ctx->desc_prof_prio << ICE_FXD_FLTR_QW1_PROF_PRI_S) &
431 ICE_FXD_FLTR_QW1_PROF_PRI_M;
432 qword |= ((u64)ctx->desc_prof << ICE_FXD_FLTR_QW1_PROF_S) &
433 ICE_FXD_FLTR_QW1_PROF_M;
434 qword |= ((u64)ctx->fd_vsi << ICE_FXD_FLTR_QW1_FD_VSI_S) &
435 ICE_FXD_FLTR_QW1_FD_VSI_M;
436 qword |= ((u64)ctx->swap << ICE_FXD_FLTR_QW1_SWAP_S) &
437 ICE_FXD_FLTR_QW1_SWAP_M;
438 qword |= ((u64)ctx->fdid_prio << ICE_FXD_FLTR_QW1_FDID_PRI_S) &
439 ICE_FXD_FLTR_QW1_FDID_PRI_M;
440 qword |= ((u64)ctx->fdid_mdid << ICE_FXD_FLTR_QW1_FDID_MDID_S) &
441 ICE_FXD_FLTR_QW1_FDID_MDID_M;
442 qword |= ((u64)ctx->fdid << ICE_FXD_FLTR_QW1_FDID_S) &
443 ICE_FXD_FLTR_QW1_FDID_M;
444 fdir_desc->dtype_cmd_vsi_fdid = CPU_TO_LE64(qword);
445}
446
9f95a23c
TL
447/**
448 * ice_fdir_get_prgm_desc - set a fdir descriptor from a fdir filter struct
449 * @hw: pointer to the hardware structure
450 * @input: filter
451 * @fdesc: filter descriptor
452 * @add: if add is true, this is an add operation, false implies delete
453 */
454void
455ice_fdir_get_prgm_desc(struct ice_hw *hw, struct ice_fdir_fltr *input,
456 struct ice_fltr_desc *fdesc, bool add)
457{
458 struct ice_fd_fltr_desc_ctx fdir_fltr_ctx = { 0 };
459
460 /* set default context info */
461 ice_set_dflt_val_fd_desc(&fdir_fltr_ctx);
462
463 /* change sideband filtering values */
464 fdir_fltr_ctx.fdid = input->fltr_id;
465 if (input->dest_ctl == ICE_FLTR_PRGM_DESC_DEST_DROP_PKT) {
466 fdir_fltr_ctx.drop = ICE_FXD_FLTR_QW0_DROP_YES;
467 fdir_fltr_ctx.qindex = 0;
f67539c2
TL
468 } else if (input->dest_ctl ==
469 ICE_FLTR_PRGM_DESC_DEST_DIRECT_PKT_OTHER) {
470 fdir_fltr_ctx.drop = ICE_FXD_FLTR_QW0_DROP_NO;
471 fdir_fltr_ctx.qindex = 0;
9f95a23c 472 } else {
f67539c2
TL
473 if (input->dest_ctl ==
474 ICE_FLTR_PRGM_DESC_DEST_DIRECT_PKT_QGROUP)
475 fdir_fltr_ctx.toq = input->q_region;
9f95a23c
TL
476 fdir_fltr_ctx.drop = ICE_FXD_FLTR_QW0_DROP_NO;
477 fdir_fltr_ctx.qindex = input->q_index;
478 }
f67539c2 479 fdir_fltr_ctx.cnt_ena = input->cnt_ena;
9f95a23c
TL
480 fdir_fltr_ctx.cnt_index = input->cnt_index;
481 fdir_fltr_ctx.fd_vsi = ice_get_hw_vsi_num(hw, input->dest_vsi);
482 fdir_fltr_ctx.evict_ena = ICE_FXD_FLTR_QW0_EVICT_ENA_FALSE;
f67539c2
TL
483 if (input->dest_ctl == ICE_FLTR_PRGM_DESC_DEST_DIRECT_PKT_OTHER)
484 fdir_fltr_ctx.toq_prio = 0;
485 else
486 fdir_fltr_ctx.toq_prio = 3;
9f95a23c
TL
487 fdir_fltr_ctx.pcmd = (add) ? ICE_FXD_FLTR_QW1_PCMD_ADD :
488 ICE_FXD_FLTR_QW1_PCMD_REMOVE;
489 fdir_fltr_ctx.swap = ICE_FXD_FLTR_QW1_SWAP_NOT_SET;
490 fdir_fltr_ctx.comp_q = ICE_FXD_FLTR_QW0_COMP_Q_ZERO;
491 fdir_fltr_ctx.comp_report = ICE_FXD_FLTR_QW0_COMP_REPORT_SW;
f67539c2 492 fdir_fltr_ctx.fdid_prio = input->fdid_prio;
9f95a23c
TL
493 fdir_fltr_ctx.desc_prof = 1;
494 fdir_fltr_ctx.desc_prof_prio = 3;
495 ice_set_fd_desc_val(&fdir_fltr_ctx, fdesc);
496}
497
9f95a23c
TL
498/**
499 * ice_alloc_fd_res_cntr - obtain counter resource for FD type
500 * @hw: pointer to the hardware structure
501 * @cntr_id: returns counter index
502 */
503enum ice_status ice_alloc_fd_res_cntr(struct ice_hw *hw, u16 *cntr_id)
504{
505 return ice_alloc_res_cntr(hw, ICE_AQC_RES_TYPE_FDIR_COUNTER_BLOCK,
506 ICE_AQC_RES_TYPE_FLAG_DEDICATED, 1, cntr_id);
507}
508
509/**
510 * ice_free_fd_res_cntr - Free counter resource for FD type
511 * @hw: pointer to the hardware structure
512 * @cntr_id: counter index to be freed
513 */
514enum ice_status ice_free_fd_res_cntr(struct ice_hw *hw, u16 cntr_id)
515{
516 return ice_free_res_cntr(hw, ICE_AQC_RES_TYPE_FDIR_COUNTER_BLOCK,
517 ICE_AQC_RES_TYPE_FLAG_DEDICATED, 1, cntr_id);
518}
519
520/**
521 * ice_alloc_fd_guar_item - allocate resource for FD guaranteed entries
522 * @hw: pointer to the hardware structure
523 * @cntr_id: returns counter index
524 * @num_fltr: number of filter entries to be allocated
525 */
526enum ice_status
527ice_alloc_fd_guar_item(struct ice_hw *hw, u16 *cntr_id, u16 num_fltr)
528{
529 return ice_alloc_res_cntr(hw, ICE_AQC_RES_TYPE_FDIR_GUARANTEED_ENTRIES,
530 ICE_AQC_RES_TYPE_FLAG_DEDICATED, num_fltr,
531 cntr_id);
532}
533
534/**
535 * ice_free_fd_guar_item - Free flow director guaranteed entries
536 * @hw: pointer to the hardware structure
537 * @cntr_id: counter index that needs to be freed
538 * @num_fltr: number of filters to be freed
539 */
540enum ice_status
541ice_free_fd_guar_item(struct ice_hw *hw, u16 cntr_id, u16 num_fltr)
542{
543 return ice_free_res_cntr(hw, ICE_AQC_RES_TYPE_FDIR_GUARANTEED_ENTRIES,
544 ICE_AQC_RES_TYPE_FLAG_DEDICATED, num_fltr,
545 cntr_id);
546}
547
548/**
549 * ice_alloc_fd_shrd_item - allocate resource for flow director shared entries
550 * @hw: pointer to the hardware structure
551 * @cntr_id: returns counter index
552 * @num_fltr: number of filter entries to be allocated
553 */
554enum ice_status
555ice_alloc_fd_shrd_item(struct ice_hw *hw, u16 *cntr_id, u16 num_fltr)
556{
557 return ice_alloc_res_cntr(hw, ICE_AQC_RES_TYPE_FDIR_SHARED_ENTRIES,
558 ICE_AQC_RES_TYPE_FLAG_DEDICATED, num_fltr,
559 cntr_id);
560}
561
562/**
563 * ice_free_fd_shrd_item - Free flow director shared entries
564 * @hw: pointer to the hardware structure
565 * @cntr_id: counter index that needs to be freed
566 * @num_fltr: number of filters to be freed
567 */
568enum ice_status
569ice_free_fd_shrd_item(struct ice_hw *hw, u16 cntr_id, u16 num_fltr)
570{
571 return ice_free_res_cntr(hw, ICE_AQC_RES_TYPE_FDIR_SHARED_ENTRIES,
572 ICE_AQC_RES_TYPE_FLAG_DEDICATED, num_fltr,
573 cntr_id);
574}
575
576/**
577 * ice_get_fdir_cnt_all - get the number of Flow Director filters
578 * @hw: hardware data structure
579 *
580 * Returns the number of filters available on device
581 */
582int ice_get_fdir_cnt_all(struct ice_hw *hw)
583{
f67539c2 584 return hw->func_caps.fd_fltr_guar + hw->func_caps.fd_fltr_best_effort;
9f95a23c
TL
585}
586
587/**
588 * ice_pkt_insert_ipv6_addr - insert a be32 IPv6 address into a memory buffer.
589 * @pkt: packet buffer
590 * @offset: offset into buffer
591 * @addr: IPv6 address to convert and insert into pkt at offset
592 */
593static void ice_pkt_insert_ipv6_addr(u8 *pkt, int offset, __be32 *addr)
594{
595 int idx;
596
597 for (idx = 0; idx < ICE_IPV6_ADDR_LEN_AS_U32; idx++)
598 ice_memcpy(pkt + offset + idx * sizeof(*addr), &addr[idx],
599 sizeof(*addr), ICE_NONDMA_TO_NONDMA);
600}
601
f67539c2
TL
602/**
603 * ice_pkt_insert_u6_qfi - insert a u6 value qfi into a memory buffer for gtpu
604 * @pkt: packet buffer
605 * @offset: offset into buffer
606 * @data: 8 bit value to convert and insert into pkt at offset
607 *
608 * This function is designed for inserting qfi (6 bits) for gtpu.
609 */
610static void ice_pkt_insert_u6_qfi(u8 *pkt, int offset, u8 data)
611{
612 u8 ret;
613
614 ret = (data & 0x3F) + (*(pkt + offset) & 0xC0);
615 ice_memcpy(pkt + offset, &ret, sizeof(ret), ICE_NONDMA_TO_NONDMA);
616}
617
618/**
619 * ice_pkt_insert_u8 - insert a u8 value into a memory buffer.
620 * @pkt: packet buffer
621 * @offset: offset into buffer
622 * @data: 8 bit value to convert and insert into pkt at offset
623 */
624static void ice_pkt_insert_u8(u8 *pkt, int offset, u8 data)
625{
626 ice_memcpy(pkt + offset, &data, sizeof(data), ICE_NONDMA_TO_NONDMA);
627}
628
629/**
630 * ice_pkt_insert_u8_tc - insert a u8 value into a memory buffer for TC ipv6.
631 * @pkt: packet buffer
632 * @offset: offset into buffer
633 * @data: 8 bit value to convert and insert into pkt at offset
634 *
635 * This function is designed for inserting Traffic Class (TC) for IPv6,
636 * since that TC is not aligned in number of bytes. Here we split it out
637 * into two part and fill each byte with data copy from pkt, then insert
638 * the two bytes data one by one.
639 */
640static void ice_pkt_insert_u8_tc(u8 *pkt, int offset, u8 data)
641{
642 u8 high, low;
643
644 high = (data >> 4) + (*(pkt + offset) & 0xF0);
645 ice_memcpy(pkt + offset, &high, sizeof(high), ICE_NONDMA_TO_NONDMA);
646
647 low = (*(pkt + offset + 1) & 0x0F) + ((data & 0x0F) << 4);
648 ice_memcpy(pkt + offset + 1, &low, sizeof(low), ICE_NONDMA_TO_NONDMA);
649}
650
9f95a23c
TL
651/**
652 * ice_pkt_insert_u16 - insert a be16 value into a memory buffer.
653 * @pkt: packet buffer
654 * @offset: offset into buffer
655 * @data: 16 bit value to convert and insert into pkt at offset
656 */
657static void ice_pkt_insert_u16(u8 *pkt, int offset, __be16 data)
658{
659 ice_memcpy(pkt + offset, &data, sizeof(data), ICE_NONDMA_TO_NONDMA);
660}
661
662/**
663 * ice_pkt_insert_u32 - insert a be32 value into a memory buffer.
664 * @pkt: packet buffer
665 * @offset: offset into buffer
666 * @data: 32 bit value to convert and insert into pkt at offset
667 */
668static void ice_pkt_insert_u32(u8 *pkt, int offset, __be32 data)
669{
670 ice_memcpy(pkt + offset, &data, sizeof(data), ICE_NONDMA_TO_NONDMA);
671}
672
673/**
f67539c2
TL
674 * ice_pkt_insert_mac_addr - insert a MAC addr into a memory buffer.
675 * @pkt: packet buffer
676 * @offset: offset into buffer
677 * @addr: MAC address to convert and insert into pkt at offset
678 */
679static void ice_pkt_insert_mac_addr(u8 *pkt, u8 *addr)
680{
681 ice_memcpy(pkt, addr, ETH_ALEN, ICE_NONDMA_TO_NONDMA);
682}
683
684/**
685 * ice_fdir_get_gen_prgm_pkt - generate a training packet
686 * @hw: pointer to the hardware structure
9f95a23c
TL
687 * @input: flow director filter data structure
688 * @pkt: pointer to return filter packet
689 * @frag: generate a fragment packet
f67539c2 690 * @tun: true implies generate a tunnel packet
9f95a23c
TL
691 */
692enum ice_status
f67539c2
TL
693ice_fdir_get_gen_prgm_pkt(struct ice_hw *hw, struct ice_fdir_fltr *input,
694 u8 *pkt, bool frag, bool tun)
9f95a23c
TL
695{
696 enum ice_fltr_ptype flow;
f67539c2
TL
697 u16 tnl_port;
698 u8 *loc;
9f95a23c
TL
699 u16 idx;
700
701 if (input->flow_type == ICE_FLTR_PTYPE_NONF_IPV4_OTHER) {
702 switch (input->ip.v4.proto) {
703 case ICE_IP_PROTO_TCP:
704 flow = ICE_FLTR_PTYPE_NONF_IPV4_TCP;
705 break;
706 case ICE_IP_PROTO_UDP:
707 flow = ICE_FLTR_PTYPE_NONF_IPV4_UDP;
708 break;
709 case ICE_IP_PROTO_SCTP:
710 flow = ICE_FLTR_PTYPE_NONF_IPV4_SCTP;
711 break;
f67539c2 712 default:
9f95a23c
TL
713 flow = ICE_FLTR_PTYPE_NONF_IPV4_OTHER;
714 break;
9f95a23c
TL
715 }
716 } else if (input->flow_type == ICE_FLTR_PTYPE_NONF_IPV6_OTHER) {
717 switch (input->ip.v6.proto) {
718 case ICE_IP_PROTO_TCP:
719 flow = ICE_FLTR_PTYPE_NONF_IPV6_TCP;
720 break;
721 case ICE_IP_PROTO_UDP:
722 flow = ICE_FLTR_PTYPE_NONF_IPV6_UDP;
723 break;
724 case ICE_IP_PROTO_SCTP:
725 flow = ICE_FLTR_PTYPE_NONF_IPV6_SCTP;
726 break;
f67539c2 727 default:
9f95a23c
TL
728 flow = ICE_FLTR_PTYPE_NONF_IPV6_OTHER;
729 break;
9f95a23c
TL
730 }
731 } else {
732 flow = input->flow_type;
733 }
734
735 for (idx = 0; idx < ICE_FDIR_NUM_PKT; idx++)
736 if (ice_fdir_pkt[idx].flow == flow)
737 break;
738 if (idx == ICE_FDIR_NUM_PKT)
739 return ICE_ERR_PARAM;
f67539c2
TL
740 if (!tun) {
741 ice_memcpy(pkt, ice_fdir_pkt[idx].pkt,
742 ice_fdir_pkt[idx].pkt_len, ICE_NONDMA_TO_NONDMA);
743 loc = pkt;
744 } else {
745 if (!ice_get_open_tunnel_port(hw, TNL_ALL, &tnl_port))
746 return ICE_ERR_DOES_NOT_EXIST;
747 if (!ice_fdir_pkt[idx].tun_pkt)
748 return ICE_ERR_PARAM;
749 ice_memcpy(pkt, ice_fdir_pkt[idx].tun_pkt,
750 ice_fdir_pkt[idx].tun_pkt_len, ICE_NONDMA_TO_NONDMA);
751 ice_pkt_insert_u16(pkt, ICE_IPV4_UDP_DST_PORT_OFFSET,
752 HTONS(tnl_port));
753 loc = &pkt[ICE_FDIR_TUN_PKT_OFF];
754 }
9f95a23c
TL
755
756 switch (flow) {
757 case ICE_FLTR_PTYPE_NONF_IPV4_TCP:
f67539c2 758 ice_pkt_insert_u32(loc, ICE_IPV4_DST_ADDR_OFFSET,
9f95a23c 759 input->ip.v4.dst_ip);
f67539c2 760 ice_pkt_insert_u16(loc, ICE_IPV4_TCP_DST_PORT_OFFSET,
9f95a23c 761 input->ip.v4.dst_port);
f67539c2 762 ice_pkt_insert_u32(loc, ICE_IPV4_SRC_ADDR_OFFSET,
9f95a23c 763 input->ip.v4.src_ip);
f67539c2 764 ice_pkt_insert_u16(loc, ICE_IPV4_TCP_SRC_PORT_OFFSET,
9f95a23c 765 input->ip.v4.src_port);
f67539c2
TL
766 ice_pkt_insert_u8(loc, ICE_IPV4_TOS_OFFSET, input->ip.v4.tos);
767 ice_pkt_insert_u8(loc, ICE_IPV4_TTL_OFFSET, input->ip.v4.ttl);
768 ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac);
9f95a23c 769 if (frag)
f67539c2 770 loc[20] = ICE_FDIR_IPV4_PKT_FLAG_DF;
9f95a23c
TL
771 break;
772 case ICE_FLTR_PTYPE_NONF_IPV4_UDP:
f67539c2 773 ice_pkt_insert_u32(loc, ICE_IPV4_DST_ADDR_OFFSET,
9f95a23c 774 input->ip.v4.dst_ip);
f67539c2 775 ice_pkt_insert_u16(loc, ICE_IPV4_UDP_DST_PORT_OFFSET,
9f95a23c 776 input->ip.v4.dst_port);
f67539c2 777 ice_pkt_insert_u32(loc, ICE_IPV4_SRC_ADDR_OFFSET,
9f95a23c 778 input->ip.v4.src_ip);
f67539c2 779 ice_pkt_insert_u16(loc, ICE_IPV4_UDP_SRC_PORT_OFFSET,
9f95a23c 780 input->ip.v4.src_port);
f67539c2
TL
781 ice_pkt_insert_u8(loc, ICE_IPV4_TOS_OFFSET, input->ip.v4.tos);
782 ice_pkt_insert_u8(loc, ICE_IPV4_TTL_OFFSET, input->ip.v4.ttl);
783 ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac);
9f95a23c
TL
784 break;
785 case ICE_FLTR_PTYPE_NONF_IPV4_SCTP:
f67539c2 786 ice_pkt_insert_u32(loc, ICE_IPV4_DST_ADDR_OFFSET,
9f95a23c 787 input->ip.v4.dst_ip);
f67539c2 788 ice_pkt_insert_u16(loc, ICE_IPV4_SCTP_DST_PORT_OFFSET,
9f95a23c 789 input->ip.v4.dst_port);
f67539c2 790 ice_pkt_insert_u32(loc, ICE_IPV4_SRC_ADDR_OFFSET,
9f95a23c 791 input->ip.v4.src_ip);
f67539c2 792 ice_pkt_insert_u16(loc, ICE_IPV4_SCTP_SRC_PORT_OFFSET,
9f95a23c 793 input->ip.v4.src_port);
f67539c2
TL
794 ice_pkt_insert_u8(loc, ICE_IPV4_TOS_OFFSET, input->ip.v4.tos);
795 ice_pkt_insert_u8(loc, ICE_IPV4_TTL_OFFSET, input->ip.v4.ttl);
796 ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac);
9f95a23c
TL
797 break;
798 case ICE_FLTR_PTYPE_NONF_IPV4_OTHER:
f67539c2 799 ice_pkt_insert_u32(loc, ICE_IPV4_DST_ADDR_OFFSET,
9f95a23c 800 input->ip.v4.dst_ip);
f67539c2 801 ice_pkt_insert_u32(loc, ICE_IPV4_SRC_ADDR_OFFSET,
9f95a23c 802 input->ip.v4.src_ip);
f67539c2
TL
803 ice_pkt_insert_u8(loc, ICE_IPV4_TOS_OFFSET, input->ip.v4.tos);
804 ice_pkt_insert_u8(loc, ICE_IPV4_TTL_OFFSET, input->ip.v4.ttl);
805 ice_pkt_insert_u8(loc, ICE_IPV4_PROTO_OFFSET,
806 input->ip.v4.proto);
807 ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac);
808 break;
809 case ICE_FLTR_PTYPE_NONF_IPV4_GTPU_IPV4_UDP:
810 case ICE_FLTR_PTYPE_NONF_IPV4_GTPU_IPV4_TCP:
811 case ICE_FLTR_PTYPE_NONF_IPV4_GTPU_IPV4_ICMP:
812 case ICE_FLTR_PTYPE_NONF_IPV4_GTPU_IPV4_OTHER:
813 ice_pkt_insert_u32(loc, ICE_IPV4_SRC_ADDR_OFFSET,
814 input->ip.v4.src_ip);
815 ice_pkt_insert_u32(loc, ICE_IPV4_DST_ADDR_OFFSET,
816 input->ip.v4.dst_ip);
817 ice_pkt_insert_u32(loc, ICE_IPV4_GTPU_TEID_OFFSET,
818 input->gtpu_data.teid);
819 ice_pkt_insert_u6_qfi(loc, ICE_IPV4_GTPU_QFI_OFFSET,
820 input->gtpu_data.qfi);
9f95a23c
TL
821 break;
822 case ICE_FLTR_PTYPE_NONF_IPV6_TCP:
f67539c2 823 ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_DST_ADDR_OFFSET,
9f95a23c 824 input->ip.v6.dst_ip);
f67539c2 825 ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_SRC_ADDR_OFFSET,
9f95a23c 826 input->ip.v6.src_ip);
f67539c2 827 ice_pkt_insert_u16(loc, ICE_IPV6_TCP_DST_PORT_OFFSET,
9f95a23c 828 input->ip.v6.dst_port);
f67539c2 829 ice_pkt_insert_u16(loc, ICE_IPV6_TCP_SRC_PORT_OFFSET,
9f95a23c 830 input->ip.v6.src_port);
f67539c2
TL
831 ice_pkt_insert_u8_tc(loc, ICE_IPV6_TC_OFFSET, input->ip.v6.tc);
832 ice_pkt_insert_u8(loc, ICE_IPV6_HLIM_OFFSET, input->ip.v6.hlim);
833 ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac);
9f95a23c
TL
834 break;
835 case ICE_FLTR_PTYPE_NONF_IPV6_UDP:
f67539c2 836 ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_DST_ADDR_OFFSET,
9f95a23c 837 input->ip.v6.dst_ip);
f67539c2 838 ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_SRC_ADDR_OFFSET,
9f95a23c 839 input->ip.v6.src_ip);
f67539c2 840 ice_pkt_insert_u16(loc, ICE_IPV6_UDP_DST_PORT_OFFSET,
9f95a23c 841 input->ip.v6.dst_port);
f67539c2 842 ice_pkt_insert_u16(loc, ICE_IPV6_UDP_SRC_PORT_OFFSET,
9f95a23c 843 input->ip.v6.src_port);
f67539c2
TL
844 ice_pkt_insert_u8_tc(loc, ICE_IPV6_TC_OFFSET, input->ip.v6.tc);
845 ice_pkt_insert_u8(loc, ICE_IPV6_HLIM_OFFSET, input->ip.v6.hlim);
846 ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac);
9f95a23c
TL
847 break;
848 case ICE_FLTR_PTYPE_NONF_IPV6_SCTP:
f67539c2 849 ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_DST_ADDR_OFFSET,
9f95a23c 850 input->ip.v6.dst_ip);
f67539c2 851 ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_SRC_ADDR_OFFSET,
9f95a23c 852 input->ip.v6.src_ip);
f67539c2 853 ice_pkt_insert_u16(loc, ICE_IPV6_SCTP_DST_PORT_OFFSET,
9f95a23c 854 input->ip.v6.dst_port);
f67539c2 855 ice_pkt_insert_u16(loc, ICE_IPV6_SCTP_SRC_PORT_OFFSET,
9f95a23c 856 input->ip.v6.src_port);
f67539c2
TL
857 ice_pkt_insert_u8_tc(loc, ICE_IPV6_TC_OFFSET, input->ip.v6.tc);
858 ice_pkt_insert_u8(loc, ICE_IPV6_HLIM_OFFSET, input->ip.v6.hlim);
859 ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac);
9f95a23c
TL
860 break;
861 case ICE_FLTR_PTYPE_NONF_IPV6_OTHER:
f67539c2 862 ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_DST_ADDR_OFFSET,
9f95a23c 863 input->ip.v6.dst_ip);
f67539c2 864 ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_SRC_ADDR_OFFSET,
9f95a23c 865 input->ip.v6.src_ip);
f67539c2
TL
866 ice_pkt_insert_u8_tc(loc, ICE_IPV6_TC_OFFSET, input->ip.v6.tc);
867 ice_pkt_insert_u8(loc, ICE_IPV6_HLIM_OFFSET, input->ip.v6.hlim);
868 ice_pkt_insert_u8(loc, ICE_IPV6_PROTO_OFFSET,
869 input->ip.v6.proto);
870 ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac);
9f95a23c
TL
871 break;
872 default:
873 return ICE_ERR_PARAM;
874 }
875
876 if (input->flex_fltr)
f67539c2 877 ice_pkt_insert_u16(loc, input->flex_offset, input->flex_word);
9f95a23c
TL
878
879 return ICE_SUCCESS;
880}
881
f67539c2
TL
882/**
883 * ice_fdir_get_prgm_pkt - generate a training packet
884 * @input: flow director filter data structure
885 * @pkt: pointer to return filter packet
886 * @frag: generate a fragment packet
887 */
888enum ice_status
889ice_fdir_get_prgm_pkt(struct ice_fdir_fltr *input, u8 *pkt, bool frag)
890{
891 return ice_fdir_get_gen_prgm_pkt(NULL, input, pkt, frag, false);
892}
893
9f95a23c
TL
894/**
895 * ice_fdir_has_frag - does flow type have 2 ptypes
896 * @flow: flow ptype
897 *
898 * returns true is there is a fragment packet for this ptype
899 */
900bool ice_fdir_has_frag(enum ice_fltr_ptype flow)
901{
902 if (flow == ICE_FLTR_PTYPE_NONF_IPV4_OTHER)
903 return true;
904 else
905 return false;
906}
907
908/**
909 * ice_fdir_find_by_idx - find filter with idx
910 * @hw: pointer to hardware structure
911 * @fltr_idx: index to find.
912 *
913 * Returns pointer to filter if found or null
914 */
915struct ice_fdir_fltr *
916ice_fdir_find_fltr_by_idx(struct ice_hw *hw, u32 fltr_idx)
917{
f67539c2 918 struct ice_fdir_fltr *rule;
9f95a23c
TL
919
920 LIST_FOR_EACH_ENTRY(rule, &hw->fdir_list_head, ice_fdir_fltr,
921 fltr_node) {
922 /* rule ID found in the list */
923 if (fltr_idx == rule->fltr_id)
924 return rule;
925 if (fltr_idx < rule->fltr_id)
926 break;
927 }
928 return NULL;
929}
930
931/**
932 * ice_fdir_list_add_fltr - add a new node to the flow director filter list
933 * @hw: hardware structure
934 * @fltr: filter node to add to structure
935 */
936void ice_fdir_list_add_fltr(struct ice_hw *hw, struct ice_fdir_fltr *fltr)
937{
938 struct ice_fdir_fltr *rule, *parent = NULL;
939
940 LIST_FOR_EACH_ENTRY(rule, &hw->fdir_list_head, ice_fdir_fltr,
941 fltr_node) {
942 /* rule ID found or pass its spot in the list */
943 if (rule->fltr_id >= fltr->fltr_id)
944 break;
945 parent = rule;
946 }
947
948 if (parent)
949 LIST_ADD_AFTER(&fltr->fltr_node, &parent->fltr_node);
950 else
951 LIST_ADD(&fltr->fltr_node, &hw->fdir_list_head);
952}
953
954/**
955 * ice_fdir_update_cntrs - increment / decrement filter counter
956 * @hw: pointer to hardware structure
957 * @flow: filter flow type
f67539c2 958 * @acl_fltr: true indicates an ACL filter
9f95a23c
TL
959 * @add: true implies filters added
960 */
961void
f67539c2
TL
962ice_fdir_update_cntrs(struct ice_hw *hw, enum ice_fltr_ptype flow,
963 bool acl_fltr, bool add)
9f95a23c
TL
964{
965 int incr;
966
f67539c2 967 incr = add ? 1 : -1;
9f95a23c 968 hw->fdir_active_fltr += incr;
f67539c2 969 if (flow == ICE_FLTR_PTYPE_NONF_NONE || flow >= ICE_FLTR_PTYPE_MAX) {
9f95a23c 970 ice_debug(hw, ICE_DBG_SW, "Unknown filter type %d\n", flow);
f67539c2
TL
971 } else {
972 if (acl_fltr)
973 hw->acl_fltr_cnt[flow] += incr;
974 else
975 hw->fdir_fltr_cnt[flow] += incr;
976 }
9f95a23c
TL
977}
978
979/**
980 * ice_cmp_ipv6_addr - compare 2 IP v6 addresses
981 * @a: IP v6 address
982 * @b: IP v6 address
983 *
984 * Returns 0 on equal, returns non-0 if different
985 */
986static int ice_cmp_ipv6_addr(__be32 *a, __be32 *b)
987{
988 return memcmp(a, b, 4 * sizeof(__be32));
989}
990
991/**
f67539c2 992 * ice_fdir_comp_rules - compare 2 filters
9f95a23c
TL
993 * @a: a Flow Director filter data structure
994 * @b: a Flow Director filter data structure
995 * @v6: bool true if v6 filter
996 *
997 * Returns true if the filters match
998 */
999static bool
1000ice_fdir_comp_rules(struct ice_fdir_fltr *a, struct ice_fdir_fltr *b, bool v6)
1001{
1002 enum ice_fltr_ptype flow_type = a->flow_type;
1003
1004 /* The calling function already checks that the two filters have the
1005 * same flow_type.
1006 */
1007 if (!v6) {
1008 if (flow_type == ICE_FLTR_PTYPE_NONF_IPV4_TCP ||
1009 flow_type == ICE_FLTR_PTYPE_NONF_IPV4_UDP ||
1010 flow_type == ICE_FLTR_PTYPE_NONF_IPV4_SCTP) {
1011 if (a->ip.v4.dst_ip == b->ip.v4.dst_ip &&
1012 a->ip.v4.src_ip == b->ip.v4.src_ip &&
1013 a->ip.v4.dst_port == b->ip.v4.dst_port &&
1014 a->ip.v4.src_port == b->ip.v4.src_port)
1015 return true;
1016 } else if (flow_type == ICE_FLTR_PTYPE_NONF_IPV4_OTHER) {
1017 if (a->ip.v4.dst_ip == b->ip.v4.dst_ip &&
1018 a->ip.v4.src_ip == b->ip.v4.src_ip &&
1019 a->ip.v4.l4_header == b->ip.v4.l4_header &&
1020 a->ip.v4.proto == b->ip.v4.proto &&
1021 a->ip.v4.ip_ver == b->ip.v4.ip_ver &&
1022 a->ip.v4.tos == b->ip.v4.tos)
1023 return true;
1024 }
1025 } else {
1026 if (flow_type == ICE_FLTR_PTYPE_NONF_IPV6_UDP ||
1027 flow_type == ICE_FLTR_PTYPE_NONF_IPV6_TCP ||
1028 flow_type == ICE_FLTR_PTYPE_NONF_IPV6_SCTP) {
1029 if (a->ip.v6.dst_port == b->ip.v6.dst_port &&
1030 a->ip.v6.src_port == b->ip.v6.src_port &&
1031 !ice_cmp_ipv6_addr(a->ip.v6.dst_ip,
1032 b->ip.v6.dst_ip) &&
1033 !ice_cmp_ipv6_addr(a->ip.v6.src_ip,
1034 b->ip.v6.src_ip))
1035 return true;
1036 } else if (flow_type == ICE_FLTR_PTYPE_NONF_IPV6_OTHER) {
1037 if (a->ip.v6.dst_port == b->ip.v6.dst_port &&
1038 a->ip.v6.src_port == b->ip.v6.src_port)
1039 return true;
1040 }
1041 }
1042
1043 return false;
1044}
1045
1046/**
1047 * ice_fdir_is_dup_fltr - test if filter is already in list for PF
1048 * @hw: hardware data structure
1049 * @input: Flow Director filter data structure
1050 *
1051 * Returns true if the filter is found in the list
1052 */
1053bool ice_fdir_is_dup_fltr(struct ice_hw *hw, struct ice_fdir_fltr *input)
1054{
9f95a23c
TL
1055 struct ice_fdir_fltr *rule;
1056 bool ret = false;
1057
9f95a23c
TL
1058 LIST_FOR_EACH_ENTRY(rule, &hw->fdir_list_head, ice_fdir_fltr,
1059 fltr_node) {
f67539c2
TL
1060 enum ice_fltr_ptype flow_type;
1061
1062 if (rule->flow_type != input->flow_type)
1063 continue;
1064
1065 flow_type = input->flow_type;
1066 if (flow_type == ICE_FLTR_PTYPE_NONF_IPV4_TCP ||
1067 flow_type == ICE_FLTR_PTYPE_NONF_IPV4_UDP ||
1068 flow_type == ICE_FLTR_PTYPE_NONF_IPV4_SCTP ||
1069 flow_type == ICE_FLTR_PTYPE_NONF_IPV4_OTHER)
1070 ret = ice_fdir_comp_rules(rule, input, false);
1071 else
1072 ret = ice_fdir_comp_rules(rule, input, true);
1073 if (ret) {
1074 if (rule->fltr_id == input->fltr_id &&
1075 rule->q_index != input->q_index)
1076 ret = false;
9f95a23c 1077 else
9f95a23c
TL
1078 break;
1079 }
1080 }
1081
1082 return ret;
1083}
1084
1085/**
1086 * ice_clear_vsi_fd_table - admin command to clear FD table for a VSI
1087 * @hw: hardware data structure
1088 * @vsi_num: vsi_num (HW VSI num)
1089 *
1090 * Clears FD table entries by issuing admin command (direct, 0x0B06)
1091 * Must to pass valid vsi_num as returned by "AddVSI".
1092 */
1093enum ice_status ice_clear_vsi_fd_table(struct ice_hw *hw, u16 vsi_num)
1094{
1095 struct ice_aqc_clear_fd_table *cmd;
1096 struct ice_aq_desc desc;
1097
1098 cmd = &desc.params.clear_fd_table;
1099 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_clear_fd_table);
1100 cmd->clear_type = CL_FD_VM_VF_TYPE_VSI_IDX;
1101
1102 cmd->vsi_index = CPU_TO_LE16(vsi_num);
1103 return ice_aq_send_cmd(hw, &desc, NULL, 0, NULL);
1104}
1105
1106/**
1107 * ice_clear_pf_fd_table - admin command to clear FD table for PF
1108 * @hw: hardware data structure
1109 *
1110 * Clears FD table entries for a PF by issuing admin command (direct, 0x0B06)
1111 */
1112enum ice_status ice_clear_pf_fd_table(struct ice_hw *hw)
1113{
1114 struct ice_aqc_clear_fd_table *cmd;
1115 struct ice_aq_desc desc;
1116
1117 cmd = &desc.params.clear_fd_table;
1118 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_clear_fd_table);
1119 cmd->clear_type = CL_FD_VM_VF_TYPE_PF_IDX;
1120 /* vsi_index must be 0 to clear FD table for a PF */
1121 cmd->vsi_index = CPU_TO_LE16(0);
1122
1123 return ice_aq_send_cmd(hw, &desc, NULL, 0, NULL);
1124}