15a93b4cdSHans Petter Selasky /*- 25a93b4cdSHans Petter Selasky * Copyright (c) 2013-2017, Mellanox Technologies, Ltd. All rights reserved. 35a93b4cdSHans Petter Selasky * 45a93b4cdSHans Petter Selasky * Redistribution and use in source and binary forms, with or without 55a93b4cdSHans Petter Selasky * modification, are permitted provided that the following conditions 65a93b4cdSHans Petter Selasky * are met: 75a93b4cdSHans Petter Selasky * 1. Redistributions of source code must retain the above copyright 85a93b4cdSHans Petter Selasky * notice, this list of conditions and the following disclaimer. 95a93b4cdSHans Petter Selasky * 2. Redistributions in binary form must reproduce the above copyright 105a93b4cdSHans Petter Selasky * notice, this list of conditions and the following disclaimer in the 115a93b4cdSHans Petter Selasky * documentation and/or other materials provided with the distribution. 125a93b4cdSHans Petter Selasky * 135a93b4cdSHans Petter Selasky * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS `AS IS' AND 145a93b4cdSHans Petter Selasky * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 155a93b4cdSHans Petter Selasky * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 165a93b4cdSHans Petter Selasky * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE 175a93b4cdSHans Petter Selasky * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 185a93b4cdSHans Petter Selasky * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 195a93b4cdSHans Petter Selasky * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 205a93b4cdSHans Petter Selasky * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 215a93b4cdSHans Petter Selasky * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 225a93b4cdSHans Petter Selasky * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 235a93b4cdSHans Petter Selasky * SUCH DAMAGE. 245a93b4cdSHans Petter Selasky * 255a93b4cdSHans Petter Selasky * $FreeBSD$ 265a93b4cdSHans Petter Selasky */ 275a93b4cdSHans Petter Selasky 285a93b4cdSHans Petter Selasky #ifndef _MLX5_FS_CORE_ 295a93b4cdSHans Petter Selasky #define _MLX5_FS_CORE_ 305a93b4cdSHans Petter Selasky 315a93b4cdSHans Petter Selasky #include <asm/atomic.h> 325a93b4cdSHans Petter Selasky #include <linux/completion.h> 335a93b4cdSHans Petter Selasky #include <linux/mutex.h> 345a93b4cdSHans Petter Selasky #include <dev/mlx5/fs.h> 355a93b4cdSHans Petter Selasky 365a93b4cdSHans Petter Selasky enum fs_type { 375a93b4cdSHans Petter Selasky FS_TYPE_NAMESPACE, 385a93b4cdSHans Petter Selasky FS_TYPE_PRIO, 395a93b4cdSHans Petter Selasky FS_TYPE_FLOW_TABLE, 405a93b4cdSHans Petter Selasky FS_TYPE_FLOW_GROUP, 415a93b4cdSHans Petter Selasky FS_TYPE_FLOW_ENTRY, 425a93b4cdSHans Petter Selasky FS_TYPE_FLOW_DEST 435a93b4cdSHans Petter Selasky }; 445a93b4cdSHans Petter Selasky 455a93b4cdSHans Petter Selasky enum fs_ft_type { 465a93b4cdSHans Petter Selasky FS_FT_NIC_RX = 0x0, 475a93b4cdSHans Petter Selasky FS_FT_ESW_EGRESS_ACL = 0x2, 485a93b4cdSHans Petter Selasky FS_FT_ESW_INGRESS_ACL = 0x3, 495a93b4cdSHans Petter Selasky FS_FT_FDB = 0X4, 505a93b4cdSHans Petter Selasky FS_FT_SNIFFER_RX = 0x5, 515a93b4cdSHans Petter Selasky FS_FT_SNIFFER_TX = 0x6 525a93b4cdSHans Petter Selasky }; 535a93b4cdSHans Petter Selasky 545a93b4cdSHans Petter Selasky enum fs_fte_status { 555a93b4cdSHans Petter Selasky FS_FTE_STATUS_EXISTING = 1UL << 0, 565a93b4cdSHans Petter Selasky }; 575a93b4cdSHans Petter Selasky 585a93b4cdSHans Petter Selasky /* Should always be the first variable in the struct */ 595a93b4cdSHans Petter Selasky struct fs_base { 605a93b4cdSHans Petter Selasky struct list_head list; 615a93b4cdSHans Petter Selasky struct fs_base *parent; 625a93b4cdSHans Petter Selasky enum fs_type type; 635a93b4cdSHans Petter Selasky struct kref refcount; 645a93b4cdSHans Petter Selasky /* lock the node for writing and traversing */ 655a93b4cdSHans Petter Selasky struct mutex lock; 665a93b4cdSHans Petter Selasky struct completion complete; 675a93b4cdSHans Petter Selasky atomic_t users_refcount; 685a93b4cdSHans Petter Selasky const char *name; 695a93b4cdSHans Petter Selasky }; 705a93b4cdSHans Petter Selasky 715a93b4cdSHans Petter Selasky struct mlx5_flow_rule { 725a93b4cdSHans Petter Selasky struct fs_base base; 735a93b4cdSHans Petter Selasky struct mlx5_flow_destination dest_attr; 745a93b4cdSHans Petter Selasky struct list_head clients_data; 755a93b4cdSHans Petter Selasky /*protect clients lits*/ 765a93b4cdSHans Petter Selasky struct mutex clients_lock; 775a93b4cdSHans Petter Selasky }; 785a93b4cdSHans Petter Selasky 795a93b4cdSHans Petter Selasky struct fs_fte { 805a93b4cdSHans Petter Selasky struct fs_base base; 815a93b4cdSHans Petter Selasky u32 val[MLX5_ST_SZ_DW(fte_match_param)]; 825a93b4cdSHans Petter Selasky uint32_t dests_size; 835a93b4cdSHans Petter Selasky uint32_t flow_tag; 845a93b4cdSHans Petter Selasky struct list_head dests; 855a93b4cdSHans Petter Selasky uint32_t index; /* index in ft */ 865a93b4cdSHans Petter Selasky u8 action; /* MLX5_FLOW_CONTEXT_ACTION */ 875a93b4cdSHans Petter Selasky enum fs_fte_status status; 885a93b4cdSHans Petter Selasky }; 895a93b4cdSHans Petter Selasky 905a93b4cdSHans Petter Selasky struct fs_star_rule { 915a93b4cdSHans Petter Selasky struct mlx5_flow_group *fg; 925a93b4cdSHans Petter Selasky struct fs_fte *fte; 935a93b4cdSHans Petter Selasky }; 945a93b4cdSHans Petter Selasky 955a93b4cdSHans Petter Selasky struct mlx5_flow_table { 965a93b4cdSHans Petter Selasky struct fs_base base; 975a93b4cdSHans Petter Selasky /* sorted list by start_index */ 985a93b4cdSHans Petter Selasky struct list_head fgs; 995a93b4cdSHans Petter Selasky struct { 1005a93b4cdSHans Petter Selasky bool active; 1015a93b4cdSHans Petter Selasky unsigned int max_types; 1025a93b4cdSHans Petter Selasky unsigned int num_types; 1035a93b4cdSHans Petter Selasky } autogroup; 1045a93b4cdSHans Petter Selasky unsigned int max_fte; 1055a93b4cdSHans Petter Selasky unsigned int level; 1065a93b4cdSHans Petter Selasky uint32_t id; 1075a93b4cdSHans Petter Selasky u16 vport; 1085a93b4cdSHans Petter Selasky enum fs_ft_type type; 1095a93b4cdSHans Petter Selasky struct fs_star_rule star_rule; 1105a93b4cdSHans Petter Selasky unsigned int shared_refcount; 1115a93b4cdSHans Petter Selasky }; 1125a93b4cdSHans Petter Selasky 1135a93b4cdSHans Petter Selasky enum fs_prio_flags { 1145a93b4cdSHans Petter Selasky MLX5_CORE_FS_PRIO_SHARED = 1 1155a93b4cdSHans Petter Selasky }; 1165a93b4cdSHans Petter Selasky 1175a93b4cdSHans Petter Selasky struct fs_prio { 1185a93b4cdSHans Petter Selasky struct fs_base base; 1195a93b4cdSHans Petter Selasky struct list_head objs; /* each object is a namespace or ft */ 1205a93b4cdSHans Petter Selasky unsigned int max_ft; 1215a93b4cdSHans Petter Selasky unsigned int num_ft; 1225a93b4cdSHans Petter Selasky unsigned int max_ns; 1235a93b4cdSHans Petter Selasky unsigned int prio; 1245a93b4cdSHans Petter Selasky /*When create shared flow table, this lock should be taken*/ 1255a93b4cdSHans Petter Selasky struct mutex shared_lock; 1265a93b4cdSHans Petter Selasky u8 flags; 1275a93b4cdSHans Petter Selasky }; 1285a93b4cdSHans Petter Selasky 1295a93b4cdSHans Petter Selasky struct mlx5_flow_namespace { 1305a93b4cdSHans Petter Selasky /* parent == NULL => root ns */ 1315a93b4cdSHans Petter Selasky struct fs_base base; 1325a93b4cdSHans Petter Selasky /* sorted by priority number */ 1335a93b4cdSHans Petter Selasky struct list_head prios; /* list of fs_prios */ 1345a93b4cdSHans Petter Selasky struct list_head list_notifiers; 1355a93b4cdSHans Petter Selasky struct rw_semaphore notifiers_rw_sem; 1365a93b4cdSHans Petter Selasky struct rw_semaphore dests_rw_sem; 1375a93b4cdSHans Petter Selasky }; 1385a93b4cdSHans Petter Selasky 1395a93b4cdSHans Petter Selasky struct mlx5_flow_root_namespace { 1405a93b4cdSHans Petter Selasky struct mlx5_flow_namespace ns; 1415a93b4cdSHans Petter Selasky struct mlx5_flow_table *ft_level_0; 1425a93b4cdSHans Petter Selasky enum fs_ft_type table_type; 1435a93b4cdSHans Petter Selasky struct mlx5_core_dev *dev; 1445a93b4cdSHans Petter Selasky struct mlx5_flow_table *root_ft; 1455a93b4cdSHans Petter Selasky /* When chaining flow-tables, this lock should be taken */ 1465a93b4cdSHans Petter Selasky struct mutex fs_chain_lock; 1475a93b4cdSHans Petter Selasky }; 1485a93b4cdSHans Petter Selasky 1495a93b4cdSHans Petter Selasky struct mlx5_flow_group { 1505a93b4cdSHans Petter Selasky struct fs_base base; 1515a93b4cdSHans Petter Selasky struct list_head ftes; 1525a93b4cdSHans Petter Selasky struct mlx5_core_fs_mask mask; 1535a93b4cdSHans Petter Selasky uint32_t start_index; 1545a93b4cdSHans Petter Selasky uint32_t max_ftes; 1555a93b4cdSHans Petter Selasky uint32_t num_ftes; 1565a93b4cdSHans Petter Selasky uint32_t id; 1575a93b4cdSHans Petter Selasky }; 1585a93b4cdSHans Petter Selasky 1595a93b4cdSHans Petter Selasky struct mlx5_flow_handler { 1605a93b4cdSHans Petter Selasky struct list_head list; 1615a93b4cdSHans Petter Selasky rule_event_fn add_dst_cb; 1625a93b4cdSHans Petter Selasky rule_event_fn del_dst_cb; 1635a93b4cdSHans Petter Selasky void *client_context; 1645a93b4cdSHans Petter Selasky struct mlx5_flow_namespace *ns; 1655a93b4cdSHans Petter Selasky }; 1665a93b4cdSHans Petter Selasky 1675a93b4cdSHans Petter Selasky struct fs_client_priv_data { 1685a93b4cdSHans Petter Selasky struct mlx5_flow_handler *fs_handler; 1695a93b4cdSHans Petter Selasky struct list_head list; 1705a93b4cdSHans Petter Selasky void *client_dst_data; 1715a93b4cdSHans Petter Selasky }; 1725a93b4cdSHans Petter Selasky 1735a93b4cdSHans Petter Selasky void _fs_remove_node(struct kref *kref); 1745a93b4cdSHans Petter Selasky #define fs_get_obj(v, _base) {v = container_of((_base), typeof(*v), base); } 1755a93b4cdSHans Petter Selasky #define fs_get_parent(v, child) {v = (child)->base.parent ? \ 1765a93b4cdSHans Petter Selasky container_of((child)->base.parent, \ 1775a93b4cdSHans Petter Selasky typeof(*v), base) : NULL; } 1785a93b4cdSHans Petter Selasky 1795a93b4cdSHans Petter Selasky #define fs_list_for_each_entry(pos, cond, root) \ 1805a93b4cdSHans Petter Selasky list_for_each_entry(pos, root, base.list) \ 1815a93b4cdSHans Petter Selasky if (!(cond)) {} else 1825a93b4cdSHans Petter Selasky 1835a93b4cdSHans Petter Selasky #define fs_list_for_each_entry_continue(pos, cond, root) \ 1845a93b4cdSHans Petter Selasky list_for_each_entry_continue(pos, root, base.list) \ 1855a93b4cdSHans Petter Selasky if (!(cond)) {} else 1865a93b4cdSHans Petter Selasky 1875a93b4cdSHans Petter Selasky #define fs_list_for_each_entry_reverse(pos, cond, root) \ 1885a93b4cdSHans Petter Selasky list_for_each_entry_reverse(pos, root, base.list) \ 1895a93b4cdSHans Petter Selasky if (!(cond)) {} else 1905a93b4cdSHans Petter Selasky 1915a93b4cdSHans Petter Selasky #define fs_list_for_each_entry_continue_reverse(pos, cond, root) \ 1925a93b4cdSHans Petter Selasky list_for_each_entry_continue_reverse(pos, root, base.list) \ 1935a93b4cdSHans Petter Selasky if (!(cond)) {} else 1945a93b4cdSHans Petter Selasky 1955a93b4cdSHans Petter Selasky #define fs_for_each_ft(pos, prio) \ 1965a93b4cdSHans Petter Selasky fs_list_for_each_entry(pos, (pos)->base.type == FS_TYPE_FLOW_TABLE, \ 1975a93b4cdSHans Petter Selasky &(prio)->objs) 1985a93b4cdSHans Petter Selasky 1995a93b4cdSHans Petter Selasky #define fs_for_each_ft_reverse(pos, prio) \ 2005a93b4cdSHans Petter Selasky fs_list_for_each_entry_reverse(pos, \ 2015a93b4cdSHans Petter Selasky (pos)->base.type == FS_TYPE_FLOW_TABLE, \ 2025a93b4cdSHans Petter Selasky &(prio)->objs) 2035a93b4cdSHans Petter Selasky 2045a93b4cdSHans Petter Selasky #define fs_for_each_ns(pos, prio) \ 2055a93b4cdSHans Petter Selasky fs_list_for_each_entry(pos, \ 2065a93b4cdSHans Petter Selasky (pos)->base.type == FS_TYPE_NAMESPACE, \ 2075a93b4cdSHans Petter Selasky &(prio)->objs) 2085a93b4cdSHans Petter Selasky 2095a93b4cdSHans Petter Selasky #define fs_for_each_ns_or_ft_reverse(pos, prio) \ 2105a93b4cdSHans Petter Selasky list_for_each_entry_reverse(pos, &(prio)->objs, list) \ 2115a93b4cdSHans Petter Selasky if (!((pos)->type == FS_TYPE_NAMESPACE || \ 2125a93b4cdSHans Petter Selasky (pos)->type == FS_TYPE_FLOW_TABLE)) {} else 2135a93b4cdSHans Petter Selasky 2145a93b4cdSHans Petter Selasky #define fs_for_each_ns_or_ft(pos, prio) \ 2155a93b4cdSHans Petter Selasky list_for_each_entry(pos, &(prio)->objs, list) \ 2165a93b4cdSHans Petter Selasky if (!((pos)->type == FS_TYPE_NAMESPACE || \ 2175a93b4cdSHans Petter Selasky (pos)->type == FS_TYPE_FLOW_TABLE)) {} else 2185a93b4cdSHans Petter Selasky 2195a93b4cdSHans Petter Selasky #define fs_for_each_ns_or_ft_continue_reverse(pos, prio) \ 2205a93b4cdSHans Petter Selasky list_for_each_entry_continue_reverse(pos, &(prio)->objs, list) \ 2215a93b4cdSHans Petter Selasky if (!((pos)->type == FS_TYPE_NAMESPACE || \ 2225a93b4cdSHans Petter Selasky (pos)->type == FS_TYPE_FLOW_TABLE)) {} else 2235a93b4cdSHans Petter Selasky 2245a93b4cdSHans Petter Selasky #define fs_for_each_ns_or_ft_continue(pos, prio) \ 2255a93b4cdSHans Petter Selasky list_for_each_entry_continue(pos, &(prio)->objs, list) \ 2265a93b4cdSHans Petter Selasky if (!((pos)->type == FS_TYPE_NAMESPACE || \ 2275a93b4cdSHans Petter Selasky (pos)->type == FS_TYPE_FLOW_TABLE)) {} else 2285a93b4cdSHans Petter Selasky 2295a93b4cdSHans Petter Selasky #define fs_for_each_prio(pos, ns) \ 2305a93b4cdSHans Petter Selasky fs_list_for_each_entry(pos, (pos)->base.type == FS_TYPE_PRIO, \ 2315a93b4cdSHans Petter Selasky &(ns)->prios) 2325a93b4cdSHans Petter Selasky 2335a93b4cdSHans Petter Selasky #define fs_for_each_prio_reverse(pos, ns) \ 2345a93b4cdSHans Petter Selasky fs_list_for_each_entry_reverse(pos, (pos)->base.type == FS_TYPE_PRIO, \ 2355a93b4cdSHans Petter Selasky &(ns)->prios) 2365a93b4cdSHans Petter Selasky 2375a93b4cdSHans Petter Selasky #define fs_for_each_prio_continue(pos, ns) \ 2385a93b4cdSHans Petter Selasky fs_list_for_each_entry_continue(pos, (pos)->base.type == FS_TYPE_PRIO, \ 2395a93b4cdSHans Petter Selasky &(ns)->prios) 2405a93b4cdSHans Petter Selasky 2415a93b4cdSHans Petter Selasky #define fs_for_each_prio_continue_reverse(pos, ns) \ 2425a93b4cdSHans Petter Selasky fs_list_for_each_entry_continue_reverse(pos, \ 2435a93b4cdSHans Petter Selasky (pos)->base.type == FS_TYPE_PRIO, \ 2445a93b4cdSHans Petter Selasky &(ns)->prios) 2455a93b4cdSHans Petter Selasky 2465a93b4cdSHans Petter Selasky #define fs_for_each_fg(pos, ft) \ 2475a93b4cdSHans Petter Selasky fs_list_for_each_entry(pos, (pos)->base.type == FS_TYPE_FLOW_GROUP, \ 2485a93b4cdSHans Petter Selasky &(ft)->fgs) 2495a93b4cdSHans Petter Selasky 2505a93b4cdSHans Petter Selasky #define fs_for_each_fte(pos, fg) \ 2515a93b4cdSHans Petter Selasky fs_list_for_each_entry(pos, (pos)->base.type == FS_TYPE_FLOW_ENTRY, \ 2525a93b4cdSHans Petter Selasky &(fg)->ftes) 2535a93b4cdSHans Petter Selasky #define fs_for_each_dst(pos, fte) \ 2545a93b4cdSHans Petter Selasky fs_list_for_each_entry(pos, (pos)->base.type == FS_TYPE_FLOW_DEST, \ 2555a93b4cdSHans Petter Selasky &(fte)->dests) 2565a93b4cdSHans Petter Selasky 2575a93b4cdSHans Petter Selasky int mlx5_cmd_fs_create_ft(struct mlx5_core_dev *dev, 2585a93b4cdSHans Petter Selasky u16 vport, 2595a93b4cdSHans Petter Selasky enum fs_ft_type type, unsigned int level, 2605a93b4cdSHans Petter Selasky unsigned int log_size, unsigned int *table_id); 2615a93b4cdSHans Petter Selasky 2625a93b4cdSHans Petter Selasky int mlx5_cmd_fs_destroy_ft(struct mlx5_core_dev *dev, 2635a93b4cdSHans Petter Selasky u16 vport, 2645a93b4cdSHans Petter Selasky enum fs_ft_type type, unsigned int table_id); 2655a93b4cdSHans Petter Selasky 2665a93b4cdSHans Petter Selasky int mlx5_cmd_fs_create_fg(struct mlx5_core_dev *dev, 2675a93b4cdSHans Petter Selasky u32 *in, 2685a93b4cdSHans Petter Selasky u16 vport, 2695a93b4cdSHans Petter Selasky enum fs_ft_type type, unsigned int table_id, 2705a93b4cdSHans Petter Selasky unsigned int *group_id); 2715a93b4cdSHans Petter Selasky 2725a93b4cdSHans Petter Selasky int mlx5_cmd_fs_destroy_fg(struct mlx5_core_dev *dev, 2735a93b4cdSHans Petter Selasky u16 vport, 2745a93b4cdSHans Petter Selasky enum fs_ft_type type, unsigned int table_id, 2755a93b4cdSHans Petter Selasky unsigned int group_id); 2765a93b4cdSHans Petter Selasky 2775a93b4cdSHans Petter Selasky 2785a93b4cdSHans Petter Selasky int mlx5_cmd_fs_set_fte(struct mlx5_core_dev *dev, 2795a93b4cdSHans Petter Selasky u16 vport, 2805a93b4cdSHans Petter Selasky enum fs_fte_status *fte_status, 2815a93b4cdSHans Petter Selasky u32 *match_val, 2825a93b4cdSHans Petter Selasky enum fs_ft_type type, unsigned int table_id, 2835a93b4cdSHans Petter Selasky unsigned int index, unsigned int group_id, 2845a93b4cdSHans Petter Selasky unsigned int flow_tag, 2855a93b4cdSHans Petter Selasky unsigned short action, int dest_size, 2865a93b4cdSHans Petter Selasky struct list_head *dests); /* mlx5_flow_desination */ 2875a93b4cdSHans Petter Selasky 2885a93b4cdSHans Petter Selasky int mlx5_cmd_fs_delete_fte(struct mlx5_core_dev *dev, 2895a93b4cdSHans Petter Selasky u16 vport, 2905a93b4cdSHans Petter Selasky enum fs_fte_status *fte_status, 2915a93b4cdSHans Petter Selasky enum fs_ft_type type, unsigned int table_id, 2925a93b4cdSHans Petter Selasky unsigned int index); 2935a93b4cdSHans Petter Selasky 2945a93b4cdSHans Petter Selasky int mlx5_cmd_update_root_ft(struct mlx5_core_dev *dev, 2955a93b4cdSHans Petter Selasky enum fs_ft_type type, 2965a93b4cdSHans Petter Selasky unsigned int id); 2975a93b4cdSHans Petter Selasky 2985a93b4cdSHans Petter Selasky int mlx5_init_fs(struct mlx5_core_dev *dev); 2995a93b4cdSHans Petter Selasky void mlx5_cleanup_fs(struct mlx5_core_dev *dev); 3005a93b4cdSHans Petter Selasky #endif 301