1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (C) 2018-2020, Intel Corporation. */
3
4 #include "ice_common.h"
5
6 /* These are training packet headers used to program flow director filters. */
7 static const u8 ice_fdir_eth_pkt[22];
8
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_ipv4_l2tpv3_pkt[] = {
106 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
107 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00,
108 0x00, 0x14, 0x00, 0x00, 0x40, 0x00, 0x40, 0x73,
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,
112 };
113
114 static const u8 ice_fdir_ipv6_l2tpv3_pkt[] = {
115 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
116 0x00, 0x00, 0x00, 0x00, 0x86, 0xDD, 0x60, 0x00,
117 0x00, 0x00, 0x00, 0x00, 0x73, 0x40, 0x00, 0x00,
118 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
119 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
120 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
121 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
122 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
123 0x00, 0x00,
124 };
125
126 static const u8 ice_fdir_ipv4_esp_pkt[] = {
127 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
128 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00,
129 0x00, 0x14, 0x00, 0x00, 0x40, 0x00, 0x40, 0x32,
130 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
131 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
132 0x00, 0x00
133 };
134
135 static const u8 ice_fdir_ipv6_esp_pkt[] = {
136 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
137 0x00, 0x00, 0x00, 0x00, 0x86, 0xDD, 0x60, 0x00,
138 0x00, 0x00, 0x00, 0x00, 0x32, 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,
144 };
145
146 static const u8 ice_fdir_ipv4_ah_pkt[] = {
147 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
148 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00,
149 0x00, 0x14, 0x00, 0x00, 0x40, 0x00, 0x40, 0x33,
150 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
151 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
152 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
153 0x00, 0x00
154 };
155
156 static const u8 ice_fdir_ipv6_ah_pkt[] = {
157 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
158 0x00, 0x00, 0x00, 0x00, 0x86, 0xDD, 0x60, 0x00,
159 0x00, 0x00, 0x00, 0x00, 0x33, 0x40, 0x00, 0x00,
160 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
161 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
162 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
163 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
164 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
165 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
166 };
167
168 static const u8 ice_fdir_ipv4_nat_t_esp_pkt[] = {
169 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
170 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00,
171 0x00, 0x1C, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11,
172 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
173 0x00, 0x00, 0x00, 0x00, 0x11, 0x94, 0x00, 0x00,
174 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
175 0x00, 0x00,
176 };
177
178 static const u8 ice_fdir_ipv6_nat_t_esp_pkt[] = {
179 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
180 0x00, 0x00, 0x00, 0x00, 0x86, 0xDD, 0x60, 0x00,
181 0x00, 0x00, 0x00, 0x08, 0x11, 0x40, 0x00, 0x00,
182 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
183 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
184 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
185 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
186 0x11, 0x94, 0x00, 0x00, 0x00, 0x08,
187 };
188
189 static const u8 ice_fdir_ipv4_pfcp_node_pkt[] = {
190 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
191 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00,
192 0x00, 0x2C, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11,
193 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
194 0x00, 0x00, 0x22, 0x65, 0x22, 0x65, 0x00, 0x00,
195 0x00, 0x00, 0x20, 0x00, 0x00, 0x10, 0x00, 0x00,
196 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
197 0x00, 0x00,
198 };
199
200 static const u8 ice_fdir_ipv4_pfcp_session_pkt[] = {
201 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
202 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00,
203 0x00, 0x2C, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11,
204 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
205 0x00, 0x00, 0x22, 0x65, 0x22, 0x65, 0x00, 0x00,
206 0x00, 0x00, 0x21, 0x00, 0x00, 0x10, 0x00, 0x00,
207 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
208 0x00, 0x00,
209 };
210
211 static const u8 ice_fdir_ipv6_pfcp_node_pkt[] = {
212 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
213 0x00, 0x00, 0x00, 0x00, 0x86, 0xDD, 0x60, 0x00,
214 0x00, 0x00, 0x00, 0x18, 0x11, 0x40, 0x00, 0x00,
215 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
216 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
217 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
218 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x65,
219 0x22, 0x65, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00,
220 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
221 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
222 };
223
224 static const u8 ice_fdir_ipv6_pfcp_session_pkt[] = {
225 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
226 0x00, 0x00, 0x00, 0x00, 0x86, 0xDD, 0x60, 0x00,
227 0x00, 0x00, 0x00, 0x18, 0x11, 0x40, 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, 0x22, 0x65,
232 0x22, 0x65, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00,
233 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
234 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
235 };
236
237 static const u8 ice_fdir_non_ip_l2_pkt[] = {
238 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
239 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
240 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
241 };
242
243 static const u8 ice_fdir_tcpv6_pkt[] = {
244 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
245 0x00, 0x00, 0x00, 0x00, 0x86, 0xDD, 0x60, 0x00,
246 0x00, 0x00, 0x00, 0x14, 0x06, 0x40, 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,
251 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
252 0x00, 0x00, 0x50, 0x00, 0x20, 0x00, 0x00, 0x00,
253 0x00, 0x00,
254 };
255
256 static const u8 ice_fdir_udpv6_pkt[] = {
257 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
258 0x00, 0x00, 0x00, 0x00, 0x86, 0xDD, 0x60, 0x00,
259 0x00, 0x00, 0x00, 0x08, 0x11, 0x40, 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, 0x00, 0x00, 0x00, 0x00,
263 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
264 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
265 };
266
267 static const u8 ice_fdir_sctpv6_pkt[] = {
268 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
269 0x00, 0x00, 0x00, 0x00, 0x86, 0xDD, 0x60, 0x00,
270 0x00, 0x00, 0x00, 0x0C, 0x84, 0x40, 0x00, 0x00,
271 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
272 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
273 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
274 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
275 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
276 0x00, 0x00,
277 };
278
279 static const u8 ice_fdir_ipv6_pkt[] = {
280 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
281 0x00, 0x00, 0x00, 0x00, 0x86, 0xDD, 0x60, 0x00,
282 0x00, 0x00, 0x00, 0x00, 0x3B, 0x40, 0x00, 0x00,
283 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
284 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
285 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
286 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
287 };
288
289 static const u8 ice_fdir_tcp4_tun_pkt[] = {
290 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
291 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00,
292 0x00, 0x5a, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11,
293 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
294 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
295 0x00, 0x00, 0x04, 0x00, 0x00, 0x03, 0x00, 0x00,
296 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
297 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
298 0x45, 0x00, 0x00, 0x28, 0x00, 0x00, 0x40, 0x00,
299 0x40, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
300 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
301 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
302 0x50, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00,
303 };
304
305 static const u8 ice_fdir_udp4_tun_pkt[] = {
306 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
307 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00,
308 0x00, 0x4e, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11,
309 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
310 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
311 0x00, 0x00, 0x04, 0x00, 0x00, 0x03, 0x00, 0x00,
312 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
313 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
314 0x45, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x40, 0x00,
315 0x40, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
316 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
317 0x00, 0x00, 0x00, 0x00,
318 };
319
320 static const u8 ice_fdir_sctp4_tun_pkt[] = {
321 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
322 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00,
323 0x00, 0x52, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11,
324 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
325 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
326 0x00, 0x00, 0x04, 0x00, 0x00, 0x03, 0x00, 0x00,
327 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
328 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
329 0x45, 0x00, 0x00, 0x20, 0x00, 0x01, 0x00, 0x00,
330 0x40, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
331 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
332 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
333 };
334
335 static const u8 ice_fdir_ip4_tun_pkt[] = {
336 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
337 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00,
338 0x00, 0x46, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11,
339 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
340 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
341 0x00, 0x00, 0x04, 0x00, 0x00, 0x03, 0x00, 0x00,
342 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
343 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
344 0x45, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00,
345 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
346 0x00, 0x00, 0x00, 0x00,
347 };
348
349 static const u8 ice_fdir_tcp6_tun_pkt[] = {
350 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
351 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00,
352 0x00, 0x6e, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11,
353 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
354 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
355 0x00, 0x00, 0x04, 0x00, 0x00, 0x03, 0x00, 0x00,
356 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
357 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0xdd,
358 0x60, 0x00, 0x00, 0x00, 0x00, 0x14, 0x06, 0x40,
359 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
360 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
361 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
362 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
363 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
364 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x20, 0x00,
365 0x00, 0x00, 0x00, 0x00,
366 };
367
368 static const u8 ice_fdir_udp6_tun_pkt[] = {
369 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
370 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00,
371 0x00, 0x62, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11,
372 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
373 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
374 0x00, 0x00, 0x04, 0x00, 0x00, 0x03, 0x00, 0x00,
375 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
376 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0xdd,
377 0x60, 0x00, 0x00, 0x00, 0x00, 0x08, 0x11, 0x40,
378 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
379 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
380 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
381 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
382 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
383 };
384
385 static const u8 ice_fdir_sctp6_tun_pkt[] = {
386 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
387 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00,
388 0x00, 0x66, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11,
389 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
390 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
391 0x00, 0x00, 0x04, 0x00, 0x00, 0x03, 0x00, 0x00,
392 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
393 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0xdd,
394 0x60, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x84, 0x40,
395 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
396 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
397 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
398 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
399 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
400 0x00, 0x00, 0x00, 0x00,
401 };
402
403 static const u8 ice_fdir_ip6_tun_pkt[] = {
404 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
405 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00,
406 0x00, 0x5a, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11,
407 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
408 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
409 0x00, 0x00, 0x04, 0x00, 0x00, 0x03, 0x00, 0x00,
410 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
411 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0xdd,
412 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3b, 0x40,
413 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
414 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
415 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
416 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
417 };
418
419 /* Flow Director no-op training packet table */
420 static const struct ice_fdir_base_pkt ice_fdir_pkt[] = {
421 {
422 ICE_FLTR_PTYPE_NONF_ETH,
423 sizeof(ice_fdir_eth_pkt), ice_fdir_eth_pkt,
424 sizeof(ice_fdir_eth_pkt), ice_fdir_eth_pkt,
425 },
426 {
427 ICE_FLTR_PTYPE_NONF_IPV4_TCP,
428 sizeof(ice_fdir_tcpv4_pkt), ice_fdir_tcpv4_pkt,
429 sizeof(ice_fdir_tcp4_tun_pkt), ice_fdir_tcp4_tun_pkt,
430 },
431 {
432 ICE_FLTR_PTYPE_NONF_IPV4_UDP,
433 sizeof(ice_fdir_udpv4_pkt), ice_fdir_udpv4_pkt,
434 sizeof(ice_fdir_udp4_tun_pkt), ice_fdir_udp4_tun_pkt,
435 },
436 {
437 ICE_FLTR_PTYPE_NONF_IPV4_SCTP,
438 sizeof(ice_fdir_sctpv4_pkt), ice_fdir_sctpv4_pkt,
439 sizeof(ice_fdir_sctp4_tun_pkt), ice_fdir_sctp4_tun_pkt,
440 },
441 {
442 ICE_FLTR_PTYPE_NONF_IPV4_OTHER,
443 sizeof(ice_fdir_ipv4_pkt), ice_fdir_ipv4_pkt,
444 sizeof(ice_fdir_ip4_tun_pkt), ice_fdir_ip4_tun_pkt,
445 },
446 {
447 ICE_FLTR_PTYPE_NONF_IPV4_GTPU_IPV4_UDP,
448 sizeof(ice_fdir_udp4_gtpu4_pkt),
449 ice_fdir_udp4_gtpu4_pkt,
450 sizeof(ice_fdir_udp4_gtpu4_pkt),
451 ice_fdir_udp4_gtpu4_pkt,
452 },
453 {
454 ICE_FLTR_PTYPE_NONF_IPV4_GTPU_IPV4_TCP,
455 sizeof(ice_fdir_tcp4_gtpu4_pkt),
456 ice_fdir_tcp4_gtpu4_pkt,
457 sizeof(ice_fdir_tcp4_gtpu4_pkt),
458 ice_fdir_tcp4_gtpu4_pkt,
459 },
460 {
461 ICE_FLTR_PTYPE_NONF_IPV4_GTPU_IPV4_ICMP,
462 sizeof(ice_fdir_icmp4_gtpu4_pkt),
463 ice_fdir_icmp4_gtpu4_pkt,
464 sizeof(ice_fdir_icmp4_gtpu4_pkt),
465 ice_fdir_icmp4_gtpu4_pkt,
466 },
467 {
468 ICE_FLTR_PTYPE_NONF_IPV4_GTPU_IPV4_OTHER,
469 sizeof(ice_fdir_ipv4_gtpu4_pkt),
470 ice_fdir_ipv4_gtpu4_pkt,
471 sizeof(ice_fdir_ipv4_gtpu4_pkt),
472 ice_fdir_ipv4_gtpu4_pkt,
473 },
474 {
475 ICE_FLTR_PTYPE_NONF_IPV4_L2TPV3,
476 sizeof(ice_fdir_ipv4_l2tpv3_pkt), ice_fdir_ipv4_l2tpv3_pkt,
477 sizeof(ice_fdir_ipv4_l2tpv3_pkt), ice_fdir_ipv4_l2tpv3_pkt,
478 },
479 {
480 ICE_FLTR_PTYPE_NONF_IPV6_L2TPV3,
481 sizeof(ice_fdir_ipv6_l2tpv3_pkt), ice_fdir_ipv6_l2tpv3_pkt,
482 sizeof(ice_fdir_ipv6_l2tpv3_pkt), ice_fdir_ipv6_l2tpv3_pkt,
483 },
484 {
485 ICE_FLTR_PTYPE_NONF_IPV4_ESP,
486 sizeof(ice_fdir_ipv4_esp_pkt), ice_fdir_ipv4_esp_pkt,
487 sizeof(ice_fdir_ipv4_esp_pkt), ice_fdir_ipv4_esp_pkt,
488 },
489 {
490 ICE_FLTR_PTYPE_NONF_IPV6_ESP,
491 sizeof(ice_fdir_ipv6_esp_pkt), ice_fdir_ipv6_esp_pkt,
492 sizeof(ice_fdir_ipv6_esp_pkt), ice_fdir_ipv6_esp_pkt,
493 },
494 {
495 ICE_FLTR_PTYPE_NONF_IPV4_AH,
496 sizeof(ice_fdir_ipv4_ah_pkt), ice_fdir_ipv4_ah_pkt,
497 sizeof(ice_fdir_ipv4_ah_pkt), ice_fdir_ipv4_ah_pkt,
498 },
499 {
500 ICE_FLTR_PTYPE_NONF_IPV6_AH,
501 sizeof(ice_fdir_ipv6_ah_pkt), ice_fdir_ipv6_ah_pkt,
502 sizeof(ice_fdir_ipv6_ah_pkt), ice_fdir_ipv6_ah_pkt,
503 },
504 {
505 ICE_FLTR_PTYPE_NONF_IPV4_NAT_T_ESP,
506 sizeof(ice_fdir_ipv4_nat_t_esp_pkt),
507 ice_fdir_ipv4_nat_t_esp_pkt,
508 sizeof(ice_fdir_ipv4_nat_t_esp_pkt),
509 ice_fdir_ipv4_nat_t_esp_pkt,
510 },
511 {
512 ICE_FLTR_PTYPE_NONF_IPV6_NAT_T_ESP,
513 sizeof(ice_fdir_ipv6_nat_t_esp_pkt),
514 ice_fdir_ipv6_nat_t_esp_pkt,
515 sizeof(ice_fdir_ipv6_nat_t_esp_pkt),
516 ice_fdir_ipv6_nat_t_esp_pkt,
517 },
518 {
519 ICE_FLTR_PTYPE_NONF_IPV4_PFCP_NODE,
520 sizeof(ice_fdir_ipv4_pfcp_node_pkt),
521 ice_fdir_ipv4_pfcp_node_pkt,
522 sizeof(ice_fdir_ipv4_pfcp_node_pkt),
523 ice_fdir_ipv4_pfcp_node_pkt,
524 },
525 {
526 ICE_FLTR_PTYPE_NONF_IPV4_PFCP_SESSION,
527 sizeof(ice_fdir_ipv4_pfcp_session_pkt),
528 ice_fdir_ipv4_pfcp_session_pkt,
529 sizeof(ice_fdir_ipv4_pfcp_session_pkt),
530 ice_fdir_ipv4_pfcp_session_pkt,
531 },
532 {
533 ICE_FLTR_PTYPE_NONF_IPV6_PFCP_NODE,
534 sizeof(ice_fdir_ipv6_pfcp_node_pkt),
535 ice_fdir_ipv6_pfcp_node_pkt,
536 sizeof(ice_fdir_ipv6_pfcp_node_pkt),
537 ice_fdir_ipv6_pfcp_node_pkt,
538 },
539 {
540 ICE_FLTR_PTYPE_NONF_IPV6_PFCP_SESSION,
541 sizeof(ice_fdir_ipv6_pfcp_session_pkt),
542 ice_fdir_ipv6_pfcp_session_pkt,
543 sizeof(ice_fdir_ipv6_pfcp_session_pkt),
544 ice_fdir_ipv6_pfcp_session_pkt,
545 },
546 {
547 ICE_FLTR_PTYPE_NON_IP_L2,
548 sizeof(ice_fdir_non_ip_l2_pkt), ice_fdir_non_ip_l2_pkt,
549 sizeof(ice_fdir_non_ip_l2_pkt), ice_fdir_non_ip_l2_pkt,
550 },
551 {
552 ICE_FLTR_PTYPE_NONF_IPV6_TCP,
553 sizeof(ice_fdir_tcpv6_pkt), ice_fdir_tcpv6_pkt,
554 sizeof(ice_fdir_tcp6_tun_pkt), ice_fdir_tcp6_tun_pkt,
555 },
556 {
557 ICE_FLTR_PTYPE_NONF_IPV6_UDP,
558 sizeof(ice_fdir_udpv6_pkt), ice_fdir_udpv6_pkt,
559 sizeof(ice_fdir_udp6_tun_pkt), ice_fdir_udp6_tun_pkt,
560 },
561 {
562 ICE_FLTR_PTYPE_NONF_IPV6_SCTP,
563 sizeof(ice_fdir_sctpv6_pkt), ice_fdir_sctpv6_pkt,
564 sizeof(ice_fdir_sctp6_tun_pkt), ice_fdir_sctp6_tun_pkt,
565 },
566 {
567 ICE_FLTR_PTYPE_NONF_IPV6_OTHER,
568 sizeof(ice_fdir_ipv6_pkt), ice_fdir_ipv6_pkt,
569 sizeof(ice_fdir_ip6_tun_pkt), ice_fdir_ip6_tun_pkt,
570 },
571 };
572
573 #define ICE_FDIR_NUM_PKT ARRAY_SIZE(ice_fdir_pkt)
574
575 /**
576 * ice_set_dflt_val_fd_desc
577 * @fd_fltr_ctx: pointer to fd filter descriptor
578 */
ice_set_dflt_val_fd_desc(struct ice_fd_fltr_desc_ctx * fd_fltr_ctx)579 static void ice_set_dflt_val_fd_desc(struct ice_fd_fltr_desc_ctx *fd_fltr_ctx)
580 {
581 fd_fltr_ctx->comp_q = ICE_FXD_FLTR_QW0_COMP_Q_ZERO;
582 fd_fltr_ctx->comp_report = ICE_FXD_FLTR_QW0_COMP_REPORT_SW_FAIL;
583 fd_fltr_ctx->fd_space = ICE_FXD_FLTR_QW0_FD_SPACE_GUAR_BEST;
584 fd_fltr_ctx->cnt_ena = ICE_FXD_FLTR_QW0_STAT_ENA_PKTS;
585 fd_fltr_ctx->evict_ena = ICE_FXD_FLTR_QW0_EVICT_ENA_TRUE;
586 fd_fltr_ctx->toq = ICE_FXD_FLTR_QW0_TO_Q_EQUALS_QINDEX;
587 fd_fltr_ctx->toq_prio = ICE_FXD_FLTR_QW0_TO_Q_PRIO1;
588 fd_fltr_ctx->dpu_recipe = ICE_FXD_FLTR_QW0_DPU_RECIPE_DFLT;
589 fd_fltr_ctx->drop = ICE_FXD_FLTR_QW0_DROP_NO;
590 fd_fltr_ctx->flex_prio = ICE_FXD_FLTR_QW0_FLEX_PRI_NONE;
591 fd_fltr_ctx->flex_mdid = ICE_FXD_FLTR_QW0_FLEX_MDID0;
592 fd_fltr_ctx->flex_val = ICE_FXD_FLTR_QW0_FLEX_VAL0;
593 fd_fltr_ctx->dtype = ICE_TX_DESC_DTYPE_FLTR_PROG;
594 fd_fltr_ctx->desc_prof_prio = ICE_FXD_FLTR_QW1_PROF_PRIO_ZERO;
595 fd_fltr_ctx->desc_prof = ICE_FXD_FLTR_QW1_PROF_ZERO;
596 fd_fltr_ctx->swap = ICE_FXD_FLTR_QW1_SWAP_SET;
597 fd_fltr_ctx->fdid_prio = ICE_FXD_FLTR_QW1_FDID_PRI_ONE;
598 fd_fltr_ctx->fdid_mdid = ICE_FXD_FLTR_QW1_FDID_MDID_FD;
599 fd_fltr_ctx->fdid = ICE_FXD_FLTR_QW1_FDID_ZERO;
600 }
601
602 /**
603 * ice_set_fd_desc_val
604 * @ctx: pointer to fd filter descriptor context
605 * @fdir_desc: populated with fd filter descriptor values
606 */
607 static void
ice_set_fd_desc_val(struct ice_fd_fltr_desc_ctx * ctx,struct ice_fltr_desc * fdir_desc)608 ice_set_fd_desc_val(struct ice_fd_fltr_desc_ctx *ctx,
609 struct ice_fltr_desc *fdir_desc)
610 {
611 u64 qword;
612
613 /* prep QW0 of FD filter programming desc */
614 qword = FIELD_PREP(ICE_FXD_FLTR_QW0_QINDEX_M, ctx->qindex);
615 qword |= FIELD_PREP(ICE_FXD_FLTR_QW0_COMP_Q_M, ctx->comp_q);
616 qword |= FIELD_PREP(ICE_FXD_FLTR_QW0_COMP_REPORT_M, ctx->comp_report);
617 qword |= FIELD_PREP(ICE_FXD_FLTR_QW0_FD_SPACE_M, ctx->fd_space);
618 qword |= FIELD_PREP(ICE_FXD_FLTR_QW0_STAT_CNT_M, ctx->cnt_index);
619 qword |= FIELD_PREP(ICE_FXD_FLTR_QW0_STAT_ENA_M, ctx->cnt_ena);
620 qword |= FIELD_PREP(ICE_FXD_FLTR_QW0_EVICT_ENA_M, ctx->evict_ena);
621 qword |= FIELD_PREP(ICE_FXD_FLTR_QW0_TO_Q_M, ctx->toq);
622 qword |= FIELD_PREP(ICE_FXD_FLTR_QW0_TO_Q_PRI_M, ctx->toq_prio);
623 qword |= FIELD_PREP(ICE_FXD_FLTR_QW0_DPU_RECIPE_M, ctx->dpu_recipe);
624 qword |= FIELD_PREP(ICE_FXD_FLTR_QW0_DROP_M, ctx->drop);
625 qword |= FIELD_PREP(ICE_FXD_FLTR_QW0_FLEX_PRI_M, ctx->flex_prio);
626 qword |= FIELD_PREP(ICE_FXD_FLTR_QW0_FLEX_MDID_M, ctx->flex_mdid);
627 qword |= FIELD_PREP(ICE_FXD_FLTR_QW0_FLEX_VAL_M, ctx->flex_val);
628 fdir_desc->qidx_compq_space_stat = cpu_to_le64(qword);
629
630 /* prep QW1 of FD filter programming desc */
631 qword = FIELD_PREP(ICE_FXD_FLTR_QW1_DTYPE_M, ctx->dtype);
632 qword |= FIELD_PREP(ICE_FXD_FLTR_QW1_PCMD_M, ctx->pcmd);
633 qword |= FIELD_PREP(ICE_FXD_FLTR_QW1_PROF_PRI_M, ctx->desc_prof_prio);
634 qword |= FIELD_PREP(ICE_FXD_FLTR_QW1_PROF_M, ctx->desc_prof);
635 qword |= FIELD_PREP(ICE_FXD_FLTR_QW1_FD_VSI_M, ctx->fd_vsi);
636 qword |= FIELD_PREP(ICE_FXD_FLTR_QW1_SWAP_M, ctx->swap);
637 qword |= FIELD_PREP(ICE_FXD_FLTR_QW1_FDID_PRI_M, ctx->fdid_prio);
638 qword |= FIELD_PREP(ICE_FXD_FLTR_QW1_FDID_MDID_M, ctx->fdid_mdid);
639 qword |= FIELD_PREP(ICE_FXD_FLTR_QW1_FDID_M, ctx->fdid);
640 fdir_desc->dtype_cmd_vsi_fdid = cpu_to_le64(qword);
641 }
642
643 /**
644 * ice_fdir_get_prgm_desc - set a fdir descriptor from a fdir filter struct
645 * @hw: pointer to the hardware structure
646 * @input: filter
647 * @fdesc: filter descriptor
648 * @add: if add is true, this is an add operation, false implies delete
649 */
650 void
ice_fdir_get_prgm_desc(struct ice_hw * hw,struct ice_fdir_fltr * input,struct ice_fltr_desc * fdesc,bool add)651 ice_fdir_get_prgm_desc(struct ice_hw *hw, struct ice_fdir_fltr *input,
652 struct ice_fltr_desc *fdesc, bool add)
653 {
654 struct ice_fd_fltr_desc_ctx fdir_fltr_ctx = { 0 };
655
656 /* set default context info */
657 ice_set_dflt_val_fd_desc(&fdir_fltr_ctx);
658
659 /* change sideband filtering values */
660 fdir_fltr_ctx.fdid = input->fltr_id;
661 if (input->dest_ctl == ICE_FLTR_PRGM_DESC_DEST_DROP_PKT) {
662 fdir_fltr_ctx.drop = ICE_FXD_FLTR_QW0_DROP_YES;
663 fdir_fltr_ctx.qindex = 0;
664 } else if (input->dest_ctl ==
665 ICE_FLTR_PRGM_DESC_DEST_DIRECT_PKT_OTHER) {
666 fdir_fltr_ctx.drop = ICE_FXD_FLTR_QW0_DROP_NO;
667 fdir_fltr_ctx.qindex = 0;
668 } else {
669 if (input->dest_ctl ==
670 ICE_FLTR_PRGM_DESC_DEST_DIRECT_PKT_QGROUP)
671 fdir_fltr_ctx.toq = input->q_region;
672 fdir_fltr_ctx.drop = ICE_FXD_FLTR_QW0_DROP_NO;
673 fdir_fltr_ctx.qindex = input->q_index;
674 }
675 fdir_fltr_ctx.cnt_ena = input->cnt_ena;
676 fdir_fltr_ctx.cnt_index = input->cnt_index;
677 fdir_fltr_ctx.fd_vsi = ice_get_hw_vsi_num(hw, input->dest_vsi);
678 fdir_fltr_ctx.evict_ena = ICE_FXD_FLTR_QW0_EVICT_ENA_FALSE;
679 if (input->dest_ctl == ICE_FLTR_PRGM_DESC_DEST_DIRECT_PKT_OTHER)
680 fdir_fltr_ctx.toq_prio = 0;
681 else
682 fdir_fltr_ctx.toq_prio = 3;
683 fdir_fltr_ctx.pcmd = add ? ICE_FXD_FLTR_QW1_PCMD_ADD :
684 ICE_FXD_FLTR_QW1_PCMD_REMOVE;
685 fdir_fltr_ctx.swap = ICE_FXD_FLTR_QW1_SWAP_NOT_SET;
686 fdir_fltr_ctx.comp_q = ICE_FXD_FLTR_QW0_COMP_Q_ZERO;
687 fdir_fltr_ctx.comp_report = input->comp_report;
688 fdir_fltr_ctx.fdid_prio = input->fdid_prio;
689 fdir_fltr_ctx.desc_prof = 1;
690 fdir_fltr_ctx.desc_prof_prio = 3;
691 ice_set_fd_desc_val(&fdir_fltr_ctx, fdesc);
692 }
693
694 /**
695 * ice_alloc_fd_res_cntr - obtain counter resource for FD type
696 * @hw: pointer to the hardware structure
697 * @cntr_id: returns counter index
698 */
ice_alloc_fd_res_cntr(struct ice_hw * hw,u16 * cntr_id)699 int ice_alloc_fd_res_cntr(struct ice_hw *hw, u16 *cntr_id)
700 {
701 return ice_alloc_res_cntr(hw, ICE_AQC_RES_TYPE_FDIR_COUNTER_BLOCK,
702 ICE_AQC_RES_TYPE_FLAG_DEDICATED, 1, cntr_id);
703 }
704
705 /**
706 * ice_free_fd_res_cntr - Free counter resource for FD type
707 * @hw: pointer to the hardware structure
708 * @cntr_id: counter index to be freed
709 */
ice_free_fd_res_cntr(struct ice_hw * hw,u16 cntr_id)710 int ice_free_fd_res_cntr(struct ice_hw *hw, u16 cntr_id)
711 {
712 return ice_free_res_cntr(hw, ICE_AQC_RES_TYPE_FDIR_COUNTER_BLOCK,
713 ICE_AQC_RES_TYPE_FLAG_DEDICATED, 1, cntr_id);
714 }
715
716 /**
717 * ice_alloc_fd_guar_item - allocate resource for FD guaranteed entries
718 * @hw: pointer to the hardware structure
719 * @cntr_id: returns counter index
720 * @num_fltr: number of filter entries to be allocated
721 */
ice_alloc_fd_guar_item(struct ice_hw * hw,u16 * cntr_id,u16 num_fltr)722 int ice_alloc_fd_guar_item(struct ice_hw *hw, u16 *cntr_id, u16 num_fltr)
723 {
724 return ice_alloc_res_cntr(hw, ICE_AQC_RES_TYPE_FDIR_GUARANTEED_ENTRIES,
725 ICE_AQC_RES_TYPE_FLAG_DEDICATED, num_fltr,
726 cntr_id);
727 }
728
729 /**
730 * ice_alloc_fd_shrd_item - allocate resource for flow director shared entries
731 * @hw: pointer to the hardware structure
732 * @cntr_id: returns counter index
733 * @num_fltr: number of filter entries to be allocated
734 */
ice_alloc_fd_shrd_item(struct ice_hw * hw,u16 * cntr_id,u16 num_fltr)735 int ice_alloc_fd_shrd_item(struct ice_hw *hw, u16 *cntr_id, u16 num_fltr)
736 {
737 return ice_alloc_res_cntr(hw, ICE_AQC_RES_TYPE_FDIR_SHARED_ENTRIES,
738 ICE_AQC_RES_TYPE_FLAG_DEDICATED, num_fltr,
739 cntr_id);
740 }
741
742 /**
743 * ice_get_fdir_cnt_all - get the number of Flow Director filters
744 * @hw: hardware data structure
745 *
746 * Returns the number of filters available on device
747 */
ice_get_fdir_cnt_all(struct ice_hw * hw)748 int ice_get_fdir_cnt_all(struct ice_hw *hw)
749 {
750 return hw->func_caps.fd_fltr_guar + hw->func_caps.fd_fltr_best_effort;
751 }
752
753 /**
754 * ice_pkt_insert_ipv6_addr - insert a be32 IPv6 address into a memory buffer
755 * @pkt: packet buffer
756 * @offset: offset into buffer
757 * @addr: IPv6 address to convert and insert into pkt at offset
758 */
ice_pkt_insert_ipv6_addr(u8 * pkt,int offset,__be32 * addr)759 static void ice_pkt_insert_ipv6_addr(u8 *pkt, int offset, __be32 *addr)
760 {
761 int idx;
762
763 for (idx = 0; idx < ICE_IPV6_ADDR_LEN_AS_U32; idx++)
764 memcpy(pkt + offset + idx * sizeof(*addr), &addr[idx],
765 sizeof(*addr));
766 }
767
768 /**
769 * ice_pkt_insert_u6_qfi - insert a u6 value QFI into a memory buffer for GTPU
770 * @pkt: packet buffer
771 * @offset: offset into buffer
772 * @data: 8 bit value to convert and insert into pkt at offset
773 *
774 * This function is designed for inserting QFI (6 bits) for GTPU.
775 */
ice_pkt_insert_u6_qfi(u8 * pkt,int offset,u8 data)776 static void ice_pkt_insert_u6_qfi(u8 *pkt, int offset, u8 data)
777 {
778 u8 ret;
779
780 ret = (data & 0x3F) + (*(pkt + offset) & 0xC0);
781 memcpy(pkt + offset, &ret, sizeof(ret));
782 }
783
784 /**
785 * ice_pkt_insert_u8 - insert a u8 value into a memory buffer.
786 * @pkt: packet buffer
787 * @offset: offset into buffer
788 * @data: 8 bit value to convert and insert into pkt at offset
789 */
ice_pkt_insert_u8(u8 * pkt,int offset,u8 data)790 static void ice_pkt_insert_u8(u8 *pkt, int offset, u8 data)
791 {
792 memcpy(pkt + offset, &data, sizeof(data));
793 }
794
795 /**
796 * ice_pkt_insert_u8_tc - insert a u8 value into a memory buffer for TC ipv6.
797 * @pkt: packet buffer
798 * @offset: offset into buffer
799 * @data: 8 bit value to convert and insert into pkt at offset
800 *
801 * This function is designed for inserting Traffic Class (TC) for IPv6,
802 * since that TC is not aligned in number of bytes. Here we split it out
803 * into two part and fill each byte with data copy from pkt, then insert
804 * the two bytes data one by one.
805 */
ice_pkt_insert_u8_tc(u8 * pkt,int offset,u8 data)806 static void ice_pkt_insert_u8_tc(u8 *pkt, int offset, u8 data)
807 {
808 u8 high, low;
809
810 high = (data >> 4) + (*(pkt + offset) & 0xF0);
811 memcpy(pkt + offset, &high, sizeof(high));
812
813 low = (*(pkt + offset + 1) & 0x0F) + ((data & 0x0F) << 4);
814 memcpy(pkt + offset + 1, &low, sizeof(low));
815 }
816
817 /**
818 * ice_pkt_insert_u16 - insert a be16 value into a memory buffer
819 * @pkt: packet buffer
820 * @offset: offset into buffer
821 * @data: 16 bit value to convert and insert into pkt at offset
822 */
ice_pkt_insert_u16(u8 * pkt,int offset,__be16 data)823 static void ice_pkt_insert_u16(u8 *pkt, int offset, __be16 data)
824 {
825 memcpy(pkt + offset, &data, sizeof(data));
826 }
827
828 /**
829 * ice_pkt_insert_u32 - insert a be32 value into a memory buffer
830 * @pkt: packet buffer
831 * @offset: offset into buffer
832 * @data: 32 bit value to convert and insert into pkt at offset
833 */
ice_pkt_insert_u32(u8 * pkt,int offset,__be32 data)834 static void ice_pkt_insert_u32(u8 *pkt, int offset, __be32 data)
835 {
836 memcpy(pkt + offset, &data, sizeof(data));
837 }
838
839 /**
840 * ice_pkt_insert_mac_addr - insert a MAC addr into a memory buffer.
841 * @pkt: packet buffer
842 * @addr: MAC address to convert and insert into pkt at offset
843 */
ice_pkt_insert_mac_addr(u8 * pkt,u8 * addr)844 static void ice_pkt_insert_mac_addr(u8 *pkt, u8 *addr)
845 {
846 ether_addr_copy(pkt, addr);
847 }
848
849 /**
850 * ice_fdir_get_gen_prgm_pkt - generate a training packet
851 * @hw: pointer to the hardware structure
852 * @input: flow director filter data structure
853 * @pkt: pointer to return filter packet
854 * @frag: generate a fragment packet
855 * @tun: true implies generate a tunnel packet
856 */
857 int
ice_fdir_get_gen_prgm_pkt(struct ice_hw * hw,struct ice_fdir_fltr * input,u8 * pkt,bool frag,bool tun)858 ice_fdir_get_gen_prgm_pkt(struct ice_hw *hw, struct ice_fdir_fltr *input,
859 u8 *pkt, bool frag, bool tun)
860 {
861 enum ice_fltr_ptype flow;
862 u16 tnl_port;
863 u8 *loc;
864 u16 idx;
865
866 if (input->flow_type == ICE_FLTR_PTYPE_NONF_IPV4_OTHER) {
867 switch (input->ip.v4.proto) {
868 case IPPROTO_TCP:
869 flow = ICE_FLTR_PTYPE_NONF_IPV4_TCP;
870 break;
871 case IPPROTO_UDP:
872 flow = ICE_FLTR_PTYPE_NONF_IPV4_UDP;
873 break;
874 case IPPROTO_SCTP:
875 flow = ICE_FLTR_PTYPE_NONF_IPV4_SCTP;
876 break;
877 default:
878 flow = ICE_FLTR_PTYPE_NONF_IPV4_OTHER;
879 break;
880 }
881 } else if (input->flow_type == ICE_FLTR_PTYPE_NONF_IPV6_OTHER) {
882 switch (input->ip.v6.proto) {
883 case IPPROTO_TCP:
884 flow = ICE_FLTR_PTYPE_NONF_IPV6_TCP;
885 break;
886 case IPPROTO_UDP:
887 flow = ICE_FLTR_PTYPE_NONF_IPV6_UDP;
888 break;
889 case IPPROTO_SCTP:
890 flow = ICE_FLTR_PTYPE_NONF_IPV6_SCTP;
891 break;
892 default:
893 flow = ICE_FLTR_PTYPE_NONF_IPV6_OTHER;
894 break;
895 }
896 } else {
897 flow = input->flow_type;
898 }
899
900 for (idx = 0; idx < ICE_FDIR_NUM_PKT; idx++)
901 if (ice_fdir_pkt[idx].flow == flow)
902 break;
903 if (idx == ICE_FDIR_NUM_PKT)
904 return -EINVAL;
905 if (!tun) {
906 memcpy(pkt, ice_fdir_pkt[idx].pkt, ice_fdir_pkt[idx].pkt_len);
907 loc = pkt;
908 } else {
909 if (!ice_get_open_tunnel_port(hw, &tnl_port, TNL_ALL))
910 return -ENOENT;
911 if (!ice_fdir_pkt[idx].tun_pkt)
912 return -EINVAL;
913 memcpy(pkt, ice_fdir_pkt[idx].tun_pkt,
914 ice_fdir_pkt[idx].tun_pkt_len);
915 ice_pkt_insert_u16(pkt, ICE_IPV4_UDP_DST_PORT_OFFSET,
916 htons(tnl_port));
917 loc = &pkt[ICE_FDIR_TUN_PKT_OFF];
918 }
919
920 /* Reverse the src and dst, since the HW expects them to be from Tx
921 * perspective. The input from user is from Rx filter perspective.
922 */
923 switch (flow) {
924 case ICE_FLTR_PTYPE_NONF_ETH:
925 ice_pkt_insert_mac_addr(loc, input->eth.h_dest);
926 ice_pkt_insert_mac_addr(loc + ETH_ALEN, input->eth.h_source);
927 if (input->ext_data.vlan_tag || input->ext_data.vlan_type) {
928 ice_pkt_insert_u16(loc, ICE_ETH_TYPE_F_OFFSET,
929 input->ext_data.vlan_type);
930 ice_pkt_insert_u16(loc, ICE_ETH_VLAN_TCI_OFFSET,
931 input->ext_data.vlan_tag);
932 ice_pkt_insert_u16(loc, ICE_ETH_TYPE_VLAN_OFFSET,
933 input->eth.h_proto);
934 } else {
935 ice_pkt_insert_u16(loc, ICE_ETH_TYPE_F_OFFSET,
936 input->eth.h_proto);
937 }
938 break;
939 case ICE_FLTR_PTYPE_NONF_IPV4_TCP:
940 ice_pkt_insert_u32(loc, ICE_IPV4_DST_ADDR_OFFSET,
941 input->ip.v4.src_ip);
942 ice_pkt_insert_u16(loc, ICE_IPV4_TCP_DST_PORT_OFFSET,
943 input->ip.v4.src_port);
944 ice_pkt_insert_u32(loc, ICE_IPV4_SRC_ADDR_OFFSET,
945 input->ip.v4.dst_ip);
946 ice_pkt_insert_u16(loc, ICE_IPV4_TCP_SRC_PORT_OFFSET,
947 input->ip.v4.dst_port);
948 ice_pkt_insert_u8(loc, ICE_IPV4_TOS_OFFSET, input->ip.v4.tos);
949 ice_pkt_insert_u8(loc, ICE_IPV4_TTL_OFFSET, input->ip.v4.ttl);
950 ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac);
951 if (frag)
952 loc[20] = ICE_FDIR_IPV4_PKT_FLAG_MF;
953 break;
954 case ICE_FLTR_PTYPE_NONF_IPV4_UDP:
955 ice_pkt_insert_u32(loc, ICE_IPV4_DST_ADDR_OFFSET,
956 input->ip.v4.src_ip);
957 ice_pkt_insert_u16(loc, ICE_IPV4_UDP_DST_PORT_OFFSET,
958 input->ip.v4.src_port);
959 ice_pkt_insert_u32(loc, ICE_IPV4_SRC_ADDR_OFFSET,
960 input->ip.v4.dst_ip);
961 ice_pkt_insert_u16(loc, ICE_IPV4_UDP_SRC_PORT_OFFSET,
962 input->ip.v4.dst_port);
963 ice_pkt_insert_u8(loc, ICE_IPV4_TOS_OFFSET, input->ip.v4.tos);
964 ice_pkt_insert_u8(loc, ICE_IPV4_TTL_OFFSET, input->ip.v4.ttl);
965 ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac);
966 ice_pkt_insert_mac_addr(loc + ETH_ALEN,
967 input->ext_data.src_mac);
968 break;
969 case ICE_FLTR_PTYPE_NONF_IPV4_SCTP:
970 ice_pkt_insert_u32(loc, ICE_IPV4_DST_ADDR_OFFSET,
971 input->ip.v4.src_ip);
972 ice_pkt_insert_u16(loc, ICE_IPV4_SCTP_DST_PORT_OFFSET,
973 input->ip.v4.src_port);
974 ice_pkt_insert_u32(loc, ICE_IPV4_SRC_ADDR_OFFSET,
975 input->ip.v4.dst_ip);
976 ice_pkt_insert_u16(loc, ICE_IPV4_SCTP_SRC_PORT_OFFSET,
977 input->ip.v4.dst_port);
978 ice_pkt_insert_u8(loc, ICE_IPV4_TOS_OFFSET, input->ip.v4.tos);
979 ice_pkt_insert_u8(loc, ICE_IPV4_TTL_OFFSET, input->ip.v4.ttl);
980 ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac);
981 break;
982 case ICE_FLTR_PTYPE_NONF_IPV4_OTHER:
983 ice_pkt_insert_u32(loc, ICE_IPV4_DST_ADDR_OFFSET,
984 input->ip.v4.src_ip);
985 ice_pkt_insert_u32(loc, ICE_IPV4_SRC_ADDR_OFFSET,
986 input->ip.v4.dst_ip);
987 ice_pkt_insert_u8(loc, ICE_IPV4_TOS_OFFSET, input->ip.v4.tos);
988 ice_pkt_insert_u8(loc, ICE_IPV4_TTL_OFFSET, input->ip.v4.ttl);
989 ice_pkt_insert_u8(loc, ICE_IPV4_PROTO_OFFSET,
990 input->ip.v4.proto);
991 ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac);
992 break;
993 case ICE_FLTR_PTYPE_NONF_IPV4_GTPU_IPV4_UDP:
994 case ICE_FLTR_PTYPE_NONF_IPV4_GTPU_IPV4_TCP:
995 case ICE_FLTR_PTYPE_NONF_IPV4_GTPU_IPV4_ICMP:
996 case ICE_FLTR_PTYPE_NONF_IPV4_GTPU_IPV4_OTHER:
997 ice_pkt_insert_u32(loc, ICE_IPV4_DST_ADDR_OFFSET,
998 input->ip.v4.src_ip);
999 ice_pkt_insert_u32(loc, ICE_IPV4_SRC_ADDR_OFFSET,
1000 input->ip.v4.dst_ip);
1001 ice_pkt_insert_u32(loc, ICE_IPV4_GTPU_TEID_OFFSET,
1002 input->gtpu_data.teid);
1003 ice_pkt_insert_u6_qfi(loc, ICE_IPV4_GTPU_QFI_OFFSET,
1004 input->gtpu_data.qfi);
1005 break;
1006 case ICE_FLTR_PTYPE_NONF_IPV4_L2TPV3:
1007 ice_pkt_insert_u32(loc, ICE_IPV4_L2TPV3_SESS_ID_OFFSET,
1008 input->l2tpv3_data.session_id);
1009 break;
1010 case ICE_FLTR_PTYPE_NONF_IPV6_L2TPV3:
1011 ice_pkt_insert_u32(loc, ICE_IPV6_L2TPV3_SESS_ID_OFFSET,
1012 input->l2tpv3_data.session_id);
1013 break;
1014 case ICE_FLTR_PTYPE_NONF_IPV4_ESP:
1015 ice_pkt_insert_u32(loc, ICE_IPV4_ESP_SPI_OFFSET,
1016 input->ip.v4.sec_parm_idx);
1017 break;
1018 case ICE_FLTR_PTYPE_NONF_IPV6_ESP:
1019 ice_pkt_insert_u32(loc, ICE_IPV6_ESP_SPI_OFFSET,
1020 input->ip.v6.sec_parm_idx);
1021 break;
1022 case ICE_FLTR_PTYPE_NONF_IPV4_AH:
1023 ice_pkt_insert_u32(loc, ICE_IPV4_AH_SPI_OFFSET,
1024 input->ip.v4.sec_parm_idx);
1025 break;
1026 case ICE_FLTR_PTYPE_NONF_IPV6_AH:
1027 ice_pkt_insert_u32(loc, ICE_IPV6_AH_SPI_OFFSET,
1028 input->ip.v6.sec_parm_idx);
1029 break;
1030 case ICE_FLTR_PTYPE_NONF_IPV4_NAT_T_ESP:
1031 ice_pkt_insert_u32(loc, ICE_IPV4_DST_ADDR_OFFSET,
1032 input->ip.v4.src_ip);
1033 ice_pkt_insert_u32(loc, ICE_IPV4_SRC_ADDR_OFFSET,
1034 input->ip.v4.dst_ip);
1035 ice_pkt_insert_u32(loc, ICE_IPV4_NAT_T_ESP_SPI_OFFSET,
1036 input->ip.v4.sec_parm_idx);
1037 break;
1038 case ICE_FLTR_PTYPE_NONF_IPV6_NAT_T_ESP:
1039 ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_DST_ADDR_OFFSET,
1040 input->ip.v6.src_ip);
1041 ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_SRC_ADDR_OFFSET,
1042 input->ip.v6.dst_ip);
1043 ice_pkt_insert_u32(loc, ICE_IPV6_NAT_T_ESP_SPI_OFFSET,
1044 input->ip.v6.sec_parm_idx);
1045 break;
1046 case ICE_FLTR_PTYPE_NONF_IPV4_PFCP_NODE:
1047 case ICE_FLTR_PTYPE_NONF_IPV4_PFCP_SESSION:
1048 ice_pkt_insert_u16(loc, ICE_IPV4_UDP_SRC_PORT_OFFSET,
1049 input->ip.v4.dst_port);
1050 break;
1051 case ICE_FLTR_PTYPE_NONF_IPV6_PFCP_NODE:
1052 case ICE_FLTR_PTYPE_NONF_IPV6_PFCP_SESSION:
1053 ice_pkt_insert_u16(loc, ICE_IPV6_UDP_SRC_PORT_OFFSET,
1054 input->ip.v6.dst_port);
1055 break;
1056 case ICE_FLTR_PTYPE_NON_IP_L2:
1057 ice_pkt_insert_u16(loc, ICE_MAC_ETHTYPE_OFFSET,
1058 input->ext_data.ether_type);
1059 break;
1060 case ICE_FLTR_PTYPE_NONF_IPV6_TCP:
1061 ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_DST_ADDR_OFFSET,
1062 input->ip.v6.src_ip);
1063 ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_SRC_ADDR_OFFSET,
1064 input->ip.v6.dst_ip);
1065 ice_pkt_insert_u16(loc, ICE_IPV6_TCP_DST_PORT_OFFSET,
1066 input->ip.v6.src_port);
1067 ice_pkt_insert_u16(loc, ICE_IPV6_TCP_SRC_PORT_OFFSET,
1068 input->ip.v6.dst_port);
1069 ice_pkt_insert_u8_tc(loc, ICE_IPV6_TC_OFFSET, input->ip.v6.tc);
1070 ice_pkt_insert_u8(loc, ICE_IPV6_HLIM_OFFSET, input->ip.v6.hlim);
1071 ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac);
1072 break;
1073 case ICE_FLTR_PTYPE_NONF_IPV6_UDP:
1074 ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_DST_ADDR_OFFSET,
1075 input->ip.v6.src_ip);
1076 ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_SRC_ADDR_OFFSET,
1077 input->ip.v6.dst_ip);
1078 ice_pkt_insert_u16(loc, ICE_IPV6_UDP_DST_PORT_OFFSET,
1079 input->ip.v6.src_port);
1080 ice_pkt_insert_u16(loc, ICE_IPV6_UDP_SRC_PORT_OFFSET,
1081 input->ip.v6.dst_port);
1082 ice_pkt_insert_u8_tc(loc, ICE_IPV6_TC_OFFSET, input->ip.v6.tc);
1083 ice_pkt_insert_u8(loc, ICE_IPV6_HLIM_OFFSET, input->ip.v6.hlim);
1084 ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac);
1085 break;
1086 case ICE_FLTR_PTYPE_NONF_IPV6_SCTP:
1087 ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_DST_ADDR_OFFSET,
1088 input->ip.v6.src_ip);
1089 ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_SRC_ADDR_OFFSET,
1090 input->ip.v6.dst_ip);
1091 ice_pkt_insert_u16(loc, ICE_IPV6_SCTP_DST_PORT_OFFSET,
1092 input->ip.v6.src_port);
1093 ice_pkt_insert_u16(loc, ICE_IPV6_SCTP_SRC_PORT_OFFSET,
1094 input->ip.v6.dst_port);
1095 ice_pkt_insert_u8_tc(loc, ICE_IPV6_TC_OFFSET, input->ip.v6.tc);
1096 ice_pkt_insert_u8(loc, ICE_IPV6_HLIM_OFFSET, input->ip.v6.hlim);
1097 ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac);
1098 break;
1099 case ICE_FLTR_PTYPE_NONF_IPV6_OTHER:
1100 ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_DST_ADDR_OFFSET,
1101 input->ip.v6.src_ip);
1102 ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_SRC_ADDR_OFFSET,
1103 input->ip.v6.dst_ip);
1104 ice_pkt_insert_u8_tc(loc, ICE_IPV6_TC_OFFSET, input->ip.v6.tc);
1105 ice_pkt_insert_u8(loc, ICE_IPV6_HLIM_OFFSET, input->ip.v6.hlim);
1106 ice_pkt_insert_u8(loc, ICE_IPV6_PROTO_OFFSET,
1107 input->ip.v6.proto);
1108 ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac);
1109 break;
1110 default:
1111 return -EINVAL;
1112 }
1113
1114 if (input->flex_fltr)
1115 ice_pkt_insert_u16(loc, input->flex_offset, input->flex_word);
1116
1117 return 0;
1118 }
1119
1120 /**
1121 * ice_fdir_has_frag - does flow type have 2 ptypes
1122 * @flow: flow ptype
1123 *
1124 * returns true is there is a fragment packet for this ptype
1125 */
ice_fdir_has_frag(enum ice_fltr_ptype flow)1126 bool ice_fdir_has_frag(enum ice_fltr_ptype flow)
1127 {
1128 if (flow == ICE_FLTR_PTYPE_NONF_IPV4_OTHER)
1129 return true;
1130 else
1131 return false;
1132 }
1133
1134 /**
1135 * ice_fdir_find_fltr_by_idx - find filter with idx
1136 * @hw: pointer to hardware structure
1137 * @fltr_idx: index to find.
1138 *
1139 * Returns pointer to filter if found or null
1140 */
1141 struct ice_fdir_fltr *
ice_fdir_find_fltr_by_idx(struct ice_hw * hw,u32 fltr_idx)1142 ice_fdir_find_fltr_by_idx(struct ice_hw *hw, u32 fltr_idx)
1143 {
1144 struct ice_fdir_fltr *rule;
1145
1146 list_for_each_entry(rule, &hw->fdir_list_head, fltr_node) {
1147 /* rule ID found in the list */
1148 if (fltr_idx == rule->fltr_id)
1149 return rule;
1150 if (fltr_idx < rule->fltr_id)
1151 break;
1152 }
1153 return NULL;
1154 }
1155
1156 /**
1157 * ice_fdir_list_add_fltr - add a new node to the flow director filter list
1158 * @hw: hardware structure
1159 * @fltr: filter node to add to structure
1160 */
ice_fdir_list_add_fltr(struct ice_hw * hw,struct ice_fdir_fltr * fltr)1161 void ice_fdir_list_add_fltr(struct ice_hw *hw, struct ice_fdir_fltr *fltr)
1162 {
1163 struct ice_fdir_fltr *rule, *parent = NULL;
1164
1165 list_for_each_entry(rule, &hw->fdir_list_head, fltr_node) {
1166 /* rule ID found or pass its spot in the list */
1167 if (rule->fltr_id >= fltr->fltr_id)
1168 break;
1169 parent = rule;
1170 }
1171
1172 if (parent)
1173 list_add(&fltr->fltr_node, &parent->fltr_node);
1174 else
1175 list_add(&fltr->fltr_node, &hw->fdir_list_head);
1176 }
1177
1178 /**
1179 * ice_fdir_update_cntrs - increment / decrement filter counter
1180 * @hw: pointer to hardware structure
1181 * @flow: filter flow type
1182 * @add: true implies filters added
1183 */
1184 void
ice_fdir_update_cntrs(struct ice_hw * hw,enum ice_fltr_ptype flow,bool add)1185 ice_fdir_update_cntrs(struct ice_hw *hw, enum ice_fltr_ptype flow, bool add)
1186 {
1187 int incr;
1188
1189 incr = add ? 1 : -1;
1190 hw->fdir_active_fltr += incr;
1191
1192 if (flow == ICE_FLTR_PTYPE_NONF_NONE || flow >= ICE_FLTR_PTYPE_MAX)
1193 ice_debug(hw, ICE_DBG_SW, "Unknown filter type %d\n", flow);
1194 else
1195 hw->fdir_fltr_cnt[flow] += incr;
1196 }
1197
1198 /**
1199 * ice_cmp_ipv6_addr - compare 2 IP v6 addresses
1200 * @a: IP v6 address
1201 * @b: IP v6 address
1202 *
1203 * Returns 0 on equal, returns non-0 if different
1204 */
ice_cmp_ipv6_addr(__be32 * a,__be32 * b)1205 static int ice_cmp_ipv6_addr(__be32 *a, __be32 *b)
1206 {
1207 return memcmp(a, b, 4 * sizeof(__be32));
1208 }
1209
1210 /**
1211 * ice_fdir_comp_rules - compare 2 filters
1212 * @a: a Flow Director filter data structure
1213 * @b: a Flow Director filter data structure
1214 *
1215 * Returns true if the filters match
1216 */
1217 static bool
ice_fdir_comp_rules(struct ice_fdir_fltr * a,struct ice_fdir_fltr * b)1218 ice_fdir_comp_rules(struct ice_fdir_fltr *a, struct ice_fdir_fltr *b)
1219 {
1220 enum ice_fltr_ptype flow_type = a->flow_type;
1221
1222 /* The calling function already checks that the two filters have the
1223 * same flow_type.
1224 */
1225 switch (flow_type) {
1226 case ICE_FLTR_PTYPE_NONF_ETH:
1227 if (!memcmp(&a->eth, &b->eth, sizeof(a->eth)))
1228 return true;
1229 break;
1230 case ICE_FLTR_PTYPE_NONF_IPV4_TCP:
1231 case ICE_FLTR_PTYPE_NONF_IPV4_UDP:
1232 case ICE_FLTR_PTYPE_NONF_IPV4_SCTP:
1233 if (a->ip.v4.dst_ip == b->ip.v4.dst_ip &&
1234 a->ip.v4.src_ip == b->ip.v4.src_ip &&
1235 a->ip.v4.dst_port == b->ip.v4.dst_port &&
1236 a->ip.v4.src_port == b->ip.v4.src_port)
1237 return true;
1238 break;
1239 case ICE_FLTR_PTYPE_NONF_IPV4_OTHER:
1240 if (a->ip.v4.dst_ip == b->ip.v4.dst_ip &&
1241 a->ip.v4.src_ip == b->ip.v4.src_ip &&
1242 a->ip.v4.l4_header == b->ip.v4.l4_header &&
1243 a->ip.v4.proto == b->ip.v4.proto &&
1244 a->ip.v4.ip_ver == b->ip.v4.ip_ver &&
1245 a->ip.v4.tos == b->ip.v4.tos)
1246 return true;
1247 break;
1248 case ICE_FLTR_PTYPE_NONF_IPV6_UDP:
1249 case ICE_FLTR_PTYPE_NONF_IPV6_TCP:
1250 case ICE_FLTR_PTYPE_NONF_IPV6_SCTP:
1251 if (a->ip.v6.dst_port == b->ip.v6.dst_port &&
1252 a->ip.v6.src_port == b->ip.v6.src_port &&
1253 !ice_cmp_ipv6_addr(a->ip.v6.dst_ip,
1254 b->ip.v6.dst_ip) &&
1255 !ice_cmp_ipv6_addr(a->ip.v6.src_ip,
1256 b->ip.v6.src_ip))
1257 return true;
1258 break;
1259 case ICE_FLTR_PTYPE_NONF_IPV6_OTHER:
1260 if (a->ip.v6.dst_port == b->ip.v6.dst_port &&
1261 a->ip.v6.src_port == b->ip.v6.src_port)
1262 return true;
1263 break;
1264 default:
1265 break;
1266 }
1267
1268 return false;
1269 }
1270
1271 /**
1272 * ice_fdir_is_dup_fltr - test if filter is already in list for PF
1273 * @hw: hardware data structure
1274 * @input: Flow Director filter data structure
1275 *
1276 * Returns true if the filter is found in the list
1277 */
ice_fdir_is_dup_fltr(struct ice_hw * hw,struct ice_fdir_fltr * input)1278 bool ice_fdir_is_dup_fltr(struct ice_hw *hw, struct ice_fdir_fltr *input)
1279 {
1280 struct ice_fdir_fltr *rule;
1281 bool ret = false;
1282
1283 list_for_each_entry(rule, &hw->fdir_list_head, fltr_node) {
1284 if (rule->flow_type != input->flow_type)
1285 continue;
1286
1287 ret = ice_fdir_comp_rules(rule, input);
1288 if (ret) {
1289 if (rule->fltr_id == input->fltr_id &&
1290 rule->q_index != input->q_index)
1291 ret = false;
1292 else
1293 break;
1294 }
1295 }
1296
1297 return ret;
1298 }
1299