Linux Audio

Check our new training course

Loading...
Note: File does not exist in v4.6.
  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}