Commit 7d0314b1 authored by Ron Diskin's avatar Ron Diskin Committed by Saeed Mahameed

net/mlx5e: Modify uplink state on interface up/down

When setting the PF interface up/down, notify the firmware to update
uplink state via MODIFY_VPORT_STATE, when E-Switch is enabled.

This behavior will prevent sending traffic out on uplink port when PF is
down, such as sending traffic from a VF interface which is still up.
Currently when calling mlx5e_open/close(), the driver only sends PAOS
command to notify the firmware to set the physical port state to
up/down, however, it is not sufficient. When VF is in "auto" state, it
follows the uplink state, which was not updated on mlx5e_open/close()
before this patch.

When switchdev mode is enabled and uplink representor is first enabled,
set the uplink port state value back to its FW default "AUTO".

Fixes: 63bfd399 ("net/mlx5e: Send PAOS command on interface up/down")
Signed-off-by: default avatarRon Diskin <rondi@mellanox.com>
Reviewed-by: default avatarRoi Dayan <roid@mellanox.com>
Reviewed-by: default avatarMoshe Shemesh <moshe@mellanox.com>
Signed-off-by: default avatarSaeed Mahameed <saeedm@mellanox.com>
parent ed56d749
...@@ -3069,6 +3069,25 @@ void mlx5e_timestamp_init(struct mlx5e_priv *priv) ...@@ -3069,6 +3069,25 @@ void mlx5e_timestamp_init(struct mlx5e_priv *priv)
priv->tstamp.rx_filter = HWTSTAMP_FILTER_NONE; priv->tstamp.rx_filter = HWTSTAMP_FILTER_NONE;
} }
static void mlx5e_modify_admin_state(struct mlx5_core_dev *mdev,
enum mlx5_port_status state)
{
struct mlx5_eswitch *esw = mdev->priv.eswitch;
int vport_admin_state;
mlx5_set_port_admin_status(mdev, state);
if (!MLX5_ESWITCH_MANAGER(mdev) || mlx5_eswitch_mode(esw) == MLX5_ESWITCH_OFFLOADS)
return;
if (state == MLX5_PORT_UP)
vport_admin_state = MLX5_VPORT_ADMIN_STATE_AUTO;
else
vport_admin_state = MLX5_VPORT_ADMIN_STATE_DOWN;
mlx5_eswitch_set_vport_state(esw, MLX5_VPORT_UPLINK, vport_admin_state);
}
int mlx5e_open_locked(struct net_device *netdev) int mlx5e_open_locked(struct net_device *netdev)
{ {
struct mlx5e_priv *priv = netdev_priv(netdev); struct mlx5e_priv *priv = netdev_priv(netdev);
...@@ -3101,7 +3120,7 @@ int mlx5e_open(struct net_device *netdev) ...@@ -3101,7 +3120,7 @@ int mlx5e_open(struct net_device *netdev)
mutex_lock(&priv->state_lock); mutex_lock(&priv->state_lock);
err = mlx5e_open_locked(netdev); err = mlx5e_open_locked(netdev);
if (!err) if (!err)
mlx5_set_port_admin_status(priv->mdev, MLX5_PORT_UP); mlx5e_modify_admin_state(priv->mdev, MLX5_PORT_UP);
mutex_unlock(&priv->state_lock); mutex_unlock(&priv->state_lock);
return err; return err;
...@@ -3135,7 +3154,7 @@ int mlx5e_close(struct net_device *netdev) ...@@ -3135,7 +3154,7 @@ int mlx5e_close(struct net_device *netdev)
return -ENODEV; return -ENODEV;
mutex_lock(&priv->state_lock); mutex_lock(&priv->state_lock);
mlx5_set_port_admin_status(priv->mdev, MLX5_PORT_DOWN); mlx5e_modify_admin_state(priv->mdev, MLX5_PORT_DOWN);
err = mlx5e_close_locked(netdev); err = mlx5e_close_locked(netdev);
mutex_unlock(&priv->state_lock); mutex_unlock(&priv->state_lock);
...@@ -5182,7 +5201,7 @@ static void mlx5e_nic_enable(struct mlx5e_priv *priv) ...@@ -5182,7 +5201,7 @@ static void mlx5e_nic_enable(struct mlx5e_priv *priv)
/* Marking the link as currently not needed by the Driver */ /* Marking the link as currently not needed by the Driver */
if (!netif_running(netdev)) if (!netif_running(netdev))
mlx5_set_port_admin_status(mdev, MLX5_PORT_DOWN); mlx5e_modify_admin_state(mdev, MLX5_PORT_DOWN);
mlx5e_set_netdev_mtu_boundaries(priv); mlx5e_set_netdev_mtu_boundaries(priv);
mlx5e_set_dev_port_mtu(priv); mlx5e_set_dev_port_mtu(priv);
......
...@@ -1081,6 +1081,8 @@ static void mlx5e_uplink_rep_enable(struct mlx5e_priv *priv) ...@@ -1081,6 +1081,8 @@ static void mlx5e_uplink_rep_enable(struct mlx5e_priv *priv)
mlx5e_rep_tc_enable(priv); mlx5e_rep_tc_enable(priv);
mlx5_modify_vport_admin_state(mdev, MLX5_VPORT_STATE_OP_MOD_UPLINK,
0, 0, MLX5_VPORT_ADMIN_STATE_AUTO);
mlx5_lag_add(mdev, netdev); mlx5_lag_add(mdev, netdev);
priv->events_nb.notifier_call = uplink_rep_async_event; priv->events_nb.notifier_call = uplink_rep_async_event;
mlx5_notifier_register(mdev, &priv->events_nb); mlx5_notifier_register(mdev, &priv->events_nb);
......
...@@ -1826,6 +1826,8 @@ int mlx5_eswitch_set_vport_state(struct mlx5_eswitch *esw, ...@@ -1826,6 +1826,8 @@ int mlx5_eswitch_set_vport_state(struct mlx5_eswitch *esw,
u16 vport, int link_state) u16 vport, int link_state)
{ {
struct mlx5_vport *evport = mlx5_eswitch_get_vport(esw, vport); struct mlx5_vport *evport = mlx5_eswitch_get_vport(esw, vport);
int opmod = MLX5_VPORT_STATE_OP_MOD_ESW_VPORT;
int other_vport = 1;
int err = 0; int err = 0;
if (!ESW_ALLOWED(esw)) if (!ESW_ALLOWED(esw))
...@@ -1833,15 +1835,17 @@ int mlx5_eswitch_set_vport_state(struct mlx5_eswitch *esw, ...@@ -1833,15 +1835,17 @@ int mlx5_eswitch_set_vport_state(struct mlx5_eswitch *esw,
if (IS_ERR(evport)) if (IS_ERR(evport))
return PTR_ERR(evport); return PTR_ERR(evport);
if (vport == MLX5_VPORT_UPLINK) {
opmod = MLX5_VPORT_STATE_OP_MOD_UPLINK;
other_vport = 0;
vport = 0;
}
mutex_lock(&esw->state_lock); mutex_lock(&esw->state_lock);
err = mlx5_modify_vport_admin_state(esw->dev, err = mlx5_modify_vport_admin_state(esw->dev, opmod, vport, other_vport, link_state);
MLX5_VPORT_STATE_OP_MOD_ESW_VPORT,
vport, 1, link_state);
if (err) { if (err) {
mlx5_core_warn(esw->dev, mlx5_core_warn(esw->dev, "Failed to set vport %d link state, opmod = %d, err = %d",
"Failed to set vport %d link state, err = %d", vport, opmod, err);
vport, err);
goto unlock; goto unlock;
} }
......
...@@ -680,6 +680,8 @@ static inline int mlx5_eswitch_enable(struct mlx5_eswitch *esw, int num_vfs) { r ...@@ -680,6 +680,8 @@ static inline int mlx5_eswitch_enable(struct mlx5_eswitch *esw, int num_vfs) { r
static inline void mlx5_eswitch_disable(struct mlx5_eswitch *esw, bool clear_vf) {} static inline void mlx5_eswitch_disable(struct mlx5_eswitch *esw, bool clear_vf) {}
static inline bool mlx5_esw_lag_prereq(struct mlx5_core_dev *dev0, struct mlx5_core_dev *dev1) { return true; } static inline bool mlx5_esw_lag_prereq(struct mlx5_core_dev *dev0, struct mlx5_core_dev *dev1) { return true; }
static inline bool mlx5_eswitch_is_funcs_handler(struct mlx5_core_dev *dev) { return false; } static inline bool mlx5_eswitch_is_funcs_handler(struct mlx5_core_dev *dev) { return false; }
static inline
int mlx5_eswitch_set_vport_state(struct mlx5_eswitch *esw, u16 vport, int link_state) { return 0; }
static inline const u32 *mlx5_esw_query_functions(struct mlx5_core_dev *dev) static inline const u32 *mlx5_esw_query_functions(struct mlx5_core_dev *dev)
{ {
return ERR_PTR(-EOPNOTSUPP); return ERR_PTR(-EOPNOTSUPP);
......
...@@ -4381,6 +4381,7 @@ struct mlx5_ifc_query_vport_state_out_bits { ...@@ -4381,6 +4381,7 @@ struct mlx5_ifc_query_vport_state_out_bits {
enum { enum {
MLX5_VPORT_STATE_OP_MOD_VNIC_VPORT = 0x0, MLX5_VPORT_STATE_OP_MOD_VNIC_VPORT = 0x0,
MLX5_VPORT_STATE_OP_MOD_ESW_VPORT = 0x1, MLX5_VPORT_STATE_OP_MOD_ESW_VPORT = 0x1,
MLX5_VPORT_STATE_OP_MOD_UPLINK = 0x2,
}; };
struct mlx5_ifc_arm_monitor_counter_in_bits { struct mlx5_ifc_arm_monitor_counter_in_bits {
......
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