1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2018 Chelsio Communications.
6 #ifndef _CXGBE_FILTER_H_
7 #define _CXGBE_FILTER_H_
9 #include "base/t4_msg.h"
11 * Defined bit width of user definable filter tuples
13 #define ETHTYPE_BITWIDTH 16
14 #define FRAG_BITWIDTH 1
15 #define MACIDX_BITWIDTH 9
16 #define FCOE_BITWIDTH 1
17 #define IPORT_BITWIDTH 3
18 #define MATCHTYPE_BITWIDTH 3
19 #define PROTO_BITWIDTH 8
20 #define TOS_BITWIDTH 8
22 #define VF_BITWIDTH 13
23 #define IVLAN_BITWIDTH 16
24 #define OVLAN_BITWIDTH 16
27 * Filter matching rules. These consist of a set of ingress packet field
28 * (value, mask) tuples. The associated ingress packet field matches the
29 * tuple when ((field & mask) == value). (Thus a wildcard "don't care" field
30 * rule can be constructed by specifying a tuple of (0, 0).) A filter rule
31 * matches an ingress packet when all of the individual individual field
32 * matching rules are true.
34 * Partial field masks are always valid, however, while it may be easy to
35 * understand their meanings for some fields (e.g. IP address to match a
36 * subnet), for others making sensible partial masks is less intuitive (e.g.
39 struct ch_filter_tuple {
41 * Compressed header matching field rules. The TP_VLAN_PRI_MAP
42 * register selects which of these fields will participate in the
43 * filter match rules -- up to a maximum of 36 bits. Because
44 * TP_VLAN_PRI_MAP is a global register, all filters must use the same
47 uint32_t ethtype:ETHTYPE_BITWIDTH; /* Ethernet type */
48 uint32_t frag:FRAG_BITWIDTH; /* IP fragmentation header */
49 uint32_t ivlan_vld:1; /* inner VLAN valid */
50 uint32_t ovlan_vld:1; /* outer VLAN valid */
51 uint32_t pfvf_vld:1; /* PF/VF valid */
52 uint32_t macidx:MACIDX_BITWIDTH; /* exact match MAC index */
53 uint32_t fcoe:FCOE_BITWIDTH; /* FCoE packet */
54 uint32_t iport:IPORT_BITWIDTH; /* ingress port */
55 uint32_t matchtype:MATCHTYPE_BITWIDTH; /* MPS match type */
56 uint32_t proto:PROTO_BITWIDTH; /* protocol type */
57 uint32_t tos:TOS_BITWIDTH; /* TOS/Traffic Type */
58 uint32_t pf:PF_BITWIDTH; /* PCI-E PF ID */
59 uint32_t vf:VF_BITWIDTH; /* PCI-E VF ID */
60 uint32_t ivlan:IVLAN_BITWIDTH; /* inner VLAN */
61 uint32_t ovlan:OVLAN_BITWIDTH; /* outer VLAN */
64 * Uncompressed header matching field rules. These are always
65 * available for field rules.
67 uint8_t lip[16]; /* local IP address (IPv4 in [3:0]) */
68 uint8_t fip[16]; /* foreign IP address (IPv4 in [3:0]) */
69 uint16_t lport; /* local port */
70 uint16_t fport; /* foreign port */
72 /* reservations for future additions */
77 * Filter specification
79 struct ch_filter_specification {
81 /* Administrative fields for filter. */
82 uint32_t hitcnts:1; /* count filter hits in TCB */
83 uint32_t prio:1; /* filter has priority over active/server */
86 * Fundamental filter typing. This is the one element of filter
87 * matching that doesn't exist as a (value, mask) tuple.
89 uint32_t type:1; /* 0 => IPv4, 1 => IPv6 */
90 uint32_t cap:1; /* 0 => LE-TCAM, 1 => Hash */
93 * Packet dispatch information. Ingress packets which match the
94 * filter rules will be dropped, passed to the host or switched back
95 * out as egress packets.
97 uint32_t action:2; /* drop, pass, switch */
99 uint32_t dirsteer:1; /* 0 => RSS, 1 => steer to iq */
100 uint32_t iq:10; /* ingress queue */
102 uint32_t eport:2; /* egress port to switch packet out */
103 uint32_t newsmac:1; /* rewrite source MAC address */
104 uint32_t newdmac:1; /* rewrite destination MAC address */
105 uint32_t swapmac:1; /* swap SMAC/DMAC for loopback packet */
106 uint32_t newvlan:2; /* rewrite VLAN Tag */
107 uint8_t smac[RTE_ETHER_ADDR_LEN]; /* new source MAC address */
108 uint8_t dmac[RTE_ETHER_ADDR_LEN]; /* new destination MAC address */
109 uint16_t vlan; /* VLAN Tag to insert */
112 * Switch proxy/rewrite fields. An ingress packet which matches a
113 * filter with "switch" set will be looped back out as an egress
114 * packet -- potentially with some header rewriting.
116 uint32_t nat_mode:3; /* specify NAT operation mode */
118 uint8_t nat_lip[16]; /* local IP to use after NAT'ing */
119 uint8_t nat_fip[16]; /* foreign IP to use after NAT'ing */
120 uint16_t nat_lport; /* local port number to use after NAT'ing */
121 uint16_t nat_fport; /* foreign port number to use after NAT'ing */
123 /* Filter rule value/mask pairs. */
124 struct ch_filter_tuple val;
125 struct ch_filter_tuple mask;
129 FILTER_PASS = 0, /* default */
141 NAT_MODE_NONE = 0, /* No NAT performed */
142 NAT_MODE_DIP, /* NAT on Dst IP */
143 NAT_MODE_DIP_DP, /* NAT on Dst IP, Dst Port */
144 NAT_MODE_DIP_DP_SIP, /* NAT on Dst IP, Dst Port and Src IP */
145 NAT_MODE_DIP_DP_SP, /* NAT on Dst IP, Dst Port and Src Port */
146 NAT_MODE_SIP_SP, /* NAT on Src IP and Src Port */
147 NAT_MODE_DIP_SIP_SP, /* NAT on Dst IP, Src IP and Src Port */
148 NAT_MODE_ALL /* NAT on entire 4-tuple */
152 FILTER_TYPE_IPV4 = 0,
156 struct t4_completion {
157 unsigned int done; /* completion done (0 - No, 1 - Yes) */
158 rte_spinlock_t lock; /* completion lock */
162 * Filter operation context to allow callers to wait for
163 * an asynchronous completion.
166 struct t4_completion completion; /* completion rendezvous */
167 int result; /* result of operation */
168 u32 tid; /* to store tid of hash filter */
172 * Host shadow copy of ingress filter entry. This is in host native format
173 * and doesn't match the ordering or bit order, etc. of the hardware or the
176 struct filter_entry {
178 * Administrative fields for filter.
180 u32 valid:1; /* filter allocated and valid */
181 u32 locked:1; /* filter is administratively locked */
182 u32 pending:1; /* filter action is pending FW reply */
183 struct filter_ctx *ctx; /* caller's completion hook */
184 struct clip_entry *clipt; /* CLIP Table entry for IPv6 */
185 struct l2t_entry *l2t; /* Layer Two Table entry for dmac */
186 struct smt_entry *smt; /* Source Mac Table entry for smac */
187 struct rte_eth_dev *dev; /* Port's rte eth device */
188 void *private; /* For use by apps using filter_entry */
190 /* This will store the actual tid */
196 struct ch_filter_specification fs;
199 #define FILTER_ID_MAX (~0U)
205 * Find first clear bit in the bitmap.
207 static inline unsigned int cxgbe_find_first_zero_bit(struct rte_bitmap *bmap,
212 for (idx = 0; idx < size; idx++)
213 if (!rte_bitmap_get(bmap, idx))
220 * Find a free region of 'num' consecutive entries.
222 static inline unsigned int
223 cxgbe_bitmap_find_free_region(struct rte_bitmap *bmap, unsigned int size,
226 unsigned int idx, j, free = 0;
231 for (idx = 0; idx < size; idx += num) {
232 for (j = 0; j < num; j++) {
233 if (!rte_bitmap_get(bmap, idx + j)) {
241 /* Found the Region */
245 /* Reached the end and still no region found */
246 if ((idx + num) > size) {
255 u8 cxgbe_filter_slots(struct adapter *adap, u8 family);
256 bool cxgbe_is_filter_set(struct tid_info *t, u32 fidx, u8 nentries);
257 void cxgbe_filter_rpl(struct adapter *adap, const struct cpl_set_tcb_rpl *rpl);
258 int cxgbe_set_filter(struct rte_eth_dev *dev, unsigned int filter_id,
259 struct ch_filter_specification *fs,
260 struct filter_ctx *ctx);
261 int cxgbe_del_filter(struct rte_eth_dev *dev, unsigned int filter_id,
262 struct ch_filter_specification *fs,
263 struct filter_ctx *ctx);
264 int cxgbe_alloc_ftid(struct adapter *adap, u8 nentries);
265 int cxgbe_init_hash_filter(struct adapter *adap);
266 void cxgbe_hash_filter_rpl(struct adapter *adap,
267 const struct cpl_act_open_rpl *rpl);
268 void cxgbe_hash_del_filter_rpl(struct adapter *adap,
269 const struct cpl_abort_rpl_rss *rpl);
270 int cxgbe_validate_filter(struct adapter *adap,
271 struct ch_filter_specification *fs);
272 int cxgbe_get_filter_count(struct adapter *adapter, unsigned int fidx,
273 u64 *c, int hash, bool get_byte);
274 int cxgbe_clear_filter_count(struct adapter *adapter, unsigned int fidx,
275 int hash, bool clear_byte);
276 #endif /* _CXGBE_FILTER_H_ */