Skip to content

Commit a2c6162

Browse files
Eli BritsteinSaeed Mahameed
authored andcommitted
net/mlx5: Support extended destination format in flow steering command
Update the flow steering command formatting according to the extended destination API. Note that the FW dictates that multi destination FTEs that involve at least one encap must use the extended destination format, while single destination ones must use the legacy format. Using extended destination format requires FW support. Check for its capabilities and return error if not supported. Signed-off-by: Eli Britstein <elibr@mellanox.com> Reviewed-by: Or Gerlitz <ogerlitz@mellanox.com> Reviewed-by: Oz Shlomo <ozsh@mellanox.com> Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
1 parent aa39c2c commit a2c6162

File tree

2 files changed

+75
-7
lines changed
  • drivers/net/ethernet/mellanox/mlx5/core
  • include/linux/mlx5

2 files changed

+75
-7
lines changed

drivers/net/ethernet/mellanox/mlx5/core/fs_cmd.c

Lines changed: 73 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -308,22 +308,68 @@ static int mlx5_cmd_destroy_flow_group(struct mlx5_core_dev *dev,
308308
return mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
309309
}
310310

311+
static int mlx5_set_extended_dest(struct mlx5_core_dev *dev,
312+
struct fs_fte *fte, bool *extended_dest)
313+
{
314+
int fw_log_max_fdb_encap_uplink =
315+
MLX5_CAP_ESW(dev, log_max_fdb_encap_uplink);
316+
int num_fwd_destinations = 0;
317+
struct mlx5_flow_rule *dst;
318+
int num_encap = 0;
319+
320+
*extended_dest = false;
321+
if (!(fte->action.action & MLX5_FLOW_CONTEXT_ACTION_FWD_DEST))
322+
return 0;
323+
324+
list_for_each_entry(dst, &fte->node.children, node.list) {
325+
if (dst->dest_attr.type == MLX5_FLOW_DESTINATION_TYPE_COUNTER)
326+
continue;
327+
if (dst->dest_attr.type == MLX5_FLOW_DESTINATION_TYPE_VPORT &&
328+
dst->dest_attr.vport.flags & MLX5_FLOW_DEST_VPORT_REFORMAT_ID)
329+
num_encap++;
330+
num_fwd_destinations++;
331+
}
332+
if (num_fwd_destinations > 1 && num_encap > 0)
333+
*extended_dest = true;
334+
335+
if (*extended_dest && !fw_log_max_fdb_encap_uplink) {
336+
mlx5_core_warn(dev, "FW does not support extended destination");
337+
return -EOPNOTSUPP;
338+
}
339+
if (num_encap > (1 << fw_log_max_fdb_encap_uplink)) {
340+
mlx5_core_warn(dev, "FW does not support more than %d encaps",
341+
1 << fw_log_max_fdb_encap_uplink);
342+
return -EOPNOTSUPP;
343+
}
344+
345+
return 0;
346+
}
311347
static int mlx5_cmd_set_fte(struct mlx5_core_dev *dev,
312348
int opmod, int modify_mask,
313349
struct mlx5_flow_table *ft,
314350
unsigned group_id,
315351
struct fs_fte *fte)
316352
{
317-
unsigned int inlen = MLX5_ST_SZ_BYTES(set_fte_in) +
318-
fte->dests_size * MLX5_ST_SZ_BYTES(dest_format_struct);
319353
u32 out[MLX5_ST_SZ_DW(set_fte_out)] = {0};
354+
bool extended_dest = false;
320355
struct mlx5_flow_rule *dst;
321356
void *in_flow_context, *vlan;
322357
void *in_match_value;
358+
unsigned int inlen;
359+
int dst_cnt_size;
323360
void *in_dests;
324361
u32 *in;
325362
int err;
326363

364+
if (mlx5_set_extended_dest(dev, fte, &extended_dest))
365+
return -EOPNOTSUPP;
366+
367+
if (!extended_dest)
368+
dst_cnt_size = MLX5_ST_SZ_BYTES(dest_format_struct);
369+
else
370+
dst_cnt_size = MLX5_ST_SZ_BYTES(extended_dest_format);
371+
372+
inlen = MLX5_ST_SZ_BYTES(set_fte_in) + fte->dests_size * dst_cnt_size;
327373
in = kvzalloc(inlen, GFP_KERNEL);
328374
if (!in)
329375
return -ENOMEM;
@@ -343,9 +389,20 @@ static int mlx5_cmd_set_fte(struct mlx5_core_dev *dev,
343389
MLX5_SET(flow_context, in_flow_context, group_id, group_id);
344390

345391
MLX5_SET(flow_context, in_flow_context, flow_tag, fte->action.flow_tag);
346-
MLX5_SET(flow_context, in_flow_context, action, fte->action.action);
347-
MLX5_SET(flow_context, in_flow_context, packet_reformat_id,
348-
fte->action.reformat_id);
392+
MLX5_SET(flow_context, in_flow_context, extended_destination,
393+
extended_dest);
394+
if (extended_dest) {
395+
u32 action;
396+
397+
action = fte->action.action &
398+
~MLX5_FLOW_CONTEXT_ACTION_PACKET_REFORMAT;
399+
MLX5_SET(flow_context, in_flow_context, action, action);
400+
} else {
401+
MLX5_SET(flow_context, in_flow_context, action,
402+
fte->action.action);
403+
MLX5_SET(flow_context, in_flow_context, packet_reformat_id,
404+
fte->action.reformat_id);
405+
}
349406
MLX5_SET(flow_context, in_flow_context, modify_header_id,
350407
fte->action.modify_id);
351408

@@ -392,6 +449,15 @@ static int mlx5_cmd_set_fte(struct mlx5_core_dev *dev,
392449
MLX5_SET(dest_format_struct, in_dests,
393450
destination_eswitch_owner_vhca_id,
394451
dst->dest_attr.vport.vhca_id);
452+
if (extended_dest) {
453+
MLX5_SET(dest_format_struct, in_dests,
454+
packet_reformat,
455+
!!(dst->dest_attr.vport.flags &
456+
MLX5_FLOW_DEST_VPORT_REFORMAT_ID));
457+
MLX5_SET(extended_dest_format, in_dests,
458+
packet_reformat_id,
459+
dst->dest_attr.vport.reformat_id);
460+
}
395461
break;
396462
default:
397463
id = dst->dest_attr.tir_num;
@@ -400,7 +466,7 @@ static int mlx5_cmd_set_fte(struct mlx5_core_dev *dev,
400466
MLX5_SET(dest_format_struct, in_dests, destination_type,
401467
type);
402468
MLX5_SET(dest_format_struct, in_dests, destination_id, id);
403-
in_dests += MLX5_ST_SZ_BYTES(dest_format_struct);
469+
in_dests += dst_cnt_size;
404470
list_size++;
405471
}
406472

@@ -421,7 +487,7 @@ static int mlx5_cmd_set_fte(struct mlx5_core_dev *dev,
421487

422488
MLX5_SET(flow_counter_list, in_dests, flow_counter_id,
423489
dst->dest_attr.counter_id);
424-
in_dests += MLX5_ST_SZ_BYTES(dest_format_struct);
490+
in_dests += dst_cnt_size;
425491
list_size++;
426492
}
427493
if (list_size > max_list_size) {

include/linux/mlx5/fs.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ struct mlx5_flow_spec {
8888

8989
enum {
9090
MLX5_FLOW_DEST_VPORT_VHCA_ID = BIT(0),
91+
MLX5_FLOW_DEST_VPORT_REFORMAT_ID = BIT(1),
9192
};
9293

9394
struct mlx5_flow_destination {
@@ -100,6 +101,7 @@ struct mlx5_flow_destination {
100101
struct {
101102
u16 num;
102103
u16 vhca_id;
104+
u32 reformat_id;
103105
u8 flags;
104106
} vport;
105107
};

0 commit comments

Comments
 (0)