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