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_eth_pkt[22];
8
9static const u8 ice_fdir_tcpv4_pkt[] = {
10 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00,
12 0x00, 0x28, 0x00, 0x01, 0x00, 0x00, 0x40, 0x06,
13 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
14 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
15 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00,
16 0x20, 0x00, 0x00, 0x00, 0x00, 0x00
17};
18
19static const u8 ice_fdir_udpv4_pkt[] = {
20 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
21 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00,
22 0x00, 0x1C, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11,
23 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
24 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
25 0x00, 0x00,
26};
27
28static const u8 ice_fdir_sctpv4_pkt[] = {
29 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
30 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00,
31 0x00, 0x20, 0x00, 0x00, 0x40, 0x00, 0x40, 0x84,
32 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
33 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
34 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
35};
36
37static const u8 ice_fdir_ipv4_pkt[] = {
38 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
39 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00,
40 0x00, 0x14, 0x00, 0x00, 0x40, 0x00, 0x40, 0x10,
41 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
42 0x00, 0x00
43};
44
45static const u8 ice_fdir_udp4_gtpu4_pkt[] = {
46 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
47 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00,
48 0x00, 0x4c, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11,
49 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
50 0x00, 0x00, 0x08, 0x68, 0x08, 0x68, 0x00, 0x00,
51 0x00, 0x00, 0x34, 0xff, 0x00, 0x28, 0x00, 0x00,
52 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x02, 0x00,
53 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x00,
54 0x00, 0x1c, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11,
55 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
56 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
57 0x00, 0x00,
58};
59
60static const u8 ice_fdir_tcp4_gtpu4_pkt[] = {
61 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
62 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00,
63 0x00, 0x58, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11,
64 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
65 0x00, 0x00, 0x08, 0x68, 0x08, 0x68, 0x00, 0x00,
66 0x00, 0x00, 0x34, 0xff, 0x00, 0x28, 0x00, 0x00,
67 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x02, 0x00,
68 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x00,
69 0x00, 0x28, 0x00, 0x00, 0x40, 0x00, 0x40, 0x06,
70 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
71 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
72 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
73 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
74};
75
76static const u8 ice_fdir_icmp4_gtpu4_pkt[] = {
77 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
78 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00,
79 0x00, 0x4c, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11,
80 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
81 0x00, 0x00, 0x08, 0x68, 0x08, 0x68, 0x00, 0x00,
82 0x00, 0x00, 0x34, 0xff, 0x00, 0x28, 0x00, 0x00,
83 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x02, 0x00,
84 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x00,
85 0x00, 0x1c, 0x00, 0x00, 0x40, 0x00, 0x40, 0x01,
86 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
87 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
88 0x00, 0x00,
89};
90
91static const u8 ice_fdir_ipv4_gtpu4_pkt[] = {
92 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
93 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00,
94 0x00, 0x44, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11,
95 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
96 0x00, 0x00, 0x08, 0x68, 0x08, 0x68, 0x00, 0x00,
97 0x00, 0x00, 0x34, 0xff, 0x00, 0x28, 0x00, 0x00,
98 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x02, 0x00,
99 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x00,
100 0x00, 0x14, 0x00, 0x00, 0x40, 0x00, 0x40, 0x00,
101 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
102 0x00, 0x00,
103};
104
105static 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
114static 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
126static 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
135static 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
146static 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
156static 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
168static 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
178static 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
189static 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
200static 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
211static 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
224static 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
237static 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
243static 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
256static 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
267static 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
279static 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
289static 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
305static 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
320static 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
335static 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
349static 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
368static 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
385static 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
403static 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 */
420static 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 */
579static 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 */
607static void
608ice_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 */
650void
651ice_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 */
699int 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 */
710int 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 */
722int 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 */
735int 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 */
748int 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 */
759static 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 */
776static 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 */
790static 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 */
806static 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 */
823static 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 */
834static 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 */
844static 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 */
857int
858ice_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 */
1126bool 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 */
1141struct ice_fdir_fltr *
1142ice_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 */
1161void 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 */
1184void
1185ice_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 */
1205static 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 */
1217static bool
1218ice_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 */
1278bool 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}
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}