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