Commit 475cbcef491ace969e1ba7d30f4743f9840a5937

Authored by Ron Diskin
Committed by Greg Kroah-Hartman
1 parent 43608372b8

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

[ Upstream commit 7d0314b11cdd92bca8b89684c06953bf114605fc ]

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: 63bfd399de55 ("net/mlx5e: Send PAOS command on interface up/down")
Signed-off-by: Ron Diskin <rondi@mellanox.com>
Reviewed-by: Roi Dayan <roid@mellanox.com>
Reviewed-by: Moshe Shemesh <moshe@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>

Showing 5 changed files with 37 additions and 9 deletions Side-by-side Diff

drivers/net/ethernet/mellanox/mlx5/core/en_main.c
... ... @@ -3038,6 +3038,25 @@
3038 3038 priv->tstamp.rx_filter = HWTSTAMP_FILTER_NONE;
3039 3039 }
3040 3040  
  3041 +static void mlx5e_modify_admin_state(struct mlx5_core_dev *mdev,
  3042 + enum mlx5_port_status state)
  3043 +{
  3044 + struct mlx5_eswitch *esw = mdev->priv.eswitch;
  3045 + int vport_admin_state;
  3046 +
  3047 + mlx5_set_port_admin_status(mdev, state);
  3048 +
  3049 + if (!MLX5_ESWITCH_MANAGER(mdev) || mlx5_eswitch_mode(esw) == MLX5_ESWITCH_OFFLOADS)
  3050 + return;
  3051 +
  3052 + if (state == MLX5_PORT_UP)
  3053 + vport_admin_state = MLX5_VPORT_ADMIN_STATE_AUTO;
  3054 + else
  3055 + vport_admin_state = MLX5_VPORT_ADMIN_STATE_DOWN;
  3056 +
  3057 + mlx5_eswitch_set_vport_state(esw, MLX5_VPORT_UPLINK, vport_admin_state);
  3058 +}
  3059 +
3041 3060 int mlx5e_open_locked(struct net_device *netdev)
3042 3061 {
3043 3062 struct mlx5e_priv *priv = netdev_priv(netdev);
... ... @@ -3070,7 +3089,7 @@
3070 3089 mutex_lock(&priv->state_lock);
3071 3090 err = mlx5e_open_locked(netdev);
3072 3091 if (!err)
3073   - mlx5_set_port_admin_status(priv->mdev, MLX5_PORT_UP);
  3092 + mlx5e_modify_admin_state(priv->mdev, MLX5_PORT_UP);
3074 3093 mutex_unlock(&priv->state_lock);
3075 3094  
3076 3095 if (mlx5_vxlan_allowed(priv->mdev->vxlan))
... ... @@ -3107,7 +3126,7 @@
3107 3126 return -ENODEV;
3108 3127  
3109 3128 mutex_lock(&priv->state_lock);
3110   - mlx5_set_port_admin_status(priv->mdev, MLX5_PORT_DOWN);
  3129 + mlx5e_modify_admin_state(priv->mdev, MLX5_PORT_DOWN);
3111 3130 err = mlx5e_close_locked(netdev);
3112 3131 mutex_unlock(&priv->state_lock);
3113 3132  
... ... @@ -5172,7 +5191,7 @@
5172 5191  
5173 5192 /* Marking the link as currently not needed by the Driver */
5174 5193 if (!netif_running(netdev))
5175   - mlx5_set_port_admin_status(mdev, MLX5_PORT_DOWN);
  5194 + mlx5e_modify_admin_state(mdev, MLX5_PORT_DOWN);
5176 5195  
5177 5196 mlx5e_set_netdev_mtu_boundaries(priv);
5178 5197 mlx5e_set_dev_port_mtu(priv);
drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
... ... @@ -1736,6 +1736,8 @@
1736 1736 INIT_WORK(&rpriv->uplink_priv.reoffload_flows_work,
1737 1737 mlx5e_tc_reoffload_flows_work);
1738 1738  
  1739 + mlx5_modify_vport_admin_state(mdev, MLX5_VPORT_STATE_OP_MOD_UPLINK,
  1740 + 0, 0, MLX5_VPORT_ADMIN_STATE_AUTO);
1739 1741 mlx5_lag_add(mdev, netdev);
1740 1742 priv->events_nb.notifier_call = uplink_rep_async_event;
1741 1743 mlx5_notifier_register(mdev, &priv->events_nb);
drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
... ... @@ -2094,6 +2094,8 @@
2094 2094 u16 vport, int link_state)
2095 2095 {
2096 2096 struct mlx5_vport *evport = mlx5_eswitch_get_vport(esw, vport);
  2097 + int opmod = MLX5_VPORT_STATE_OP_MOD_ESW_VPORT;
  2098 + int other_vport = 1;
2097 2099 int err = 0;
2098 2100  
2099 2101 if (!ESW_ALLOWED(esw))
2100 2102  
2101 2103  
... ... @@ -2101,15 +2103,17 @@
2101 2103 if (IS_ERR(evport))
2102 2104 return PTR_ERR(evport);
2103 2105  
  2106 + if (vport == MLX5_VPORT_UPLINK) {
  2107 + opmod = MLX5_VPORT_STATE_OP_MOD_UPLINK;
  2108 + other_vport = 0;
  2109 + vport = 0;
  2110 + }
2104 2111 mutex_lock(&esw->state_lock);
2105 2112  
2106   - err = mlx5_modify_vport_admin_state(esw->dev,
2107   - MLX5_VPORT_STATE_OP_MOD_ESW_VPORT,
2108   - vport, 1, link_state);
  2113 + err = mlx5_modify_vport_admin_state(esw->dev, opmod, vport, other_vport, link_state);
2109 2114 if (err) {
2110   - mlx5_core_warn(esw->dev,
2111   - "Failed to set vport %d link state, err = %d",
2112   - vport, err);
  2115 + mlx5_core_warn(esw->dev, "Failed to set vport %d link state, opmod = %d, err = %d",
  2116 + vport, opmod, err);
2113 2117 goto unlock;
2114 2118 }
2115 2119  
drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
... ... @@ -606,6 +606,8 @@
606 606 static inline void mlx5_eswitch_disable(struct mlx5_eswitch *esw) {}
607 607 static inline bool mlx5_esw_lag_prereq(struct mlx5_core_dev *dev0, struct mlx5_core_dev *dev1) { return true; }
608 608 static inline bool mlx5_eswitch_is_funcs_handler(struct mlx5_core_dev *dev) { return false; }
  609 +static inline
  610 +int mlx5_eswitch_set_vport_state(struct mlx5_eswitch *esw, u16 vport, int link_state) { return 0; }
609 611 static inline const u32 *mlx5_esw_query_functions(struct mlx5_core_dev *dev)
610 612 {
611 613 return ERR_PTR(-EOPNOTSUPP);
include/linux/mlx5/mlx5_ifc.h
... ... @@ -4177,6 +4177,7 @@
4177 4177 enum {
4178 4178 MLX5_VPORT_STATE_OP_MOD_VNIC_VPORT = 0x0,
4179 4179 MLX5_VPORT_STATE_OP_MOD_ESW_VPORT = 0x1,
  4180 + MLX5_VPORT_STATE_OP_MOD_UPLINK = 0x2,
4180 4181 };
4181 4182  
4182 4183 struct mlx5_ifc_arm_monitor_counter_in_bits {