Merge tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
[sfrench/cifs-2.6.git] / drivers / net / ethernet / mellanox / mlx5 / core / fs_core.h
1 /*
2  * Copyright (c) 2015, Mellanox Technologies. All rights reserved.
3  *
4  * This software is available to you under a choice of one of two
5  * licenses.  You may choose to be licensed under the terms of the GNU
6  * General Public License (GPL) Version 2, available from the file
7  * COPYING in the main directory of this source tree, or the
8  * OpenIB.org BSD license below:
9  *
10  *     Redistribution and use in source and binary forms, with or
11  *     without modification, are permitted provided that the following
12  *     conditions are met:
13  *
14  *      - Redistributions of source code must retain the above
15  *        copyright notice, this list of conditions and the following
16  *        disclaimer.
17  *
18  *      - Redistributions in binary form must reproduce the above
19  *        copyright notice, this list of conditions and the following
20  *        disclaimer in the documentation and/or other materials
21  *        provided with the distribution.
22  *
23  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30  * SOFTWARE.
31  */
32
33 #ifndef _MLX5_FS_CORE_
34 #define _MLX5_FS_CORE_
35
36 #include <linux/mlx5/fs.h>
37 #include <linux/rhashtable.h>
38
39 enum fs_node_type {
40         FS_TYPE_NAMESPACE,
41         FS_TYPE_PRIO,
42         FS_TYPE_FLOW_TABLE,
43         FS_TYPE_FLOW_GROUP,
44         FS_TYPE_FLOW_ENTRY,
45         FS_TYPE_FLOW_DEST
46 };
47
48 enum fs_flow_table_type {
49         FS_FT_NIC_RX          = 0x0,
50         FS_FT_ESW_EGRESS_ACL  = 0x2,
51         FS_FT_ESW_INGRESS_ACL = 0x3,
52         FS_FT_FDB             = 0X4,
53         FS_FT_SNIFFER_RX        = 0X5,
54         FS_FT_SNIFFER_TX        = 0X6,
55 };
56
57 enum fs_flow_table_op_mod {
58         FS_FT_OP_MOD_NORMAL,
59         FS_FT_OP_MOD_LAG_DEMUX,
60 };
61
62 enum fs_fte_status {
63         FS_FTE_STATUS_EXISTING = 1UL << 0,
64 };
65
66 struct mlx5_flow_steering {
67         struct mlx5_core_dev *dev;
68         struct mlx5_flow_root_namespace *root_ns;
69         struct mlx5_flow_root_namespace *fdb_root_ns;
70         struct mlx5_flow_root_namespace *esw_egress_root_ns;
71         struct mlx5_flow_root_namespace *esw_ingress_root_ns;
72         struct mlx5_flow_root_namespace *sniffer_tx_root_ns;
73         struct mlx5_flow_root_namespace *sniffer_rx_root_ns;
74 };
75
76 struct fs_node {
77         struct list_head        list;
78         struct list_head        children;
79         enum fs_node_type       type;
80         struct fs_node          *parent;
81         struct fs_node          *root;
82         /* lock the node for writing and traversing */
83         struct mutex            lock;
84         atomic_t                refcount;
85         void                    (*remove_func)(struct fs_node *);
86 };
87
88 struct mlx5_flow_rule {
89         struct fs_node                          node;
90         struct mlx5_flow_destination            dest_attr;
91         /* next_ft should be accessed under chain_lock and only of
92          * destination type is FWD_NEXT_fT.
93          */
94         struct list_head                        next_ft;
95         u32                                     sw_action;
96 };
97
98 struct mlx5_flow_handle {
99         int num_rules;
100         struct mlx5_flow_rule *rule[];
101 };
102
103 /* Type of children is mlx5_flow_group */
104 struct mlx5_flow_table {
105         struct fs_node                  node;
106         u32                             id;
107         u16                             vport;
108         unsigned int                    max_fte;
109         unsigned int                    level;
110         enum fs_flow_table_type         type;
111         enum fs_flow_table_op_mod       op_mod;
112         struct {
113                 bool                    active;
114                 unsigned int            required_groups;
115                 unsigned int            num_groups;
116         } autogroup;
117         /* Protect fwd_rules */
118         struct mutex                    lock;
119         /* FWD rules that point on this flow table */
120         struct list_head                fwd_rules;
121         u32                             flags;
122         struct ida                      fte_allocator;
123         struct rhltable                 fgs_hash;
124 };
125
126 struct mlx5_fc_cache {
127         u64 packets;
128         u64 bytes;
129         u64 lastuse;
130 };
131
132 struct mlx5_fc {
133         struct rb_node node;
134         struct list_head list;
135
136         /* last{packets,bytes} members are used when calculating the delta since
137          * last reading
138          */
139         u64 lastpackets;
140         u64 lastbytes;
141
142         u32 id;
143         bool deleted;
144         bool aging;
145
146         struct mlx5_fc_cache cache ____cacheline_aligned_in_smp;
147 };
148
149 #define MLX5_FTE_MATCH_PARAM_RESERVED   reserved_at_600
150 /* Calculate the fte_match_param length and without the reserved length.
151  * Make sure the reserved field is the last.
152  */
153 #define MLX5_ST_SZ_DW_MATCH_PARAM                                           \
154         ((MLX5_BYTE_OFF(fte_match_param, MLX5_FTE_MATCH_PARAM_RESERVED) / sizeof(u32)) + \
155          BUILD_BUG_ON_ZERO(MLX5_ST_SZ_BYTES(fte_match_param) !=              \
156                            MLX5_FLD_SZ_BYTES(fte_match_param,                \
157                                              MLX5_FTE_MATCH_PARAM_RESERVED) +\
158                            MLX5_BYTE_OFF(fte_match_param,                    \
159                                          MLX5_FTE_MATCH_PARAM_RESERVED)))
160
161 /* Type of children is mlx5_flow_rule */
162 struct fs_fte {
163         struct fs_node                  node;
164         u32                             val[MLX5_ST_SZ_DW_MATCH_PARAM];
165         u32                             dests_size;
166         u32                             flow_tag;
167         u32                             index;
168         u32                             action;
169         u32                             encap_id;
170         u32                             modify_id;
171         enum fs_fte_status              status;
172         struct mlx5_fc                  *counter;
173         struct rhash_head               hash;
174 };
175
176 /* Type of children is mlx5_flow_table/namespace */
177 struct fs_prio {
178         struct fs_node                  node;
179         unsigned int                    num_levels;
180         unsigned int                    start_level;
181         unsigned int                    prio;
182         unsigned int                    num_ft;
183 };
184
185 /* Type of children is fs_prio */
186 struct mlx5_flow_namespace {
187         /* parent == NULL => root ns */
188         struct  fs_node                 node;
189 };
190
191 struct mlx5_flow_group_mask {
192         u8      match_criteria_enable;
193         u32     match_criteria[MLX5_ST_SZ_DW_MATCH_PARAM];
194 };
195
196 /* Type of children is fs_fte */
197 struct mlx5_flow_group {
198         struct fs_node                  node;
199         struct mlx5_flow_group_mask     mask;
200         u32                             start_index;
201         u32                             max_ftes;
202         u32                             id;
203         struct rhashtable               ftes_hash;
204         struct rhlist_head              hash;
205 };
206
207 struct mlx5_flow_root_namespace {
208         struct mlx5_flow_namespace      ns;
209         enum   fs_flow_table_type       table_type;
210         struct mlx5_core_dev            *dev;
211         struct mlx5_flow_table          *root_ft;
212         /* Should be held when chaining flow tables */
213         struct mutex                    chain_lock;
214         u32                             underlay_qpn;
215 };
216
217 int mlx5_init_fc_stats(struct mlx5_core_dev *dev);
218 void mlx5_cleanup_fc_stats(struct mlx5_core_dev *dev);
219 void mlx5_fc_queue_stats_work(struct mlx5_core_dev *dev,
220                               struct delayed_work *dwork,
221                               unsigned long delay);
222 void mlx5_fc_update_sampling_interval(struct mlx5_core_dev *dev,
223                                       unsigned long interval);
224
225 int mlx5_init_fs(struct mlx5_core_dev *dev);
226 void mlx5_cleanup_fs(struct mlx5_core_dev *dev);
227
228 #define fs_get_obj(v, _node)  {v = container_of((_node), typeof(*v), node); }
229
230 #define fs_list_for_each_entry(pos, root)               \
231         list_for_each_entry(pos, root, node.list)
232
233 #define fs_list_for_each_entry_safe(pos, tmp, root)             \
234         list_for_each_entry_safe(pos, tmp, root, node.list)
235
236 #define fs_for_each_ns_or_ft_reverse(pos, prio)                         \
237         list_for_each_entry_reverse(pos, &(prio)->node.children, list)
238
239 #define fs_for_each_ns_or_ft(pos, prio)                                 \
240         list_for_each_entry(pos, (&(prio)->node.children), list)
241
242 #define fs_for_each_prio(pos, ns)                       \
243         fs_list_for_each_entry(pos, &(ns)->node.children)
244
245 #define fs_for_each_ns(pos, prio)                       \
246         fs_list_for_each_entry(pos, &(prio)->node.children)
247
248 #define fs_for_each_ft(pos, prio)                       \
249         fs_list_for_each_entry(pos, &(prio)->node.children)
250
251 #define fs_for_each_ft_safe(pos, tmp, prio)                     \
252         fs_list_for_each_entry_safe(pos, tmp, &(prio)->node.children)
253
254 #define fs_for_each_fg(pos, ft)                 \
255         fs_list_for_each_entry(pos, &(ft)->node.children)
256
257 #define fs_for_each_fte(pos, fg)                        \
258         fs_list_for_each_entry(pos, &(fg)->node.children)
259
260 #define fs_for_each_dst(pos, fte)                       \
261         fs_list_for_each_entry(pos, &(fte)->node.children)
262
263 #endif