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
Cache object: b8f3a3ce4a0daad4c94507ea1a0bdbe0
|