1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33#ifndef _MLX5_FS_CORE_
34#define _MLX5_FS_CORE_
35
36#include <linux/refcount.h>
37#include <linux/mlx5/fs.h>
38#include <linux/rhashtable.h>
39#include <linux/llist.h>
40#include <steering/fs_dr.h>
41
42#define FDB_TC_MAX_CHAIN 3
43#define FDB_FT_CHAIN (FDB_TC_MAX_CHAIN + 1)
44#define FDB_TC_SLOW_PATH_CHAIN (FDB_FT_CHAIN + 1)
45
46
47#define FDB_NUM_CHAINS (FDB_FT_CHAIN + 1)
48
49#define FDB_TC_MAX_PRIO 16
50#define FDB_TC_LEVELS_PER_PRIO 2
51
52struct mlx5_modify_hdr {
53 enum mlx5_flow_namespace_type ns_type;
54 union {
55 struct mlx5_fs_dr_action action;
56 u32 id;
57 };
58};
59
60struct mlx5_pkt_reformat {
61 enum mlx5_flow_namespace_type ns_type;
62 int reformat_type;
63 union {
64 struct mlx5_fs_dr_action action;
65 u32 id;
66 };
67};
68
69
70
71
72
73
74
75
76
77
78
79
80enum fs_node_type {
81 FS_TYPE_NAMESPACE,
82 FS_TYPE_PRIO,
83 FS_TYPE_PRIO_CHAINS,
84 FS_TYPE_FLOW_TABLE,
85 FS_TYPE_FLOW_GROUP,
86 FS_TYPE_FLOW_ENTRY,
87 FS_TYPE_FLOW_DEST
88};
89
90enum fs_flow_table_type {
91 FS_FT_NIC_RX = 0x0,
92 FS_FT_NIC_TX = 0x1,
93 FS_FT_ESW_EGRESS_ACL = 0x2,
94 FS_FT_ESW_INGRESS_ACL = 0x3,
95 FS_FT_FDB = 0X4,
96 FS_FT_SNIFFER_RX = 0X5,
97 FS_FT_SNIFFER_TX = 0X6,
98 FS_FT_RDMA_RX = 0X7,
99 FS_FT_RDMA_TX = 0X8,
100 FS_FT_MAX_TYPE = FS_FT_RDMA_TX,
101};
102
103enum fs_flow_table_op_mod {
104 FS_FT_OP_MOD_NORMAL,
105 FS_FT_OP_MOD_LAG_DEMUX,
106};
107
108enum fs_fte_status {
109 FS_FTE_STATUS_EXISTING = 1UL << 0,
110};
111
112enum mlx5_flow_steering_mode {
113 MLX5_FLOW_STEERING_MODE_DMFS,
114 MLX5_FLOW_STEERING_MODE_SMFS
115};
116
117struct mlx5_flow_steering {
118 struct mlx5_core_dev *dev;
119 enum mlx5_flow_steering_mode mode;
120 struct kmem_cache *fgs_cache;
121 struct kmem_cache *ftes_cache;
122 struct mlx5_flow_root_namespace *root_ns;
123 struct mlx5_flow_root_namespace *fdb_root_ns;
124 struct mlx5_flow_namespace **fdb_sub_ns;
125 struct mlx5_flow_root_namespace **esw_egress_root_ns;
126 struct mlx5_flow_root_namespace **esw_ingress_root_ns;
127 struct mlx5_flow_root_namespace *sniffer_tx_root_ns;
128 struct mlx5_flow_root_namespace *sniffer_rx_root_ns;
129 struct mlx5_flow_root_namespace *rdma_rx_root_ns;
130 struct mlx5_flow_root_namespace *rdma_tx_root_ns;
131 struct mlx5_flow_root_namespace *egress_root_ns;
132};
133
134struct fs_node {
135 struct list_head list;
136 struct list_head children;
137 enum fs_node_type type;
138 struct fs_node *parent;
139 struct fs_node *root;
140
141 struct rw_semaphore lock;
142 refcount_t refcount;
143 bool active;
144 void (*del_hw_func)(struct fs_node *);
145 void (*del_sw_func)(struct fs_node *);
146 atomic_t version;
147};
148
149struct mlx5_flow_rule {
150 struct fs_node node;
151 struct mlx5_flow_table *ft;
152 struct mlx5_flow_destination dest_attr;
153
154
155
156 struct list_head next_ft;
157 u32 sw_action;
158};
159
160struct mlx5_flow_handle {
161 int num_rules;
162 struct mlx5_flow_rule *rule[];
163};
164
165
166struct mlx5_flow_table {
167 struct fs_node node;
168 struct mlx5_fs_dr_table fs_dr_table;
169 u32 id;
170 u16 vport;
171 unsigned int max_fte;
172 unsigned int level;
173 enum fs_flow_table_type type;
174 enum fs_flow_table_op_mod op_mod;
175 struct {
176 bool active;
177 unsigned int required_groups;
178 unsigned int group_size;
179 unsigned int num_groups;
180 unsigned int max_fte;
181 } autogroup;
182
183 struct mutex lock;
184
185 struct list_head fwd_rules;
186 u32 flags;
187 struct rhltable fgs_hash;
188 enum mlx5_flow_table_miss_action def_miss_action;
189 struct mlx5_flow_namespace *ns;
190};
191
192struct mlx5_ft_underlay_qp {
193 struct list_head list;
194 u32 qpn;
195};
196
197#define MLX5_FTE_MATCH_PARAM_RESERVED reserved_at_a00
198
199
200
201#define MLX5_ST_SZ_DW_MATCH_PARAM \
202 ((MLX5_BYTE_OFF(fte_match_param, MLX5_FTE_MATCH_PARAM_RESERVED) / sizeof(u32)) + \
203 BUILD_BUG_ON_ZERO(MLX5_ST_SZ_BYTES(fte_match_param) != \
204 MLX5_FLD_SZ_BYTES(fte_match_param, \
205 MLX5_FTE_MATCH_PARAM_RESERVED) +\
206 MLX5_BYTE_OFF(fte_match_param, \
207 MLX5_FTE_MATCH_PARAM_RESERVED)))
208
209
210struct fs_fte {
211 struct fs_node node;
212 struct mlx5_fs_dr_rule fs_dr_rule;
213 u32 val[MLX5_ST_SZ_DW_MATCH_PARAM];
214 u32 dests_size;
215 u32 index;
216 struct mlx5_flow_context flow_context;
217 struct mlx5_flow_act action;
218 enum fs_fte_status status;
219 struct mlx5_fc *counter;
220 struct rhash_head hash;
221 int modify_mask;
222};
223
224
225struct fs_prio {
226 struct fs_node node;
227 unsigned int num_levels;
228 unsigned int start_level;
229 unsigned int prio;
230 unsigned int num_ft;
231};
232
233
234struct mlx5_flow_namespace {
235
236 struct fs_node node;
237 enum mlx5_flow_table_miss_action def_miss_action;
238};
239
240struct mlx5_flow_group_mask {
241 u8 match_criteria_enable;
242 u32 match_criteria[MLX5_ST_SZ_DW_MATCH_PARAM];
243};
244
245
246struct mlx5_flow_group {
247 struct fs_node node;
248 struct mlx5_fs_dr_matcher fs_dr_matcher;
249 struct mlx5_flow_group_mask mask;
250 u32 start_index;
251 u32 max_ftes;
252 struct ida fte_allocator;
253 u32 id;
254 struct rhashtable ftes_hash;
255 struct rhlist_head hash;
256};
257
258struct mlx5_flow_root_namespace {
259 struct mlx5_flow_namespace ns;
260 enum mlx5_flow_steering_mode mode;
261 struct mlx5_fs_dr_domain fs_dr_domain;
262 enum fs_flow_table_type table_type;
263 struct mlx5_core_dev *dev;
264 struct mlx5_flow_table *root_ft;
265
266 struct mutex chain_lock;
267 struct list_head underlay_qpns;
268 const struct mlx5_flow_cmds *cmds;
269};
270
271int mlx5_init_fc_stats(struct mlx5_core_dev *dev);
272void mlx5_cleanup_fc_stats(struct mlx5_core_dev *dev);
273void mlx5_fc_queue_stats_work(struct mlx5_core_dev *dev,
274 struct delayed_work *dwork,
275 unsigned long delay);
276void mlx5_fc_update_sampling_interval(struct mlx5_core_dev *dev,
277 unsigned long interval);
278
279const struct mlx5_flow_cmds *mlx5_fs_cmd_get_fw_cmds(void);
280
281int mlx5_flow_namespace_set_peer(struct mlx5_flow_root_namespace *ns,
282 struct mlx5_flow_root_namespace *peer_ns);
283
284int mlx5_flow_namespace_set_mode(struct mlx5_flow_namespace *ns,
285 enum mlx5_flow_steering_mode mode);
286
287int mlx5_init_fs(struct mlx5_core_dev *dev);
288void mlx5_cleanup_fs(struct mlx5_core_dev *dev);
289
290#define fs_get_obj(v, _node) {v = container_of((_node), typeof(*v), node); }
291
292#define fs_list_for_each_entry(pos, root) \
293 list_for_each_entry(pos, root, node.list)
294
295#define fs_list_for_each_entry_safe(pos, tmp, root) \
296 list_for_each_entry_safe(pos, tmp, root, node.list)
297
298#define fs_for_each_ns_or_ft_reverse(pos, prio) \
299 list_for_each_entry_reverse(pos, &(prio)->node.children, list)
300
301#define fs_for_each_ns_or_ft(pos, prio) \
302 list_for_each_entry(pos, (&(prio)->node.children), list)
303
304#define fs_for_each_prio(pos, ns) \
305 fs_list_for_each_entry(pos, &(ns)->node.children)
306
307#define fs_for_each_ns(pos, prio) \
308 fs_list_for_each_entry(pos, &(prio)->node.children)
309
310#define fs_for_each_ft(pos, prio) \
311 fs_list_for_each_entry(pos, &(prio)->node.children)
312
313#define fs_for_each_ft_safe(pos, tmp, prio) \
314 fs_list_for_each_entry_safe(pos, tmp, &(prio)->node.children)
315
316#define fs_for_each_fg(pos, ft) \
317 fs_list_for_each_entry(pos, &(ft)->node.children)
318
319#define fs_for_each_fte(pos, fg) \
320 fs_list_for_each_entry(pos, &(fg)->node.children)
321
322#define fs_for_each_dst(pos, fte) \
323 fs_list_for_each_entry(pos, &(fte)->node.children)
324
325#define MLX5_CAP_FLOWTABLE_TYPE(mdev, cap, type) ( \
326 (type == FS_FT_NIC_RX) ? MLX5_CAP_FLOWTABLE_NIC_RX(mdev, cap) : \
327 (type == FS_FT_ESW_EGRESS_ACL) ? MLX5_CAP_ESW_EGRESS_ACL(mdev, cap) : \
328 (type == FS_FT_ESW_INGRESS_ACL) ? MLX5_CAP_ESW_INGRESS_ACL(mdev, cap) : \
329 (type == FS_FT_FDB) ? MLX5_CAP_ESW_FLOWTABLE_FDB(mdev, cap) : \
330 (type == FS_FT_SNIFFER_RX) ? MLX5_CAP_FLOWTABLE_SNIFFER_RX(mdev, cap) : \
331 (type == FS_FT_SNIFFER_TX) ? MLX5_CAP_FLOWTABLE_SNIFFER_TX(mdev, cap) : \
332 (type == FS_FT_RDMA_RX) ? MLX5_CAP_FLOWTABLE_RDMA_RX(mdev, cap) : \
333 (type == FS_FT_RDMA_TX) ? MLX5_CAP_FLOWTABLE_RDMA_TX(mdev, cap) : \
334 (BUILD_BUG_ON_ZERO(FS_FT_RDMA_TX != FS_FT_MAX_TYPE))\
335 )
336
337#endif
338