xref: /freebsd/sys/dev/mlx5/mlx5_core/fs_core.h (revision 45e2e55d)
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 
26 #ifndef _MLX5_FS_CORE_
27 #define _MLX5_FS_CORE_
28 
29 #include <asm/atomic.h>
30 #include <linux/completion.h>
31 #include <linux/mutex.h>
32 #include <dev/mlx5/fs.h>
33 
34 enum fs_type {
35 	FS_TYPE_NAMESPACE,
36 	FS_TYPE_PRIO,
37 	FS_TYPE_FLOW_TABLE,
38 	FS_TYPE_FLOW_GROUP,
39 	FS_TYPE_FLOW_ENTRY,
40 	FS_TYPE_FLOW_DEST
41 };
42 
43 enum fs_ft_type {
44 	FS_FT_NIC_RX          = 0x0,
45 	FS_FT_ESW_EGRESS_ACL  = 0x2,
46 	FS_FT_ESW_INGRESS_ACL = 0x3,
47 	FS_FT_FDB             = 0X4,
48 	FS_FT_SNIFFER_RX      = 0x5,
49 	FS_FT_SNIFFER_TX      = 0x6
50 };
51 
52 enum fs_fte_status {
53 	FS_FTE_STATUS_EXISTING = 1UL << 0,
54 };
55 
56 /* Should always be the first variable in the struct */
57 struct fs_base {
58 	struct list_head			list;
59 	struct fs_base			*parent;
60 	enum fs_type			type;
61 	struct kref			refcount;
62 	/* lock the node for writing and traversing */
63 	struct mutex		lock;
64 	struct completion			complete;
65 	atomic_t			users_refcount;
66 	const char			*name;
67 };
68 
69 struct mlx5_flow_rule {
70 	struct fs_base				base;
71 	struct mlx5_flow_destination		dest_attr;
72 	struct list_head			clients_data;
73 	/*protect clients lits*/
74 	struct mutex			clients_lock;
75 };
76 
77 struct fs_fte {
78 	struct fs_base				base;
79 	u32					val[MLX5_ST_SZ_DW(fte_match_param)];
80 	uint32_t				dests_size;
81 	struct list_head			dests;
82 	uint32_t				index; /* index in ft */
83 	struct mlx5_flow_act			flow_act;
84 	u8					action; /* MLX5_FLOW_CONTEXT_ACTION */
85 	enum fs_fte_status			status;
86 };
87 
88 struct fs_star_rule {
89 	struct	mlx5_flow_group	 *fg;
90 	struct	fs_fte		*fte;
91 };
92 
93 struct mlx5_flow_table {
94 	struct fs_base			base;
95 	/* sorted list by start_index */
96 	struct list_head		fgs;
97 	struct {
98 		bool			active;
99 		unsigned int		max_types;
100 		unsigned int		num_types;
101 	} autogroup;
102 	unsigned int			max_fte;
103 	unsigned int			level;
104 	uint32_t			id;
105 	u16                             vport;
106 	enum fs_ft_type			type;
107 	struct fs_star_rule		star_rule;
108 	unsigned int			shared_refcount;
109 };
110 
111 enum fs_prio_flags {
112 	MLX5_CORE_FS_PRIO_SHARED = 1
113 };
114 
115 struct fs_prio {
116 	struct fs_base			base;
117 	struct list_head		objs; /* each object is a namespace or ft */
118 	unsigned int			max_ft;
119 	unsigned int			num_ft;
120 	unsigned int			max_ns;
121 	unsigned int			prio;
122 	/*When create shared flow table, this lock should be taken*/
123 	struct mutex		shared_lock;
124 	u8				flags;
125 };
126 
127 struct mlx5_flow_namespace {
128 	/* parent == NULL => root ns */
129 	struct	fs_base			base;
130 	/* sorted by priority number */
131 	struct	list_head		prios; /* list of fs_prios */
132 	struct  list_head		list_notifiers;
133 	struct	rw_semaphore		notifiers_rw_sem;
134 	struct  rw_semaphore		dests_rw_sem;
135 };
136 
137 struct mlx5_flow_root_namespace {
138 	struct mlx5_flow_namespace	ns;
139 	struct mlx5_flow_table		*ft_level_0;
140 	enum   fs_ft_type		table_type;
141 	struct mlx5_core_dev		*dev;
142 	struct mlx5_flow_table		*root_ft;
143 	/* When chaining flow-tables, this lock should be taken */
144 	struct mutex		fs_chain_lock;
145 };
146 
147 struct mlx5_flow_group {
148 	struct fs_base			base;
149 	struct list_head		ftes;
150 	struct mlx5_core_fs_mask	mask;
151 	uint32_t			start_index;
152 	uint32_t			max_ftes;
153 	uint32_t			num_ftes;
154 	uint32_t			id;
155 };
156 
157 struct mlx5_flow_handler {
158 	struct list_head list;
159 	rule_event_fn add_dst_cb;
160 	rule_event_fn del_dst_cb;
161 	void *client_context;
162 	struct mlx5_flow_namespace *ns;
163 };
164 
165 struct fs_client_priv_data {
166 	struct mlx5_flow_handler *fs_handler;
167 	struct list_head list;
168 	void   *client_dst_data;
169 };
170 
171 struct mlx5_modify_hdr {
172 	enum mlx5_flow_namespace_type ns_type;
173 	u32 id;
174 };
175 
176 struct mlx5_pkt_reformat {
177         enum mlx5_flow_namespace_type ns_type;
178         int reformat_type; /* from mlx5_ifc */
179 	u32 id;
180 };
181 
182 void _fs_remove_node(struct kref *kref);
183 #define fs_get_obj(v, _base)  {v = container_of((_base), typeof(*v), base); }
184 #define fs_get_parent(v, child)  {v = (child)->base.parent ?		     \
185 				  container_of((child)->base.parent,	     \
186 					       typeof(*v), base) : NULL; }
187 
188 #define fs_list_for_each_entry(pos, cond, root)		\
189 	list_for_each_entry(pos, root, base.list)	\
190 		if (!(cond)) {} else
191 
192 #define fs_list_for_each_entry_continue(pos, cond, root)	\
193 	list_for_each_entry_continue(pos, root, base.list)	\
194 		if (!(cond)) {} else
195 
196 #define fs_list_for_each_entry_reverse(pos, cond, root)		\
197 	list_for_each_entry_reverse(pos, root, base.list)	\
198 		if (!(cond)) {} else
199 
200 #define fs_list_for_each_entry_continue_reverse(pos, cond, root)	\
201 	list_for_each_entry_continue_reverse(pos, root, base.list)	\
202 		if (!(cond)) {} else
203 
204 #define fs_for_each_ft(pos, prio)			\
205 	fs_list_for_each_entry(pos, (pos)->base.type == FS_TYPE_FLOW_TABLE, \
206 			       &(prio)->objs)
207 
208 #define fs_for_each_ft_reverse(pos, prio)			\
209 	fs_list_for_each_entry_reverse(pos,			\
210 				       (pos)->base.type == FS_TYPE_FLOW_TABLE, \
211 				       &(prio)->objs)
212 
213 #define fs_for_each_ns(pos, prio)			\
214 	fs_list_for_each_entry(pos,			\
215 			       (pos)->base.type == FS_TYPE_NAMESPACE, \
216 			       &(prio)->objs)
217 
218 #define fs_for_each_ns_or_ft_reverse(pos, prio)			\
219 	list_for_each_entry_reverse(pos, &(prio)->objs, list)		\
220 		if (!((pos)->type == FS_TYPE_NAMESPACE ||		\
221 		      (pos)->type == FS_TYPE_FLOW_TABLE)) {} else
222 
223 #define fs_for_each_ns_or_ft(pos, prio)			\
224 	list_for_each_entry(pos, &(prio)->objs, list)		\
225 		if (!((pos)->type == FS_TYPE_NAMESPACE ||	\
226 		      (pos)->type == FS_TYPE_FLOW_TABLE)) {} else
227 
228 #define fs_for_each_ns_or_ft_continue_reverse(pos, prio)		\
229 	list_for_each_entry_continue_reverse(pos, &(prio)->objs, list)	\
230 		if (!((pos)->type == FS_TYPE_NAMESPACE ||		\
231 		      (pos)->type == FS_TYPE_FLOW_TABLE)) {} else
232 
233 #define fs_for_each_ns_or_ft_continue(pos, prio)			\
234 	list_for_each_entry_continue(pos, &(prio)->objs, list)		\
235 		if (!((pos)->type == FS_TYPE_NAMESPACE ||		\
236 		      (pos)->type == FS_TYPE_FLOW_TABLE)) {} else
237 
238 #define fs_for_each_prio(pos, ns)			\
239 	fs_list_for_each_entry(pos, (pos)->base.type == FS_TYPE_PRIO, \
240 			       &(ns)->prios)
241 
242 #define fs_for_each_prio_reverse(pos, ns)			\
243 	fs_list_for_each_entry_reverse(pos, (pos)->base.type == FS_TYPE_PRIO, \
244 				       &(ns)->prios)
245 
246 #define fs_for_each_prio_continue(pos, ns)			\
247 	fs_list_for_each_entry_continue(pos, (pos)->base.type == FS_TYPE_PRIO, \
248 				       &(ns)->prios)
249 
250 #define fs_for_each_prio_continue_reverse(pos, ns)			\
251 	fs_list_for_each_entry_continue_reverse(pos,			\
252 						(pos)->base.type == FS_TYPE_PRIO, \
253 						&(ns)->prios)
254 
255 #define fs_for_each_fg(pos, ft)			\
256 	fs_list_for_each_entry(pos, (pos)->base.type == FS_TYPE_FLOW_GROUP, \
257 			       &(ft)->fgs)
258 
259 #define fs_for_each_fte(pos, fg)			\
260 	fs_list_for_each_entry(pos, (pos)->base.type == FS_TYPE_FLOW_ENTRY, \
261 			       &(fg)->ftes)
262 #define fs_for_each_dst(pos, fte)			\
263 	fs_list_for_each_entry(pos, (pos)->base.type == FS_TYPE_FLOW_DEST, \
264 			       &(fte)->dests)
265 
266 int mlx5_cmd_fs_create_ft(struct mlx5_core_dev *dev,
267 			  u16 vport, enum fs_ft_type type, unsigned int level,
268 			  unsigned int log_size, const char *name, unsigned int *table_id);
269 
270 int mlx5_cmd_fs_destroy_ft(struct mlx5_core_dev *dev,
271 			   u16 vport,
272 			   enum fs_ft_type type, unsigned int table_id);
273 
274 int mlx5_cmd_fs_create_fg(struct mlx5_core_dev *dev,
275 			  u32 *in,
276 			  u16 vport,
277 			  enum fs_ft_type type, unsigned int table_id,
278 			  unsigned int *group_id);
279 
280 int mlx5_cmd_fs_destroy_fg(struct mlx5_core_dev *dev,
281 			   u16 vport,
282 			   enum fs_ft_type type, unsigned int table_id,
283 			   unsigned int group_id);
284 
285 
286 int mlx5_cmd_fs_set_fte(struct mlx5_core_dev *dev,
287 			u16 vport,
288 			enum fs_fte_status *fte_status,
289 			u32 *match_val,
290 			enum fs_ft_type type, unsigned int table_id,
291 			unsigned int index, unsigned int group_id,
292 			struct mlx5_flow_act *flow_act,
293 			unsigned short action, int dest_size,
294 			struct list_head *dests);  /* mlx5_flow_desination */
295 
296 int mlx5_cmd_fs_delete_fte(struct mlx5_core_dev *dev,
297 			   u16 vport,
298 			   enum fs_fte_status *fte_status,
299 			   enum fs_ft_type type, unsigned int table_id,
300 			   unsigned int index);
301 
302 int mlx5_cmd_update_root_ft(struct mlx5_core_dev *dev,
303 			    enum fs_ft_type type,
304 			    unsigned int id);
305 
306 int mlx5_init_fs(struct mlx5_core_dev *dev);
307 void mlx5_cleanup_fs(struct mlx5_core_dev *dev);
308 void mlx5_fc_update_sampling_interval(struct mlx5_core_dev *dev,
309 				      unsigned long interval);
310 
311 int mlx5_cmd_modify_header_alloc(struct mlx5_core_dev *dev,
312 				 enum mlx5_flow_namespace_type namespace,
313 				 u8 num_actions,
314 				 void *modify_actions,
315 				 struct mlx5_modify_hdr *modify_hdr);
316 void mlx5_cmd_modify_header_dealloc(struct mlx5_core_dev *dev,
317 				    struct mlx5_modify_hdr *modify_hdr);
318 int mlx5_cmd_packet_reformat_alloc(struct mlx5_core_dev *dev,
319 				   struct mlx5_pkt_reformat_params *params,
320 				   enum mlx5_flow_namespace_type namespace,
321 				   struct mlx5_pkt_reformat *pkt_reformat);
322 void mlx5_cmd_packet_reformat_dealloc(struct mlx5_core_dev *dev,
323 				      struct mlx5_pkt_reformat *pkt_reformat);
324 #endif
325