xref: /freebsd/sys/dev/mlx5/mlx5_core/fs_core.h (revision 5a93b4cd)
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
301