Loading...
1// SPDX-License-Identifier: GPL-2.0
2/* Copyright (C) 2018-2020, Intel Corporation. */
3
4/* flow director ethtool support for ice */
5
6#include "ice.h"
7#include "ice_lib.h"
8#include "ice_fdir.h"
9#include "ice_flow.h"
10
11static struct in6_addr full_ipv6_addr_mask = {
12 .in6_u = {
13 .u6_addr8 = {
14 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
15 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
16 }
17 }
18};
19
20static struct in6_addr zero_ipv6_addr_mask = {
21 .in6_u = {
22 .u6_addr8 = {
23 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
24 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
25 }
26 }
27};
28
29/* calls to ice_flow_add_prof require the number of segments in the array
30 * for segs_cnt. In this code that is one more than the index.
31 */
32#define TNL_SEG_CNT(_TNL_) ((_TNL_) + 1)
33
34/**
35 * ice_fltr_to_ethtool_flow - convert filter type values to ethtool
36 * flow type values
37 * @flow: filter type to be converted
38 *
39 * Returns the corresponding ethtool flow type.
40 */
41static int ice_fltr_to_ethtool_flow(enum ice_fltr_ptype flow)
42{
43 switch (flow) {
44 case ICE_FLTR_PTYPE_NONF_IPV4_TCP:
45 return TCP_V4_FLOW;
46 case ICE_FLTR_PTYPE_NONF_IPV4_UDP:
47 return UDP_V4_FLOW;
48 case ICE_FLTR_PTYPE_NONF_IPV4_SCTP:
49 return SCTP_V4_FLOW;
50 case ICE_FLTR_PTYPE_NONF_IPV4_OTHER:
51 return IPV4_USER_FLOW;
52 case ICE_FLTR_PTYPE_NONF_IPV6_TCP:
53 return TCP_V6_FLOW;
54 case ICE_FLTR_PTYPE_NONF_IPV6_UDP:
55 return UDP_V6_FLOW;
56 case ICE_FLTR_PTYPE_NONF_IPV6_SCTP:
57 return SCTP_V6_FLOW;
58 case ICE_FLTR_PTYPE_NONF_IPV6_OTHER:
59 return IPV6_USER_FLOW;
60 default:
61 /* 0 is undefined ethtool flow */
62 return 0;
63 }
64}
65
66/**
67 * ice_ethtool_flow_to_fltr - convert ethtool flow type to filter enum
68 * @eth: Ethtool flow type to be converted
69 *
70 * Returns flow enum
71 */
72static enum ice_fltr_ptype ice_ethtool_flow_to_fltr(int eth)
73{
74 switch (eth) {
75 case TCP_V4_FLOW:
76 return ICE_FLTR_PTYPE_NONF_IPV4_TCP;
77 case UDP_V4_FLOW:
78 return ICE_FLTR_PTYPE_NONF_IPV4_UDP;
79 case SCTP_V4_FLOW:
80 return ICE_FLTR_PTYPE_NONF_IPV4_SCTP;
81 case IPV4_USER_FLOW:
82 return ICE_FLTR_PTYPE_NONF_IPV4_OTHER;
83 case TCP_V6_FLOW:
84 return ICE_FLTR_PTYPE_NONF_IPV6_TCP;
85 case UDP_V6_FLOW:
86 return ICE_FLTR_PTYPE_NONF_IPV6_UDP;
87 case SCTP_V6_FLOW:
88 return ICE_FLTR_PTYPE_NONF_IPV6_SCTP;
89 case IPV6_USER_FLOW:
90 return ICE_FLTR_PTYPE_NONF_IPV6_OTHER;
91 default:
92 return ICE_FLTR_PTYPE_NONF_NONE;
93 }
94}
95
96/**
97 * ice_is_mask_valid - check mask field set
98 * @mask: full mask to check
99 * @field: field for which mask should be valid
100 *
101 * If the mask is fully set return true. If it is not valid for field return
102 * false.
103 */
104static bool ice_is_mask_valid(u64 mask, u64 field)
105{
106 return (mask & field) == field;
107}
108
109/**
110 * ice_get_ethtool_fdir_entry - fill ethtool structure with fdir filter data
111 * @hw: hardware structure that contains filter list
112 * @cmd: ethtool command data structure to receive the filter data
113 *
114 * Returns 0 on success and -EINVAL on failure
115 */
116int ice_get_ethtool_fdir_entry(struct ice_hw *hw, struct ethtool_rxnfc *cmd)
117{
118 struct ethtool_rx_flow_spec *fsp;
119 struct ice_fdir_fltr *rule;
120 int ret = 0;
121 u16 idx;
122
123 fsp = (struct ethtool_rx_flow_spec *)&cmd->fs;
124
125 mutex_lock(&hw->fdir_fltr_lock);
126
127 rule = ice_fdir_find_fltr_by_idx(hw, fsp->location);
128
129 if (!rule || fsp->location != rule->fltr_id) {
130 ret = -EINVAL;
131 goto release_lock;
132 }
133
134 fsp->flow_type = ice_fltr_to_ethtool_flow(rule->flow_type);
135
136 memset(&fsp->m_u, 0, sizeof(fsp->m_u));
137 memset(&fsp->m_ext, 0, sizeof(fsp->m_ext));
138
139 switch (fsp->flow_type) {
140 case IPV4_USER_FLOW:
141 fsp->h_u.usr_ip4_spec.ip_ver = ETH_RX_NFC_IP4;
142 fsp->h_u.usr_ip4_spec.proto = 0;
143 fsp->h_u.usr_ip4_spec.l4_4_bytes = rule->ip.v4.l4_header;
144 fsp->h_u.usr_ip4_spec.tos = rule->ip.v4.tos;
145 fsp->h_u.usr_ip4_spec.ip4src = rule->ip.v4.src_ip;
146 fsp->h_u.usr_ip4_spec.ip4dst = rule->ip.v4.dst_ip;
147 fsp->m_u.usr_ip4_spec.ip4src = rule->mask.v4.src_ip;
148 fsp->m_u.usr_ip4_spec.ip4dst = rule->mask.v4.dst_ip;
149 fsp->m_u.usr_ip4_spec.ip_ver = 0xFF;
150 fsp->m_u.usr_ip4_spec.proto = 0;
151 fsp->m_u.usr_ip4_spec.l4_4_bytes = rule->mask.v4.l4_header;
152 fsp->m_u.usr_ip4_spec.tos = rule->mask.v4.tos;
153 break;
154 case TCP_V4_FLOW:
155 case UDP_V4_FLOW:
156 case SCTP_V4_FLOW:
157 fsp->h_u.tcp_ip4_spec.psrc = rule->ip.v4.src_port;
158 fsp->h_u.tcp_ip4_spec.pdst = rule->ip.v4.dst_port;
159 fsp->h_u.tcp_ip4_spec.ip4src = rule->ip.v4.src_ip;
160 fsp->h_u.tcp_ip4_spec.ip4dst = rule->ip.v4.dst_ip;
161 fsp->m_u.tcp_ip4_spec.psrc = rule->mask.v4.src_port;
162 fsp->m_u.tcp_ip4_spec.pdst = rule->mask.v4.dst_port;
163 fsp->m_u.tcp_ip4_spec.ip4src = rule->mask.v4.src_ip;
164 fsp->m_u.tcp_ip4_spec.ip4dst = rule->mask.v4.dst_ip;
165 break;
166 case IPV6_USER_FLOW:
167 fsp->h_u.usr_ip6_spec.l4_4_bytes = rule->ip.v6.l4_header;
168 fsp->h_u.usr_ip6_spec.tclass = rule->ip.v6.tc;
169 fsp->h_u.usr_ip6_spec.l4_proto = rule->ip.v6.proto;
170 memcpy(fsp->h_u.tcp_ip6_spec.ip6src, rule->ip.v6.src_ip,
171 sizeof(struct in6_addr));
172 memcpy(fsp->h_u.tcp_ip6_spec.ip6dst, rule->ip.v6.dst_ip,
173 sizeof(struct in6_addr));
174 memcpy(fsp->m_u.tcp_ip6_spec.ip6src, rule->mask.v6.src_ip,
175 sizeof(struct in6_addr));
176 memcpy(fsp->m_u.tcp_ip6_spec.ip6dst, rule->mask.v6.dst_ip,
177 sizeof(struct in6_addr));
178 fsp->m_u.usr_ip6_spec.l4_4_bytes = rule->mask.v6.l4_header;
179 fsp->m_u.usr_ip6_spec.tclass = rule->mask.v6.tc;
180 fsp->m_u.usr_ip6_spec.l4_proto = rule->mask.v6.proto;
181 break;
182 case TCP_V6_FLOW:
183 case UDP_V6_FLOW:
184 case SCTP_V6_FLOW:
185 memcpy(fsp->h_u.tcp_ip6_spec.ip6src, rule->ip.v6.src_ip,
186 sizeof(struct in6_addr));
187 memcpy(fsp->h_u.tcp_ip6_spec.ip6dst, rule->ip.v6.dst_ip,
188 sizeof(struct in6_addr));
189 fsp->h_u.tcp_ip6_spec.psrc = rule->ip.v6.src_port;
190 fsp->h_u.tcp_ip6_spec.pdst = rule->ip.v6.dst_port;
191 memcpy(fsp->m_u.tcp_ip6_spec.ip6src,
192 rule->mask.v6.src_ip,
193 sizeof(struct in6_addr));
194 memcpy(fsp->m_u.tcp_ip6_spec.ip6dst,
195 rule->mask.v6.dst_ip,
196 sizeof(struct in6_addr));
197 fsp->m_u.tcp_ip6_spec.psrc = rule->mask.v6.src_port;
198 fsp->m_u.tcp_ip6_spec.pdst = rule->mask.v6.dst_port;
199 fsp->h_u.tcp_ip6_spec.tclass = rule->ip.v6.tc;
200 fsp->m_u.tcp_ip6_spec.tclass = rule->mask.v6.tc;
201 break;
202 default:
203 break;
204 }
205
206 if (rule->dest_ctl == ICE_FLTR_PRGM_DESC_DEST_DROP_PKT)
207 fsp->ring_cookie = RX_CLS_FLOW_DISC;
208 else
209 fsp->ring_cookie = rule->orig_q_index;
210
211 idx = ice_ethtool_flow_to_fltr(fsp->flow_type);
212 if (idx == ICE_FLTR_PTYPE_NONF_NONE) {
213 dev_err(ice_hw_to_dev(hw), "Missing input index for flow_type %d\n",
214 rule->flow_type);
215 ret = -EINVAL;
216 }
217
218release_lock:
219 mutex_unlock(&hw->fdir_fltr_lock);
220 return ret;
221}
222
223/**
224 * ice_get_fdir_fltr_ids - fill buffer with filter IDs of active filters
225 * @hw: hardware structure containing the filter list
226 * @cmd: ethtool command data structure
227 * @rule_locs: ethtool array passed in from OS to receive filter IDs
228 *
229 * Returns 0 as expected for success by ethtool
230 */
231int
232ice_get_fdir_fltr_ids(struct ice_hw *hw, struct ethtool_rxnfc *cmd,
233 u32 *rule_locs)
234{
235 struct ice_fdir_fltr *f_rule;
236 unsigned int cnt = 0;
237 int val = 0;
238
239 /* report total rule count */
240 cmd->data = ice_get_fdir_cnt_all(hw);
241
242 mutex_lock(&hw->fdir_fltr_lock);
243
244 list_for_each_entry(f_rule, &hw->fdir_list_head, fltr_node) {
245 if (cnt == cmd->rule_cnt) {
246 val = -EMSGSIZE;
247 goto release_lock;
248 }
249 rule_locs[cnt] = f_rule->fltr_id;
250 cnt++;
251 }
252
253release_lock:
254 mutex_unlock(&hw->fdir_fltr_lock);
255 if (!val)
256 cmd->rule_cnt = cnt;
257 return val;
258}
259
260/**
261 * ice_fdir_remap_entries - update the FDir entries in profile
262 * @prof: FDir structure pointer
263 * @tun: tunneled or non-tunneled packet
264 * @idx: FDir entry index
265 */
266static void
267ice_fdir_remap_entries(struct ice_fd_hw_prof *prof, int tun, int idx)
268{
269 if (idx != prof->cnt && tun < ICE_FD_HW_SEG_MAX) {
270 int i;
271
272 for (i = idx; i < (prof->cnt - 1); i++) {
273 u64 old_entry_h;
274
275 old_entry_h = prof->entry_h[i + 1][tun];
276 prof->entry_h[i][tun] = old_entry_h;
277 prof->vsi_h[i] = prof->vsi_h[i + 1];
278 }
279
280 prof->entry_h[i][tun] = 0;
281 prof->vsi_h[i] = 0;
282 }
283}
284
285/**
286 * ice_fdir_rem_adq_chnl - remove an ADQ channel from HW filter rules
287 * @hw: hardware structure containing filter list
288 * @vsi_idx: VSI handle
289 */
290void ice_fdir_rem_adq_chnl(struct ice_hw *hw, u16 vsi_idx)
291{
292 int status, flow;
293
294 if (!hw->fdir_prof)
295 return;
296
297 for (flow = 0; flow < ICE_FLTR_PTYPE_MAX; flow++) {
298 struct ice_fd_hw_prof *prof = hw->fdir_prof[flow];
299 int tun, i;
300
301 if (!prof || !prof->cnt)
302 continue;
303
304 for (tun = 0; tun < ICE_FD_HW_SEG_MAX; tun++) {
305 u64 prof_id;
306
307 prof_id = flow + tun * ICE_FLTR_PTYPE_MAX;
308
309 for (i = 0; i < prof->cnt; i++) {
310 if (prof->vsi_h[i] != vsi_idx)
311 continue;
312
313 prof->entry_h[i][tun] = 0;
314 prof->vsi_h[i] = 0;
315 break;
316 }
317
318 /* after clearing FDir entries update the remaining */
319 ice_fdir_remap_entries(prof, tun, i);
320
321 /* find flow profile corresponding to prof_id and clear
322 * vsi_idx from bitmap.
323 */
324 status = ice_flow_rem_vsi_prof(hw, vsi_idx, prof_id);
325 if (status) {
326 dev_err(ice_hw_to_dev(hw), "ice_flow_rem_vsi_prof() failed status=%d\n",
327 status);
328 }
329 }
330 prof->cnt--;
331 }
332}
333
334/**
335 * ice_fdir_get_hw_prof - return the ice_fd_hw_proc associated with a flow
336 * @hw: hardware structure containing the filter list
337 * @blk: hardware block
338 * @flow: FDir flow type to release
339 */
340static struct ice_fd_hw_prof *
341ice_fdir_get_hw_prof(struct ice_hw *hw, enum ice_block blk, int flow)
342{
343 if (blk == ICE_BLK_FD && hw->fdir_prof)
344 return hw->fdir_prof[flow];
345
346 return NULL;
347}
348
349/**
350 * ice_fdir_erase_flow_from_hw - remove a flow from the HW profile tables
351 * @hw: hardware structure containing the filter list
352 * @blk: hardware block
353 * @flow: FDir flow type to release
354 */
355static void
356ice_fdir_erase_flow_from_hw(struct ice_hw *hw, enum ice_block blk, int flow)
357{
358 struct ice_fd_hw_prof *prof = ice_fdir_get_hw_prof(hw, blk, flow);
359 int tun;
360
361 if (!prof)
362 return;
363
364 for (tun = 0; tun < ICE_FD_HW_SEG_MAX; tun++) {
365 u64 prof_id;
366 int j;
367
368 prof_id = flow + tun * ICE_FLTR_PTYPE_MAX;
369 for (j = 0; j < prof->cnt; j++) {
370 u16 vsi_num;
371
372 if (!prof->entry_h[j][tun] || !prof->vsi_h[j])
373 continue;
374 vsi_num = ice_get_hw_vsi_num(hw, prof->vsi_h[j]);
375 ice_rem_prof_id_flow(hw, blk, vsi_num, prof_id);
376 ice_flow_rem_entry(hw, blk, prof->entry_h[j][tun]);
377 prof->entry_h[j][tun] = 0;
378 }
379 ice_flow_rem_prof(hw, blk, prof_id);
380 }
381}
382
383/**
384 * ice_fdir_rem_flow - release the ice_flow structures for a filter type
385 * @hw: hardware structure containing the filter list
386 * @blk: hardware block
387 * @flow_type: FDir flow type to release
388 */
389static void
390ice_fdir_rem_flow(struct ice_hw *hw, enum ice_block blk,
391 enum ice_fltr_ptype flow_type)
392{
393 int flow = (int)flow_type & ~FLOW_EXT;
394 struct ice_fd_hw_prof *prof;
395 int tun, i;
396
397 prof = ice_fdir_get_hw_prof(hw, blk, flow);
398 if (!prof)
399 return;
400
401 ice_fdir_erase_flow_from_hw(hw, blk, flow);
402 for (i = 0; i < prof->cnt; i++)
403 prof->vsi_h[i] = 0;
404 for (tun = 0; tun < ICE_FD_HW_SEG_MAX; tun++) {
405 if (!prof->fdir_seg[tun])
406 continue;
407 devm_kfree(ice_hw_to_dev(hw), prof->fdir_seg[tun]);
408 prof->fdir_seg[tun] = NULL;
409 }
410 prof->cnt = 0;
411}
412
413/**
414 * ice_fdir_release_flows - release all flows in use for later replay
415 * @hw: pointer to HW instance
416 */
417void ice_fdir_release_flows(struct ice_hw *hw)
418{
419 int flow;
420
421 /* release Flow Director HW table entries */
422 for (flow = 0; flow < ICE_FLTR_PTYPE_MAX; flow++)
423 ice_fdir_erase_flow_from_hw(hw, ICE_BLK_FD, flow);
424}
425
426/**
427 * ice_fdir_replay_flows - replay HW Flow Director filter info
428 * @hw: pointer to HW instance
429 */
430void ice_fdir_replay_flows(struct ice_hw *hw)
431{
432 int flow;
433
434 for (flow = 0; flow < ICE_FLTR_PTYPE_MAX; flow++) {
435 int tun;
436
437 if (!hw->fdir_prof[flow] || !hw->fdir_prof[flow]->cnt)
438 continue;
439 for (tun = 0; tun < ICE_FD_HW_SEG_MAX; tun++) {
440 struct ice_flow_prof *hw_prof;
441 struct ice_fd_hw_prof *prof;
442 u64 prof_id;
443 int j;
444
445 prof = hw->fdir_prof[flow];
446 prof_id = flow + tun * ICE_FLTR_PTYPE_MAX;
447 ice_flow_add_prof(hw, ICE_BLK_FD, ICE_FLOW_RX, prof_id,
448 prof->fdir_seg[tun], TNL_SEG_CNT(tun),
449 &hw_prof);
450 for (j = 0; j < prof->cnt; j++) {
451 enum ice_flow_priority prio;
452 u64 entry_h = 0;
453 int err;
454
455 prio = ICE_FLOW_PRIO_NORMAL;
456 err = ice_flow_add_entry(hw, ICE_BLK_FD,
457 prof_id,
458 prof->vsi_h[0],
459 prof->vsi_h[j],
460 prio, prof->fdir_seg,
461 &entry_h);
462 if (err) {
463 dev_err(ice_hw_to_dev(hw), "Could not replay Flow Director, flow type %d\n",
464 flow);
465 continue;
466 }
467 prof->entry_h[j][tun] = entry_h;
468 }
469 }
470 }
471}
472
473/**
474 * ice_parse_rx_flow_user_data - deconstruct user-defined data
475 * @fsp: pointer to ethtool Rx flow specification
476 * @data: pointer to userdef data structure for storage
477 *
478 * Returns 0 on success, negative error value on failure
479 */
480static int
481ice_parse_rx_flow_user_data(struct ethtool_rx_flow_spec *fsp,
482 struct ice_rx_flow_userdef *data)
483{
484 u64 value, mask;
485
486 memset(data, 0, sizeof(*data));
487 if (!(fsp->flow_type & FLOW_EXT))
488 return 0;
489
490 value = be64_to_cpu(*((__force __be64 *)fsp->h_ext.data));
491 mask = be64_to_cpu(*((__force __be64 *)fsp->m_ext.data));
492 if (!mask)
493 return 0;
494
495#define ICE_USERDEF_FLEX_WORD_M GENMASK_ULL(15, 0)
496#define ICE_USERDEF_FLEX_OFFS_S 16
497#define ICE_USERDEF_FLEX_OFFS_M GENMASK_ULL(31, ICE_USERDEF_FLEX_OFFS_S)
498#define ICE_USERDEF_FLEX_FLTR_M GENMASK_ULL(31, 0)
499
500 /* 0x1fe is the maximum value for offsets stored in the internal
501 * filtering tables.
502 */
503#define ICE_USERDEF_FLEX_MAX_OFFS_VAL 0x1fe
504
505 if (!ice_is_mask_valid(mask, ICE_USERDEF_FLEX_FLTR_M) ||
506 value > ICE_USERDEF_FLEX_FLTR_M)
507 return -EINVAL;
508
509 data->flex_word = value & ICE_USERDEF_FLEX_WORD_M;
510 data->flex_offset = (value & ICE_USERDEF_FLEX_OFFS_M) >>
511 ICE_USERDEF_FLEX_OFFS_S;
512 if (data->flex_offset > ICE_USERDEF_FLEX_MAX_OFFS_VAL)
513 return -EINVAL;
514
515 data->flex_fltr = true;
516
517 return 0;
518}
519
520/**
521 * ice_fdir_num_avail_fltr - return the number of unused flow director filters
522 * @hw: pointer to hardware structure
523 * @vsi: software VSI structure
524 *
525 * There are 2 filter pools: guaranteed and best effort(shared). Each VSI can
526 * use filters from either pool. The guaranteed pool is divided between VSIs.
527 * The best effort filter pool is common to all VSIs and is a device shared
528 * resource pool. The number of filters available to this VSI is the sum of
529 * the VSIs guaranteed filter pool and the global available best effort
530 * filter pool.
531 *
532 * Returns the number of available flow director filters to this VSI
533 */
534static int ice_fdir_num_avail_fltr(struct ice_hw *hw, struct ice_vsi *vsi)
535{
536 u16 vsi_num = ice_get_hw_vsi_num(hw, vsi->idx);
537 u16 num_guar;
538 u16 num_be;
539
540 /* total guaranteed filters assigned to this VSI */
541 num_guar = vsi->num_gfltr;
542
543 /* minus the guaranteed filters programed by this VSI */
544 num_guar -= (rd32(hw, VSIQF_FD_CNT(vsi_num)) &
545 VSIQF_FD_CNT_FD_GCNT_M) >> VSIQF_FD_CNT_FD_GCNT_S;
546
547 /* total global best effort filters */
548 num_be = hw->func_caps.fd_fltr_best_effort;
549
550 /* minus the global best effort filters programmed */
551 num_be -= (rd32(hw, GLQF_FD_CNT) & GLQF_FD_CNT_FD_BCNT_M) >>
552 GLQF_FD_CNT_FD_BCNT_S;
553
554 return num_guar + num_be;
555}
556
557/**
558 * ice_fdir_alloc_flow_prof - allocate FDir flow profile structure(s)
559 * @hw: HW structure containing the FDir flow profile structure(s)
560 * @flow: flow type to allocate the flow profile for
561 *
562 * Allocate the fdir_prof and fdir_prof[flow] if not already created. Return 0
563 * on success and negative on error.
564 */
565static int
566ice_fdir_alloc_flow_prof(struct ice_hw *hw, enum ice_fltr_ptype flow)
567{
568 if (!hw)
569 return -EINVAL;
570
571 if (!hw->fdir_prof) {
572 hw->fdir_prof = devm_kcalloc(ice_hw_to_dev(hw),
573 ICE_FLTR_PTYPE_MAX,
574 sizeof(*hw->fdir_prof),
575 GFP_KERNEL);
576 if (!hw->fdir_prof)
577 return -ENOMEM;
578 }
579
580 if (!hw->fdir_prof[flow]) {
581 hw->fdir_prof[flow] = devm_kzalloc(ice_hw_to_dev(hw),
582 sizeof(**hw->fdir_prof),
583 GFP_KERNEL);
584 if (!hw->fdir_prof[flow])
585 return -ENOMEM;
586 }
587
588 return 0;
589}
590
591/**
592 * ice_fdir_prof_vsi_idx - find or insert a vsi_idx in structure
593 * @prof: pointer to flow director HW profile
594 * @vsi_idx: vsi_idx to locate
595 *
596 * return the index of the vsi_idx. if vsi_idx is not found insert it
597 * into the vsi_h table.
598 */
599static u16
600ice_fdir_prof_vsi_idx(struct ice_fd_hw_prof *prof, int vsi_idx)
601{
602 u16 idx = 0;
603
604 for (idx = 0; idx < prof->cnt; idx++)
605 if (prof->vsi_h[idx] == vsi_idx)
606 return idx;
607
608 if (idx == prof->cnt)
609 prof->vsi_h[prof->cnt++] = vsi_idx;
610 return idx;
611}
612
613/**
614 * ice_fdir_set_hw_fltr_rule - Configure HW tables to generate a FDir rule
615 * @pf: pointer to the PF structure
616 * @seg: protocol header description pointer
617 * @flow: filter enum
618 * @tun: FDir segment to program
619 */
620static int
621ice_fdir_set_hw_fltr_rule(struct ice_pf *pf, struct ice_flow_seg_info *seg,
622 enum ice_fltr_ptype flow, enum ice_fd_hw_seg tun)
623{
624 struct device *dev = ice_pf_to_dev(pf);
625 struct ice_vsi *main_vsi, *ctrl_vsi;
626 struct ice_flow_seg_info *old_seg;
627 struct ice_flow_prof *prof = NULL;
628 struct ice_fd_hw_prof *hw_prof;
629 struct ice_hw *hw = &pf->hw;
630 u64 entry1_h = 0;
631 u64 entry2_h = 0;
632 bool del_last;
633 u64 prof_id;
634 int err;
635 int idx;
636
637 main_vsi = ice_get_main_vsi(pf);
638 if (!main_vsi)
639 return -EINVAL;
640
641 ctrl_vsi = ice_get_ctrl_vsi(pf);
642 if (!ctrl_vsi)
643 return -EINVAL;
644
645 err = ice_fdir_alloc_flow_prof(hw, flow);
646 if (err)
647 return err;
648
649 hw_prof = hw->fdir_prof[flow];
650 old_seg = hw_prof->fdir_seg[tun];
651 if (old_seg) {
652 /* This flow_type already has a changed input set.
653 * If it matches the requested input set then we are
654 * done. Or, if it's different then it's an error.
655 */
656 if (!memcmp(old_seg, seg, sizeof(*seg)))
657 return -EEXIST;
658
659 /* if there are FDir filters using this flow,
660 * then return error.
661 */
662 if (hw->fdir_fltr_cnt[flow]) {
663 dev_err(dev, "Failed to add filter. Flow director filters on each port must have the same input set.\n");
664 return -EINVAL;
665 }
666
667 if (ice_is_arfs_using_perfect_flow(hw, flow)) {
668 dev_err(dev, "aRFS using perfect flow type %d, cannot change input set\n",
669 flow);
670 return -EINVAL;
671 }
672
673 /* remove HW filter definition */
674 ice_fdir_rem_flow(hw, ICE_BLK_FD, flow);
675 }
676
677 /* Adding a profile, but there is only one header supported.
678 * That is the final parameters are 1 header (segment), no
679 * actions (NULL) and zero actions 0.
680 */
681 prof_id = flow + tun * ICE_FLTR_PTYPE_MAX;
682 err = ice_flow_add_prof(hw, ICE_BLK_FD, ICE_FLOW_RX, prof_id, seg,
683 TNL_SEG_CNT(tun), &prof);
684 if (err)
685 return err;
686 err = ice_flow_add_entry(hw, ICE_BLK_FD, prof_id, main_vsi->idx,
687 main_vsi->idx, ICE_FLOW_PRIO_NORMAL,
688 seg, &entry1_h);
689 if (err)
690 goto err_prof;
691 err = ice_flow_add_entry(hw, ICE_BLK_FD, prof_id, main_vsi->idx,
692 ctrl_vsi->idx, ICE_FLOW_PRIO_NORMAL,
693 seg, &entry2_h);
694 if (err)
695 goto err_entry;
696
697 hw_prof->fdir_seg[tun] = seg;
698 hw_prof->entry_h[0][tun] = entry1_h;
699 hw_prof->entry_h[1][tun] = entry2_h;
700 hw_prof->vsi_h[0] = main_vsi->idx;
701 hw_prof->vsi_h[1] = ctrl_vsi->idx;
702 if (!hw_prof->cnt)
703 hw_prof->cnt = 2;
704
705 for (idx = 1; idx < ICE_CHNL_MAX_TC; idx++) {
706 u16 vsi_idx;
707 u16 vsi_h;
708
709 if (!ice_is_adq_active(pf) || !main_vsi->tc_map_vsi[idx])
710 continue;
711
712 entry1_h = 0;
713 vsi_h = main_vsi->tc_map_vsi[idx]->idx;
714 err = ice_flow_add_entry(hw, ICE_BLK_FD, prof_id,
715 main_vsi->idx, vsi_h,
716 ICE_FLOW_PRIO_NORMAL, seg,
717 &entry1_h);
718 if (err) {
719 dev_err(dev, "Could not add Channel VSI %d to flow group\n",
720 idx);
721 goto err_unroll;
722 }
723
724 vsi_idx = ice_fdir_prof_vsi_idx(hw_prof,
725 main_vsi->tc_map_vsi[idx]->idx);
726 hw_prof->entry_h[vsi_idx][tun] = entry1_h;
727 }
728
729 return 0;
730
731err_unroll:
732 entry1_h = 0;
733 hw_prof->fdir_seg[tun] = NULL;
734
735 /* The variable del_last will be used to determine when to clean up
736 * the VSI group data. The VSI data is not needed if there are no
737 * segments.
738 */
739 del_last = true;
740 for (idx = 0; idx < ICE_FD_HW_SEG_MAX; idx++)
741 if (hw_prof->fdir_seg[idx]) {
742 del_last = false;
743 break;
744 }
745
746 for (idx = 0; idx < hw_prof->cnt; idx++) {
747 u16 vsi_num = ice_get_hw_vsi_num(hw, hw_prof->vsi_h[idx]);
748
749 if (!hw_prof->entry_h[idx][tun])
750 continue;
751 ice_rem_prof_id_flow(hw, ICE_BLK_FD, vsi_num, prof_id);
752 ice_flow_rem_entry(hw, ICE_BLK_FD, hw_prof->entry_h[idx][tun]);
753 hw_prof->entry_h[idx][tun] = 0;
754 if (del_last)
755 hw_prof->vsi_h[idx] = 0;
756 }
757 if (del_last)
758 hw_prof->cnt = 0;
759err_entry:
760 ice_rem_prof_id_flow(hw, ICE_BLK_FD,
761 ice_get_hw_vsi_num(hw, main_vsi->idx), prof_id);
762 ice_flow_rem_entry(hw, ICE_BLK_FD, entry1_h);
763err_prof:
764 ice_flow_rem_prof(hw, ICE_BLK_FD, prof_id);
765 dev_err(dev, "Failed to add filter. Flow director filters on each port must have the same input set.\n");
766
767 return err;
768}
769
770/**
771 * ice_set_init_fdir_seg
772 * @seg: flow segment for programming
773 * @l3_proto: ICE_FLOW_SEG_HDR_IPV4 or ICE_FLOW_SEG_HDR_IPV6
774 * @l4_proto: ICE_FLOW_SEG_HDR_TCP or ICE_FLOW_SEG_HDR_UDP
775 *
776 * Set the configuration for perfect filters to the provided flow segment for
777 * programming the HW filter. This is to be called only when initializing
778 * filters as this function it assumes no filters exist.
779 */
780static int
781ice_set_init_fdir_seg(struct ice_flow_seg_info *seg,
782 enum ice_flow_seg_hdr l3_proto,
783 enum ice_flow_seg_hdr l4_proto)
784{
785 enum ice_flow_field src_addr, dst_addr, src_port, dst_port;
786
787 if (!seg)
788 return -EINVAL;
789
790 if (l3_proto == ICE_FLOW_SEG_HDR_IPV4) {
791 src_addr = ICE_FLOW_FIELD_IDX_IPV4_SA;
792 dst_addr = ICE_FLOW_FIELD_IDX_IPV4_DA;
793 } else if (l3_proto == ICE_FLOW_SEG_HDR_IPV6) {
794 src_addr = ICE_FLOW_FIELD_IDX_IPV6_SA;
795 dst_addr = ICE_FLOW_FIELD_IDX_IPV6_DA;
796 } else {
797 return -EINVAL;
798 }
799
800 if (l4_proto == ICE_FLOW_SEG_HDR_TCP) {
801 src_port = ICE_FLOW_FIELD_IDX_TCP_SRC_PORT;
802 dst_port = ICE_FLOW_FIELD_IDX_TCP_DST_PORT;
803 } else if (l4_proto == ICE_FLOW_SEG_HDR_UDP) {
804 src_port = ICE_FLOW_FIELD_IDX_UDP_SRC_PORT;
805 dst_port = ICE_FLOW_FIELD_IDX_UDP_DST_PORT;
806 } else {
807 return -EINVAL;
808 }
809
810 ICE_FLOW_SET_HDRS(seg, l3_proto | l4_proto);
811
812 /* IP source address */
813 ice_flow_set_fld(seg, src_addr, ICE_FLOW_FLD_OFF_INVAL,
814 ICE_FLOW_FLD_OFF_INVAL, ICE_FLOW_FLD_OFF_INVAL, false);
815
816 /* IP destination address */
817 ice_flow_set_fld(seg, dst_addr, ICE_FLOW_FLD_OFF_INVAL,
818 ICE_FLOW_FLD_OFF_INVAL, ICE_FLOW_FLD_OFF_INVAL, false);
819
820 /* Layer 4 source port */
821 ice_flow_set_fld(seg, src_port, ICE_FLOW_FLD_OFF_INVAL,
822 ICE_FLOW_FLD_OFF_INVAL, ICE_FLOW_FLD_OFF_INVAL, false);
823
824 /* Layer 4 destination port */
825 ice_flow_set_fld(seg, dst_port, ICE_FLOW_FLD_OFF_INVAL,
826 ICE_FLOW_FLD_OFF_INVAL, ICE_FLOW_FLD_OFF_INVAL, false);
827
828 return 0;
829}
830
831/**
832 * ice_create_init_fdir_rule
833 * @pf: PF structure
834 * @flow: filter enum
835 *
836 * Return error value or 0 on success.
837 */
838static int
839ice_create_init_fdir_rule(struct ice_pf *pf, enum ice_fltr_ptype flow)
840{
841 struct ice_flow_seg_info *seg, *tun_seg;
842 struct device *dev = ice_pf_to_dev(pf);
843 struct ice_hw *hw = &pf->hw;
844 int ret;
845
846 /* if there is already a filter rule for kind return -EINVAL */
847 if (hw->fdir_prof && hw->fdir_prof[flow] &&
848 hw->fdir_prof[flow]->fdir_seg[0])
849 return -EINVAL;
850
851 seg = devm_kzalloc(dev, sizeof(*seg), GFP_KERNEL);
852 if (!seg)
853 return -ENOMEM;
854
855 tun_seg = devm_kcalloc(dev, ICE_FD_HW_SEG_MAX, sizeof(*tun_seg),
856 GFP_KERNEL);
857 if (!tun_seg) {
858 devm_kfree(dev, seg);
859 return -ENOMEM;
860 }
861
862 if (flow == ICE_FLTR_PTYPE_NONF_IPV4_TCP)
863 ret = ice_set_init_fdir_seg(seg, ICE_FLOW_SEG_HDR_IPV4,
864 ICE_FLOW_SEG_HDR_TCP);
865 else if (flow == ICE_FLTR_PTYPE_NONF_IPV4_UDP)
866 ret = ice_set_init_fdir_seg(seg, ICE_FLOW_SEG_HDR_IPV4,
867 ICE_FLOW_SEG_HDR_UDP);
868 else if (flow == ICE_FLTR_PTYPE_NONF_IPV6_TCP)
869 ret = ice_set_init_fdir_seg(seg, ICE_FLOW_SEG_HDR_IPV6,
870 ICE_FLOW_SEG_HDR_TCP);
871 else if (flow == ICE_FLTR_PTYPE_NONF_IPV6_UDP)
872 ret = ice_set_init_fdir_seg(seg, ICE_FLOW_SEG_HDR_IPV6,
873 ICE_FLOW_SEG_HDR_UDP);
874 else
875 ret = -EINVAL;
876 if (ret)
877 goto err_exit;
878
879 /* add filter for outer headers */
880 ret = ice_fdir_set_hw_fltr_rule(pf, seg, flow, ICE_FD_HW_SEG_NON_TUN);
881 if (ret)
882 /* could not write filter, free memory */
883 goto err_exit;
884
885 /* make tunneled filter HW entries if possible */
886 memcpy(&tun_seg[1], seg, sizeof(*seg));
887 ret = ice_fdir_set_hw_fltr_rule(pf, tun_seg, flow, ICE_FD_HW_SEG_TUN);
888 if (ret)
889 /* could not write tunnel filter, but outer header filter
890 * exists
891 */
892 devm_kfree(dev, tun_seg);
893
894 set_bit(flow, hw->fdir_perfect_fltr);
895 return ret;
896err_exit:
897 devm_kfree(dev, tun_seg);
898 devm_kfree(dev, seg);
899
900 return -EOPNOTSUPP;
901}
902
903/**
904 * ice_set_fdir_ip4_seg
905 * @seg: flow segment for programming
906 * @tcp_ip4_spec: mask data from ethtool
907 * @l4_proto: Layer 4 protocol to program
908 * @perfect_fltr: only valid on success; returns true if perfect filter,
909 * false if not
910 *
911 * Set the mask data into the flow segment to be used to program HW
912 * table based on provided L4 protocol for IPv4
913 */
914static int
915ice_set_fdir_ip4_seg(struct ice_flow_seg_info *seg,
916 struct ethtool_tcpip4_spec *tcp_ip4_spec,
917 enum ice_flow_seg_hdr l4_proto, bool *perfect_fltr)
918{
919 enum ice_flow_field src_port, dst_port;
920
921 /* make sure we don't have any empty rule */
922 if (!tcp_ip4_spec->psrc && !tcp_ip4_spec->ip4src &&
923 !tcp_ip4_spec->pdst && !tcp_ip4_spec->ip4dst)
924 return -EINVAL;
925
926 /* filtering on TOS not supported */
927 if (tcp_ip4_spec->tos)
928 return -EOPNOTSUPP;
929
930 if (l4_proto == ICE_FLOW_SEG_HDR_TCP) {
931 src_port = ICE_FLOW_FIELD_IDX_TCP_SRC_PORT;
932 dst_port = ICE_FLOW_FIELD_IDX_TCP_DST_PORT;
933 } else if (l4_proto == ICE_FLOW_SEG_HDR_UDP) {
934 src_port = ICE_FLOW_FIELD_IDX_UDP_SRC_PORT;
935 dst_port = ICE_FLOW_FIELD_IDX_UDP_DST_PORT;
936 } else if (l4_proto == ICE_FLOW_SEG_HDR_SCTP) {
937 src_port = ICE_FLOW_FIELD_IDX_SCTP_SRC_PORT;
938 dst_port = ICE_FLOW_FIELD_IDX_SCTP_DST_PORT;
939 } else {
940 return -EOPNOTSUPP;
941 }
942
943 *perfect_fltr = true;
944 ICE_FLOW_SET_HDRS(seg, ICE_FLOW_SEG_HDR_IPV4 | l4_proto);
945
946 /* IP source address */
947 if (tcp_ip4_spec->ip4src == htonl(0xFFFFFFFF))
948 ice_flow_set_fld(seg, ICE_FLOW_FIELD_IDX_IPV4_SA,
949 ICE_FLOW_FLD_OFF_INVAL, ICE_FLOW_FLD_OFF_INVAL,
950 ICE_FLOW_FLD_OFF_INVAL, false);
951 else if (!tcp_ip4_spec->ip4src)
952 *perfect_fltr = false;
953 else
954 return -EOPNOTSUPP;
955
956 /* IP destination address */
957 if (tcp_ip4_spec->ip4dst == htonl(0xFFFFFFFF))
958 ice_flow_set_fld(seg, ICE_FLOW_FIELD_IDX_IPV4_DA,
959 ICE_FLOW_FLD_OFF_INVAL, ICE_FLOW_FLD_OFF_INVAL,
960 ICE_FLOW_FLD_OFF_INVAL, false);
961 else if (!tcp_ip4_spec->ip4dst)
962 *perfect_fltr = false;
963 else
964 return -EOPNOTSUPP;
965
966 /* Layer 4 source port */
967 if (tcp_ip4_spec->psrc == htons(0xFFFF))
968 ice_flow_set_fld(seg, src_port, ICE_FLOW_FLD_OFF_INVAL,
969 ICE_FLOW_FLD_OFF_INVAL, ICE_FLOW_FLD_OFF_INVAL,
970 false);
971 else if (!tcp_ip4_spec->psrc)
972 *perfect_fltr = false;
973 else
974 return -EOPNOTSUPP;
975
976 /* Layer 4 destination port */
977 if (tcp_ip4_spec->pdst == htons(0xFFFF))
978 ice_flow_set_fld(seg, dst_port, ICE_FLOW_FLD_OFF_INVAL,
979 ICE_FLOW_FLD_OFF_INVAL, ICE_FLOW_FLD_OFF_INVAL,
980 false);
981 else if (!tcp_ip4_spec->pdst)
982 *perfect_fltr = false;
983 else
984 return -EOPNOTSUPP;
985
986 return 0;
987}
988
989/**
990 * ice_set_fdir_ip4_usr_seg
991 * @seg: flow segment for programming
992 * @usr_ip4_spec: ethtool userdef packet offset
993 * @perfect_fltr: only valid on success; returns true if perfect filter,
994 * false if not
995 *
996 * Set the offset data into the flow segment to be used to program HW
997 * table for IPv4
998 */
999static int
1000ice_set_fdir_ip4_usr_seg(struct ice_flow_seg_info *seg,
1001 struct ethtool_usrip4_spec *usr_ip4_spec,
1002 bool *perfect_fltr)
1003{
1004 /* first 4 bytes of Layer 4 header */
1005 if (usr_ip4_spec->l4_4_bytes)
1006 return -EINVAL;
1007 if (usr_ip4_spec->tos)
1008 return -EINVAL;
1009 if (usr_ip4_spec->ip_ver)
1010 return -EINVAL;
1011 /* Filtering on Layer 4 protocol not supported */
1012 if (usr_ip4_spec->proto)
1013 return -EOPNOTSUPP;
1014 /* empty rules are not valid */
1015 if (!usr_ip4_spec->ip4src && !usr_ip4_spec->ip4dst)
1016 return -EINVAL;
1017
1018 *perfect_fltr = true;
1019 ICE_FLOW_SET_HDRS(seg, ICE_FLOW_SEG_HDR_IPV4);
1020
1021 /* IP source address */
1022 if (usr_ip4_spec->ip4src == htonl(0xFFFFFFFF))
1023 ice_flow_set_fld(seg, ICE_FLOW_FIELD_IDX_IPV4_SA,
1024 ICE_FLOW_FLD_OFF_INVAL, ICE_FLOW_FLD_OFF_INVAL,
1025 ICE_FLOW_FLD_OFF_INVAL, false);
1026 else if (!usr_ip4_spec->ip4src)
1027 *perfect_fltr = false;
1028 else
1029 return -EOPNOTSUPP;
1030
1031 /* IP destination address */
1032 if (usr_ip4_spec->ip4dst == htonl(0xFFFFFFFF))
1033 ice_flow_set_fld(seg, ICE_FLOW_FIELD_IDX_IPV4_DA,
1034 ICE_FLOW_FLD_OFF_INVAL, ICE_FLOW_FLD_OFF_INVAL,
1035 ICE_FLOW_FLD_OFF_INVAL, false);
1036 else if (!usr_ip4_spec->ip4dst)
1037 *perfect_fltr = false;
1038 else
1039 return -EOPNOTSUPP;
1040
1041 return 0;
1042}
1043
1044/**
1045 * ice_set_fdir_ip6_seg
1046 * @seg: flow segment for programming
1047 * @tcp_ip6_spec: mask data from ethtool
1048 * @l4_proto: Layer 4 protocol to program
1049 * @perfect_fltr: only valid on success; returns true if perfect filter,
1050 * false if not
1051 *
1052 * Set the mask data into the flow segment to be used to program HW
1053 * table based on provided L4 protocol for IPv6
1054 */
1055static int
1056ice_set_fdir_ip6_seg(struct ice_flow_seg_info *seg,
1057 struct ethtool_tcpip6_spec *tcp_ip6_spec,
1058 enum ice_flow_seg_hdr l4_proto, bool *perfect_fltr)
1059{
1060 enum ice_flow_field src_port, dst_port;
1061
1062 /* make sure we don't have any empty rule */
1063 if (!memcmp(tcp_ip6_spec->ip6src, &zero_ipv6_addr_mask,
1064 sizeof(struct in6_addr)) &&
1065 !memcmp(tcp_ip6_spec->ip6dst, &zero_ipv6_addr_mask,
1066 sizeof(struct in6_addr)) &&
1067 !tcp_ip6_spec->psrc && !tcp_ip6_spec->pdst)
1068 return -EINVAL;
1069
1070 /* filtering on TC not supported */
1071 if (tcp_ip6_spec->tclass)
1072 return -EOPNOTSUPP;
1073
1074 if (l4_proto == ICE_FLOW_SEG_HDR_TCP) {
1075 src_port = ICE_FLOW_FIELD_IDX_TCP_SRC_PORT;
1076 dst_port = ICE_FLOW_FIELD_IDX_TCP_DST_PORT;
1077 } else if (l4_proto == ICE_FLOW_SEG_HDR_UDP) {
1078 src_port = ICE_FLOW_FIELD_IDX_UDP_SRC_PORT;
1079 dst_port = ICE_FLOW_FIELD_IDX_UDP_DST_PORT;
1080 } else if (l4_proto == ICE_FLOW_SEG_HDR_SCTP) {
1081 src_port = ICE_FLOW_FIELD_IDX_SCTP_SRC_PORT;
1082 dst_port = ICE_FLOW_FIELD_IDX_SCTP_DST_PORT;
1083 } else {
1084 return -EINVAL;
1085 }
1086
1087 *perfect_fltr = true;
1088 ICE_FLOW_SET_HDRS(seg, ICE_FLOW_SEG_HDR_IPV6 | l4_proto);
1089
1090 if (!memcmp(tcp_ip6_spec->ip6src, &full_ipv6_addr_mask,
1091 sizeof(struct in6_addr)))
1092 ice_flow_set_fld(seg, ICE_FLOW_FIELD_IDX_IPV6_SA,
1093 ICE_FLOW_FLD_OFF_INVAL, ICE_FLOW_FLD_OFF_INVAL,
1094 ICE_FLOW_FLD_OFF_INVAL, false);
1095 else if (!memcmp(tcp_ip6_spec->ip6src, &zero_ipv6_addr_mask,
1096 sizeof(struct in6_addr)))
1097 *perfect_fltr = false;
1098 else
1099 return -EOPNOTSUPP;
1100
1101 if (!memcmp(tcp_ip6_spec->ip6dst, &full_ipv6_addr_mask,
1102 sizeof(struct in6_addr)))
1103 ice_flow_set_fld(seg, ICE_FLOW_FIELD_IDX_IPV6_DA,
1104 ICE_FLOW_FLD_OFF_INVAL, ICE_FLOW_FLD_OFF_INVAL,
1105 ICE_FLOW_FLD_OFF_INVAL, false);
1106 else if (!memcmp(tcp_ip6_spec->ip6dst, &zero_ipv6_addr_mask,
1107 sizeof(struct in6_addr)))
1108 *perfect_fltr = false;
1109 else
1110 return -EOPNOTSUPP;
1111
1112 /* Layer 4 source port */
1113 if (tcp_ip6_spec->psrc == htons(0xFFFF))
1114 ice_flow_set_fld(seg, src_port, ICE_FLOW_FLD_OFF_INVAL,
1115 ICE_FLOW_FLD_OFF_INVAL, ICE_FLOW_FLD_OFF_INVAL,
1116 false);
1117 else if (!tcp_ip6_spec->psrc)
1118 *perfect_fltr = false;
1119 else
1120 return -EOPNOTSUPP;
1121
1122 /* Layer 4 destination port */
1123 if (tcp_ip6_spec->pdst == htons(0xFFFF))
1124 ice_flow_set_fld(seg, dst_port, ICE_FLOW_FLD_OFF_INVAL,
1125 ICE_FLOW_FLD_OFF_INVAL, ICE_FLOW_FLD_OFF_INVAL,
1126 false);
1127 else if (!tcp_ip6_spec->pdst)
1128 *perfect_fltr = false;
1129 else
1130 return -EOPNOTSUPP;
1131
1132 return 0;
1133}
1134
1135/**
1136 * ice_set_fdir_ip6_usr_seg
1137 * @seg: flow segment for programming
1138 * @usr_ip6_spec: ethtool userdef packet offset
1139 * @perfect_fltr: only valid on success; returns true if perfect filter,
1140 * false if not
1141 *
1142 * Set the offset data into the flow segment to be used to program HW
1143 * table for IPv6
1144 */
1145static int
1146ice_set_fdir_ip6_usr_seg(struct ice_flow_seg_info *seg,
1147 struct ethtool_usrip6_spec *usr_ip6_spec,
1148 bool *perfect_fltr)
1149{
1150 /* filtering on Layer 4 bytes not supported */
1151 if (usr_ip6_spec->l4_4_bytes)
1152 return -EOPNOTSUPP;
1153 /* filtering on TC not supported */
1154 if (usr_ip6_spec->tclass)
1155 return -EOPNOTSUPP;
1156 /* filtering on Layer 4 protocol not supported */
1157 if (usr_ip6_spec->l4_proto)
1158 return -EOPNOTSUPP;
1159 /* empty rules are not valid */
1160 if (!memcmp(usr_ip6_spec->ip6src, &zero_ipv6_addr_mask,
1161 sizeof(struct in6_addr)) &&
1162 !memcmp(usr_ip6_spec->ip6dst, &zero_ipv6_addr_mask,
1163 sizeof(struct in6_addr)))
1164 return -EINVAL;
1165
1166 *perfect_fltr = true;
1167 ICE_FLOW_SET_HDRS(seg, ICE_FLOW_SEG_HDR_IPV6);
1168
1169 if (!memcmp(usr_ip6_spec->ip6src, &full_ipv6_addr_mask,
1170 sizeof(struct in6_addr)))
1171 ice_flow_set_fld(seg, ICE_FLOW_FIELD_IDX_IPV6_SA,
1172 ICE_FLOW_FLD_OFF_INVAL, ICE_FLOW_FLD_OFF_INVAL,
1173 ICE_FLOW_FLD_OFF_INVAL, false);
1174 else if (!memcmp(usr_ip6_spec->ip6src, &zero_ipv6_addr_mask,
1175 sizeof(struct in6_addr)))
1176 *perfect_fltr = false;
1177 else
1178 return -EOPNOTSUPP;
1179
1180 if (!memcmp(usr_ip6_spec->ip6dst, &full_ipv6_addr_mask,
1181 sizeof(struct in6_addr)))
1182 ice_flow_set_fld(seg, ICE_FLOW_FIELD_IDX_IPV6_DA,
1183 ICE_FLOW_FLD_OFF_INVAL, ICE_FLOW_FLD_OFF_INVAL,
1184 ICE_FLOW_FLD_OFF_INVAL, false);
1185 else if (!memcmp(usr_ip6_spec->ip6dst, &zero_ipv6_addr_mask,
1186 sizeof(struct in6_addr)))
1187 *perfect_fltr = false;
1188 else
1189 return -EOPNOTSUPP;
1190
1191 return 0;
1192}
1193
1194/**
1195 * ice_cfg_fdir_xtrct_seq - Configure extraction sequence for the given filter
1196 * @pf: PF structure
1197 * @fsp: pointer to ethtool Rx flow specification
1198 * @user: user defined data from flow specification
1199 *
1200 * Returns 0 on success.
1201 */
1202static int
1203ice_cfg_fdir_xtrct_seq(struct ice_pf *pf, struct ethtool_rx_flow_spec *fsp,
1204 struct ice_rx_flow_userdef *user)
1205{
1206 struct ice_flow_seg_info *seg, *tun_seg;
1207 struct device *dev = ice_pf_to_dev(pf);
1208 enum ice_fltr_ptype fltr_idx;
1209 struct ice_hw *hw = &pf->hw;
1210 bool perfect_filter;
1211 int ret;
1212
1213 seg = devm_kzalloc(dev, sizeof(*seg), GFP_KERNEL);
1214 if (!seg)
1215 return -ENOMEM;
1216
1217 tun_seg = devm_kcalloc(dev, ICE_FD_HW_SEG_MAX, sizeof(*tun_seg),
1218 GFP_KERNEL);
1219 if (!tun_seg) {
1220 devm_kfree(dev, seg);
1221 return -ENOMEM;
1222 }
1223
1224 switch (fsp->flow_type & ~FLOW_EXT) {
1225 case TCP_V4_FLOW:
1226 ret = ice_set_fdir_ip4_seg(seg, &fsp->m_u.tcp_ip4_spec,
1227 ICE_FLOW_SEG_HDR_TCP,
1228 &perfect_filter);
1229 break;
1230 case UDP_V4_FLOW:
1231 ret = ice_set_fdir_ip4_seg(seg, &fsp->m_u.tcp_ip4_spec,
1232 ICE_FLOW_SEG_HDR_UDP,
1233 &perfect_filter);
1234 break;
1235 case SCTP_V4_FLOW:
1236 ret = ice_set_fdir_ip4_seg(seg, &fsp->m_u.tcp_ip4_spec,
1237 ICE_FLOW_SEG_HDR_SCTP,
1238 &perfect_filter);
1239 break;
1240 case IPV4_USER_FLOW:
1241 ret = ice_set_fdir_ip4_usr_seg(seg, &fsp->m_u.usr_ip4_spec,
1242 &perfect_filter);
1243 break;
1244 case TCP_V6_FLOW:
1245 ret = ice_set_fdir_ip6_seg(seg, &fsp->m_u.tcp_ip6_spec,
1246 ICE_FLOW_SEG_HDR_TCP,
1247 &perfect_filter);
1248 break;
1249 case UDP_V6_FLOW:
1250 ret = ice_set_fdir_ip6_seg(seg, &fsp->m_u.tcp_ip6_spec,
1251 ICE_FLOW_SEG_HDR_UDP,
1252 &perfect_filter);
1253 break;
1254 case SCTP_V6_FLOW:
1255 ret = ice_set_fdir_ip6_seg(seg, &fsp->m_u.tcp_ip6_spec,
1256 ICE_FLOW_SEG_HDR_SCTP,
1257 &perfect_filter);
1258 break;
1259 case IPV6_USER_FLOW:
1260 ret = ice_set_fdir_ip6_usr_seg(seg, &fsp->m_u.usr_ip6_spec,
1261 &perfect_filter);
1262 break;
1263 default:
1264 ret = -EINVAL;
1265 }
1266 if (ret)
1267 goto err_exit;
1268
1269 /* tunnel segments are shifted up one. */
1270 memcpy(&tun_seg[1], seg, sizeof(*seg));
1271
1272 if (user && user->flex_fltr) {
1273 perfect_filter = false;
1274 ice_flow_add_fld_raw(seg, user->flex_offset,
1275 ICE_FLTR_PRGM_FLEX_WORD_SIZE,
1276 ICE_FLOW_FLD_OFF_INVAL,
1277 ICE_FLOW_FLD_OFF_INVAL);
1278 ice_flow_add_fld_raw(&tun_seg[1], user->flex_offset,
1279 ICE_FLTR_PRGM_FLEX_WORD_SIZE,
1280 ICE_FLOW_FLD_OFF_INVAL,
1281 ICE_FLOW_FLD_OFF_INVAL);
1282 }
1283
1284 /* add filter for outer headers */
1285 fltr_idx = ice_ethtool_flow_to_fltr(fsp->flow_type & ~FLOW_EXT);
1286 ret = ice_fdir_set_hw_fltr_rule(pf, seg, fltr_idx,
1287 ICE_FD_HW_SEG_NON_TUN);
1288 if (ret == -EEXIST)
1289 /* Rule already exists, free memory and continue */
1290 devm_kfree(dev, seg);
1291 else if (ret)
1292 /* could not write filter, free memory */
1293 goto err_exit;
1294
1295 /* make tunneled filter HW entries if possible */
1296 memcpy(&tun_seg[1], seg, sizeof(*seg));
1297 ret = ice_fdir_set_hw_fltr_rule(pf, tun_seg, fltr_idx,
1298 ICE_FD_HW_SEG_TUN);
1299 if (ret == -EEXIST) {
1300 /* Rule already exists, free memory and count as success */
1301 devm_kfree(dev, tun_seg);
1302 ret = 0;
1303 } else if (ret) {
1304 /* could not write tunnel filter, but outer filter exists */
1305 devm_kfree(dev, tun_seg);
1306 }
1307
1308 if (perfect_filter)
1309 set_bit(fltr_idx, hw->fdir_perfect_fltr);
1310 else
1311 clear_bit(fltr_idx, hw->fdir_perfect_fltr);
1312
1313 return ret;
1314
1315err_exit:
1316 devm_kfree(dev, tun_seg);
1317 devm_kfree(dev, seg);
1318
1319 return -EOPNOTSUPP;
1320}
1321
1322/**
1323 * ice_update_per_q_fltr
1324 * @vsi: ptr to VSI
1325 * @q_index: queue index
1326 * @inc: true to increment or false to decrement per queue filter count
1327 *
1328 * This function is used to keep track of per queue sideband filters
1329 */
1330static void ice_update_per_q_fltr(struct ice_vsi *vsi, u32 q_index, bool inc)
1331{
1332 struct ice_rx_ring *rx_ring;
1333
1334 if (!vsi->num_rxq || q_index >= vsi->num_rxq)
1335 return;
1336
1337 rx_ring = vsi->rx_rings[q_index];
1338 if (!rx_ring || !rx_ring->ch)
1339 return;
1340
1341 if (inc)
1342 atomic_inc(&rx_ring->ch->num_sb_fltr);
1343 else
1344 atomic_dec_if_positive(&rx_ring->ch->num_sb_fltr);
1345}
1346
1347/**
1348 * ice_fdir_write_fltr - send a flow director filter to the hardware
1349 * @pf: PF data structure
1350 * @input: filter structure
1351 * @add: true adds filter and false removed filter
1352 * @is_tun: true adds inner filter on tunnel and false outer headers
1353 *
1354 * returns 0 on success and negative value on error
1355 */
1356int
1357ice_fdir_write_fltr(struct ice_pf *pf, struct ice_fdir_fltr *input, bool add,
1358 bool is_tun)
1359{
1360 struct device *dev = ice_pf_to_dev(pf);
1361 struct ice_hw *hw = &pf->hw;
1362 struct ice_fltr_desc desc;
1363 struct ice_vsi *ctrl_vsi;
1364 u8 *pkt, *frag_pkt;
1365 bool has_frag;
1366 int err;
1367
1368 ctrl_vsi = ice_get_ctrl_vsi(pf);
1369 if (!ctrl_vsi)
1370 return -EINVAL;
1371
1372 pkt = devm_kzalloc(dev, ICE_FDIR_MAX_RAW_PKT_SIZE, GFP_KERNEL);
1373 if (!pkt)
1374 return -ENOMEM;
1375 frag_pkt = devm_kzalloc(dev, ICE_FDIR_MAX_RAW_PKT_SIZE, GFP_KERNEL);
1376 if (!frag_pkt) {
1377 err = -ENOMEM;
1378 goto err_free;
1379 }
1380
1381 ice_fdir_get_prgm_desc(hw, input, &desc, add);
1382 err = ice_fdir_get_gen_prgm_pkt(hw, input, pkt, false, is_tun);
1383 if (err)
1384 goto err_free_all;
1385 err = ice_prgm_fdir_fltr(ctrl_vsi, &desc, pkt);
1386 if (err)
1387 goto err_free_all;
1388
1389 /* repeat for fragment packet */
1390 has_frag = ice_fdir_has_frag(input->flow_type);
1391 if (has_frag) {
1392 /* does not return error */
1393 ice_fdir_get_prgm_desc(hw, input, &desc, add);
1394 err = ice_fdir_get_gen_prgm_pkt(hw, input, frag_pkt, true,
1395 is_tun);
1396 if (err)
1397 goto err_frag;
1398 err = ice_prgm_fdir_fltr(ctrl_vsi, &desc, frag_pkt);
1399 if (err)
1400 goto err_frag;
1401 } else {
1402 devm_kfree(dev, frag_pkt);
1403 }
1404
1405 return 0;
1406
1407err_free_all:
1408 devm_kfree(dev, frag_pkt);
1409err_free:
1410 devm_kfree(dev, pkt);
1411 return err;
1412
1413err_frag:
1414 devm_kfree(dev, frag_pkt);
1415 return err;
1416}
1417
1418/**
1419 * ice_fdir_write_all_fltr - send a flow director filter to the hardware
1420 * @pf: PF data structure
1421 * @input: filter structure
1422 * @add: true adds filter and false removed filter
1423 *
1424 * returns 0 on success and negative value on error
1425 */
1426static int
1427ice_fdir_write_all_fltr(struct ice_pf *pf, struct ice_fdir_fltr *input,
1428 bool add)
1429{
1430 u16 port_num;
1431 int tun;
1432
1433 for (tun = 0; tun < ICE_FD_HW_SEG_MAX; tun++) {
1434 bool is_tun = tun == ICE_FD_HW_SEG_TUN;
1435 int err;
1436
1437 if (is_tun && !ice_get_open_tunnel_port(&pf->hw, &port_num, TNL_ALL))
1438 continue;
1439 err = ice_fdir_write_fltr(pf, input, add, is_tun);
1440 if (err)
1441 return err;
1442 }
1443 return 0;
1444}
1445
1446/**
1447 * ice_fdir_replay_fltrs - replay filters from the HW filter list
1448 * @pf: board private structure
1449 */
1450void ice_fdir_replay_fltrs(struct ice_pf *pf)
1451{
1452 struct ice_fdir_fltr *f_rule;
1453 struct ice_hw *hw = &pf->hw;
1454
1455 list_for_each_entry(f_rule, &hw->fdir_list_head, fltr_node) {
1456 int err = ice_fdir_write_all_fltr(pf, f_rule, true);
1457
1458 if (err)
1459 dev_dbg(ice_pf_to_dev(pf), "Flow Director error %d, could not reprogram filter %d\n",
1460 err, f_rule->fltr_id);
1461 }
1462}
1463
1464/**
1465 * ice_fdir_create_dflt_rules - create default perfect filters
1466 * @pf: PF data structure
1467 *
1468 * Returns 0 for success or error.
1469 */
1470int ice_fdir_create_dflt_rules(struct ice_pf *pf)
1471{
1472 int err;
1473
1474 /* Create perfect TCP and UDP rules in hardware. */
1475 err = ice_create_init_fdir_rule(pf, ICE_FLTR_PTYPE_NONF_IPV4_TCP);
1476 if (err)
1477 return err;
1478
1479 err = ice_create_init_fdir_rule(pf, ICE_FLTR_PTYPE_NONF_IPV4_UDP);
1480 if (err)
1481 return err;
1482
1483 err = ice_create_init_fdir_rule(pf, ICE_FLTR_PTYPE_NONF_IPV6_TCP);
1484 if (err)
1485 return err;
1486
1487 err = ice_create_init_fdir_rule(pf, ICE_FLTR_PTYPE_NONF_IPV6_UDP);
1488
1489 return err;
1490}
1491
1492/**
1493 * ice_fdir_del_all_fltrs - Delete all flow director filters
1494 * @vsi: the VSI being changed
1495 *
1496 * This function needs to be called while holding hw->fdir_fltr_lock
1497 */
1498void ice_fdir_del_all_fltrs(struct ice_vsi *vsi)
1499{
1500 struct ice_fdir_fltr *f_rule, *tmp;
1501 struct ice_pf *pf = vsi->back;
1502 struct ice_hw *hw = &pf->hw;
1503
1504 list_for_each_entry_safe(f_rule, tmp, &hw->fdir_list_head, fltr_node) {
1505 ice_fdir_write_all_fltr(pf, f_rule, false);
1506 ice_fdir_update_cntrs(hw, f_rule->flow_type, false);
1507 list_del(&f_rule->fltr_node);
1508 devm_kfree(ice_pf_to_dev(pf), f_rule);
1509 }
1510}
1511
1512/**
1513 * ice_vsi_manage_fdir - turn on/off flow director
1514 * @vsi: the VSI being changed
1515 * @ena: boolean value indicating if this is an enable or disable request
1516 */
1517void ice_vsi_manage_fdir(struct ice_vsi *vsi, bool ena)
1518{
1519 struct ice_pf *pf = vsi->back;
1520 struct ice_hw *hw = &pf->hw;
1521 enum ice_fltr_ptype flow;
1522
1523 if (ena) {
1524 set_bit(ICE_FLAG_FD_ENA, pf->flags);
1525 ice_fdir_create_dflt_rules(pf);
1526 return;
1527 }
1528
1529 mutex_lock(&hw->fdir_fltr_lock);
1530 if (!test_and_clear_bit(ICE_FLAG_FD_ENA, pf->flags))
1531 goto release_lock;
1532
1533 ice_fdir_del_all_fltrs(vsi);
1534
1535 if (hw->fdir_prof)
1536 for (flow = ICE_FLTR_PTYPE_NONF_NONE; flow < ICE_FLTR_PTYPE_MAX;
1537 flow++)
1538 if (hw->fdir_prof[flow])
1539 ice_fdir_rem_flow(hw, ICE_BLK_FD, flow);
1540
1541release_lock:
1542 mutex_unlock(&hw->fdir_fltr_lock);
1543}
1544
1545/**
1546 * ice_fdir_do_rem_flow - delete flow and possibly add perfect flow
1547 * @pf: PF structure
1548 * @flow_type: FDir flow type to release
1549 */
1550static void
1551ice_fdir_do_rem_flow(struct ice_pf *pf, enum ice_fltr_ptype flow_type)
1552{
1553 struct ice_hw *hw = &pf->hw;
1554 bool need_perfect = false;
1555
1556 if (flow_type == ICE_FLTR_PTYPE_NONF_IPV4_TCP ||
1557 flow_type == ICE_FLTR_PTYPE_NONF_IPV4_UDP ||
1558 flow_type == ICE_FLTR_PTYPE_NONF_IPV6_TCP ||
1559 flow_type == ICE_FLTR_PTYPE_NONF_IPV6_UDP)
1560 need_perfect = true;
1561
1562 if (need_perfect && test_bit(flow_type, hw->fdir_perfect_fltr))
1563 return;
1564
1565 ice_fdir_rem_flow(hw, ICE_BLK_FD, flow_type);
1566 if (need_perfect)
1567 ice_create_init_fdir_rule(pf, flow_type);
1568}
1569
1570/**
1571 * ice_fdir_update_list_entry - add or delete a filter from the filter list
1572 * @pf: PF structure
1573 * @input: filter structure
1574 * @fltr_idx: ethtool index of filter to modify
1575 *
1576 * returns 0 on success and negative on errors
1577 */
1578static int
1579ice_fdir_update_list_entry(struct ice_pf *pf, struct ice_fdir_fltr *input,
1580 int fltr_idx)
1581{
1582 struct ice_fdir_fltr *old_fltr;
1583 struct ice_hw *hw = &pf->hw;
1584 struct ice_vsi *vsi;
1585 int err = -ENOENT;
1586
1587 /* Do not update filters during reset */
1588 if (ice_is_reset_in_progress(pf->state))
1589 return -EBUSY;
1590
1591 vsi = ice_get_main_vsi(pf);
1592 if (!vsi)
1593 return -EINVAL;
1594
1595 old_fltr = ice_fdir_find_fltr_by_idx(hw, fltr_idx);
1596 if (old_fltr) {
1597 err = ice_fdir_write_all_fltr(pf, old_fltr, false);
1598 if (err)
1599 return err;
1600 ice_fdir_update_cntrs(hw, old_fltr->flow_type, false);
1601 /* update sb-filters count, specific to ring->channel */
1602 ice_update_per_q_fltr(vsi, old_fltr->orig_q_index, false);
1603 if (!input && !hw->fdir_fltr_cnt[old_fltr->flow_type])
1604 /* we just deleted the last filter of flow_type so we
1605 * should also delete the HW filter info.
1606 */
1607 ice_fdir_do_rem_flow(pf, old_fltr->flow_type);
1608 list_del(&old_fltr->fltr_node);
1609 devm_kfree(ice_hw_to_dev(hw), old_fltr);
1610 }
1611 if (!input)
1612 return err;
1613 ice_fdir_list_add_fltr(hw, input);
1614 /* update sb-filters count, specific to ring->channel */
1615 ice_update_per_q_fltr(vsi, input->orig_q_index, true);
1616 ice_fdir_update_cntrs(hw, input->flow_type, true);
1617 return 0;
1618}
1619
1620/**
1621 * ice_del_fdir_ethtool - delete Flow Director filter
1622 * @vsi: pointer to target VSI
1623 * @cmd: command to add or delete Flow Director filter
1624 *
1625 * Returns 0 on success and negative values for failure
1626 */
1627int ice_del_fdir_ethtool(struct ice_vsi *vsi, struct ethtool_rxnfc *cmd)
1628{
1629 struct ethtool_rx_flow_spec *fsp =
1630 (struct ethtool_rx_flow_spec *)&cmd->fs;
1631 struct ice_pf *pf = vsi->back;
1632 struct ice_hw *hw = &pf->hw;
1633 int val;
1634
1635 if (!test_bit(ICE_FLAG_FD_ENA, pf->flags))
1636 return -EOPNOTSUPP;
1637
1638 /* Do not delete filters during reset */
1639 if (ice_is_reset_in_progress(pf->state)) {
1640 dev_err(ice_pf_to_dev(pf), "Device is resetting - deleting Flow Director filters not supported during reset\n");
1641 return -EBUSY;
1642 }
1643
1644 if (test_bit(ICE_FD_FLUSH_REQ, pf->state))
1645 return -EBUSY;
1646
1647 mutex_lock(&hw->fdir_fltr_lock);
1648 val = ice_fdir_update_list_entry(pf, NULL, fsp->location);
1649 mutex_unlock(&hw->fdir_fltr_lock);
1650
1651 return val;
1652}
1653
1654/**
1655 * ice_update_ring_dest_vsi - update dest ring and dest VSI
1656 * @vsi: pointer to target VSI
1657 * @dest_vsi: ptr to dest VSI index
1658 * @ring: ptr to dest ring
1659 *
1660 * This function updates destination VSI and queue if user specifies
1661 * target queue which falls in channel's (aka ADQ) queue region
1662 */
1663static void
1664ice_update_ring_dest_vsi(struct ice_vsi *vsi, u16 *dest_vsi, u32 *ring)
1665{
1666 struct ice_channel *ch;
1667
1668 list_for_each_entry(ch, &vsi->ch_list, list) {
1669 if (!ch->ch_vsi)
1670 continue;
1671
1672 /* make sure to locate corresponding channel based on "queue"
1673 * specified
1674 */
1675 if ((*ring < ch->base_q) ||
1676 (*ring >= (ch->base_q + ch->num_rxq)))
1677 continue;
1678
1679 /* update the dest_vsi based on channel */
1680 *dest_vsi = ch->ch_vsi->idx;
1681
1682 /* update the "ring" to be correct based on channel */
1683 *ring -= ch->base_q;
1684 }
1685}
1686
1687/**
1688 * ice_set_fdir_input_set - Set the input set for Flow Director
1689 * @vsi: pointer to target VSI
1690 * @fsp: pointer to ethtool Rx flow specification
1691 * @input: filter structure
1692 */
1693static int
1694ice_set_fdir_input_set(struct ice_vsi *vsi, struct ethtool_rx_flow_spec *fsp,
1695 struct ice_fdir_fltr *input)
1696{
1697 u16 dest_vsi, q_index = 0;
1698 u16 orig_q_index = 0;
1699 struct ice_pf *pf;
1700 struct ice_hw *hw;
1701 int flow_type;
1702 u8 dest_ctl;
1703
1704 if (!vsi || !fsp || !input)
1705 return -EINVAL;
1706
1707 pf = vsi->back;
1708 hw = &pf->hw;
1709
1710 dest_vsi = vsi->idx;
1711 if (fsp->ring_cookie == RX_CLS_FLOW_DISC) {
1712 dest_ctl = ICE_FLTR_PRGM_DESC_DEST_DROP_PKT;
1713 } else {
1714 u32 ring = ethtool_get_flow_spec_ring(fsp->ring_cookie);
1715 u8 vf = ethtool_get_flow_spec_ring_vf(fsp->ring_cookie);
1716
1717 if (vf) {
1718 dev_err(ice_pf_to_dev(pf), "Failed to add filter. Flow director filters are not supported on VF queues.\n");
1719 return -EINVAL;
1720 }
1721
1722 if (ring >= vsi->num_rxq)
1723 return -EINVAL;
1724
1725 orig_q_index = ring;
1726 ice_update_ring_dest_vsi(vsi, &dest_vsi, &ring);
1727 dest_ctl = ICE_FLTR_PRGM_DESC_DEST_DIRECT_PKT_QINDEX;
1728 q_index = ring;
1729 }
1730
1731 input->fltr_id = fsp->location;
1732 input->q_index = q_index;
1733 flow_type = fsp->flow_type & ~FLOW_EXT;
1734
1735 /* Record the original queue index as specified by user.
1736 * with channel configuration 'q_index' becomes relative
1737 * to TC (channel).
1738 */
1739 input->orig_q_index = orig_q_index;
1740 input->dest_vsi = dest_vsi;
1741 input->dest_ctl = dest_ctl;
1742 input->fltr_status = ICE_FLTR_PRGM_DESC_FD_STATUS_FD_ID;
1743 input->cnt_index = ICE_FD_SB_STAT_IDX(hw->fd_ctr_base);
1744 input->flow_type = ice_ethtool_flow_to_fltr(flow_type);
1745
1746 if (fsp->flow_type & FLOW_EXT) {
1747 memcpy(input->ext_data.usr_def, fsp->h_ext.data,
1748 sizeof(input->ext_data.usr_def));
1749 input->ext_data.vlan_type = fsp->h_ext.vlan_etype;
1750 input->ext_data.vlan_tag = fsp->h_ext.vlan_tci;
1751 memcpy(input->ext_mask.usr_def, fsp->m_ext.data,
1752 sizeof(input->ext_mask.usr_def));
1753 input->ext_mask.vlan_type = fsp->m_ext.vlan_etype;
1754 input->ext_mask.vlan_tag = fsp->m_ext.vlan_tci;
1755 }
1756
1757 switch (flow_type) {
1758 case TCP_V4_FLOW:
1759 case UDP_V4_FLOW:
1760 case SCTP_V4_FLOW:
1761 input->ip.v4.dst_port = fsp->h_u.tcp_ip4_spec.pdst;
1762 input->ip.v4.src_port = fsp->h_u.tcp_ip4_spec.psrc;
1763 input->ip.v4.dst_ip = fsp->h_u.tcp_ip4_spec.ip4dst;
1764 input->ip.v4.src_ip = fsp->h_u.tcp_ip4_spec.ip4src;
1765 input->mask.v4.dst_port = fsp->m_u.tcp_ip4_spec.pdst;
1766 input->mask.v4.src_port = fsp->m_u.tcp_ip4_spec.psrc;
1767 input->mask.v4.dst_ip = fsp->m_u.tcp_ip4_spec.ip4dst;
1768 input->mask.v4.src_ip = fsp->m_u.tcp_ip4_spec.ip4src;
1769 break;
1770 case IPV4_USER_FLOW:
1771 input->ip.v4.dst_ip = fsp->h_u.usr_ip4_spec.ip4dst;
1772 input->ip.v4.src_ip = fsp->h_u.usr_ip4_spec.ip4src;
1773 input->ip.v4.l4_header = fsp->h_u.usr_ip4_spec.l4_4_bytes;
1774 input->ip.v4.proto = fsp->h_u.usr_ip4_spec.proto;
1775 input->ip.v4.ip_ver = fsp->h_u.usr_ip4_spec.ip_ver;
1776 input->ip.v4.tos = fsp->h_u.usr_ip4_spec.tos;
1777 input->mask.v4.dst_ip = fsp->m_u.usr_ip4_spec.ip4dst;
1778 input->mask.v4.src_ip = fsp->m_u.usr_ip4_spec.ip4src;
1779 input->mask.v4.l4_header = fsp->m_u.usr_ip4_spec.l4_4_bytes;
1780 input->mask.v4.proto = fsp->m_u.usr_ip4_spec.proto;
1781 input->mask.v4.ip_ver = fsp->m_u.usr_ip4_spec.ip_ver;
1782 input->mask.v4.tos = fsp->m_u.usr_ip4_spec.tos;
1783 break;
1784 case TCP_V6_FLOW:
1785 case UDP_V6_FLOW:
1786 case SCTP_V6_FLOW:
1787 memcpy(input->ip.v6.dst_ip, fsp->h_u.usr_ip6_spec.ip6dst,
1788 sizeof(struct in6_addr));
1789 memcpy(input->ip.v6.src_ip, fsp->h_u.usr_ip6_spec.ip6src,
1790 sizeof(struct in6_addr));
1791 input->ip.v6.dst_port = fsp->h_u.tcp_ip6_spec.pdst;
1792 input->ip.v6.src_port = fsp->h_u.tcp_ip6_spec.psrc;
1793 input->ip.v6.tc = fsp->h_u.tcp_ip6_spec.tclass;
1794 memcpy(input->mask.v6.dst_ip, fsp->m_u.tcp_ip6_spec.ip6dst,
1795 sizeof(struct in6_addr));
1796 memcpy(input->mask.v6.src_ip, fsp->m_u.tcp_ip6_spec.ip6src,
1797 sizeof(struct in6_addr));
1798 input->mask.v6.dst_port = fsp->m_u.tcp_ip6_spec.pdst;
1799 input->mask.v6.src_port = fsp->m_u.tcp_ip6_spec.psrc;
1800 input->mask.v6.tc = fsp->m_u.tcp_ip6_spec.tclass;
1801 break;
1802 case IPV6_USER_FLOW:
1803 memcpy(input->ip.v6.dst_ip, fsp->h_u.usr_ip6_spec.ip6dst,
1804 sizeof(struct in6_addr));
1805 memcpy(input->ip.v6.src_ip, fsp->h_u.usr_ip6_spec.ip6src,
1806 sizeof(struct in6_addr));
1807 input->ip.v6.l4_header = fsp->h_u.usr_ip6_spec.l4_4_bytes;
1808 input->ip.v6.tc = fsp->h_u.usr_ip6_spec.tclass;
1809
1810 /* if no protocol requested, use IPPROTO_NONE */
1811 if (!fsp->m_u.usr_ip6_spec.l4_proto)
1812 input->ip.v6.proto = IPPROTO_NONE;
1813 else
1814 input->ip.v6.proto = fsp->h_u.usr_ip6_spec.l4_proto;
1815
1816 memcpy(input->mask.v6.dst_ip, fsp->m_u.usr_ip6_spec.ip6dst,
1817 sizeof(struct in6_addr));
1818 memcpy(input->mask.v6.src_ip, fsp->m_u.usr_ip6_spec.ip6src,
1819 sizeof(struct in6_addr));
1820 input->mask.v6.l4_header = fsp->m_u.usr_ip6_spec.l4_4_bytes;
1821 input->mask.v6.tc = fsp->m_u.usr_ip6_spec.tclass;
1822 input->mask.v6.proto = fsp->m_u.usr_ip6_spec.l4_proto;
1823 break;
1824 default:
1825 /* not doing un-parsed flow types */
1826 return -EINVAL;
1827 }
1828
1829 return 0;
1830}
1831
1832/**
1833 * ice_add_fdir_ethtool - Add/Remove Flow Director filter
1834 * @vsi: pointer to target VSI
1835 * @cmd: command to add or delete Flow Director filter
1836 *
1837 * Returns 0 on success and negative values for failure
1838 */
1839int ice_add_fdir_ethtool(struct ice_vsi *vsi, struct ethtool_rxnfc *cmd)
1840{
1841 struct ice_rx_flow_userdef userdata;
1842 struct ethtool_rx_flow_spec *fsp;
1843 struct ice_fdir_fltr *input;
1844 struct device *dev;
1845 struct ice_pf *pf;
1846 struct ice_hw *hw;
1847 int fltrs_needed;
1848 u16 tunnel_port;
1849 int ret;
1850
1851 if (!vsi)
1852 return -EINVAL;
1853
1854 pf = vsi->back;
1855 hw = &pf->hw;
1856 dev = ice_pf_to_dev(pf);
1857
1858 if (!test_bit(ICE_FLAG_FD_ENA, pf->flags))
1859 return -EOPNOTSUPP;
1860
1861 /* Do not program filters during reset */
1862 if (ice_is_reset_in_progress(pf->state)) {
1863 dev_err(dev, "Device is resetting - adding Flow Director filters not supported during reset\n");
1864 return -EBUSY;
1865 }
1866
1867 fsp = (struct ethtool_rx_flow_spec *)&cmd->fs;
1868
1869 if (ice_parse_rx_flow_user_data(fsp, &userdata))
1870 return -EINVAL;
1871
1872 if (fsp->flow_type & FLOW_MAC_EXT)
1873 return -EINVAL;
1874
1875 ret = ice_cfg_fdir_xtrct_seq(pf, fsp, &userdata);
1876 if (ret)
1877 return ret;
1878
1879 if (fsp->location >= ice_get_fdir_cnt_all(hw)) {
1880 dev_err(dev, "Failed to add filter. The maximum number of flow director filters has been reached.\n");
1881 return -ENOSPC;
1882 }
1883
1884 /* return error if not an update and no available filters */
1885 fltrs_needed = ice_get_open_tunnel_port(hw, &tunnel_port, TNL_ALL) ? 2 : 1;
1886 if (!ice_fdir_find_fltr_by_idx(hw, fsp->location) &&
1887 ice_fdir_num_avail_fltr(hw, pf->vsi[vsi->idx]) < fltrs_needed) {
1888 dev_err(dev, "Failed to add filter. The maximum number of flow director filters has been reached.\n");
1889 return -ENOSPC;
1890 }
1891
1892 input = devm_kzalloc(dev, sizeof(*input), GFP_KERNEL);
1893 if (!input)
1894 return -ENOMEM;
1895
1896 ret = ice_set_fdir_input_set(vsi, fsp, input);
1897 if (ret)
1898 goto free_input;
1899
1900 mutex_lock(&hw->fdir_fltr_lock);
1901 if (ice_fdir_is_dup_fltr(hw, input)) {
1902 ret = -EINVAL;
1903 goto release_lock;
1904 }
1905
1906 if (userdata.flex_fltr) {
1907 input->flex_fltr = true;
1908 input->flex_word = cpu_to_be16(userdata.flex_word);
1909 input->flex_offset = userdata.flex_offset;
1910 }
1911
1912 input->cnt_ena = ICE_FXD_FLTR_QW0_STAT_ENA_PKTS;
1913 input->fdid_prio = ICE_FXD_FLTR_QW1_FDID_PRI_THREE;
1914 input->comp_report = ICE_FXD_FLTR_QW0_COMP_REPORT_SW_FAIL;
1915
1916 /* input struct is added to the HW filter list */
1917 ice_fdir_update_list_entry(pf, input, fsp->location);
1918
1919 ret = ice_fdir_write_all_fltr(pf, input, true);
1920 if (ret)
1921 goto remove_sw_rule;
1922
1923 goto release_lock;
1924
1925remove_sw_rule:
1926 ice_fdir_update_cntrs(hw, input->flow_type, false);
1927 /* update sb-filters count, specific to ring->channel */
1928 ice_update_per_q_fltr(vsi, input->orig_q_index, false);
1929 list_del(&input->fltr_node);
1930release_lock:
1931 mutex_unlock(&hw->fdir_fltr_lock);
1932free_input:
1933 if (ret)
1934 devm_kfree(dev, input);
1935
1936 return ret;
1937}
1// SPDX-License-Identifier: GPL-2.0
2/* Copyright (C) 2018-2020, Intel Corporation. */
3
4/* flow director ethtool support for ice */
5
6#include "ice.h"
7#include "ice_lib.h"
8#include "ice_flow.h"
9
10static struct in6_addr full_ipv6_addr_mask = {
11 .in6_u = {
12 .u6_addr8 = {
13 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
14 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
15 }
16 }
17};
18
19static struct in6_addr zero_ipv6_addr_mask = {
20 .in6_u = {
21 .u6_addr8 = {
22 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
23 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
24 }
25 }
26};
27
28/* calls to ice_flow_add_prof require the number of segments in the array
29 * for segs_cnt. In this code that is one more than the index.
30 */
31#define TNL_SEG_CNT(_TNL_) ((_TNL_) + 1)
32
33/**
34 * ice_fltr_to_ethtool_flow - convert filter type values to ethtool
35 * flow type values
36 * @flow: filter type to be converted
37 *
38 * Returns the corresponding ethtool flow type.
39 */
40static int ice_fltr_to_ethtool_flow(enum ice_fltr_ptype flow)
41{
42 switch (flow) {
43 case ICE_FLTR_PTYPE_NONF_IPV4_TCP:
44 return TCP_V4_FLOW;
45 case ICE_FLTR_PTYPE_NONF_IPV4_UDP:
46 return UDP_V4_FLOW;
47 case ICE_FLTR_PTYPE_NONF_IPV4_SCTP:
48 return SCTP_V4_FLOW;
49 case ICE_FLTR_PTYPE_NONF_IPV4_OTHER:
50 return IPV4_USER_FLOW;
51 case ICE_FLTR_PTYPE_NONF_IPV6_TCP:
52 return TCP_V6_FLOW;
53 case ICE_FLTR_PTYPE_NONF_IPV6_UDP:
54 return UDP_V6_FLOW;
55 case ICE_FLTR_PTYPE_NONF_IPV6_SCTP:
56 return SCTP_V6_FLOW;
57 case ICE_FLTR_PTYPE_NONF_IPV6_OTHER:
58 return IPV6_USER_FLOW;
59 default:
60 /* 0 is undefined ethtool flow */
61 return 0;
62 }
63}
64
65/**
66 * ice_ethtool_flow_to_fltr - convert ethtool flow type to filter enum
67 * @eth: Ethtool flow type to be converted
68 *
69 * Returns flow enum
70 */
71static enum ice_fltr_ptype ice_ethtool_flow_to_fltr(int eth)
72{
73 switch (eth) {
74 case TCP_V4_FLOW:
75 return ICE_FLTR_PTYPE_NONF_IPV4_TCP;
76 case UDP_V4_FLOW:
77 return ICE_FLTR_PTYPE_NONF_IPV4_UDP;
78 case SCTP_V4_FLOW:
79 return ICE_FLTR_PTYPE_NONF_IPV4_SCTP;
80 case IPV4_USER_FLOW:
81 return ICE_FLTR_PTYPE_NONF_IPV4_OTHER;
82 case TCP_V6_FLOW:
83 return ICE_FLTR_PTYPE_NONF_IPV6_TCP;
84 case UDP_V6_FLOW:
85 return ICE_FLTR_PTYPE_NONF_IPV6_UDP;
86 case SCTP_V6_FLOW:
87 return ICE_FLTR_PTYPE_NONF_IPV6_SCTP;
88 case IPV6_USER_FLOW:
89 return ICE_FLTR_PTYPE_NONF_IPV6_OTHER;
90 default:
91 return ICE_FLTR_PTYPE_NONF_NONE;
92 }
93}
94
95/**
96 * ice_is_mask_valid - check mask field set
97 * @mask: full mask to check
98 * @field: field for which mask should be valid
99 *
100 * If the mask is fully set return true. If it is not valid for field return
101 * false.
102 */
103static bool ice_is_mask_valid(u64 mask, u64 field)
104{
105 return (mask & field) == field;
106}
107
108/**
109 * ice_get_ethtool_fdir_entry - fill ethtool structure with fdir filter data
110 * @hw: hardware structure that contains filter list
111 * @cmd: ethtool command data structure to receive the filter data
112 *
113 * Returns 0 on success and -EINVAL on failure
114 */
115int ice_get_ethtool_fdir_entry(struct ice_hw *hw, struct ethtool_rxnfc *cmd)
116{
117 struct ethtool_rx_flow_spec *fsp;
118 struct ice_fdir_fltr *rule;
119 int ret = 0;
120 u16 idx;
121
122 fsp = (struct ethtool_rx_flow_spec *)&cmd->fs;
123
124 mutex_lock(&hw->fdir_fltr_lock);
125
126 rule = ice_fdir_find_fltr_by_idx(hw, fsp->location);
127
128 if (!rule || fsp->location != rule->fltr_id) {
129 ret = -EINVAL;
130 goto release_lock;
131 }
132
133 fsp->flow_type = ice_fltr_to_ethtool_flow(rule->flow_type);
134
135 memset(&fsp->m_u, 0, sizeof(fsp->m_u));
136 memset(&fsp->m_ext, 0, sizeof(fsp->m_ext));
137
138 switch (fsp->flow_type) {
139 case IPV4_USER_FLOW:
140 fsp->h_u.usr_ip4_spec.ip_ver = ETH_RX_NFC_IP4;
141 fsp->h_u.usr_ip4_spec.proto = 0;
142 fsp->h_u.usr_ip4_spec.l4_4_bytes = rule->ip.v4.l4_header;
143 fsp->h_u.usr_ip4_spec.tos = rule->ip.v4.tos;
144 fsp->h_u.usr_ip4_spec.ip4src = rule->ip.v4.src_ip;
145 fsp->h_u.usr_ip4_spec.ip4dst = rule->ip.v4.dst_ip;
146 fsp->m_u.usr_ip4_spec.ip4src = rule->mask.v4.src_ip;
147 fsp->m_u.usr_ip4_spec.ip4dst = rule->mask.v4.dst_ip;
148 fsp->m_u.usr_ip4_spec.ip_ver = 0xFF;
149 fsp->m_u.usr_ip4_spec.proto = 0;
150 fsp->m_u.usr_ip4_spec.l4_4_bytes = rule->mask.v4.l4_header;
151 fsp->m_u.usr_ip4_spec.tos = rule->mask.v4.tos;
152 break;
153 case TCP_V4_FLOW:
154 case UDP_V4_FLOW:
155 case SCTP_V4_FLOW:
156 fsp->h_u.tcp_ip4_spec.psrc = rule->ip.v4.src_port;
157 fsp->h_u.tcp_ip4_spec.pdst = rule->ip.v4.dst_port;
158 fsp->h_u.tcp_ip4_spec.ip4src = rule->ip.v4.src_ip;
159 fsp->h_u.tcp_ip4_spec.ip4dst = rule->ip.v4.dst_ip;
160 fsp->m_u.tcp_ip4_spec.psrc = rule->mask.v4.src_port;
161 fsp->m_u.tcp_ip4_spec.pdst = rule->mask.v4.dst_port;
162 fsp->m_u.tcp_ip4_spec.ip4src = rule->mask.v4.src_ip;
163 fsp->m_u.tcp_ip4_spec.ip4dst = rule->mask.v4.dst_ip;
164 break;
165 case IPV6_USER_FLOW:
166 fsp->h_u.usr_ip6_spec.l4_4_bytes = rule->ip.v6.l4_header;
167 fsp->h_u.usr_ip6_spec.tclass = rule->ip.v6.tc;
168 fsp->h_u.usr_ip6_spec.l4_proto = rule->ip.v6.proto;
169 memcpy(fsp->h_u.tcp_ip6_spec.ip6src, rule->ip.v6.src_ip,
170 sizeof(struct in6_addr));
171 memcpy(fsp->h_u.tcp_ip6_spec.ip6dst, rule->ip.v6.dst_ip,
172 sizeof(struct in6_addr));
173 memcpy(fsp->m_u.tcp_ip6_spec.ip6src, rule->mask.v6.src_ip,
174 sizeof(struct in6_addr));
175 memcpy(fsp->m_u.tcp_ip6_spec.ip6dst, rule->mask.v6.dst_ip,
176 sizeof(struct in6_addr));
177 fsp->m_u.usr_ip6_spec.l4_4_bytes = rule->mask.v6.l4_header;
178 fsp->m_u.usr_ip6_spec.tclass = rule->mask.v6.tc;
179 fsp->m_u.usr_ip6_spec.l4_proto = rule->mask.v6.proto;
180 break;
181 case TCP_V6_FLOW:
182 case UDP_V6_FLOW:
183 case SCTP_V6_FLOW:
184 memcpy(fsp->h_u.tcp_ip6_spec.ip6src, rule->ip.v6.src_ip,
185 sizeof(struct in6_addr));
186 memcpy(fsp->h_u.tcp_ip6_spec.ip6dst, rule->ip.v6.dst_ip,
187 sizeof(struct in6_addr));
188 fsp->h_u.tcp_ip6_spec.psrc = rule->ip.v6.src_port;
189 fsp->h_u.tcp_ip6_spec.pdst = rule->ip.v6.dst_port;
190 memcpy(fsp->m_u.tcp_ip6_spec.ip6src,
191 rule->mask.v6.src_ip,
192 sizeof(struct in6_addr));
193 memcpy(fsp->m_u.tcp_ip6_spec.ip6dst,
194 rule->mask.v6.dst_ip,
195 sizeof(struct in6_addr));
196 fsp->m_u.tcp_ip6_spec.psrc = rule->mask.v6.src_port;
197 fsp->m_u.tcp_ip6_spec.pdst = rule->mask.v6.dst_port;
198 fsp->h_u.tcp_ip6_spec.tclass = rule->ip.v6.tc;
199 fsp->m_u.tcp_ip6_spec.tclass = rule->mask.v6.tc;
200 break;
201 default:
202 break;
203 }
204
205 if (rule->dest_ctl == ICE_FLTR_PRGM_DESC_DEST_DROP_PKT)
206 fsp->ring_cookie = RX_CLS_FLOW_DISC;
207 else
208 fsp->ring_cookie = rule->q_index;
209
210 idx = ice_ethtool_flow_to_fltr(fsp->flow_type);
211 if (idx == ICE_FLTR_PTYPE_NONF_NONE) {
212 dev_err(ice_hw_to_dev(hw), "Missing input index for flow_type %d\n",
213 rule->flow_type);
214 ret = -EINVAL;
215 }
216
217release_lock:
218 mutex_unlock(&hw->fdir_fltr_lock);
219 return ret;
220}
221
222/**
223 * ice_get_fdir_fltr_ids - fill buffer with filter IDs of active filters
224 * @hw: hardware structure containing the filter list
225 * @cmd: ethtool command data structure
226 * @rule_locs: ethtool array passed in from OS to receive filter IDs
227 *
228 * Returns 0 as expected for success by ethtool
229 */
230int
231ice_get_fdir_fltr_ids(struct ice_hw *hw, struct ethtool_rxnfc *cmd,
232 u32 *rule_locs)
233{
234 struct ice_fdir_fltr *f_rule;
235 unsigned int cnt = 0;
236 int val = 0;
237
238 /* report total rule count */
239 cmd->data = ice_get_fdir_cnt_all(hw);
240
241 mutex_lock(&hw->fdir_fltr_lock);
242
243 list_for_each_entry(f_rule, &hw->fdir_list_head, fltr_node) {
244 if (cnt == cmd->rule_cnt) {
245 val = -EMSGSIZE;
246 goto release_lock;
247 }
248 rule_locs[cnt] = f_rule->fltr_id;
249 cnt++;
250 }
251
252release_lock:
253 mutex_unlock(&hw->fdir_fltr_lock);
254 if (!val)
255 cmd->rule_cnt = cnt;
256 return val;
257}
258
259/**
260 * ice_fdir_get_hw_prof - return the ice_fd_hw_proc associated with a flow
261 * @hw: hardware structure containing the filter list
262 * @blk: hardware block
263 * @flow: FDir flow type to release
264 */
265static struct ice_fd_hw_prof *
266ice_fdir_get_hw_prof(struct ice_hw *hw, enum ice_block blk, int flow)
267{
268 if (blk == ICE_BLK_FD && hw->fdir_prof)
269 return hw->fdir_prof[flow];
270
271 return NULL;
272}
273
274/**
275 * ice_fdir_erase_flow_from_hw - remove a flow from the HW profile tables
276 * @hw: hardware structure containing the filter list
277 * @blk: hardware block
278 * @flow: FDir flow type to release
279 */
280static void
281ice_fdir_erase_flow_from_hw(struct ice_hw *hw, enum ice_block blk, int flow)
282{
283 struct ice_fd_hw_prof *prof = ice_fdir_get_hw_prof(hw, blk, flow);
284 int tun;
285
286 if (!prof)
287 return;
288
289 for (tun = 0; tun < ICE_FD_HW_SEG_MAX; tun++) {
290 u64 prof_id;
291 int j;
292
293 prof_id = flow + tun * ICE_FLTR_PTYPE_MAX;
294 for (j = 0; j < prof->cnt; j++) {
295 u16 vsi_num;
296
297 if (!prof->entry_h[j][tun] || !prof->vsi_h[j])
298 continue;
299 vsi_num = ice_get_hw_vsi_num(hw, prof->vsi_h[j]);
300 ice_rem_prof_id_flow(hw, blk, vsi_num, prof_id);
301 ice_flow_rem_entry(hw, blk, prof->entry_h[j][tun]);
302 prof->entry_h[j][tun] = 0;
303 }
304 ice_flow_rem_prof(hw, blk, prof_id);
305 }
306}
307
308/**
309 * ice_fdir_rem_flow - release the ice_flow structures for a filter type
310 * @hw: hardware structure containing the filter list
311 * @blk: hardware block
312 * @flow_type: FDir flow type to release
313 */
314static void
315ice_fdir_rem_flow(struct ice_hw *hw, enum ice_block blk,
316 enum ice_fltr_ptype flow_type)
317{
318 int flow = (int)flow_type & ~FLOW_EXT;
319 struct ice_fd_hw_prof *prof;
320 int tun, i;
321
322 prof = ice_fdir_get_hw_prof(hw, blk, flow);
323 if (!prof)
324 return;
325
326 ice_fdir_erase_flow_from_hw(hw, blk, flow);
327 for (i = 0; i < prof->cnt; i++)
328 prof->vsi_h[i] = 0;
329 for (tun = 0; tun < ICE_FD_HW_SEG_MAX; tun++) {
330 if (!prof->fdir_seg[tun])
331 continue;
332 devm_kfree(ice_hw_to_dev(hw), prof->fdir_seg[tun]);
333 prof->fdir_seg[tun] = NULL;
334 }
335 prof->cnt = 0;
336}
337
338/**
339 * ice_fdir_release_flows - release all flows in use for later replay
340 * @hw: pointer to HW instance
341 */
342void ice_fdir_release_flows(struct ice_hw *hw)
343{
344 int flow;
345
346 /* release Flow Director HW table entries */
347 for (flow = 0; flow < ICE_FLTR_PTYPE_MAX; flow++)
348 ice_fdir_erase_flow_from_hw(hw, ICE_BLK_FD, flow);
349}
350
351/**
352 * ice_fdir_replay_flows - replay HW Flow Director filter info
353 * @hw: pointer to HW instance
354 */
355void ice_fdir_replay_flows(struct ice_hw *hw)
356{
357 int flow;
358
359 for (flow = 0; flow < ICE_FLTR_PTYPE_MAX; flow++) {
360 int tun;
361
362 if (!hw->fdir_prof[flow] || !hw->fdir_prof[flow]->cnt)
363 continue;
364 for (tun = 0; tun < ICE_FD_HW_SEG_MAX; tun++) {
365 struct ice_flow_prof *hw_prof;
366 struct ice_fd_hw_prof *prof;
367 u64 prof_id;
368 int j;
369
370 prof = hw->fdir_prof[flow];
371 prof_id = flow + tun * ICE_FLTR_PTYPE_MAX;
372 ice_flow_add_prof(hw, ICE_BLK_FD, ICE_FLOW_RX, prof_id,
373 prof->fdir_seg[tun], TNL_SEG_CNT(tun),
374 &hw_prof);
375 for (j = 0; j < prof->cnt; j++) {
376 enum ice_flow_priority prio;
377 u64 entry_h = 0;
378 int err;
379
380 prio = ICE_FLOW_PRIO_NORMAL;
381 err = ice_flow_add_entry(hw, ICE_BLK_FD,
382 prof_id,
383 prof->vsi_h[0],
384 prof->vsi_h[j],
385 prio, prof->fdir_seg,
386 &entry_h);
387 if (err) {
388 dev_err(ice_hw_to_dev(hw), "Could not replay Flow Director, flow type %d\n",
389 flow);
390 continue;
391 }
392 prof->entry_h[j][tun] = entry_h;
393 }
394 }
395 }
396}
397
398/**
399 * ice_parse_rx_flow_user_data - deconstruct user-defined data
400 * @fsp: pointer to ethtool Rx flow specification
401 * @data: pointer to userdef data structure for storage
402 *
403 * Returns 0 on success, negative error value on failure
404 */
405static int
406ice_parse_rx_flow_user_data(struct ethtool_rx_flow_spec *fsp,
407 struct ice_rx_flow_userdef *data)
408{
409 u64 value, mask;
410
411 memset(data, 0, sizeof(*data));
412 if (!(fsp->flow_type & FLOW_EXT))
413 return 0;
414
415 value = be64_to_cpu(*((__force __be64 *)fsp->h_ext.data));
416 mask = be64_to_cpu(*((__force __be64 *)fsp->m_ext.data));
417 if (!mask)
418 return 0;
419
420#define ICE_USERDEF_FLEX_WORD_M GENMASK_ULL(15, 0)
421#define ICE_USERDEF_FLEX_OFFS_S 16
422#define ICE_USERDEF_FLEX_OFFS_M GENMASK_ULL(31, ICE_USERDEF_FLEX_OFFS_S)
423#define ICE_USERDEF_FLEX_FLTR_M GENMASK_ULL(31, 0)
424
425 /* 0x1fe is the maximum value for offsets stored in the internal
426 * filtering tables.
427 */
428#define ICE_USERDEF_FLEX_MAX_OFFS_VAL 0x1fe
429
430 if (!ice_is_mask_valid(mask, ICE_USERDEF_FLEX_FLTR_M) ||
431 value > ICE_USERDEF_FLEX_FLTR_M)
432 return -EINVAL;
433
434 data->flex_word = value & ICE_USERDEF_FLEX_WORD_M;
435 data->flex_offset = (value & ICE_USERDEF_FLEX_OFFS_M) >>
436 ICE_USERDEF_FLEX_OFFS_S;
437 if (data->flex_offset > ICE_USERDEF_FLEX_MAX_OFFS_VAL)
438 return -EINVAL;
439
440 data->flex_fltr = true;
441
442 return 0;
443}
444
445/**
446 * ice_fdir_num_avail_fltr - return the number of unused flow director filters
447 * @hw: pointer to hardware structure
448 * @vsi: software VSI structure
449 *
450 * There are 2 filter pools: guaranteed and best effort(shared). Each VSI can
451 * use filters from either pool. The guaranteed pool is divided between VSIs.
452 * The best effort filter pool is common to all VSIs and is a device shared
453 * resource pool. The number of filters available to this VSI is the sum of
454 * the VSIs guaranteed filter pool and the global available best effort
455 * filter pool.
456 *
457 * Returns the number of available flow director filters to this VSI
458 */
459static int ice_fdir_num_avail_fltr(struct ice_hw *hw, struct ice_vsi *vsi)
460{
461 u16 vsi_num = ice_get_hw_vsi_num(hw, vsi->idx);
462 u16 num_guar;
463 u16 num_be;
464
465 /* total guaranteed filters assigned to this VSI */
466 num_guar = vsi->num_gfltr;
467
468 /* minus the guaranteed filters programed by this VSI */
469 num_guar -= (rd32(hw, VSIQF_FD_CNT(vsi_num)) &
470 VSIQF_FD_CNT_FD_GCNT_M) >> VSIQF_FD_CNT_FD_GCNT_S;
471
472 /* total global best effort filters */
473 num_be = hw->func_caps.fd_fltr_best_effort;
474
475 /* minus the global best effort filters programmed */
476 num_be -= (rd32(hw, GLQF_FD_CNT) & GLQF_FD_CNT_FD_BCNT_M) >>
477 GLQF_FD_CNT_FD_BCNT_S;
478
479 return num_guar + num_be;
480}
481
482/**
483 * ice_fdir_alloc_flow_prof - allocate FDir flow profile structure(s)
484 * @hw: HW structure containing the FDir flow profile structure(s)
485 * @flow: flow type to allocate the flow profile for
486 *
487 * Allocate the fdir_prof and fdir_prof[flow] if not already created. Return 0
488 * on success and negative on error.
489 */
490static int
491ice_fdir_alloc_flow_prof(struct ice_hw *hw, enum ice_fltr_ptype flow)
492{
493 if (!hw)
494 return -EINVAL;
495
496 if (!hw->fdir_prof) {
497 hw->fdir_prof = devm_kcalloc(ice_hw_to_dev(hw),
498 ICE_FLTR_PTYPE_MAX,
499 sizeof(*hw->fdir_prof),
500 GFP_KERNEL);
501 if (!hw->fdir_prof)
502 return -ENOMEM;
503 }
504
505 if (!hw->fdir_prof[flow]) {
506 hw->fdir_prof[flow] = devm_kzalloc(ice_hw_to_dev(hw),
507 sizeof(**hw->fdir_prof),
508 GFP_KERNEL);
509 if (!hw->fdir_prof[flow])
510 return -ENOMEM;
511 }
512
513 return 0;
514}
515
516/**
517 * ice_fdir_set_hw_fltr_rule - Configure HW tables to generate a FDir rule
518 * @pf: pointer to the PF structure
519 * @seg: protocol header description pointer
520 * @flow: filter enum
521 * @tun: FDir segment to program
522 */
523static int
524ice_fdir_set_hw_fltr_rule(struct ice_pf *pf, struct ice_flow_seg_info *seg,
525 enum ice_fltr_ptype flow, enum ice_fd_hw_seg tun)
526{
527 struct device *dev = ice_pf_to_dev(pf);
528 struct ice_vsi *main_vsi, *ctrl_vsi;
529 struct ice_flow_seg_info *old_seg;
530 struct ice_flow_prof *prof = NULL;
531 struct ice_fd_hw_prof *hw_prof;
532 struct ice_hw *hw = &pf->hw;
533 enum ice_status status;
534 u64 entry1_h = 0;
535 u64 entry2_h = 0;
536 u64 prof_id;
537 int err;
538
539 main_vsi = ice_get_main_vsi(pf);
540 if (!main_vsi)
541 return -EINVAL;
542
543 ctrl_vsi = ice_get_ctrl_vsi(pf);
544 if (!ctrl_vsi)
545 return -EINVAL;
546
547 err = ice_fdir_alloc_flow_prof(hw, flow);
548 if (err)
549 return err;
550
551 hw_prof = hw->fdir_prof[flow];
552 old_seg = hw_prof->fdir_seg[tun];
553 if (old_seg) {
554 /* This flow_type already has a changed input set.
555 * If it matches the requested input set then we are
556 * done. Or, if it's different then it's an error.
557 */
558 if (!memcmp(old_seg, seg, sizeof(*seg)))
559 return -EEXIST;
560
561 /* if there are FDir filters using this flow,
562 * then return error.
563 */
564 if (hw->fdir_fltr_cnt[flow]) {
565 dev_err(dev, "Failed to add filter. Flow director filters on each port must have the same input set.\n");
566 return -EINVAL;
567 }
568
569 if (ice_is_arfs_using_perfect_flow(hw, flow)) {
570 dev_err(dev, "aRFS using perfect flow type %d, cannot change input set\n",
571 flow);
572 return -EINVAL;
573 }
574
575 /* remove HW filter definition */
576 ice_fdir_rem_flow(hw, ICE_BLK_FD, flow);
577 }
578
579 /* Adding a profile, but there is only one header supported.
580 * That is the final parameters are 1 header (segment), no
581 * actions (NULL) and zero actions 0.
582 */
583 prof_id = flow + tun * ICE_FLTR_PTYPE_MAX;
584 status = ice_flow_add_prof(hw, ICE_BLK_FD, ICE_FLOW_RX, prof_id, seg,
585 TNL_SEG_CNT(tun), &prof);
586 if (status)
587 return ice_status_to_errno(status);
588 status = ice_flow_add_entry(hw, ICE_BLK_FD, prof_id, main_vsi->idx,
589 main_vsi->idx, ICE_FLOW_PRIO_NORMAL,
590 seg, &entry1_h);
591 if (status) {
592 err = ice_status_to_errno(status);
593 goto err_prof;
594 }
595 status = ice_flow_add_entry(hw, ICE_BLK_FD, prof_id, main_vsi->idx,
596 ctrl_vsi->idx, ICE_FLOW_PRIO_NORMAL,
597 seg, &entry2_h);
598 if (status) {
599 err = ice_status_to_errno(status);
600 goto err_entry;
601 }
602
603 hw_prof->fdir_seg[tun] = seg;
604 hw_prof->entry_h[0][tun] = entry1_h;
605 hw_prof->entry_h[1][tun] = entry2_h;
606 hw_prof->vsi_h[0] = main_vsi->idx;
607 hw_prof->vsi_h[1] = ctrl_vsi->idx;
608 if (!hw_prof->cnt)
609 hw_prof->cnt = 2;
610
611 return 0;
612
613err_entry:
614 ice_rem_prof_id_flow(hw, ICE_BLK_FD,
615 ice_get_hw_vsi_num(hw, main_vsi->idx), prof_id);
616 ice_flow_rem_entry(hw, ICE_BLK_FD, entry1_h);
617err_prof:
618 ice_flow_rem_prof(hw, ICE_BLK_FD, prof_id);
619 dev_err(dev, "Failed to add filter. Flow director filters on each port must have the same input set.\n");
620
621 return err;
622}
623
624/**
625 * ice_set_init_fdir_seg
626 * @seg: flow segment for programming
627 * @l3_proto: ICE_FLOW_SEG_HDR_IPV4 or ICE_FLOW_SEG_HDR_IPV6
628 * @l4_proto: ICE_FLOW_SEG_HDR_TCP or ICE_FLOW_SEG_HDR_UDP
629 *
630 * Set the configuration for perfect filters to the provided flow segment for
631 * programming the HW filter. This is to be called only when initializing
632 * filters as this function it assumes no filters exist.
633 */
634static int
635ice_set_init_fdir_seg(struct ice_flow_seg_info *seg,
636 enum ice_flow_seg_hdr l3_proto,
637 enum ice_flow_seg_hdr l4_proto)
638{
639 enum ice_flow_field src_addr, dst_addr, src_port, dst_port;
640
641 if (!seg)
642 return -EINVAL;
643
644 if (l3_proto == ICE_FLOW_SEG_HDR_IPV4) {
645 src_addr = ICE_FLOW_FIELD_IDX_IPV4_SA;
646 dst_addr = ICE_FLOW_FIELD_IDX_IPV4_DA;
647 } else if (l3_proto == ICE_FLOW_SEG_HDR_IPV6) {
648 src_addr = ICE_FLOW_FIELD_IDX_IPV6_SA;
649 dst_addr = ICE_FLOW_FIELD_IDX_IPV6_DA;
650 } else {
651 return -EINVAL;
652 }
653
654 if (l4_proto == ICE_FLOW_SEG_HDR_TCP) {
655 src_port = ICE_FLOW_FIELD_IDX_TCP_SRC_PORT;
656 dst_port = ICE_FLOW_FIELD_IDX_TCP_DST_PORT;
657 } else if (l4_proto == ICE_FLOW_SEG_HDR_UDP) {
658 src_port = ICE_FLOW_FIELD_IDX_UDP_SRC_PORT;
659 dst_port = ICE_FLOW_FIELD_IDX_UDP_DST_PORT;
660 } else {
661 return -EINVAL;
662 }
663
664 ICE_FLOW_SET_HDRS(seg, l3_proto | l4_proto);
665
666 /* IP source address */
667 ice_flow_set_fld(seg, src_addr, ICE_FLOW_FLD_OFF_INVAL,
668 ICE_FLOW_FLD_OFF_INVAL, ICE_FLOW_FLD_OFF_INVAL, false);
669
670 /* IP destination address */
671 ice_flow_set_fld(seg, dst_addr, ICE_FLOW_FLD_OFF_INVAL,
672 ICE_FLOW_FLD_OFF_INVAL, ICE_FLOW_FLD_OFF_INVAL, false);
673
674 /* Layer 4 source port */
675 ice_flow_set_fld(seg, src_port, ICE_FLOW_FLD_OFF_INVAL,
676 ICE_FLOW_FLD_OFF_INVAL, ICE_FLOW_FLD_OFF_INVAL, false);
677
678 /* Layer 4 destination port */
679 ice_flow_set_fld(seg, dst_port, ICE_FLOW_FLD_OFF_INVAL,
680 ICE_FLOW_FLD_OFF_INVAL, ICE_FLOW_FLD_OFF_INVAL, false);
681
682 return 0;
683}
684
685/**
686 * ice_create_init_fdir_rule
687 * @pf: PF structure
688 * @flow: filter enum
689 *
690 * Return error value or 0 on success.
691 */
692static int
693ice_create_init_fdir_rule(struct ice_pf *pf, enum ice_fltr_ptype flow)
694{
695 struct ice_flow_seg_info *seg, *tun_seg;
696 struct device *dev = ice_pf_to_dev(pf);
697 struct ice_hw *hw = &pf->hw;
698 int ret;
699
700 /* if there is already a filter rule for kind return -EINVAL */
701 if (hw->fdir_prof && hw->fdir_prof[flow] &&
702 hw->fdir_prof[flow]->fdir_seg[0])
703 return -EINVAL;
704
705 seg = devm_kzalloc(dev, sizeof(*seg), GFP_KERNEL);
706 if (!seg)
707 return -ENOMEM;
708
709 tun_seg = devm_kzalloc(dev, sizeof(*seg) * ICE_FD_HW_SEG_MAX,
710 GFP_KERNEL);
711 if (!tun_seg) {
712 devm_kfree(dev, seg);
713 return -ENOMEM;
714 }
715
716 if (flow == ICE_FLTR_PTYPE_NONF_IPV4_TCP)
717 ret = ice_set_init_fdir_seg(seg, ICE_FLOW_SEG_HDR_IPV4,
718 ICE_FLOW_SEG_HDR_TCP);
719 else if (flow == ICE_FLTR_PTYPE_NONF_IPV4_UDP)
720 ret = ice_set_init_fdir_seg(seg, ICE_FLOW_SEG_HDR_IPV4,
721 ICE_FLOW_SEG_HDR_UDP);
722 else if (flow == ICE_FLTR_PTYPE_NONF_IPV6_TCP)
723 ret = ice_set_init_fdir_seg(seg, ICE_FLOW_SEG_HDR_IPV6,
724 ICE_FLOW_SEG_HDR_TCP);
725 else if (flow == ICE_FLTR_PTYPE_NONF_IPV6_UDP)
726 ret = ice_set_init_fdir_seg(seg, ICE_FLOW_SEG_HDR_IPV6,
727 ICE_FLOW_SEG_HDR_UDP);
728 else
729 ret = -EINVAL;
730 if (ret)
731 goto err_exit;
732
733 /* add filter for outer headers */
734 ret = ice_fdir_set_hw_fltr_rule(pf, seg, flow, ICE_FD_HW_SEG_NON_TUN);
735 if (ret)
736 /* could not write filter, free memory */
737 goto err_exit;
738
739 /* make tunneled filter HW entries if possible */
740 memcpy(&tun_seg[1], seg, sizeof(*seg));
741 ret = ice_fdir_set_hw_fltr_rule(pf, tun_seg, flow, ICE_FD_HW_SEG_TUN);
742 if (ret)
743 /* could not write tunnel filter, but outer header filter
744 * exists
745 */
746 devm_kfree(dev, tun_seg);
747
748 set_bit(flow, hw->fdir_perfect_fltr);
749 return ret;
750err_exit:
751 devm_kfree(dev, tun_seg);
752 devm_kfree(dev, seg);
753
754 return -EOPNOTSUPP;
755}
756
757/**
758 * ice_set_fdir_ip4_seg
759 * @seg: flow segment for programming
760 * @tcp_ip4_spec: mask data from ethtool
761 * @l4_proto: Layer 4 protocol to program
762 * @perfect_fltr: only valid on success; returns true if perfect filter,
763 * false if not
764 *
765 * Set the mask data into the flow segment to be used to program HW
766 * table based on provided L4 protocol for IPv4
767 */
768static int
769ice_set_fdir_ip4_seg(struct ice_flow_seg_info *seg,
770 struct ethtool_tcpip4_spec *tcp_ip4_spec,
771 enum ice_flow_seg_hdr l4_proto, bool *perfect_fltr)
772{
773 enum ice_flow_field src_port, dst_port;
774
775 /* make sure we don't have any empty rule */
776 if (!tcp_ip4_spec->psrc && !tcp_ip4_spec->ip4src &&
777 !tcp_ip4_spec->pdst && !tcp_ip4_spec->ip4dst)
778 return -EINVAL;
779
780 /* filtering on TOS not supported */
781 if (tcp_ip4_spec->tos)
782 return -EOPNOTSUPP;
783
784 if (l4_proto == ICE_FLOW_SEG_HDR_TCP) {
785 src_port = ICE_FLOW_FIELD_IDX_TCP_SRC_PORT;
786 dst_port = ICE_FLOW_FIELD_IDX_TCP_DST_PORT;
787 } else if (l4_proto == ICE_FLOW_SEG_HDR_UDP) {
788 src_port = ICE_FLOW_FIELD_IDX_UDP_SRC_PORT;
789 dst_port = ICE_FLOW_FIELD_IDX_UDP_DST_PORT;
790 } else if (l4_proto == ICE_FLOW_SEG_HDR_SCTP) {
791 src_port = ICE_FLOW_FIELD_IDX_SCTP_SRC_PORT;
792 dst_port = ICE_FLOW_FIELD_IDX_SCTP_DST_PORT;
793 } else {
794 return -EOPNOTSUPP;
795 }
796
797 *perfect_fltr = true;
798 ICE_FLOW_SET_HDRS(seg, ICE_FLOW_SEG_HDR_IPV4 | l4_proto);
799
800 /* IP source address */
801 if (tcp_ip4_spec->ip4src == htonl(0xFFFFFFFF))
802 ice_flow_set_fld(seg, ICE_FLOW_FIELD_IDX_IPV4_SA,
803 ICE_FLOW_FLD_OFF_INVAL, ICE_FLOW_FLD_OFF_INVAL,
804 ICE_FLOW_FLD_OFF_INVAL, false);
805 else if (!tcp_ip4_spec->ip4src)
806 *perfect_fltr = false;
807 else
808 return -EOPNOTSUPP;
809
810 /* IP destination address */
811 if (tcp_ip4_spec->ip4dst == htonl(0xFFFFFFFF))
812 ice_flow_set_fld(seg, ICE_FLOW_FIELD_IDX_IPV4_DA,
813 ICE_FLOW_FLD_OFF_INVAL, ICE_FLOW_FLD_OFF_INVAL,
814 ICE_FLOW_FLD_OFF_INVAL, false);
815 else if (!tcp_ip4_spec->ip4dst)
816 *perfect_fltr = false;
817 else
818 return -EOPNOTSUPP;
819
820 /* Layer 4 source port */
821 if (tcp_ip4_spec->psrc == htons(0xFFFF))
822 ice_flow_set_fld(seg, src_port, ICE_FLOW_FLD_OFF_INVAL,
823 ICE_FLOW_FLD_OFF_INVAL, ICE_FLOW_FLD_OFF_INVAL,
824 false);
825 else if (!tcp_ip4_spec->psrc)
826 *perfect_fltr = false;
827 else
828 return -EOPNOTSUPP;
829
830 /* Layer 4 destination port */
831 if (tcp_ip4_spec->pdst == htons(0xFFFF))
832 ice_flow_set_fld(seg, dst_port, ICE_FLOW_FLD_OFF_INVAL,
833 ICE_FLOW_FLD_OFF_INVAL, ICE_FLOW_FLD_OFF_INVAL,
834 false);
835 else if (!tcp_ip4_spec->pdst)
836 *perfect_fltr = false;
837 else
838 return -EOPNOTSUPP;
839
840 return 0;
841}
842
843/**
844 * ice_set_fdir_ip4_usr_seg
845 * @seg: flow segment for programming
846 * @usr_ip4_spec: ethtool userdef packet offset
847 * @perfect_fltr: only valid on success; returns true if perfect filter,
848 * false if not
849 *
850 * Set the offset data into the flow segment to be used to program HW
851 * table for IPv4
852 */
853static int
854ice_set_fdir_ip4_usr_seg(struct ice_flow_seg_info *seg,
855 struct ethtool_usrip4_spec *usr_ip4_spec,
856 bool *perfect_fltr)
857{
858 /* first 4 bytes of Layer 4 header */
859 if (usr_ip4_spec->l4_4_bytes)
860 return -EINVAL;
861 if (usr_ip4_spec->tos)
862 return -EINVAL;
863 if (usr_ip4_spec->ip_ver)
864 return -EINVAL;
865 /* Filtering on Layer 4 protocol not supported */
866 if (usr_ip4_spec->proto)
867 return -EOPNOTSUPP;
868 /* empty rules are not valid */
869 if (!usr_ip4_spec->ip4src && !usr_ip4_spec->ip4dst)
870 return -EINVAL;
871
872 *perfect_fltr = true;
873 ICE_FLOW_SET_HDRS(seg, ICE_FLOW_SEG_HDR_IPV4);
874
875 /* IP source address */
876 if (usr_ip4_spec->ip4src == htonl(0xFFFFFFFF))
877 ice_flow_set_fld(seg, ICE_FLOW_FIELD_IDX_IPV4_SA,
878 ICE_FLOW_FLD_OFF_INVAL, ICE_FLOW_FLD_OFF_INVAL,
879 ICE_FLOW_FLD_OFF_INVAL, false);
880 else if (!usr_ip4_spec->ip4src)
881 *perfect_fltr = false;
882 else
883 return -EOPNOTSUPP;
884
885 /* IP destination address */
886 if (usr_ip4_spec->ip4dst == htonl(0xFFFFFFFF))
887 ice_flow_set_fld(seg, ICE_FLOW_FIELD_IDX_IPV4_DA,
888 ICE_FLOW_FLD_OFF_INVAL, ICE_FLOW_FLD_OFF_INVAL,
889 ICE_FLOW_FLD_OFF_INVAL, false);
890 else if (!usr_ip4_spec->ip4dst)
891 *perfect_fltr = false;
892 else
893 return -EOPNOTSUPP;
894
895 return 0;
896}
897
898/**
899 * ice_set_fdir_ip6_seg
900 * @seg: flow segment for programming
901 * @tcp_ip6_spec: mask data from ethtool
902 * @l4_proto: Layer 4 protocol to program
903 * @perfect_fltr: only valid on success; returns true if perfect filter,
904 * false if not
905 *
906 * Set the mask data into the flow segment to be used to program HW
907 * table based on provided L4 protocol for IPv6
908 */
909static int
910ice_set_fdir_ip6_seg(struct ice_flow_seg_info *seg,
911 struct ethtool_tcpip6_spec *tcp_ip6_spec,
912 enum ice_flow_seg_hdr l4_proto, bool *perfect_fltr)
913{
914 enum ice_flow_field src_port, dst_port;
915
916 /* make sure we don't have any empty rule */
917 if (!memcmp(tcp_ip6_spec->ip6src, &zero_ipv6_addr_mask,
918 sizeof(struct in6_addr)) &&
919 !memcmp(tcp_ip6_spec->ip6dst, &zero_ipv6_addr_mask,
920 sizeof(struct in6_addr)) &&
921 !tcp_ip6_spec->psrc && !tcp_ip6_spec->pdst)
922 return -EINVAL;
923
924 /* filtering on TC not supported */
925 if (tcp_ip6_spec->tclass)
926 return -EOPNOTSUPP;
927
928 if (l4_proto == ICE_FLOW_SEG_HDR_TCP) {
929 src_port = ICE_FLOW_FIELD_IDX_TCP_SRC_PORT;
930 dst_port = ICE_FLOW_FIELD_IDX_TCP_DST_PORT;
931 } else if (l4_proto == ICE_FLOW_SEG_HDR_UDP) {
932 src_port = ICE_FLOW_FIELD_IDX_UDP_SRC_PORT;
933 dst_port = ICE_FLOW_FIELD_IDX_UDP_DST_PORT;
934 } else if (l4_proto == ICE_FLOW_SEG_HDR_SCTP) {
935 src_port = ICE_FLOW_FIELD_IDX_SCTP_SRC_PORT;
936 dst_port = ICE_FLOW_FIELD_IDX_SCTP_DST_PORT;
937 } else {
938 return -EINVAL;
939 }
940
941 *perfect_fltr = true;
942 ICE_FLOW_SET_HDRS(seg, ICE_FLOW_SEG_HDR_IPV6 | l4_proto);
943
944 if (!memcmp(tcp_ip6_spec->ip6src, &full_ipv6_addr_mask,
945 sizeof(struct in6_addr)))
946 ice_flow_set_fld(seg, ICE_FLOW_FIELD_IDX_IPV6_SA,
947 ICE_FLOW_FLD_OFF_INVAL, ICE_FLOW_FLD_OFF_INVAL,
948 ICE_FLOW_FLD_OFF_INVAL, false);
949 else if (!memcmp(tcp_ip6_spec->ip6src, &zero_ipv6_addr_mask,
950 sizeof(struct in6_addr)))
951 *perfect_fltr = false;
952 else
953 return -EOPNOTSUPP;
954
955 if (!memcmp(tcp_ip6_spec->ip6dst, &full_ipv6_addr_mask,
956 sizeof(struct in6_addr)))
957 ice_flow_set_fld(seg, ICE_FLOW_FIELD_IDX_IPV6_DA,
958 ICE_FLOW_FLD_OFF_INVAL, ICE_FLOW_FLD_OFF_INVAL,
959 ICE_FLOW_FLD_OFF_INVAL, false);
960 else if (!memcmp(tcp_ip6_spec->ip6dst, &zero_ipv6_addr_mask,
961 sizeof(struct in6_addr)))
962 *perfect_fltr = false;
963 else
964 return -EOPNOTSUPP;
965
966 /* Layer 4 source port */
967 if (tcp_ip6_spec->psrc == htons(0xFFFF))
968 ice_flow_set_fld(seg, src_port, ICE_FLOW_FLD_OFF_INVAL,
969 ICE_FLOW_FLD_OFF_INVAL, ICE_FLOW_FLD_OFF_INVAL,
970 false);
971 else if (!tcp_ip6_spec->psrc)
972 *perfect_fltr = false;
973 else
974 return -EOPNOTSUPP;
975
976 /* Layer 4 destination port */
977 if (tcp_ip6_spec->pdst == htons(0xFFFF))
978 ice_flow_set_fld(seg, dst_port, ICE_FLOW_FLD_OFF_INVAL,
979 ICE_FLOW_FLD_OFF_INVAL, ICE_FLOW_FLD_OFF_INVAL,
980 false);
981 else if (!tcp_ip6_spec->pdst)
982 *perfect_fltr = false;
983 else
984 return -EOPNOTSUPP;
985
986 return 0;
987}
988
989/**
990 * ice_set_fdir_ip6_usr_seg
991 * @seg: flow segment for programming
992 * @usr_ip6_spec: ethtool userdef packet offset
993 * @perfect_fltr: only valid on success; returns true if perfect filter,
994 * false if not
995 *
996 * Set the offset data into the flow segment to be used to program HW
997 * table for IPv6
998 */
999static int
1000ice_set_fdir_ip6_usr_seg(struct ice_flow_seg_info *seg,
1001 struct ethtool_usrip6_spec *usr_ip6_spec,
1002 bool *perfect_fltr)
1003{
1004 /* filtering on Layer 4 bytes not supported */
1005 if (usr_ip6_spec->l4_4_bytes)
1006 return -EOPNOTSUPP;
1007 /* filtering on TC not supported */
1008 if (usr_ip6_spec->tclass)
1009 return -EOPNOTSUPP;
1010 /* filtering on Layer 4 protocol not supported */
1011 if (usr_ip6_spec->l4_proto)
1012 return -EOPNOTSUPP;
1013 /* empty rules are not valid */
1014 if (!memcmp(usr_ip6_spec->ip6src, &zero_ipv6_addr_mask,
1015 sizeof(struct in6_addr)) &&
1016 !memcmp(usr_ip6_spec->ip6dst, &zero_ipv6_addr_mask,
1017 sizeof(struct in6_addr)))
1018 return -EINVAL;
1019
1020 *perfect_fltr = true;
1021 ICE_FLOW_SET_HDRS(seg, ICE_FLOW_SEG_HDR_IPV6);
1022
1023 if (!memcmp(usr_ip6_spec->ip6src, &full_ipv6_addr_mask,
1024 sizeof(struct in6_addr)))
1025 ice_flow_set_fld(seg, ICE_FLOW_FIELD_IDX_IPV6_SA,
1026 ICE_FLOW_FLD_OFF_INVAL, ICE_FLOW_FLD_OFF_INVAL,
1027 ICE_FLOW_FLD_OFF_INVAL, false);
1028 else if (!memcmp(usr_ip6_spec->ip6src, &zero_ipv6_addr_mask,
1029 sizeof(struct in6_addr)))
1030 *perfect_fltr = false;
1031 else
1032 return -EOPNOTSUPP;
1033
1034 if (!memcmp(usr_ip6_spec->ip6dst, &full_ipv6_addr_mask,
1035 sizeof(struct in6_addr)))
1036 ice_flow_set_fld(seg, ICE_FLOW_FIELD_IDX_IPV6_DA,
1037 ICE_FLOW_FLD_OFF_INVAL, ICE_FLOW_FLD_OFF_INVAL,
1038 ICE_FLOW_FLD_OFF_INVAL, false);
1039 else if (!memcmp(usr_ip6_spec->ip6dst, &zero_ipv6_addr_mask,
1040 sizeof(struct in6_addr)))
1041 *perfect_fltr = false;
1042 else
1043 return -EOPNOTSUPP;
1044
1045 return 0;
1046}
1047
1048/**
1049 * ice_cfg_fdir_xtrct_seq - Configure extraction sequence for the given filter
1050 * @pf: PF structure
1051 * @fsp: pointer to ethtool Rx flow specification
1052 * @user: user defined data from flow specification
1053 *
1054 * Returns 0 on success.
1055 */
1056static int
1057ice_cfg_fdir_xtrct_seq(struct ice_pf *pf, struct ethtool_rx_flow_spec *fsp,
1058 struct ice_rx_flow_userdef *user)
1059{
1060 struct ice_flow_seg_info *seg, *tun_seg;
1061 struct device *dev = ice_pf_to_dev(pf);
1062 enum ice_fltr_ptype fltr_idx;
1063 struct ice_hw *hw = &pf->hw;
1064 bool perfect_filter;
1065 int ret;
1066
1067 seg = devm_kzalloc(dev, sizeof(*seg), GFP_KERNEL);
1068 if (!seg)
1069 return -ENOMEM;
1070
1071 tun_seg = devm_kzalloc(dev, sizeof(*seg) * ICE_FD_HW_SEG_MAX,
1072 GFP_KERNEL);
1073 if (!tun_seg) {
1074 devm_kfree(dev, seg);
1075 return -ENOMEM;
1076 }
1077
1078 switch (fsp->flow_type & ~FLOW_EXT) {
1079 case TCP_V4_FLOW:
1080 ret = ice_set_fdir_ip4_seg(seg, &fsp->m_u.tcp_ip4_spec,
1081 ICE_FLOW_SEG_HDR_TCP,
1082 &perfect_filter);
1083 break;
1084 case UDP_V4_FLOW:
1085 ret = ice_set_fdir_ip4_seg(seg, &fsp->m_u.tcp_ip4_spec,
1086 ICE_FLOW_SEG_HDR_UDP,
1087 &perfect_filter);
1088 break;
1089 case SCTP_V4_FLOW:
1090 ret = ice_set_fdir_ip4_seg(seg, &fsp->m_u.tcp_ip4_spec,
1091 ICE_FLOW_SEG_HDR_SCTP,
1092 &perfect_filter);
1093 break;
1094 case IPV4_USER_FLOW:
1095 ret = ice_set_fdir_ip4_usr_seg(seg, &fsp->m_u.usr_ip4_spec,
1096 &perfect_filter);
1097 break;
1098 case TCP_V6_FLOW:
1099 ret = ice_set_fdir_ip6_seg(seg, &fsp->m_u.tcp_ip6_spec,
1100 ICE_FLOW_SEG_HDR_TCP,
1101 &perfect_filter);
1102 break;
1103 case UDP_V6_FLOW:
1104 ret = ice_set_fdir_ip6_seg(seg, &fsp->m_u.tcp_ip6_spec,
1105 ICE_FLOW_SEG_HDR_UDP,
1106 &perfect_filter);
1107 break;
1108 case SCTP_V6_FLOW:
1109 ret = ice_set_fdir_ip6_seg(seg, &fsp->m_u.tcp_ip6_spec,
1110 ICE_FLOW_SEG_HDR_SCTP,
1111 &perfect_filter);
1112 break;
1113 case IPV6_USER_FLOW:
1114 ret = ice_set_fdir_ip6_usr_seg(seg, &fsp->m_u.usr_ip6_spec,
1115 &perfect_filter);
1116 break;
1117 default:
1118 ret = -EINVAL;
1119 }
1120 if (ret)
1121 goto err_exit;
1122
1123 /* tunnel segments are shifted up one. */
1124 memcpy(&tun_seg[1], seg, sizeof(*seg));
1125
1126 if (user && user->flex_fltr) {
1127 perfect_filter = false;
1128 ice_flow_add_fld_raw(seg, user->flex_offset,
1129 ICE_FLTR_PRGM_FLEX_WORD_SIZE,
1130 ICE_FLOW_FLD_OFF_INVAL,
1131 ICE_FLOW_FLD_OFF_INVAL);
1132 ice_flow_add_fld_raw(&tun_seg[1], user->flex_offset,
1133 ICE_FLTR_PRGM_FLEX_WORD_SIZE,
1134 ICE_FLOW_FLD_OFF_INVAL,
1135 ICE_FLOW_FLD_OFF_INVAL);
1136 }
1137
1138 /* add filter for outer headers */
1139 fltr_idx = ice_ethtool_flow_to_fltr(fsp->flow_type & ~FLOW_EXT);
1140 ret = ice_fdir_set_hw_fltr_rule(pf, seg, fltr_idx,
1141 ICE_FD_HW_SEG_NON_TUN);
1142 if (ret == -EEXIST)
1143 /* Rule already exists, free memory and continue */
1144 devm_kfree(dev, seg);
1145 else if (ret)
1146 /* could not write filter, free memory */
1147 goto err_exit;
1148
1149 /* make tunneled filter HW entries if possible */
1150 memcpy(&tun_seg[1], seg, sizeof(*seg));
1151 ret = ice_fdir_set_hw_fltr_rule(pf, tun_seg, fltr_idx,
1152 ICE_FD_HW_SEG_TUN);
1153 if (ret == -EEXIST) {
1154 /* Rule already exists, free memory and count as success */
1155 devm_kfree(dev, tun_seg);
1156 ret = 0;
1157 } else if (ret) {
1158 /* could not write tunnel filter, but outer filter exists */
1159 devm_kfree(dev, tun_seg);
1160 }
1161
1162 if (perfect_filter)
1163 set_bit(fltr_idx, hw->fdir_perfect_fltr);
1164 else
1165 clear_bit(fltr_idx, hw->fdir_perfect_fltr);
1166
1167 return ret;
1168
1169err_exit:
1170 devm_kfree(dev, tun_seg);
1171 devm_kfree(dev, seg);
1172
1173 return -EOPNOTSUPP;
1174}
1175
1176/**
1177 * ice_fdir_write_fltr - send a flow director filter to the hardware
1178 * @pf: PF data structure
1179 * @input: filter structure
1180 * @add: true adds filter and false removed filter
1181 * @is_tun: true adds inner filter on tunnel and false outer headers
1182 *
1183 * returns 0 on success and negative value on error
1184 */
1185int
1186ice_fdir_write_fltr(struct ice_pf *pf, struct ice_fdir_fltr *input, bool add,
1187 bool is_tun)
1188{
1189 struct device *dev = ice_pf_to_dev(pf);
1190 struct ice_hw *hw = &pf->hw;
1191 struct ice_fltr_desc desc;
1192 struct ice_vsi *ctrl_vsi;
1193 enum ice_status status;
1194 u8 *pkt, *frag_pkt;
1195 bool has_frag;
1196 int err;
1197
1198 ctrl_vsi = ice_get_ctrl_vsi(pf);
1199 if (!ctrl_vsi)
1200 return -EINVAL;
1201
1202 pkt = devm_kzalloc(dev, ICE_FDIR_MAX_RAW_PKT_SIZE, GFP_KERNEL);
1203 if (!pkt)
1204 return -ENOMEM;
1205 frag_pkt = devm_kzalloc(dev, ICE_FDIR_MAX_RAW_PKT_SIZE, GFP_KERNEL);
1206 if (!frag_pkt) {
1207 err = -ENOMEM;
1208 goto err_free;
1209 }
1210
1211 ice_fdir_get_prgm_desc(hw, input, &desc, add);
1212 status = ice_fdir_get_gen_prgm_pkt(hw, input, pkt, false, is_tun);
1213 if (status) {
1214 err = ice_status_to_errno(status);
1215 goto err_free_all;
1216 }
1217 err = ice_prgm_fdir_fltr(ctrl_vsi, &desc, pkt);
1218 if (err)
1219 goto err_free_all;
1220
1221 /* repeat for fragment packet */
1222 has_frag = ice_fdir_has_frag(input->flow_type);
1223 if (has_frag) {
1224 /* does not return error */
1225 ice_fdir_get_prgm_desc(hw, input, &desc, add);
1226 status = ice_fdir_get_gen_prgm_pkt(hw, input, frag_pkt, true,
1227 is_tun);
1228 if (status) {
1229 err = ice_status_to_errno(status);
1230 goto err_frag;
1231 }
1232 err = ice_prgm_fdir_fltr(ctrl_vsi, &desc, frag_pkt);
1233 if (err)
1234 goto err_frag;
1235 } else {
1236 devm_kfree(dev, frag_pkt);
1237 }
1238
1239 return 0;
1240
1241err_free_all:
1242 devm_kfree(dev, frag_pkt);
1243err_free:
1244 devm_kfree(dev, pkt);
1245 return err;
1246
1247err_frag:
1248 devm_kfree(dev, frag_pkt);
1249 return err;
1250}
1251
1252/**
1253 * ice_fdir_write_all_fltr - send a flow director filter to the hardware
1254 * @pf: PF data structure
1255 * @input: filter structure
1256 * @add: true adds filter and false removed filter
1257 *
1258 * returns 0 on success and negative value on error
1259 */
1260static int
1261ice_fdir_write_all_fltr(struct ice_pf *pf, struct ice_fdir_fltr *input,
1262 bool add)
1263{
1264 u16 port_num;
1265 int tun;
1266
1267 for (tun = 0; tun < ICE_FD_HW_SEG_MAX; tun++) {
1268 bool is_tun = tun == ICE_FD_HW_SEG_TUN;
1269 int err;
1270
1271 if (is_tun && !ice_get_open_tunnel_port(&pf->hw, &port_num))
1272 continue;
1273 err = ice_fdir_write_fltr(pf, input, add, is_tun);
1274 if (err)
1275 return err;
1276 }
1277 return 0;
1278}
1279
1280/**
1281 * ice_fdir_replay_fltrs - replay filters from the HW filter list
1282 * @pf: board private structure
1283 */
1284void ice_fdir_replay_fltrs(struct ice_pf *pf)
1285{
1286 struct ice_fdir_fltr *f_rule;
1287 struct ice_hw *hw = &pf->hw;
1288
1289 list_for_each_entry(f_rule, &hw->fdir_list_head, fltr_node) {
1290 int err = ice_fdir_write_all_fltr(pf, f_rule, true);
1291
1292 if (err)
1293 dev_dbg(ice_pf_to_dev(pf), "Flow Director error %d, could not reprogram filter %d\n",
1294 err, f_rule->fltr_id);
1295 }
1296}
1297
1298/**
1299 * ice_fdir_create_dflt_rules - create default perfect filters
1300 * @pf: PF data structure
1301 *
1302 * Returns 0 for success or error.
1303 */
1304int ice_fdir_create_dflt_rules(struct ice_pf *pf)
1305{
1306 int err;
1307
1308 /* Create perfect TCP and UDP rules in hardware. */
1309 err = ice_create_init_fdir_rule(pf, ICE_FLTR_PTYPE_NONF_IPV4_TCP);
1310 if (err)
1311 return err;
1312
1313 err = ice_create_init_fdir_rule(pf, ICE_FLTR_PTYPE_NONF_IPV4_UDP);
1314 if (err)
1315 return err;
1316
1317 err = ice_create_init_fdir_rule(pf, ICE_FLTR_PTYPE_NONF_IPV6_TCP);
1318 if (err)
1319 return err;
1320
1321 err = ice_create_init_fdir_rule(pf, ICE_FLTR_PTYPE_NONF_IPV6_UDP);
1322
1323 return err;
1324}
1325
1326/**
1327 * ice_vsi_manage_fdir - turn on/off flow director
1328 * @vsi: the VSI being changed
1329 * @ena: boolean value indicating if this is an enable or disable request
1330 */
1331void ice_vsi_manage_fdir(struct ice_vsi *vsi, bool ena)
1332{
1333 struct ice_fdir_fltr *f_rule, *tmp;
1334 struct ice_pf *pf = vsi->back;
1335 struct ice_hw *hw = &pf->hw;
1336 enum ice_fltr_ptype flow;
1337
1338 if (ena) {
1339 set_bit(ICE_FLAG_FD_ENA, pf->flags);
1340 ice_fdir_create_dflt_rules(pf);
1341 return;
1342 }
1343
1344 mutex_lock(&hw->fdir_fltr_lock);
1345 if (!test_and_clear_bit(ICE_FLAG_FD_ENA, pf->flags))
1346 goto release_lock;
1347 list_for_each_entry_safe(f_rule, tmp, &hw->fdir_list_head, fltr_node) {
1348 /* ignore return value */
1349 ice_fdir_write_all_fltr(pf, f_rule, false);
1350 ice_fdir_update_cntrs(hw, f_rule->flow_type, false);
1351 list_del(&f_rule->fltr_node);
1352 devm_kfree(ice_hw_to_dev(hw), f_rule);
1353 }
1354
1355 if (hw->fdir_prof)
1356 for (flow = ICE_FLTR_PTYPE_NONF_NONE; flow < ICE_FLTR_PTYPE_MAX;
1357 flow++)
1358 if (hw->fdir_prof[flow])
1359 ice_fdir_rem_flow(hw, ICE_BLK_FD, flow);
1360
1361release_lock:
1362 mutex_unlock(&hw->fdir_fltr_lock);
1363}
1364
1365/**
1366 * ice_fdir_do_rem_flow - delete flow and possibly add perfect flow
1367 * @pf: PF structure
1368 * @flow_type: FDir flow type to release
1369 */
1370static void
1371ice_fdir_do_rem_flow(struct ice_pf *pf, enum ice_fltr_ptype flow_type)
1372{
1373 struct ice_hw *hw = &pf->hw;
1374 bool need_perfect = false;
1375
1376 if (flow_type == ICE_FLTR_PTYPE_NONF_IPV4_TCP ||
1377 flow_type == ICE_FLTR_PTYPE_NONF_IPV4_UDP ||
1378 flow_type == ICE_FLTR_PTYPE_NONF_IPV6_TCP ||
1379 flow_type == ICE_FLTR_PTYPE_NONF_IPV6_UDP)
1380 need_perfect = true;
1381
1382 if (need_perfect && test_bit(flow_type, hw->fdir_perfect_fltr))
1383 return;
1384
1385 ice_fdir_rem_flow(hw, ICE_BLK_FD, flow_type);
1386 if (need_perfect)
1387 ice_create_init_fdir_rule(pf, flow_type);
1388}
1389
1390/**
1391 * ice_fdir_update_list_entry - add or delete a filter from the filter list
1392 * @pf: PF structure
1393 * @input: filter structure
1394 * @fltr_idx: ethtool index of filter to modify
1395 *
1396 * returns 0 on success and negative on errors
1397 */
1398static int
1399ice_fdir_update_list_entry(struct ice_pf *pf, struct ice_fdir_fltr *input,
1400 int fltr_idx)
1401{
1402 struct ice_fdir_fltr *old_fltr;
1403 struct ice_hw *hw = &pf->hw;
1404 int err = -ENOENT;
1405
1406 /* Do not update filters during reset */
1407 if (ice_is_reset_in_progress(pf->state))
1408 return -EBUSY;
1409
1410 old_fltr = ice_fdir_find_fltr_by_idx(hw, fltr_idx);
1411 if (old_fltr) {
1412 err = ice_fdir_write_all_fltr(pf, old_fltr, false);
1413 if (err)
1414 return err;
1415 ice_fdir_update_cntrs(hw, old_fltr->flow_type, false);
1416 if (!input && !hw->fdir_fltr_cnt[old_fltr->flow_type])
1417 /* we just deleted the last filter of flow_type so we
1418 * should also delete the HW filter info.
1419 */
1420 ice_fdir_do_rem_flow(pf, old_fltr->flow_type);
1421 list_del(&old_fltr->fltr_node);
1422 devm_kfree(ice_hw_to_dev(hw), old_fltr);
1423 }
1424 if (!input)
1425 return err;
1426 ice_fdir_list_add_fltr(hw, input);
1427 ice_fdir_update_cntrs(hw, input->flow_type, true);
1428 return 0;
1429}
1430
1431/**
1432 * ice_del_fdir_ethtool - delete Flow Director filter
1433 * @vsi: pointer to target VSI
1434 * @cmd: command to add or delete Flow Director filter
1435 *
1436 * Returns 0 on success and negative values for failure
1437 */
1438int ice_del_fdir_ethtool(struct ice_vsi *vsi, struct ethtool_rxnfc *cmd)
1439{
1440 struct ethtool_rx_flow_spec *fsp =
1441 (struct ethtool_rx_flow_spec *)&cmd->fs;
1442 struct ice_pf *pf = vsi->back;
1443 struct ice_hw *hw = &pf->hw;
1444 int val;
1445
1446 if (!test_bit(ICE_FLAG_FD_ENA, pf->flags))
1447 return -EOPNOTSUPP;
1448
1449 /* Do not delete filters during reset */
1450 if (ice_is_reset_in_progress(pf->state)) {
1451 dev_err(ice_pf_to_dev(pf), "Device is resetting - deleting Flow Director filters not supported during reset\n");
1452 return -EBUSY;
1453 }
1454
1455 if (test_bit(ICE_FD_FLUSH_REQ, pf->state))
1456 return -EBUSY;
1457
1458 mutex_lock(&hw->fdir_fltr_lock);
1459 val = ice_fdir_update_list_entry(pf, NULL, fsp->location);
1460 mutex_unlock(&hw->fdir_fltr_lock);
1461
1462 return val;
1463}
1464
1465/**
1466 * ice_set_fdir_input_set - Set the input set for Flow Director
1467 * @vsi: pointer to target VSI
1468 * @fsp: pointer to ethtool Rx flow specification
1469 * @input: filter structure
1470 */
1471static int
1472ice_set_fdir_input_set(struct ice_vsi *vsi, struct ethtool_rx_flow_spec *fsp,
1473 struct ice_fdir_fltr *input)
1474{
1475 u16 dest_vsi, q_index = 0;
1476 struct ice_pf *pf;
1477 struct ice_hw *hw;
1478 int flow_type;
1479 u8 dest_ctl;
1480
1481 if (!vsi || !fsp || !input)
1482 return -EINVAL;
1483
1484 pf = vsi->back;
1485 hw = &pf->hw;
1486
1487 dest_vsi = vsi->idx;
1488 if (fsp->ring_cookie == RX_CLS_FLOW_DISC) {
1489 dest_ctl = ICE_FLTR_PRGM_DESC_DEST_DROP_PKT;
1490 } else {
1491 u32 ring = ethtool_get_flow_spec_ring(fsp->ring_cookie);
1492 u8 vf = ethtool_get_flow_spec_ring_vf(fsp->ring_cookie);
1493
1494 if (vf) {
1495 dev_err(ice_pf_to_dev(pf), "Failed to add filter. Flow director filters are not supported on VF queues.\n");
1496 return -EINVAL;
1497 }
1498
1499 if (ring >= vsi->num_rxq)
1500 return -EINVAL;
1501
1502 dest_ctl = ICE_FLTR_PRGM_DESC_DEST_DIRECT_PKT_QINDEX;
1503 q_index = ring;
1504 }
1505
1506 input->fltr_id = fsp->location;
1507 input->q_index = q_index;
1508 flow_type = fsp->flow_type & ~FLOW_EXT;
1509
1510 input->dest_vsi = dest_vsi;
1511 input->dest_ctl = dest_ctl;
1512 input->fltr_status = ICE_FLTR_PRGM_DESC_FD_STATUS_FD_ID;
1513 input->cnt_index = ICE_FD_SB_STAT_IDX(hw->fd_ctr_base);
1514 input->flow_type = ice_ethtool_flow_to_fltr(flow_type);
1515
1516 if (fsp->flow_type & FLOW_EXT) {
1517 memcpy(input->ext_data.usr_def, fsp->h_ext.data,
1518 sizeof(input->ext_data.usr_def));
1519 input->ext_data.vlan_type = fsp->h_ext.vlan_etype;
1520 input->ext_data.vlan_tag = fsp->h_ext.vlan_tci;
1521 memcpy(input->ext_mask.usr_def, fsp->m_ext.data,
1522 sizeof(input->ext_mask.usr_def));
1523 input->ext_mask.vlan_type = fsp->m_ext.vlan_etype;
1524 input->ext_mask.vlan_tag = fsp->m_ext.vlan_tci;
1525 }
1526
1527 switch (flow_type) {
1528 case TCP_V4_FLOW:
1529 case UDP_V4_FLOW:
1530 case SCTP_V4_FLOW:
1531 input->ip.v4.dst_port = fsp->h_u.tcp_ip4_spec.pdst;
1532 input->ip.v4.src_port = fsp->h_u.tcp_ip4_spec.psrc;
1533 input->ip.v4.dst_ip = fsp->h_u.tcp_ip4_spec.ip4dst;
1534 input->ip.v4.src_ip = fsp->h_u.tcp_ip4_spec.ip4src;
1535 input->mask.v4.dst_port = fsp->m_u.tcp_ip4_spec.pdst;
1536 input->mask.v4.src_port = fsp->m_u.tcp_ip4_spec.psrc;
1537 input->mask.v4.dst_ip = fsp->m_u.tcp_ip4_spec.ip4dst;
1538 input->mask.v4.src_ip = fsp->m_u.tcp_ip4_spec.ip4src;
1539 break;
1540 case IPV4_USER_FLOW:
1541 input->ip.v4.dst_ip = fsp->h_u.usr_ip4_spec.ip4dst;
1542 input->ip.v4.src_ip = fsp->h_u.usr_ip4_spec.ip4src;
1543 input->ip.v4.l4_header = fsp->h_u.usr_ip4_spec.l4_4_bytes;
1544 input->ip.v4.proto = fsp->h_u.usr_ip4_spec.proto;
1545 input->ip.v4.ip_ver = fsp->h_u.usr_ip4_spec.ip_ver;
1546 input->ip.v4.tos = fsp->h_u.usr_ip4_spec.tos;
1547 input->mask.v4.dst_ip = fsp->m_u.usr_ip4_spec.ip4dst;
1548 input->mask.v4.src_ip = fsp->m_u.usr_ip4_spec.ip4src;
1549 input->mask.v4.l4_header = fsp->m_u.usr_ip4_spec.l4_4_bytes;
1550 input->mask.v4.proto = fsp->m_u.usr_ip4_spec.proto;
1551 input->mask.v4.ip_ver = fsp->m_u.usr_ip4_spec.ip_ver;
1552 input->mask.v4.tos = fsp->m_u.usr_ip4_spec.tos;
1553 break;
1554 case TCP_V6_FLOW:
1555 case UDP_V6_FLOW:
1556 case SCTP_V6_FLOW:
1557 memcpy(input->ip.v6.dst_ip, fsp->h_u.usr_ip6_spec.ip6dst,
1558 sizeof(struct in6_addr));
1559 memcpy(input->ip.v6.src_ip, fsp->h_u.usr_ip6_spec.ip6src,
1560 sizeof(struct in6_addr));
1561 input->ip.v6.dst_port = fsp->h_u.tcp_ip6_spec.pdst;
1562 input->ip.v6.src_port = fsp->h_u.tcp_ip6_spec.psrc;
1563 input->ip.v6.tc = fsp->h_u.tcp_ip6_spec.tclass;
1564 memcpy(input->mask.v6.dst_ip, fsp->m_u.tcp_ip6_spec.ip6dst,
1565 sizeof(struct in6_addr));
1566 memcpy(input->mask.v6.src_ip, fsp->m_u.tcp_ip6_spec.ip6src,
1567 sizeof(struct in6_addr));
1568 input->mask.v6.dst_port = fsp->m_u.tcp_ip6_spec.pdst;
1569 input->mask.v6.src_port = fsp->m_u.tcp_ip6_spec.psrc;
1570 input->mask.v6.tc = fsp->m_u.tcp_ip6_spec.tclass;
1571 break;
1572 case IPV6_USER_FLOW:
1573 memcpy(input->ip.v6.dst_ip, fsp->h_u.usr_ip6_spec.ip6dst,
1574 sizeof(struct in6_addr));
1575 memcpy(input->ip.v6.src_ip, fsp->h_u.usr_ip6_spec.ip6src,
1576 sizeof(struct in6_addr));
1577 input->ip.v6.l4_header = fsp->h_u.usr_ip6_spec.l4_4_bytes;
1578 input->ip.v6.tc = fsp->h_u.usr_ip6_spec.tclass;
1579
1580 /* if no protocol requested, use IPPROTO_NONE */
1581 if (!fsp->m_u.usr_ip6_spec.l4_proto)
1582 input->ip.v6.proto = IPPROTO_NONE;
1583 else
1584 input->ip.v6.proto = fsp->h_u.usr_ip6_spec.l4_proto;
1585
1586 memcpy(input->mask.v6.dst_ip, fsp->m_u.usr_ip6_spec.ip6dst,
1587 sizeof(struct in6_addr));
1588 memcpy(input->mask.v6.src_ip, fsp->m_u.usr_ip6_spec.ip6src,
1589 sizeof(struct in6_addr));
1590 input->mask.v6.l4_header = fsp->m_u.usr_ip6_spec.l4_4_bytes;
1591 input->mask.v6.tc = fsp->m_u.usr_ip6_spec.tclass;
1592 input->mask.v6.proto = fsp->m_u.usr_ip6_spec.l4_proto;
1593 break;
1594 default:
1595 /* not doing un-parsed flow types */
1596 return -EINVAL;
1597 }
1598
1599 return 0;
1600}
1601
1602/**
1603 * ice_add_fdir_ethtool - Add/Remove Flow Director filter
1604 * @vsi: pointer to target VSI
1605 * @cmd: command to add or delete Flow Director filter
1606 *
1607 * Returns 0 on success and negative values for failure
1608 */
1609int ice_add_fdir_ethtool(struct ice_vsi *vsi, struct ethtool_rxnfc *cmd)
1610{
1611 struct ice_rx_flow_userdef userdata;
1612 struct ethtool_rx_flow_spec *fsp;
1613 struct ice_fdir_fltr *input;
1614 struct device *dev;
1615 struct ice_pf *pf;
1616 struct ice_hw *hw;
1617 int fltrs_needed;
1618 u16 tunnel_port;
1619 int ret;
1620
1621 if (!vsi)
1622 return -EINVAL;
1623
1624 pf = vsi->back;
1625 hw = &pf->hw;
1626 dev = ice_pf_to_dev(pf);
1627
1628 if (!test_bit(ICE_FLAG_FD_ENA, pf->flags))
1629 return -EOPNOTSUPP;
1630
1631 /* Do not program filters during reset */
1632 if (ice_is_reset_in_progress(pf->state)) {
1633 dev_err(dev, "Device is resetting - adding Flow Director filters not supported during reset\n");
1634 return -EBUSY;
1635 }
1636
1637 fsp = (struct ethtool_rx_flow_spec *)&cmd->fs;
1638
1639 if (ice_parse_rx_flow_user_data(fsp, &userdata))
1640 return -EINVAL;
1641
1642 if (fsp->flow_type & FLOW_MAC_EXT)
1643 return -EINVAL;
1644
1645 ret = ice_cfg_fdir_xtrct_seq(pf, fsp, &userdata);
1646 if (ret)
1647 return ret;
1648
1649 if (fsp->location >= ice_get_fdir_cnt_all(hw)) {
1650 dev_err(dev, "Failed to add filter. The maximum number of flow director filters has been reached.\n");
1651 return -ENOSPC;
1652 }
1653
1654 /* return error if not an update and no available filters */
1655 fltrs_needed = ice_get_open_tunnel_port(hw, &tunnel_port) ? 2 : 1;
1656 if (!ice_fdir_find_fltr_by_idx(hw, fsp->location) &&
1657 ice_fdir_num_avail_fltr(hw, pf->vsi[vsi->idx]) < fltrs_needed) {
1658 dev_err(dev, "Failed to add filter. The maximum number of flow director filters has been reached.\n");
1659 return -ENOSPC;
1660 }
1661
1662 input = devm_kzalloc(dev, sizeof(*input), GFP_KERNEL);
1663 if (!input)
1664 return -ENOMEM;
1665
1666 ret = ice_set_fdir_input_set(vsi, fsp, input);
1667 if (ret)
1668 goto free_input;
1669
1670 mutex_lock(&hw->fdir_fltr_lock);
1671 if (ice_fdir_is_dup_fltr(hw, input)) {
1672 ret = -EINVAL;
1673 goto release_lock;
1674 }
1675
1676 if (userdata.flex_fltr) {
1677 input->flex_fltr = true;
1678 input->flex_word = cpu_to_be16(userdata.flex_word);
1679 input->flex_offset = userdata.flex_offset;
1680 }
1681
1682 input->cnt_ena = ICE_FXD_FLTR_QW0_STAT_ENA_PKTS;
1683 input->fdid_prio = ICE_FXD_FLTR_QW1_FDID_PRI_THREE;
1684 input->comp_report = ICE_FXD_FLTR_QW0_COMP_REPORT_SW_FAIL;
1685
1686 /* input struct is added to the HW filter list */
1687 ice_fdir_update_list_entry(pf, input, fsp->location);
1688
1689 ret = ice_fdir_write_all_fltr(pf, input, true);
1690 if (ret)
1691 goto remove_sw_rule;
1692
1693 goto release_lock;
1694
1695remove_sw_rule:
1696 ice_fdir_update_cntrs(hw, input->flow_type, false);
1697 list_del(&input->fltr_node);
1698release_lock:
1699 mutex_unlock(&hw->fdir_fltr_lock);
1700free_input:
1701 if (ret)
1702 devm_kfree(dev, input);
1703
1704 return ret;
1705}