net/cxgbe: parse and validate flows
[dpdk.git] / drivers / net / cxgbe / cxgbe_filter.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2018 Chelsio Communications.
3  * All rights reserved.
4  */
5
6 #include "common.h"
7 #include "t4_regs.h"
8 #include "cxgbe_filter.h"
9
10 /**
11  * Validate if the requested filter specification can be set by checking
12  * if the requested features have been enabled
13  */
14 int validate_filter(struct adapter *adapter, struct ch_filter_specification *fs)
15 {
16         u32 fconf;
17
18         /*
19          * Check for unconfigured fields being used.
20          */
21         fconf = adapter->params.tp.vlan_pri_map;
22
23 #define S(_field) \
24         (fs->val._field || fs->mask._field)
25 #define U(_mask, _field) \
26         (!(fconf & (_mask)) && S(_field))
27
28         if (U(F_ETHERTYPE, ethtype) || U(F_PROTOCOL, proto))
29                 return -EOPNOTSUPP;
30
31 #undef S
32 #undef U
33         return 0;
34 }
35
36 /**
37  * Check if entry already filled.
38  */
39 bool is_filter_set(struct tid_info *t, int fidx, int family)
40 {
41         bool result = FALSE;
42         int i, max;
43
44         /* IPv6 requires four slots and IPv4 requires only 1 slot.
45          * Ensure, there's enough slots available.
46          */
47         max = family == FILTER_TYPE_IPV6 ? fidx + 3 : fidx;
48
49         t4_os_lock(&t->ftid_lock);
50         for (i = fidx; i <= max; i++) {
51                 if (rte_bitmap_get(t->ftid_bmap, i)) {
52                         result = TRUE;
53                         break;
54                 }
55         }
56         t4_os_unlock(&t->ftid_lock);
57         return result;
58 }
59
60 /**
61  * Allocate a available free entry
62  */
63 int cxgbe_alloc_ftid(struct adapter *adap, unsigned int family)
64 {
65         struct tid_info *t = &adap->tids;
66         int pos;
67         int size = t->nftids;
68
69         t4_os_lock(&t->ftid_lock);
70         if (family == FILTER_TYPE_IPV6)
71                 pos = cxgbe_bitmap_find_free_region(t->ftid_bmap, size, 4);
72         else
73                 pos = cxgbe_find_first_zero_bit(t->ftid_bmap, size);
74         t4_os_unlock(&t->ftid_lock);
75
76         return pos < size ? pos : -1;
77 }