2 * Copyright (c) 2013-2017, Mellanox Technologies, Ltd. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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
28 #ifndef _MLX5_FS_CORE_
29 #define _MLX5_FS_CORE_
31 #include <asm/atomic.h>
32 #include <linux/completion.h>
33 #include <linux/mutex.h>
34 #include <dev/mlx5/fs.h>
47 FS_FT_ESW_EGRESS_ACL = 0x2,
48 FS_FT_ESW_INGRESS_ACL = 0x3,
50 FS_FT_SNIFFER_RX = 0x5,
51 FS_FT_SNIFFER_TX = 0x6
55 FS_FTE_STATUS_EXISTING = 1UL << 0,
58 /* Should always be the first variable in the struct */
60 struct list_head list;
61 struct fs_base *parent;
64 /* lock the node for writing and traversing */
66 struct completion complete;
67 atomic_t users_refcount;
71 struct mlx5_flow_rule {
73 struct mlx5_flow_destination dest_attr;
74 struct list_head clients_data;
75 /*protect clients lits*/
76 struct mutex clients_lock;
81 u32 val[MLX5_ST_SZ_DW(fte_match_param)];
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;
91 struct mlx5_flow_group *fg;
95 struct mlx5_flow_table {
97 /* sorted list by start_index */
101 unsigned int max_types;
102 unsigned int num_types;
104 unsigned int max_fte;
108 enum fs_ft_type type;
109 struct fs_star_rule star_rule;
110 unsigned int shared_refcount;
114 MLX5_CORE_FS_PRIO_SHARED = 1
119 struct list_head objs; /* each object is a namespace or ft */
124 /*When create shared flow table, this lock should be taken*/
125 struct mutex shared_lock;
129 struct mlx5_flow_namespace {
130 /* parent == NULL => root ns */
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;
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;
149 struct mlx5_flow_group {
151 struct list_head ftes;
152 struct mlx5_core_fs_mask mask;
153 uint32_t start_index;
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;
167 struct fs_client_priv_data {
168 struct mlx5_flow_handler *fs_handler;
169 struct list_head list;
170 void *client_dst_data;
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; }
179 #define fs_list_for_each_entry(pos, cond, root) \
180 list_for_each_entry(pos, root, base.list) \
183 #define fs_list_for_each_entry_continue(pos, cond, root) \
184 list_for_each_entry_continue(pos, root, base.list) \
187 #define fs_list_for_each_entry_reverse(pos, cond, root) \
188 list_for_each_entry_reverse(pos, root, base.list) \
191 #define fs_list_for_each_entry_continue_reverse(pos, cond, root) \
192 list_for_each_entry_continue_reverse(pos, root, base.list) \
195 #define fs_for_each_ft(pos, prio) \
196 fs_list_for_each_entry(pos, (pos)->base.type == FS_TYPE_FLOW_TABLE, \
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, \
204 #define fs_for_each_ns(pos, prio) \
205 fs_list_for_each_entry(pos, \
206 (pos)->base.type == FS_TYPE_NAMESPACE, \
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
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
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
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
229 #define fs_for_each_prio(pos, ns) \
230 fs_list_for_each_entry(pos, (pos)->base.type == FS_TYPE_PRIO, \
233 #define fs_for_each_prio_reverse(pos, ns) \
234 fs_list_for_each_entry_reverse(pos, (pos)->base.type == FS_TYPE_PRIO, \
237 #define fs_for_each_prio_continue(pos, ns) \
238 fs_list_for_each_entry_continue(pos, (pos)->base.type == FS_TYPE_PRIO, \
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, \
246 #define fs_for_each_fg(pos, ft) \
247 fs_list_for_each_entry(pos, (pos)->base.type == FS_TYPE_FLOW_GROUP, \
250 #define fs_for_each_fte(pos, fg) \
251 fs_list_for_each_entry(pos, (pos)->base.type == FS_TYPE_FLOW_ENTRY, \
253 #define fs_for_each_dst(pos, fte) \
254 fs_list_for_each_entry(pos, (pos)->base.type == FS_TYPE_FLOW_DEST, \
257 int mlx5_cmd_fs_create_ft(struct mlx5_core_dev *dev,
259 enum fs_ft_type type, unsigned int level,
260 unsigned int log_size, unsigned int *table_id);
262 int mlx5_cmd_fs_destroy_ft(struct mlx5_core_dev *dev,
264 enum fs_ft_type type, unsigned int table_id);
266 int mlx5_cmd_fs_create_fg(struct mlx5_core_dev *dev,
269 enum fs_ft_type type, unsigned int table_id,
270 unsigned int *group_id);
272 int mlx5_cmd_fs_destroy_fg(struct mlx5_core_dev *dev,
274 enum fs_ft_type type, unsigned int table_id,
275 unsigned int group_id);
278 int mlx5_cmd_fs_set_fte(struct mlx5_core_dev *dev,
280 enum fs_fte_status *fte_status,
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 */
288 int mlx5_cmd_fs_delete_fte(struct mlx5_core_dev *dev,
290 enum fs_fte_status *fte_status,
291 enum fs_ft_type type, unsigned int table_id,
294 int mlx5_cmd_update_root_ft(struct mlx5_core_dev *dev,
295 enum fs_ft_type type,
298 int mlx5_init_fs(struct mlx5_core_dev *dev);
299 void mlx5_cleanup_fs(struct mlx5_core_dev *dev);