This source file includes following definitions.
- mlx5dr_cmd_query_esw_vport_context
- mlx5dr_cmd_query_gvmi
- mlx5dr_cmd_query_esw_caps
- mlx5dr_cmd_query_device
- mlx5dr_cmd_query_flow_table
- mlx5dr_cmd_sync_steering
- mlx5dr_cmd_set_fte_modify_and_vport
- mlx5dr_cmd_del_flow_table_entry
- mlx5dr_cmd_alloc_modify_header
- mlx5dr_cmd_dealloc_modify_header
- mlx5dr_cmd_create_empty_flow_group
- mlx5dr_cmd_destroy_flow_group
- mlx5dr_cmd_create_flow_table
- mlx5dr_cmd_destroy_flow_table
- mlx5dr_cmd_create_reformat_ctx
- mlx5dr_cmd_destroy_reformat_ctx
- mlx5dr_cmd_query_gid
1
2
3
4 #include "dr_types.h"
5
6 int mlx5dr_cmd_query_esw_vport_context(struct mlx5_core_dev *mdev,
7 bool other_vport,
8 u16 vport_number,
9 u64 *icm_address_rx,
10 u64 *icm_address_tx)
11 {
12 u32 out[MLX5_ST_SZ_DW(query_esw_vport_context_out)] = {};
13 u32 in[MLX5_ST_SZ_DW(query_esw_vport_context_in)] = {};
14 int err;
15
16 MLX5_SET(query_esw_vport_context_in, in, opcode,
17 MLX5_CMD_OP_QUERY_ESW_VPORT_CONTEXT);
18 MLX5_SET(query_esw_vport_context_in, in, other_vport, other_vport);
19 MLX5_SET(query_esw_vport_context_in, in, vport_number, vport_number);
20
21 err = mlx5_cmd_exec(mdev, in, sizeof(in), out, sizeof(out));
22 if (err)
23 return err;
24
25 *icm_address_rx =
26 MLX5_GET64(query_esw_vport_context_out, out,
27 esw_vport_context.sw_steering_vport_icm_address_rx);
28 *icm_address_tx =
29 MLX5_GET64(query_esw_vport_context_out, out,
30 esw_vport_context.sw_steering_vport_icm_address_tx);
31 return 0;
32 }
33
34 int mlx5dr_cmd_query_gvmi(struct mlx5_core_dev *mdev, bool other_vport,
35 u16 vport_number, u16 *gvmi)
36 {
37 u32 in[MLX5_ST_SZ_DW(query_hca_cap_in)] = {};
38 int out_size;
39 void *out;
40 int err;
41
42 out_size = MLX5_ST_SZ_BYTES(query_hca_cap_out);
43 out = kzalloc(out_size, GFP_KERNEL);
44 if (!out)
45 return -ENOMEM;
46
47 MLX5_SET(query_hca_cap_in, in, opcode, MLX5_CMD_OP_QUERY_HCA_CAP);
48 MLX5_SET(query_hca_cap_in, in, other_function, other_vport);
49 MLX5_SET(query_hca_cap_in, in, function_id, vport_number);
50 MLX5_SET(query_hca_cap_in, in, op_mod,
51 MLX5_SET_HCA_CAP_OP_MOD_GENERAL_DEVICE << 1 |
52 HCA_CAP_OPMOD_GET_CUR);
53
54 err = mlx5_cmd_exec(mdev, in, sizeof(in), out, out_size);
55 if (err) {
56 kfree(out);
57 return err;
58 }
59
60 *gvmi = MLX5_GET(query_hca_cap_out, out, capability.cmd_hca_cap.vhca_id);
61
62 kfree(out);
63 return 0;
64 }
65
66 int mlx5dr_cmd_query_esw_caps(struct mlx5_core_dev *mdev,
67 struct mlx5dr_esw_caps *caps)
68 {
69 caps->drop_icm_address_rx =
70 MLX5_CAP64_ESW_FLOWTABLE(mdev,
71 sw_steering_fdb_action_drop_icm_address_rx);
72 caps->drop_icm_address_tx =
73 MLX5_CAP64_ESW_FLOWTABLE(mdev,
74 sw_steering_fdb_action_drop_icm_address_tx);
75 caps->uplink_icm_address_rx =
76 MLX5_CAP64_ESW_FLOWTABLE(mdev,
77 sw_steering_uplink_icm_address_rx);
78 caps->uplink_icm_address_tx =
79 MLX5_CAP64_ESW_FLOWTABLE(mdev,
80 sw_steering_uplink_icm_address_tx);
81 caps->sw_owner =
82 MLX5_CAP_ESW_FLOWTABLE_FDB(mdev,
83 sw_owner);
84
85 return 0;
86 }
87
88 int mlx5dr_cmd_query_device(struct mlx5_core_dev *mdev,
89 struct mlx5dr_cmd_caps *caps)
90 {
91 caps->prio_tag_required = MLX5_CAP_GEN(mdev, prio_tag_required);
92 caps->eswitch_manager = MLX5_CAP_GEN(mdev, eswitch_manager);
93 caps->gvmi = MLX5_CAP_GEN(mdev, vhca_id);
94 caps->flex_protocols = MLX5_CAP_GEN(mdev, flex_parser_protocols);
95
96 if (mlx5dr_matcher_supp_flex_parser_icmp_v4(caps)) {
97 caps->flex_parser_id_icmp_dw0 = MLX5_CAP_GEN(mdev, flex_parser_id_icmp_dw0);
98 caps->flex_parser_id_icmp_dw1 = MLX5_CAP_GEN(mdev, flex_parser_id_icmp_dw1);
99 }
100
101 if (mlx5dr_matcher_supp_flex_parser_icmp_v6(caps)) {
102 caps->flex_parser_id_icmpv6_dw0 =
103 MLX5_CAP_GEN(mdev, flex_parser_id_icmpv6_dw0);
104 caps->flex_parser_id_icmpv6_dw1 =
105 MLX5_CAP_GEN(mdev, flex_parser_id_icmpv6_dw1);
106 }
107
108 caps->nic_rx_drop_address =
109 MLX5_CAP64_FLOWTABLE(mdev, sw_steering_nic_rx_action_drop_icm_address);
110 caps->nic_tx_drop_address =
111 MLX5_CAP64_FLOWTABLE(mdev, sw_steering_nic_tx_action_drop_icm_address);
112 caps->nic_tx_allow_address =
113 MLX5_CAP64_FLOWTABLE(mdev, sw_steering_nic_tx_action_allow_icm_address);
114
115 caps->rx_sw_owner = MLX5_CAP_FLOWTABLE_NIC_RX(mdev, sw_owner);
116 caps->max_ft_level = MLX5_CAP_FLOWTABLE_NIC_RX(mdev, max_ft_level);
117
118 caps->tx_sw_owner = MLX5_CAP_FLOWTABLE_NIC_TX(mdev, sw_owner);
119
120 caps->log_icm_size = MLX5_CAP_DEV_MEM(mdev, log_steering_sw_icm_size);
121 caps->hdr_modify_icm_addr =
122 MLX5_CAP64_DEV_MEM(mdev, header_modify_sw_icm_start_address);
123
124 caps->roce_min_src_udp = MLX5_CAP_ROCE(mdev, r_roce_min_src_udp_port);
125
126 return 0;
127 }
128
129 int mlx5dr_cmd_query_flow_table(struct mlx5_core_dev *dev,
130 enum fs_flow_table_type type,
131 u32 table_id,
132 struct mlx5dr_cmd_query_flow_table_details *output)
133 {
134 u32 out[MLX5_ST_SZ_DW(query_flow_table_out)] = {};
135 u32 in[MLX5_ST_SZ_DW(query_flow_table_in)] = {};
136 int err;
137
138 MLX5_SET(query_flow_table_in, in, opcode,
139 MLX5_CMD_OP_QUERY_FLOW_TABLE);
140
141 MLX5_SET(query_flow_table_in, in, table_type, type);
142 MLX5_SET(query_flow_table_in, in, table_id, table_id);
143
144 err = mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
145 if (err)
146 return err;
147
148 output->status = MLX5_GET(query_flow_table_out, out, status);
149 output->level = MLX5_GET(query_flow_table_out, out, flow_table_context.level);
150
151 output->sw_owner_icm_root_1 = MLX5_GET64(query_flow_table_out, out,
152 flow_table_context.sw_owner_icm_root_1);
153 output->sw_owner_icm_root_0 = MLX5_GET64(query_flow_table_out, out,
154 flow_table_context.sw_owner_icm_root_0);
155
156 return 0;
157 }
158
159 int mlx5dr_cmd_sync_steering(struct mlx5_core_dev *mdev)
160 {
161 u32 out[MLX5_ST_SZ_DW(sync_steering_out)] = {};
162 u32 in[MLX5_ST_SZ_DW(sync_steering_in)] = {};
163
164 MLX5_SET(sync_steering_in, in, opcode, MLX5_CMD_OP_SYNC_STEERING);
165
166 return mlx5_cmd_exec(mdev, in, sizeof(in), out, sizeof(out));
167 }
168
169 int mlx5dr_cmd_set_fte_modify_and_vport(struct mlx5_core_dev *mdev,
170 u32 table_type,
171 u32 table_id,
172 u32 group_id,
173 u32 modify_header_id,
174 u32 vport_id)
175 {
176 u32 out[MLX5_ST_SZ_DW(set_fte_out)] = {};
177 void *in_flow_context;
178 unsigned int inlen;
179 void *in_dests;
180 u32 *in;
181 int err;
182
183 inlen = MLX5_ST_SZ_BYTES(set_fte_in) +
184 1 * MLX5_ST_SZ_BYTES(dest_format_struct);
185
186 in = kvzalloc(inlen, GFP_KERNEL);
187 if (!in)
188 return -ENOMEM;
189
190 MLX5_SET(set_fte_in, in, opcode, MLX5_CMD_OP_SET_FLOW_TABLE_ENTRY);
191 MLX5_SET(set_fte_in, in, table_type, table_type);
192 MLX5_SET(set_fte_in, in, table_id, table_id);
193
194 in_flow_context = MLX5_ADDR_OF(set_fte_in, in, flow_context);
195 MLX5_SET(flow_context, in_flow_context, group_id, group_id);
196 MLX5_SET(flow_context, in_flow_context, modify_header_id, modify_header_id);
197 MLX5_SET(flow_context, in_flow_context, destination_list_size, 1);
198 MLX5_SET(flow_context, in_flow_context, action,
199 MLX5_FLOW_CONTEXT_ACTION_FWD_DEST |
200 MLX5_FLOW_CONTEXT_ACTION_MOD_HDR);
201
202 in_dests = MLX5_ADDR_OF(flow_context, in_flow_context, destination);
203 MLX5_SET(dest_format_struct, in_dests, destination_type,
204 MLX5_FLOW_DESTINATION_TYPE_VPORT);
205 MLX5_SET(dest_format_struct, in_dests, destination_id, vport_id);
206
207 err = mlx5_cmd_exec(mdev, in, inlen, out, sizeof(out));
208 kvfree(in);
209
210 return err;
211 }
212
213 int mlx5dr_cmd_del_flow_table_entry(struct mlx5_core_dev *mdev,
214 u32 table_type,
215 u32 table_id)
216 {
217 u32 out[MLX5_ST_SZ_DW(delete_fte_out)] = {};
218 u32 in[MLX5_ST_SZ_DW(delete_fte_in)] = {};
219
220 MLX5_SET(delete_fte_in, in, opcode, MLX5_CMD_OP_DELETE_FLOW_TABLE_ENTRY);
221 MLX5_SET(delete_fte_in, in, table_type, table_type);
222 MLX5_SET(delete_fte_in, in, table_id, table_id);
223
224 return mlx5_cmd_exec(mdev, in, sizeof(in), out, sizeof(out));
225 }
226
227 int mlx5dr_cmd_alloc_modify_header(struct mlx5_core_dev *mdev,
228 u32 table_type,
229 u8 num_of_actions,
230 u64 *actions,
231 u32 *modify_header_id)
232 {
233 u32 out[MLX5_ST_SZ_DW(alloc_modify_header_context_out)] = {};
234 void *p_actions;
235 u32 inlen;
236 u32 *in;
237 int err;
238
239 inlen = MLX5_ST_SZ_BYTES(alloc_modify_header_context_in) +
240 num_of_actions * sizeof(u64);
241 in = kvzalloc(inlen, GFP_KERNEL);
242 if (!in)
243 return -ENOMEM;
244
245 MLX5_SET(alloc_modify_header_context_in, in, opcode,
246 MLX5_CMD_OP_ALLOC_MODIFY_HEADER_CONTEXT);
247 MLX5_SET(alloc_modify_header_context_in, in, table_type, table_type);
248 MLX5_SET(alloc_modify_header_context_in, in, num_of_actions, num_of_actions);
249 p_actions = MLX5_ADDR_OF(alloc_modify_header_context_in, in, actions);
250 memcpy(p_actions, actions, num_of_actions * sizeof(u64));
251
252 err = mlx5_cmd_exec(mdev, in, inlen, out, sizeof(out));
253 if (err)
254 goto out;
255
256 *modify_header_id = MLX5_GET(alloc_modify_header_context_out, out,
257 modify_header_id);
258 out:
259 kvfree(in);
260 return err;
261 }
262
263 int mlx5dr_cmd_dealloc_modify_header(struct mlx5_core_dev *mdev,
264 u32 modify_header_id)
265 {
266 u32 out[MLX5_ST_SZ_DW(dealloc_modify_header_context_out)] = {};
267 u32 in[MLX5_ST_SZ_DW(dealloc_modify_header_context_in)] = {};
268
269 MLX5_SET(dealloc_modify_header_context_in, in, opcode,
270 MLX5_CMD_OP_DEALLOC_MODIFY_HEADER_CONTEXT);
271 MLX5_SET(dealloc_modify_header_context_in, in, modify_header_id,
272 modify_header_id);
273
274 return mlx5_cmd_exec(mdev, in, sizeof(in), out, sizeof(out));
275 }
276
277 int mlx5dr_cmd_create_empty_flow_group(struct mlx5_core_dev *mdev,
278 u32 table_type,
279 u32 table_id,
280 u32 *group_id)
281 {
282 u32 out[MLX5_ST_SZ_DW(create_flow_group_out)] = {};
283 int inlen = MLX5_ST_SZ_BYTES(create_flow_group_in);
284 u32 *in;
285 int err;
286
287 in = kzalloc(inlen, GFP_KERNEL);
288 if (!in)
289 return -ENOMEM;
290
291 MLX5_SET(create_flow_group_in, in, opcode, MLX5_CMD_OP_CREATE_FLOW_GROUP);
292 MLX5_SET(create_flow_group_in, in, table_type, table_type);
293 MLX5_SET(create_flow_group_in, in, table_id, table_id);
294
295 err = mlx5_cmd_exec(mdev, in, inlen, out, sizeof(out));
296 if (err)
297 goto out;
298
299 *group_id = MLX5_GET(create_flow_group_out, out, group_id);
300
301 out:
302 kfree(in);
303 return err;
304 }
305
306 int mlx5dr_cmd_destroy_flow_group(struct mlx5_core_dev *mdev,
307 u32 table_type,
308 u32 table_id,
309 u32 group_id)
310 {
311 u32 in[MLX5_ST_SZ_DW(destroy_flow_group_in)] = {};
312 u32 out[MLX5_ST_SZ_DW(destroy_flow_group_out)] = {};
313
314 MLX5_SET(create_flow_group_in, in, opcode, MLX5_CMD_OP_DESTROY_FLOW_GROUP);
315 MLX5_SET(destroy_flow_group_in, in, table_type, table_type);
316 MLX5_SET(destroy_flow_group_in, in, table_id, table_id);
317 MLX5_SET(destroy_flow_group_in, in, group_id, group_id);
318
319 return mlx5_cmd_exec(mdev, in, sizeof(in), out, sizeof(out));
320 }
321
322 int mlx5dr_cmd_create_flow_table(struct mlx5_core_dev *mdev,
323 u32 table_type,
324 u64 icm_addr_rx,
325 u64 icm_addr_tx,
326 u8 level,
327 bool sw_owner,
328 bool term_tbl,
329 u64 *fdb_rx_icm_addr,
330 u32 *table_id)
331 {
332 u32 out[MLX5_ST_SZ_DW(create_flow_table_out)] = {};
333 u32 in[MLX5_ST_SZ_DW(create_flow_table_in)] = {};
334 void *ft_mdev;
335 int err;
336
337 MLX5_SET(create_flow_table_in, in, opcode, MLX5_CMD_OP_CREATE_FLOW_TABLE);
338 MLX5_SET(create_flow_table_in, in, table_type, table_type);
339
340 ft_mdev = MLX5_ADDR_OF(create_flow_table_in, in, flow_table_context);
341 MLX5_SET(flow_table_context, ft_mdev, termination_table, term_tbl);
342 MLX5_SET(flow_table_context, ft_mdev, sw_owner, sw_owner);
343 MLX5_SET(flow_table_context, ft_mdev, level, level);
344
345 if (sw_owner) {
346
347
348
349 if (table_type == MLX5_FLOW_TABLE_TYPE_NIC_RX) {
350 MLX5_SET64(flow_table_context, ft_mdev,
351 sw_owner_icm_root_0, icm_addr_rx);
352 } else if (table_type == MLX5_FLOW_TABLE_TYPE_NIC_TX) {
353 MLX5_SET64(flow_table_context, ft_mdev,
354 sw_owner_icm_root_0, icm_addr_tx);
355 } else if (table_type == MLX5_FLOW_TABLE_TYPE_FDB) {
356 MLX5_SET64(flow_table_context, ft_mdev,
357 sw_owner_icm_root_0, icm_addr_rx);
358 MLX5_SET64(flow_table_context, ft_mdev,
359 sw_owner_icm_root_1, icm_addr_tx);
360 }
361 }
362
363 err = mlx5_cmd_exec(mdev, in, sizeof(in), out, sizeof(out));
364 if (err)
365 return err;
366
367 *table_id = MLX5_GET(create_flow_table_out, out, table_id);
368 if (!sw_owner && table_type == MLX5_FLOW_TABLE_TYPE_FDB)
369 *fdb_rx_icm_addr =
370 (u64)MLX5_GET(create_flow_table_out, out, icm_address_31_0) |
371 (u64)MLX5_GET(create_flow_table_out, out, icm_address_39_32) << 32 |
372 (u64)MLX5_GET(create_flow_table_out, out, icm_address_63_40) << 40;
373
374 return 0;
375 }
376
377 int mlx5dr_cmd_destroy_flow_table(struct mlx5_core_dev *mdev,
378 u32 table_id,
379 u32 table_type)
380 {
381 u32 out[MLX5_ST_SZ_DW(destroy_flow_table_out)] = {};
382 u32 in[MLX5_ST_SZ_DW(destroy_flow_table_in)] = {};
383
384 MLX5_SET(destroy_flow_table_in, in, opcode,
385 MLX5_CMD_OP_DESTROY_FLOW_TABLE);
386 MLX5_SET(destroy_flow_table_in, in, table_type, table_type);
387 MLX5_SET(destroy_flow_table_in, in, table_id, table_id);
388
389 return mlx5_cmd_exec(mdev, in, sizeof(in), out, sizeof(out));
390 }
391
392 int mlx5dr_cmd_create_reformat_ctx(struct mlx5_core_dev *mdev,
393 enum mlx5_reformat_ctx_type rt,
394 size_t reformat_size,
395 void *reformat_data,
396 u32 *reformat_id)
397 {
398 u32 out[MLX5_ST_SZ_DW(alloc_packet_reformat_context_out)] = {};
399 size_t inlen, cmd_data_sz, cmd_total_sz;
400 void *prctx;
401 void *pdata;
402 void *in;
403 int err;
404
405 cmd_total_sz = MLX5_ST_SZ_BYTES(alloc_packet_reformat_context_in);
406 cmd_data_sz = MLX5_FLD_SZ_BYTES(alloc_packet_reformat_context_in,
407 packet_reformat_context.reformat_data);
408 inlen = ALIGN(cmd_total_sz + reformat_size - cmd_data_sz, 4);
409 in = kvzalloc(inlen, GFP_KERNEL);
410 if (!in)
411 return -ENOMEM;
412
413 MLX5_SET(alloc_packet_reformat_context_in, in, opcode,
414 MLX5_CMD_OP_ALLOC_PACKET_REFORMAT_CONTEXT);
415
416 prctx = MLX5_ADDR_OF(alloc_packet_reformat_context_in, in, packet_reformat_context);
417 pdata = MLX5_ADDR_OF(packet_reformat_context_in, prctx, reformat_data);
418
419 MLX5_SET(packet_reformat_context_in, prctx, reformat_type, rt);
420 MLX5_SET(packet_reformat_context_in, prctx, reformat_data_size, reformat_size);
421 memcpy(pdata, reformat_data, reformat_size);
422
423 err = mlx5_cmd_exec(mdev, in, inlen, out, sizeof(out));
424 if (err)
425 return err;
426
427 *reformat_id = MLX5_GET(alloc_packet_reformat_context_out, out, packet_reformat_id);
428 kvfree(in);
429
430 return err;
431 }
432
433 void mlx5dr_cmd_destroy_reformat_ctx(struct mlx5_core_dev *mdev,
434 u32 reformat_id)
435 {
436 u32 out[MLX5_ST_SZ_DW(dealloc_packet_reformat_context_out)] = {};
437 u32 in[MLX5_ST_SZ_DW(dealloc_packet_reformat_context_in)] = {};
438
439 MLX5_SET(dealloc_packet_reformat_context_in, in, opcode,
440 MLX5_CMD_OP_DEALLOC_PACKET_REFORMAT_CONTEXT);
441 MLX5_SET(dealloc_packet_reformat_context_in, in, packet_reformat_id,
442 reformat_id);
443
444 mlx5_cmd_exec(mdev, in, sizeof(in), out, sizeof(out));
445 }
446
447 int mlx5dr_cmd_query_gid(struct mlx5_core_dev *mdev, u8 vhca_port_num,
448 u16 index, struct mlx5dr_cmd_gid_attr *attr)
449 {
450 u32 out[MLX5_ST_SZ_DW(query_roce_address_out)] = {};
451 u32 in[MLX5_ST_SZ_DW(query_roce_address_in)] = {};
452 int err;
453
454 MLX5_SET(query_roce_address_in, in, opcode,
455 MLX5_CMD_OP_QUERY_ROCE_ADDRESS);
456
457 MLX5_SET(query_roce_address_in, in, roce_address_index, index);
458 MLX5_SET(query_roce_address_in, in, vhca_port_num, vhca_port_num);
459
460 err = mlx5_cmd_exec(mdev, in, sizeof(in), out, sizeof(out));
461 if (err)
462 return err;
463
464 memcpy(&attr->gid,
465 MLX5_ADDR_OF(query_roce_address_out,
466 out, roce_address.source_l3_address),
467 sizeof(attr->gid));
468 memcpy(attr->mac,
469 MLX5_ADDR_OF(query_roce_address_out, out,
470 roce_address.source_mac_47_32),
471 sizeof(attr->mac));
472
473 if (MLX5_GET(query_roce_address_out, out,
474 roce_address.roce_version) == MLX5_ROCE_VERSION_2)
475 attr->roce_ver = MLX5_ROCE_VERSION_2;
476 else
477 attr->roce_ver = MLX5_ROCE_VERSION_1;
478
479 return 0;
480 }