Commit 8978cc92 authored by Eran Ben Elisha's avatar Eran Ben Elisha Committed by Saeed Mahameed

{net,ib}/mlx5: Don't disable local loopback multicast traffic when needed

There are systems platform information management interfaces (such as
HOST2BMC) for which we cannot disable local loopback multicast traffic.

Separate disable_local_lb_mc and disable_local_lb_uc capability bits so
driver will not disable multicast loopback traffic if not supported.
(It is expected that Firmware will not set disable_local_lb_mc if
HOST2BMC is running for example.)

Function mlx5_nic_vport_update_local_lb will do best effort to
disable/enable UC/MC loopback traffic and return success only in case it
succeeded to changed all allowed by Firmware.

Adapt mlx5_ib and mlx5e to support the new cap bits.

Fixes: 2c43c5a0 ("net/mlx5e: Enable local loopback in loopback selftest")
Fixes: c85023e1 ("IB/mlx5: Add raw ethernet local loopback support")
Fixes: bded747b ("net/mlx5: Add raw ethernet local loopback firmware command")
Signed-off-by: default avatarEran Ben Elisha <eranbe@mellanox.com>
Cc: kernel-team@fb.com
Signed-off-by: default avatarSaeed Mahameed <saeedm@mellanox.com>
parent ccc12b11
...@@ -1324,7 +1324,8 @@ static int mlx5_ib_alloc_transport_domain(struct mlx5_ib_dev *dev, u32 *tdn) ...@@ -1324,7 +1324,8 @@ static int mlx5_ib_alloc_transport_domain(struct mlx5_ib_dev *dev, u32 *tdn)
return err; return err;
if ((MLX5_CAP_GEN(dev->mdev, port_type) != MLX5_CAP_PORT_TYPE_ETH) || if ((MLX5_CAP_GEN(dev->mdev, port_type) != MLX5_CAP_PORT_TYPE_ETH) ||
!MLX5_CAP_GEN(dev->mdev, disable_local_lb)) (!MLX5_CAP_GEN(dev->mdev, disable_local_lb_uc) &&
!MLX5_CAP_GEN(dev->mdev, disable_local_lb_mc)))
return err; return err;
mutex_lock(&dev->lb_mutex); mutex_lock(&dev->lb_mutex);
...@@ -1342,7 +1343,8 @@ static void mlx5_ib_dealloc_transport_domain(struct mlx5_ib_dev *dev, u32 tdn) ...@@ -1342,7 +1343,8 @@ static void mlx5_ib_dealloc_transport_domain(struct mlx5_ib_dev *dev, u32 tdn)
mlx5_core_dealloc_transport_domain(dev->mdev, tdn); mlx5_core_dealloc_transport_domain(dev->mdev, tdn);
if ((MLX5_CAP_GEN(dev->mdev, port_type) != MLX5_CAP_PORT_TYPE_ETH) || if ((MLX5_CAP_GEN(dev->mdev, port_type) != MLX5_CAP_PORT_TYPE_ETH) ||
!MLX5_CAP_GEN(dev->mdev, disable_local_lb)) (!MLX5_CAP_GEN(dev->mdev, disable_local_lb_uc) &&
!MLX5_CAP_GEN(dev->mdev, disable_local_lb_mc)))
return; return;
mutex_lock(&dev->lb_mutex); mutex_lock(&dev->lb_mutex);
...@@ -4187,7 +4189,8 @@ static void *mlx5_ib_add(struct mlx5_core_dev *mdev) ...@@ -4187,7 +4189,8 @@ static void *mlx5_ib_add(struct mlx5_core_dev *mdev)
} }
if ((MLX5_CAP_GEN(mdev, port_type) == MLX5_CAP_PORT_TYPE_ETH) && if ((MLX5_CAP_GEN(mdev, port_type) == MLX5_CAP_PORT_TYPE_ETH) &&
MLX5_CAP_GEN(mdev, disable_local_lb)) (MLX5_CAP_GEN(mdev, disable_local_lb_uc) ||
MLX5_CAP_GEN(mdev, disable_local_lb_mc)))
mutex_init(&dev->lb_mutex); mutex_init(&dev->lb_mutex);
dev->ib_active = true; dev->ib_active = true;
......
...@@ -238,15 +238,19 @@ static int mlx5e_test_loopback_setup(struct mlx5e_priv *priv, ...@@ -238,15 +238,19 @@ static int mlx5e_test_loopback_setup(struct mlx5e_priv *priv,
int err = 0; int err = 0;
/* Temporarily enable local_lb */ /* Temporarily enable local_lb */
if (MLX5_CAP_GEN(priv->mdev, disable_local_lb)) { err = mlx5_nic_vport_query_local_lb(priv->mdev, &lbtp->local_lb);
mlx5_nic_vport_query_local_lb(priv->mdev, &lbtp->local_lb); if (err)
if (!lbtp->local_lb) return err;
mlx5_nic_vport_update_local_lb(priv->mdev, true);
if (!lbtp->local_lb) {
err = mlx5_nic_vport_update_local_lb(priv->mdev, true);
if (err)
return err;
} }
err = mlx5e_refresh_tirs(priv, true); err = mlx5e_refresh_tirs(priv, true);
if (err) if (err)
return err; goto out;
lbtp->loopback_ok = false; lbtp->loopback_ok = false;
init_completion(&lbtp->comp); init_completion(&lbtp->comp);
...@@ -256,16 +260,21 @@ static int mlx5e_test_loopback_setup(struct mlx5e_priv *priv, ...@@ -256,16 +260,21 @@ static int mlx5e_test_loopback_setup(struct mlx5e_priv *priv,
lbtp->pt.dev = priv->netdev; lbtp->pt.dev = priv->netdev;
lbtp->pt.af_packet_priv = lbtp; lbtp->pt.af_packet_priv = lbtp;
dev_add_pack(&lbtp->pt); dev_add_pack(&lbtp->pt);
return 0;
out:
if (!lbtp->local_lb)
mlx5_nic_vport_update_local_lb(priv->mdev, false);
return err; return err;
} }
static void mlx5e_test_loopback_cleanup(struct mlx5e_priv *priv, static void mlx5e_test_loopback_cleanup(struct mlx5e_priv *priv,
struct mlx5e_lbt_priv *lbtp) struct mlx5e_lbt_priv *lbtp)
{ {
if (MLX5_CAP_GEN(priv->mdev, disable_local_lb)) {
if (!lbtp->local_lb) if (!lbtp->local_lb)
mlx5_nic_vport_update_local_lb(priv->mdev, false); mlx5_nic_vport_update_local_lb(priv->mdev, false);
}
dev_remove_pack(&lbtp->pt); dev_remove_pack(&lbtp->pt);
mlx5e_refresh_tirs(priv, false); mlx5e_refresh_tirs(priv, false);
......
...@@ -578,8 +578,7 @@ static int mlx5_core_set_hca_defaults(struct mlx5_core_dev *dev) ...@@ -578,8 +578,7 @@ static int mlx5_core_set_hca_defaults(struct mlx5_core_dev *dev)
int ret = 0; int ret = 0;
/* Disable local_lb by default */ /* Disable local_lb by default */
if ((MLX5_CAP_GEN(dev, port_type) == MLX5_CAP_PORT_TYPE_ETH) && if (MLX5_CAP_GEN(dev, port_type) == MLX5_CAP_PORT_TYPE_ETH)
MLX5_CAP_GEN(dev, disable_local_lb))
ret = mlx5_nic_vport_update_local_lb(dev, false); ret = mlx5_nic_vport_update_local_lb(dev, false);
return ret; return ret;
......
...@@ -908,23 +908,33 @@ int mlx5_nic_vport_update_local_lb(struct mlx5_core_dev *mdev, bool enable) ...@@ -908,23 +908,33 @@ int mlx5_nic_vport_update_local_lb(struct mlx5_core_dev *mdev, bool enable)
void *in; void *in;
int err; int err;
mlx5_core_dbg(mdev, "%s local_lb\n", enable ? "enable" : "disable"); if (!MLX5_CAP_GEN(mdev, disable_local_lb_mc) &&
!MLX5_CAP_GEN(mdev, disable_local_lb_uc))
return 0;
in = kvzalloc(inlen, GFP_KERNEL); in = kvzalloc(inlen, GFP_KERNEL);
if (!in) if (!in)
return -ENOMEM; return -ENOMEM;
MLX5_SET(modify_nic_vport_context_in, in,
field_select.disable_mc_local_lb, 1);
MLX5_SET(modify_nic_vport_context_in, in, MLX5_SET(modify_nic_vport_context_in, in,
nic_vport_context.disable_mc_local_lb, !enable); nic_vport_context.disable_mc_local_lb, !enable);
MLX5_SET(modify_nic_vport_context_in, in,
nic_vport_context.disable_uc_local_lb, !enable);
if (MLX5_CAP_GEN(mdev, disable_local_lb_mc))
MLX5_SET(modify_nic_vport_context_in, in, MLX5_SET(modify_nic_vport_context_in, in,
field_select.disable_uc_local_lb, 1); field_select.disable_mc_local_lb, 1);
if (MLX5_CAP_GEN(mdev, disable_local_lb_uc))
MLX5_SET(modify_nic_vport_context_in, in, MLX5_SET(modify_nic_vport_context_in, in,
nic_vport_context.disable_uc_local_lb, !enable); field_select.disable_uc_local_lb, 1);
err = mlx5_modify_nic_vport_context(mdev, in, inlen); err = mlx5_modify_nic_vport_context(mdev, in, inlen);
if (!err)
mlx5_core_dbg(mdev, "%s local_lb\n",
enable ? "enable" : "disable");
kvfree(in); kvfree(in);
return err; return err;
} }
......
...@@ -1027,8 +1027,9 @@ struct mlx5_ifc_cmd_hca_cap_bits { ...@@ -1027,8 +1027,9 @@ struct mlx5_ifc_cmd_hca_cap_bits {
u8 log_max_wq_sz[0x5]; u8 log_max_wq_sz[0x5];
u8 nic_vport_change_event[0x1]; u8 nic_vport_change_event[0x1];
u8 disable_local_lb[0x1]; u8 disable_local_lb_uc[0x1];
u8 reserved_at_3e2[0x9]; u8 disable_local_lb_mc[0x1];
u8 reserved_at_3e3[0x8];
u8 log_max_vlan_list[0x5]; u8 log_max_vlan_list[0x5];
u8 reserved_at_3f0[0x3]; u8 reserved_at_3f0[0x3];
u8 log_max_current_mc_list[0x5]; u8 log_max_current_mc_list[0x5];
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment