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_
34 #define _MLX5_FS_
35
36 #include <linux/mlx5/driver.h>
37 #include <linux/mlx5/mlx5_ifc.h>
38
39 #define MLX5_FS_DEFAULT_FLOW_TAG 0x0
40
41 #define MLX5_SET_CFG(p, f, v) MLX5_SET(create_flow_group_in, p, f, v)
42
43 #define MLX5_RDMA_TRANSPORT_BYPASS_PRIO 16
44 #define MLX5_FS_MAX_POOL_SIZE BIT(30)
45
46 enum mlx5_flow_destination_type {
47 MLX5_FLOW_DESTINATION_TYPE_NONE,
48 MLX5_FLOW_DESTINATION_TYPE_VPORT,
49 MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE,
50 MLX5_FLOW_DESTINATION_TYPE_TIR,
51 MLX5_FLOW_DESTINATION_TYPE_FLOW_SAMPLER,
52 MLX5_FLOW_DESTINATION_TYPE_UPLINK,
53 MLX5_FLOW_DESTINATION_TYPE_PORT,
54 MLX5_FLOW_DESTINATION_TYPE_COUNTER,
55 MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE_NUM,
56 MLX5_FLOW_DESTINATION_TYPE_RANGE,
57 MLX5_FLOW_DESTINATION_TYPE_TABLE_TYPE,
58 };
59
60 enum {
61 MLX5_FLOW_CONTEXT_ACTION_FWD_NEXT_PRIO = 1 << 16,
62 MLX5_FLOW_CONTEXT_ACTION_ENCRYPT = 1 << 17,
63 MLX5_FLOW_CONTEXT_ACTION_DECRYPT = 1 << 18,
64 MLX5_FLOW_CONTEXT_ACTION_FWD_NEXT_NS = 1 << 19,
65 };
66
67 enum {
68 MLX5_FLOW_TABLE_TUNNEL_EN_REFORMAT = BIT(0),
69 MLX5_FLOW_TABLE_TUNNEL_EN_DECAP = BIT(1),
70 MLX5_FLOW_TABLE_TERMINATION = BIT(2),
71 MLX5_FLOW_TABLE_UNMANAGED = BIT(3),
72 MLX5_FLOW_TABLE_OTHER_VPORT = BIT(4),
73 MLX5_FLOW_TABLE_UPLINK_VPORT = BIT(5),
74 MLX5_FLOW_TABLE_OTHER_ESWITCH = BIT(6),
75 };
76
77 #define LEFTOVERS_RULE_NUM 2
build_leftovers_ft_param(int * priority,int * n_ent,int * n_grp)78 static inline void build_leftovers_ft_param(int *priority,
79 int *n_ent,
80 int *n_grp)
81 {
82 *priority = 0; /* Priority of leftovers_prio-0 */
83 *n_ent = LEFTOVERS_RULE_NUM;
84 *n_grp = LEFTOVERS_RULE_NUM;
85 }
86
87 enum mlx5_flow_namespace_type {
88 MLX5_FLOW_NAMESPACE_BYPASS,
89 MLX5_FLOW_NAMESPACE_KERNEL_RX_MACSEC,
90 MLX5_FLOW_NAMESPACE_LAG,
91 MLX5_FLOW_NAMESPACE_OFFLOADS,
92 MLX5_FLOW_NAMESPACE_ETHTOOL,
93 MLX5_FLOW_NAMESPACE_KERNEL,
94 MLX5_FLOW_NAMESPACE_LEFTOVERS,
95 MLX5_FLOW_NAMESPACE_ANCHOR,
96 MLX5_FLOW_NAMESPACE_FDB_BYPASS,
97 MLX5_FLOW_NAMESPACE_FDB,
98 MLX5_FLOW_NAMESPACE_ESW_EGRESS,
99 MLX5_FLOW_NAMESPACE_ESW_INGRESS,
100 MLX5_FLOW_NAMESPACE_SNIFFER_RX,
101 MLX5_FLOW_NAMESPACE_SNIFFER_TX,
102 MLX5_FLOW_NAMESPACE_EGRESS,
103 MLX5_FLOW_NAMESPACE_EGRESS_IPSEC,
104 MLX5_FLOW_NAMESPACE_EGRESS_MACSEC,
105 MLX5_FLOW_NAMESPACE_RDMA_RX,
106 MLX5_FLOW_NAMESPACE_RDMA_RX_KERNEL,
107 MLX5_FLOW_NAMESPACE_RDMA_TX,
108 MLX5_FLOW_NAMESPACE_PORT_SEL,
109 MLX5_FLOW_NAMESPACE_RDMA_RX_COUNTERS,
110 MLX5_FLOW_NAMESPACE_RDMA_TX_COUNTERS,
111 MLX5_FLOW_NAMESPACE_RDMA_RX_IPSEC,
112 MLX5_FLOW_NAMESPACE_RDMA_TX_IPSEC,
113 MLX5_FLOW_NAMESPACE_RDMA_RX_MACSEC,
114 MLX5_FLOW_NAMESPACE_RDMA_TX_MACSEC,
115 MLX5_FLOW_NAMESPACE_RDMA_TRANSPORT_RX,
116 MLX5_FLOW_NAMESPACE_RDMA_TRANSPORT_TX,
117 };
118
119 enum {
120 FDB_DROP_ROOT,
121 FDB_BYPASS_PATH,
122 FDB_CRYPTO_INGRESS,
123 FDB_TC_OFFLOAD,
124 FDB_FT_OFFLOAD,
125 FDB_TC_MISS,
126 FDB_BR_OFFLOAD,
127 FDB_SLOW_PATH,
128 FDB_CRYPTO_EGRESS,
129 FDB_PER_VPORT,
130 };
131
132 enum fs_flow_table_type {
133 FS_FT_NIC_RX = 0x0,
134 FS_FT_NIC_TX = 0x1,
135 FS_FT_ESW_EGRESS_ACL = 0x2,
136 FS_FT_ESW_INGRESS_ACL = 0x3,
137 FS_FT_FDB = 0X4,
138 FS_FT_SNIFFER_RX = 0X5,
139 FS_FT_SNIFFER_TX = 0X6,
140 FS_FT_RDMA_RX = 0X7,
141 FS_FT_RDMA_TX = 0X8,
142 FS_FT_PORT_SEL = 0X9,
143 FS_FT_FDB_RX = 0xa,
144 FS_FT_FDB_TX = 0xb,
145 FS_FT_RDMA_TRANSPORT_RX = 0xd,
146 FS_FT_RDMA_TRANSPORT_TX = 0xe,
147 FS_FT_MAX_TYPE = FS_FT_RDMA_TRANSPORT_TX,
148 };
149
150 struct mlx5_pkt_reformat;
151 struct mlx5_modify_hdr;
152 struct mlx5_flow_definer;
153 struct mlx5_flow_table;
154 struct mlx5_flow_group;
155 struct mlx5_flow_namespace;
156 struct mlx5_flow_handle;
157
158 enum {
159 FLOW_CONTEXT_HAS_TAG = BIT(0),
160 FLOW_CONTEXT_UPLINK_HAIRPIN_EN = BIT(1),
161 };
162
163 struct mlx5_flow_context {
164 u32 flags;
165 u32 flow_tag;
166 u32 flow_source;
167 };
168
169 struct mlx5_flow_spec {
170 u8 match_criteria_enable;
171 u32 match_criteria[MLX5_ST_SZ_DW(fte_match_param)];
172 u32 match_value[MLX5_ST_SZ_DW(fte_match_param)];
173 struct mlx5_flow_context flow_context;
174 };
175
176 enum {
177 MLX5_FLOW_DEST_VPORT_VHCA_ID = BIT(0),
178 MLX5_FLOW_DEST_VPORT_REFORMAT_ID = BIT(1),
179 };
180
181 enum mlx5_flow_dest_range_field {
182 MLX5_FLOW_DEST_RANGE_FIELD_PKT_LEN = 0,
183 };
184
185 struct mlx5_flow_destination {
186 enum mlx5_flow_destination_type type;
187 union {
188 u32 tir_num;
189 u32 ft_num;
190 struct mlx5_flow_table *ft;
191 struct mlx5_fc *counter;
192 struct {
193 u16 num;
194 u16 vhca_id;
195 struct mlx5_pkt_reformat *pkt_reformat;
196 u8 flags;
197 } vport;
198 struct {
199 struct mlx5_flow_table *hit_ft;
200 struct mlx5_flow_table *miss_ft;
201 enum mlx5_flow_dest_range_field field;
202 u32 min;
203 u32 max;
204 } range;
205 u32 sampler_id;
206 };
207 };
208
209 struct mod_hdr_tbl {
210 struct mutex lock; /* protects hlist */
211 DECLARE_HASHTABLE(hlist, 8);
212 };
213
214 struct mlx5_flow_namespace *
215 mlx5_get_fdb_sub_ns(struct mlx5_core_dev *dev, int n);
216 struct mlx5_flow_namespace *
217 mlx5_get_flow_namespace(struct mlx5_core_dev *dev,
218 enum mlx5_flow_namespace_type type);
219 struct mlx5_flow_namespace *
220 mlx5_get_flow_vport_namespace(struct mlx5_core_dev *dev,
221 enum mlx5_flow_namespace_type type,
222 int vport_idx);
223
224 struct mlx5_flow_table_attr {
225 int prio;
226 int max_fte;
227 u32 level;
228 u32 flags;
229 u16 uid;
230 u16 vport;
231 u16 esw_owner_vhca_id;
232 struct mlx5_flow_table *next_ft;
233
234 struct {
235 int max_num_groups;
236 int num_reserved_entries;
237 } autogroup;
238 };
239
240 struct mlx5_flow_table *
241 mlx5_create_flow_table(struct mlx5_flow_namespace *ns,
242 struct mlx5_flow_table_attr *ft_attr);
243
244 struct mlx5_flow_table *
245 mlx5_create_auto_grouped_flow_table(struct mlx5_flow_namespace *ns,
246 struct mlx5_flow_table_attr *ft_attr);
247
248 struct mlx5_flow_table *
249 mlx5_create_vport_flow_table(struct mlx5_flow_namespace *ns,
250 struct mlx5_flow_table_attr *ft_attr, u16 vport);
251 struct mlx5_flow_table *mlx5_create_lag_demux_flow_table(
252 struct mlx5_flow_namespace *ns,
253 int prio, u32 level);
254 int mlx5_destroy_flow_table(struct mlx5_flow_table *ft);
255
256 /* inbox should be set with the following values:
257 * start_flow_index
258 * end_flow_index
259 * match_criteria_enable
260 * match_criteria
261 */
262 struct mlx5_flow_group *
263 mlx5_create_flow_group(struct mlx5_flow_table *ft, u32 *in);
264 void mlx5_destroy_flow_group(struct mlx5_flow_group *fg);
265
266 struct mlx5_exe_aso {
267 u32 object_id;
268 int base_id;
269 u8 type;
270 u8 return_reg_id;
271 union {
272 u32 ctrl_data;
273 struct {
274 u8 meter_idx;
275 u8 init_color;
276 } flow_meter;
277 };
278 };
279
280 struct mlx5_fs_vlan {
281 u16 ethtype;
282 u16 vid;
283 u8 prio;
284 };
285
286 #define MLX5_FS_VLAN_DEPTH 2
287
288 enum {
289 FLOW_ACT_NO_APPEND = BIT(0),
290 FLOW_ACT_IGNORE_FLOW_LEVEL = BIT(1),
291 };
292
293 struct mlx5_flow_act {
294 u32 action;
295 struct mlx5_modify_hdr *modify_hdr;
296 struct mlx5_pkt_reformat *pkt_reformat;
297 struct mlx5_flow_act_crypto_params {
298 u8 type;
299 u32 obj_id;
300 } crypto;
301 u32 flags;
302 struct mlx5_fs_vlan vlan[MLX5_FS_VLAN_DEPTH];
303 struct ib_counters *counters;
304 struct mlx5_flow_group *fg;
305 struct mlx5_exe_aso exe_aso;
306 };
307
308 #define MLX5_DECLARE_FLOW_ACT(name) \
309 struct mlx5_flow_act name = { .action = MLX5_FLOW_CONTEXT_ACTION_FWD_DEST,\
310 .flags = 0, }
311
312 /* Single destination per rule.
313 * Group ID is implied by the match criteria.
314 */
315 struct mlx5_flow_handle *
316 mlx5_add_flow_rules(struct mlx5_flow_table *ft,
317 const struct mlx5_flow_spec *spec,
318 struct mlx5_flow_act *flow_act,
319 struct mlx5_flow_destination *dest,
320 int num_dest);
321 void mlx5_del_flow_rules(struct mlx5_flow_handle *fr);
322
323 int mlx5_modify_rule_destination(struct mlx5_flow_handle *handler,
324 struct mlx5_flow_destination *new_dest,
325 struct mlx5_flow_destination *old_dest);
326
327 struct mlx5_fc *mlx5_fc_create(struct mlx5_core_dev *dev, bool aging);
328
329 void mlx5_fc_destroy(struct mlx5_core_dev *dev, struct mlx5_fc *counter);
330 struct mlx5_fc *mlx5_fc_local_create(u32 counter_id, u32 offset, u32 bulk_size);
331 void mlx5_fc_local_destroy(struct mlx5_fc *counter);
332 void mlx5_fc_local_get(struct mlx5_fc *counter);
333 void mlx5_fc_local_put(struct mlx5_fc *counter);
334 u64 mlx5_fc_query_lastuse(struct mlx5_fc *counter);
335 void mlx5_fc_query_cached(struct mlx5_fc *counter,
336 u64 *bytes, u64 *packets, u64 *lastuse);
337 void mlx5_fc_query_cached_raw(struct mlx5_fc *counter,
338 u64 *bytes, u64 *packets, u64 *lastuse);
339 int mlx5_fc_query(struct mlx5_core_dev *dev, struct mlx5_fc *counter,
340 u64 *packets, u64 *bytes);
341 u32 mlx5_fc_id(struct mlx5_fc *counter);
342
343 int mlx5_fs_add_rx_underlay_qpn(struct mlx5_core_dev *dev, u32 underlay_qpn);
344 int mlx5_fs_remove_rx_underlay_qpn(struct mlx5_core_dev *dev, u32 underlay_qpn);
345
346 struct mlx5_modify_hdr *mlx5_modify_header_alloc(struct mlx5_core_dev *dev,
347 u8 ns_type, u8 num_actions,
348 void *modify_actions);
349 void mlx5_modify_header_dealloc(struct mlx5_core_dev *dev,
350 struct mlx5_modify_hdr *modify_hdr);
351 struct mlx5_flow_definer *
352 mlx5_create_match_definer(struct mlx5_core_dev *dev,
353 enum mlx5_flow_namespace_type ns_type, u16 format_id,
354 u32 *match_mask);
355 void mlx5_destroy_match_definer(struct mlx5_core_dev *dev,
356 struct mlx5_flow_definer *definer);
357 int mlx5_get_match_definer_id(struct mlx5_flow_definer *definer);
358
359 struct mlx5_pkt_reformat_params {
360 int type;
361 u8 param_0;
362 u8 param_1;
363 size_t size;
364 void *data;
365 };
366
367 struct mlx5_pkt_reformat *mlx5_packet_reformat_alloc(struct mlx5_core_dev *dev,
368 struct mlx5_pkt_reformat_params *params,
369 enum mlx5_flow_namespace_type ns_type);
370 void mlx5_packet_reformat_dealloc(struct mlx5_core_dev *dev,
371 struct mlx5_pkt_reformat *reformat);
372
373 u32 mlx5_flow_table_id(struct mlx5_flow_table *ft);
374
375 struct mlx5_flow_root_namespace *
376 mlx5_get_root_namespace(struct mlx5_core_dev *dev, enum mlx5_flow_namespace_type ns_type);
377
378 int mlx5_fs_set_root_dev(struct mlx5_core_dev *dev,
379 struct mlx5_core_dev *new_dev,
380 enum fs_flow_table_type table_type);
381 #endif
382