net/cxgbe: support flow API for source MAC rewrite
[dpdk.git] / drivers / net / cxgbe / cxgbe_filter.h
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2018 Chelsio Communications.
3  * All rights reserved.
4  */
5
6 #ifndef _CXGBE_FILTER_H_
7 #define _CXGBE_FILTER_H_
8
9 #include "base/t4_msg.h"
10 /*
11  * Defined bit width of user definable filter tuples
12  */
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
21 #define PF_BITWIDTH 3
22 #define VF_BITWIDTH 13
23 #define IVLAN_BITWIDTH 16
24 #define OVLAN_BITWIDTH 16
25
26 /*
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.
33  *
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.
37  * MPS match type) ...
38  */
39 struct ch_filter_tuple {
40         /*
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
45          * set of fields.
46          */
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 */
62
63         /*
64          * Uncompressed header matching field rules.  These are always
65          * available for field rules.
66          */
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 */
71
72         /* reservations for future additions */
73         uint8_t rsvd[12];
74 };
75
76 /*
77  * Filter specification
78  */
79 struct ch_filter_specification {
80         void *private;
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 */
84
85         /*
86          * Fundamental filter typing.  This is the one element of filter
87          * matching that doesn't exist as a (value, mask) tuple.
88          */
89         uint32_t type:1;        /* 0 => IPv4, 1 => IPv6 */
90         uint32_t cap:1;         /* 0 => LE-TCAM, 1 => Hash */
91
92         /*
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.
96          */
97         uint32_t action:2;      /* drop, pass, switch */
98
99         uint32_t dirsteer:1;    /* 0 => RSS, 1 => steer to iq */
100         uint32_t iq:10;         /* ingress queue */
101
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 */
110
111         /*
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.
115          */
116         uint32_t nat_mode:3;    /* specify NAT operation mode */
117
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 */
122
123         /* Filter rule value/mask pairs. */
124         struct ch_filter_tuple val;
125         struct ch_filter_tuple mask;
126 };
127
128 enum {
129         FILTER_PASS = 0,        /* default */
130         FILTER_DROP,
131         FILTER_SWITCH
132 };
133
134 enum {
135         VLAN_REMOVE = 1,
136         VLAN_INSERT,
137         VLAN_REWRITE
138 };
139
140 enum {
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 */
149 };
150
151 enum filter_type {
152         FILTER_TYPE_IPV4 = 0,
153         FILTER_TYPE_IPV6,
154 };
155
156 struct t4_completion {
157         unsigned int done;       /* completion done (0 - No, 1 - Yes) */
158         rte_spinlock_t lock;     /* completion lock */
159 };
160
161 /*
162  * Filter operation context to allow callers to wait for
163  * an asynchronous completion.
164  */
165 struct filter_ctx {
166         struct t4_completion completion; /* completion rendezvous */
167         int result;                      /* result of operation */
168         u32 tid;                         /* to store tid of hash filter */
169 };
170
171 /*
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
174  * firmware command.
175  */
176 struct filter_entry {
177         /*
178          * Administrative fields for filter.
179          */
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 */
189
190         /* This will store the actual tid */
191         u32 tid;
192
193         /*
194          * The filter itself.
195          */
196         struct ch_filter_specification fs;
197 };
198
199 #define FILTER_ID_MAX   (~0U)
200
201 struct tid_info;
202 struct adapter;
203
204 /**
205  * Find first clear bit in the bitmap.
206  */
207 static inline unsigned int cxgbe_find_first_zero_bit(struct rte_bitmap *bmap,
208                                                      unsigned int size)
209 {
210         unsigned int idx;
211
212         for (idx = 0; idx < size; idx++)
213                 if (!rte_bitmap_get(bmap, idx))
214                         break;
215
216         return idx;
217 }
218
219 /**
220  * Find a free region of 'num' consecutive entries.
221  */
222 static inline unsigned int
223 cxgbe_bitmap_find_free_region(struct rte_bitmap *bmap, unsigned int size,
224                               unsigned int num)
225 {
226         unsigned int idx, j, free = 0;
227
228         if (num > size)
229                 return size;
230
231         for (idx = 0; idx < size; idx += num) {
232                 for (j = 0; j < num; j++) {
233                         if (!rte_bitmap_get(bmap, idx + j)) {
234                                 free++;
235                         } else {
236                                 free = 0;
237                                 break;
238                         }
239                 }
240
241                 /* Found the Region */
242                 if (free == num)
243                         break;
244
245                 /* Reached the end and still no region found */
246                 if ((idx + num) > size) {
247                         idx = size;
248                         break;
249                 }
250         }
251
252         return idx;
253 }
254
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_ */