]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/mlx5/mlx5_core/fs_core.h
MFV r330973: 9164 assert: newds == os->os_dsl_dataset
[FreeBSD/FreeBSD.git] / sys / dev / mlx5 / mlx5_core / fs_core.h
1 /*-
2  * Copyright (c) 2013-2017, Mellanox Technologies, Ltd.  All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS `AS IS' AND
14  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16  * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
17  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23  * SUCH DAMAGE.
24  *
25  * $FreeBSD$
26  */
27
28 #ifndef _MLX5_FS_CORE_
29 #define _MLX5_FS_CORE_
30
31 #include <asm/atomic.h>
32 #include <linux/completion.h>
33 #include <linux/mutex.h>
34 #include <dev/mlx5/fs.h>
35
36 enum fs_type {
37         FS_TYPE_NAMESPACE,
38         FS_TYPE_PRIO,
39         FS_TYPE_FLOW_TABLE,
40         FS_TYPE_FLOW_GROUP,
41         FS_TYPE_FLOW_ENTRY,
42         FS_TYPE_FLOW_DEST
43 };
44
45 enum fs_ft_type {
46         FS_FT_NIC_RX          = 0x0,
47         FS_FT_ESW_EGRESS_ACL  = 0x2,
48         FS_FT_ESW_INGRESS_ACL = 0x3,
49         FS_FT_FDB             = 0X4,
50         FS_FT_SNIFFER_RX      = 0x5,
51         FS_FT_SNIFFER_TX      = 0x6
52 };
53
54 enum fs_fte_status {
55         FS_FTE_STATUS_EXISTING = 1UL << 0,
56 };
57
58 /* Should always be the first variable in the struct */
59 struct fs_base {
60         struct list_head                        list;
61         struct fs_base                  *parent;
62         enum fs_type                    type;
63         struct kref                     refcount;
64         /* lock the node for writing and traversing */
65         struct mutex            lock;
66         struct completion                       complete;
67         atomic_t                        users_refcount;
68         const char                      *name;
69 };
70
71 struct mlx5_flow_rule {
72         struct fs_base                          base;
73         struct mlx5_flow_destination            dest_attr;
74         struct list_head                        clients_data;
75         /*protect clients lits*/
76         struct mutex                    clients_lock;
77 };
78
79 struct fs_fte {
80         struct fs_base                          base;
81         u32                                     val[MLX5_ST_SZ_DW(fte_match_param)];
82         uint32_t                                dests_size;
83         uint32_t                                flow_tag;
84         struct list_head                        dests;
85         uint32_t                                index; /* index in ft */
86         u8                                      action; /* MLX5_FLOW_CONTEXT_ACTION */
87         enum fs_fte_status                      status;
88 };
89
90 struct fs_star_rule {
91         struct  mlx5_flow_group  *fg;
92         struct  fs_fte          *fte;
93 };
94
95 struct mlx5_flow_table {
96         struct fs_base                  base;
97         /* sorted list by start_index */
98         struct list_head                fgs;
99         struct {
100                 bool                    active;
101                 unsigned int            max_types;
102                 unsigned int            num_types;
103         } autogroup;
104         unsigned int                    max_fte;
105         unsigned int                    level;
106         uint32_t                        id;
107         u16                             vport;
108         enum fs_ft_type                 type;
109         struct fs_star_rule             star_rule;
110         unsigned int                    shared_refcount;
111 };
112
113 enum fs_prio_flags {
114         MLX5_CORE_FS_PRIO_SHARED = 1
115 };
116
117 struct fs_prio {
118         struct fs_base                  base;
119         struct list_head                objs; /* each object is a namespace or ft */
120         unsigned int                    max_ft;
121         unsigned int                    num_ft;
122         unsigned int                    max_ns;
123         unsigned int                    prio;
124         /*When create shared flow table, this lock should be taken*/
125         struct mutex            shared_lock;
126         u8                              flags;
127 };
128
129 struct mlx5_flow_namespace {
130         /* parent == NULL => root ns */
131         struct  fs_base                 base;
132         /* sorted by priority number */
133         struct  list_head               prios; /* list of fs_prios */
134         struct  list_head               list_notifiers;
135         struct  rw_semaphore            notifiers_rw_sem;
136         struct  rw_semaphore            dests_rw_sem;
137 };
138
139 struct mlx5_flow_root_namespace {
140         struct mlx5_flow_namespace      ns;
141         struct mlx5_flow_table          *ft_level_0;
142         enum   fs_ft_type               table_type;
143         struct mlx5_core_dev            *dev;
144         struct mlx5_flow_table          *root_ft;
145         /* When chaining flow-tables, this lock should be taken */
146         struct mutex            fs_chain_lock;
147 };
148
149 struct mlx5_flow_group {
150         struct fs_base                  base;
151         struct list_head                ftes;
152         struct mlx5_core_fs_mask        mask;
153         uint32_t                        start_index;
154         uint32_t                        max_ftes;
155         uint32_t                        num_ftes;
156         uint32_t                        id;
157 };
158
159 struct mlx5_flow_handler {
160         struct list_head list;
161         rule_event_fn add_dst_cb;
162         rule_event_fn del_dst_cb;
163         void *client_context;
164         struct mlx5_flow_namespace *ns;
165 };
166
167 struct fs_client_priv_data {
168         struct mlx5_flow_handler *fs_handler;
169         struct list_head list;
170         void   *client_dst_data;
171 };
172
173 void _fs_remove_node(struct kref *kref);
174 #define fs_get_obj(v, _base)  {v = container_of((_base), typeof(*v), base); }
175 #define fs_get_parent(v, child)  {v = (child)->base.parent ?                 \
176                                   container_of((child)->base.parent,         \
177                                                typeof(*v), base) : NULL; }
178
179 #define fs_list_for_each_entry(pos, cond, root)         \
180         list_for_each_entry(pos, root, base.list)       \
181                 if (!(cond)) {} else
182
183 #define fs_list_for_each_entry_continue(pos, cond, root)        \
184         list_for_each_entry_continue(pos, root, base.list)      \
185                 if (!(cond)) {} else
186
187 #define fs_list_for_each_entry_reverse(pos, cond, root)         \
188         list_for_each_entry_reverse(pos, root, base.list)       \
189                 if (!(cond)) {} else
190
191 #define fs_list_for_each_entry_continue_reverse(pos, cond, root)        \
192         list_for_each_entry_continue_reverse(pos, root, base.list)      \
193                 if (!(cond)) {} else
194
195 #define fs_for_each_ft(pos, prio)                       \
196         fs_list_for_each_entry(pos, (pos)->base.type == FS_TYPE_FLOW_TABLE, \
197                                &(prio)->objs)
198
199 #define fs_for_each_ft_reverse(pos, prio)                       \
200         fs_list_for_each_entry_reverse(pos,                     \
201                                        (pos)->base.type == FS_TYPE_FLOW_TABLE, \
202                                        &(prio)->objs)
203
204 #define fs_for_each_ns(pos, prio)                       \
205         fs_list_for_each_entry(pos,                     \
206                                (pos)->base.type == FS_TYPE_NAMESPACE, \
207                                &(prio)->objs)
208
209 #define fs_for_each_ns_or_ft_reverse(pos, prio)                 \
210         list_for_each_entry_reverse(pos, &(prio)->objs, list)           \
211                 if (!((pos)->type == FS_TYPE_NAMESPACE ||               \
212                       (pos)->type == FS_TYPE_FLOW_TABLE)) {} else
213
214 #define fs_for_each_ns_or_ft(pos, prio)                 \
215         list_for_each_entry(pos, &(prio)->objs, list)           \
216                 if (!((pos)->type == FS_TYPE_NAMESPACE ||       \
217                       (pos)->type == FS_TYPE_FLOW_TABLE)) {} else
218
219 #define fs_for_each_ns_or_ft_continue_reverse(pos, prio)                \
220         list_for_each_entry_continue_reverse(pos, &(prio)->objs, list)  \
221                 if (!((pos)->type == FS_TYPE_NAMESPACE ||               \
222                       (pos)->type == FS_TYPE_FLOW_TABLE)) {} else
223
224 #define fs_for_each_ns_or_ft_continue(pos, prio)                        \
225         list_for_each_entry_continue(pos, &(prio)->objs, list)          \
226                 if (!((pos)->type == FS_TYPE_NAMESPACE ||               \
227                       (pos)->type == FS_TYPE_FLOW_TABLE)) {} else
228
229 #define fs_for_each_prio(pos, ns)                       \
230         fs_list_for_each_entry(pos, (pos)->base.type == FS_TYPE_PRIO, \
231                                &(ns)->prios)
232
233 #define fs_for_each_prio_reverse(pos, ns)                       \
234         fs_list_for_each_entry_reverse(pos, (pos)->base.type == FS_TYPE_PRIO, \
235                                        &(ns)->prios)
236
237 #define fs_for_each_prio_continue(pos, ns)                      \
238         fs_list_for_each_entry_continue(pos, (pos)->base.type == FS_TYPE_PRIO, \
239                                        &(ns)->prios)
240
241 #define fs_for_each_prio_continue_reverse(pos, ns)                      \
242         fs_list_for_each_entry_continue_reverse(pos,                    \
243                                                 (pos)->base.type == FS_TYPE_PRIO, \
244                                                 &(ns)->prios)
245
246 #define fs_for_each_fg(pos, ft)                 \
247         fs_list_for_each_entry(pos, (pos)->base.type == FS_TYPE_FLOW_GROUP, \
248                                &(ft)->fgs)
249
250 #define fs_for_each_fte(pos, fg)                        \
251         fs_list_for_each_entry(pos, (pos)->base.type == FS_TYPE_FLOW_ENTRY, \
252                                &(fg)->ftes)
253 #define fs_for_each_dst(pos, fte)                       \
254         fs_list_for_each_entry(pos, (pos)->base.type == FS_TYPE_FLOW_DEST, \
255                                &(fte)->dests)
256
257 int mlx5_cmd_fs_create_ft(struct mlx5_core_dev *dev,
258                           u16 vport,
259                           enum fs_ft_type type, unsigned int level,
260                           unsigned int log_size, unsigned int *table_id);
261
262 int mlx5_cmd_fs_destroy_ft(struct mlx5_core_dev *dev,
263                            u16 vport,
264                            enum fs_ft_type type, unsigned int table_id);
265
266 int mlx5_cmd_fs_create_fg(struct mlx5_core_dev *dev,
267                           u32 *in,
268                           u16 vport,
269                           enum fs_ft_type type, unsigned int table_id,
270                           unsigned int *group_id);
271
272 int mlx5_cmd_fs_destroy_fg(struct mlx5_core_dev *dev,
273                            u16 vport,
274                            enum fs_ft_type type, unsigned int table_id,
275                            unsigned int group_id);
276
277
278 int mlx5_cmd_fs_set_fte(struct mlx5_core_dev *dev,
279                         u16 vport,
280                         enum fs_fte_status *fte_status,
281                         u32 *match_val,
282                         enum fs_ft_type type, unsigned int table_id,
283                         unsigned int index, unsigned int group_id,
284                         unsigned int flow_tag,
285                         unsigned short action, int dest_size,
286                         struct list_head *dests);  /* mlx5_flow_desination */
287
288 int mlx5_cmd_fs_delete_fte(struct mlx5_core_dev *dev,
289                            u16 vport,
290                            enum fs_fte_status *fte_status,
291                            enum fs_ft_type type, unsigned int table_id,
292                            unsigned int index);
293
294 int mlx5_cmd_update_root_ft(struct mlx5_core_dev *dev,
295                             enum fs_ft_type type,
296                             unsigned int id);
297
298 int mlx5_init_fs(struct mlx5_core_dev *dev);
299 void mlx5_cleanup_fs(struct mlx5_core_dev *dev);
300 #endif