Commit 5b7cb745 authored by Paul Blakey's avatar Paul Blakey Committed by David S. Miller
Browse files

net/mlx5: E-Switch, Enable reg c1 loopback when possible



Enable reg c1 loopback if firmware reports it's supported,
as this is needed for restoring packet metadata (e.g chain).

Also define helper to query if it is enabled.

Signed-off-by: default avatarPaul Blakey <paulb@mellanox.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent bf3347c4
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -236,6 +236,7 @@ struct mlx5_esw_functions {

enum {
	MLX5_ESWITCH_VPORT_MATCH_METADATA = BIT(0),
	MLX5_ESWITCH_REG_C1_LOOPBACK_ENABLED = BIT(1),
};

struct mlx5_eswitch {
+33 −11
Original line number Diff line number Diff line
@@ -763,14 +763,21 @@ void mlx5_eswitch_del_send_to_vport_rule(struct mlx5_flow_handle *rule)
	mlx5_del_flow_rules(rule);
}

static bool mlx5_eswitch_reg_c1_loopback_supported(struct mlx5_eswitch *esw)
{
	return MLX5_CAP_ESW_FLOWTABLE(esw->dev, fdb_to_vport_reg_c_id) &
	       MLX5_FDB_TO_VPORT_REG_C_1;
}

static int esw_set_passing_vport_metadata(struct mlx5_eswitch *esw, bool enable)
{
	u32 out[MLX5_ST_SZ_DW(query_esw_vport_context_out)] = {};
	u32 in[MLX5_ST_SZ_DW(modify_esw_vport_context_in)] = {};
	u8 fdb_to_vport_reg_c_id;
	u8 curr, wanted;
	int err;

	if (!mlx5_eswitch_vport_match_metadata_enabled(esw))
	if (!mlx5_eswitch_reg_c1_loopback_supported(esw) &&
	    !mlx5_eswitch_vport_match_metadata_enabled(esw))
		return 0;

	err = mlx5_eswitch_query_esw_vport_context(esw->dev, 0, false,
@@ -778,24 +785,33 @@ static int esw_set_passing_vport_metadata(struct mlx5_eswitch *esw, bool enable)
	if (err)
		return err;

	fdb_to_vport_reg_c_id = MLX5_GET(query_esw_vport_context_out, out,
	curr = MLX5_GET(query_esw_vport_context_out, out,
			esw_vport_context.fdb_to_vport_reg_c_id);
	wanted = MLX5_FDB_TO_VPORT_REG_C_0;
	if (mlx5_eswitch_reg_c1_loopback_supported(esw))
		wanted |= MLX5_FDB_TO_VPORT_REG_C_1;

	if (enable)
		fdb_to_vport_reg_c_id |= MLX5_FDB_TO_VPORT_REG_C_0 |
					 MLX5_FDB_TO_VPORT_REG_C_1;
		curr |= wanted;
	else
		fdb_to_vport_reg_c_id &= ~(MLX5_FDB_TO_VPORT_REG_C_0 |
					   MLX5_FDB_TO_VPORT_REG_C_1);
		curr &= ~wanted;

	MLX5_SET(modify_esw_vport_context_in, in,
		 esw_vport_context.fdb_to_vport_reg_c_id, fdb_to_vport_reg_c_id);
		 esw_vport_context.fdb_to_vport_reg_c_id, curr);

	MLX5_SET(modify_esw_vport_context_in, in,
		 field_select.fdb_to_vport_reg_c_id, 1);

	return mlx5_eswitch_modify_esw_vport_context(esw->dev, 0, false,
						     in, sizeof(in));
	err = mlx5_eswitch_modify_esw_vport_context(esw->dev, 0, false, in,
						    sizeof(in));
	if (!err) {
		if (enable && (curr & MLX5_FDB_TO_VPORT_REG_C_1))
			esw->flags |= MLX5_ESWITCH_REG_C1_LOOPBACK_ENABLED;
		else
			esw->flags &= ~MLX5_ESWITCH_REG_C1_LOOPBACK_ENABLED;
	}

	return err;
}

static void peer_miss_rules_setup(struct mlx5_eswitch *esw,
@@ -2831,6 +2847,12 @@ bool mlx5_eswitch_is_vf_vport(const struct mlx5_eswitch *esw, u16 vport_num)
	       vport_num <= esw->dev->priv.sriov.max_vfs;
}

bool mlx5_eswitch_reg_c1_loopback_enabled(const struct mlx5_eswitch *esw)
{
	return !!(esw->flags & MLX5_ESWITCH_REG_C1_LOOPBACK_ENABLED);
}
EXPORT_SYMBOL(mlx5_eswitch_reg_c1_loopback_enabled);

bool mlx5_eswitch_vport_match_metadata_enabled(const struct mlx5_eswitch *esw)
{
	return !!(esw->flags & MLX5_ESWITCH_VPORT_MATCH_METADATA);
+7 −0
Original line number Diff line number Diff line
@@ -70,6 +70,7 @@ u16 mlx5_eswitch_get_total_vports(const struct mlx5_core_dev *dev);
enum devlink_eswitch_encap_mode
mlx5_eswitch_get_encap_mode(const struct mlx5_core_dev *dev);

bool mlx5_eswitch_reg_c1_loopback_enabled(const struct mlx5_eswitch *esw);
bool mlx5_eswitch_vport_match_metadata_enabled(const struct mlx5_eswitch *esw);

/* Reg C0 usage:
@@ -108,6 +109,12 @@ mlx5_eswitch_get_encap_mode(const struct mlx5_core_dev *dev)
	return DEVLINK_ESWITCH_ENCAP_MODE_NONE;
}

static inline bool
mlx5_eswitch_reg_c1_loopback_enabled(const struct mlx5_eswitch *esw)
{
	return false;
};

static inline bool
mlx5_eswitch_vport_match_metadata_enabled(const struct mlx5_eswitch *esw)
{