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}
1280