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