diff mbox series

[net,11/12] net/mlx5e: Modify uplink state on interface up/down

Message ID 20200728091035.112067-12-saeedm@mellanox.com
State Changes Requested
Delegated to: David Miller
Headers show
Series [net,01/12] net/mlx5e: Hold reference on mirred devices while accessing them | expand

Commit Message

Saeed Mahameed July 28, 2020, 9:10 a.m. UTC
From: Ron Diskin <rondi@mellanox.com>

When setting the PF interface up/down, notify the firmware to update
uplink state via MODIFY_VPORT_STATE.

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.

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>
---
 .../net/ethernet/mellanox/mlx5/core/en_main.c | 25 ++++++++++++++++---
 .../net/ethernet/mellanox/mlx5/core/en_rep.c  |  2 ++
 .../net/ethernet/mellanox/mlx5/core/eswitch.c | 16 +++++++-----
 .../net/ethernet/mellanox/mlx5/core/eswitch.h |  2 ++
 include/linux/mlx5/mlx5_ifc.h                 |  1 +
 5 files changed, 37 insertions(+), 9 deletions(-)

Comments

Or Gerlitz July 28, 2020, 10:24 a.m. UTC | #1
On Tue, Jul 28, 2020 at 12:16 PM Saeed Mahameed <saeedm@mellanox.com> wrote:
> From: Ron Diskin <rondi@mellanox.com>
>
> When setting the PF interface up/down, notify the firmware to update
> uplink state via MODIFY_VPORT_STATE

How this relates to e-switching? the patch touches the e-switch code
but I don't see mentioning of that in the change-log..

> 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

"auto" is nasty concept that applies only to legacy mode. However, the patch
touches the switchdev mode (representors) code, please explain...

> follows the uplink state, which was not updated on mlx5e_open/close()
> before this patch.
>
> 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>
Saeed Mahameed July 28, 2020, 7:40 p.m. UTC | #2
On Tue, 2020-07-28 at 13:24 +0300, Or Gerlitz wrote:
> On Tue, Jul 28, 2020 at 12:16 PM Saeed Mahameed <saeedm@mellanox.com>
> wrote:
> > From: Ron Diskin <rondi@mellanox.com>
> > 
> > When setting the PF interface up/down, notify the firmware to
> > update
> > uplink state via MODIFY_VPORT_STATE
> 
> How this relates to e-switching? the patch touches the e-switch code
> but I don't see mentioning of that in the change-log..
> 

see below "uplink port" and "VF" these terms are only used in with e-
switching..

> > 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
> 
> "auto" is nasty concept that applies only to legacy mode. However,
> the patch
> touches the switchdev mode (representors) code, please explain...
> 

"AUTO" is also mlx5 concept which is default by FW.

Prior to this patch the uplink state was never touched by driver so now
as it can be overwritten by the PF driver on legacy/single nic mode,
when switching to switchdev mode we need to bring back the FW default
value "AUTO".

Will add this to the commit message.

> > follows the uplink state, which was not updated on
> > mlx5e_open/close()
> > before this patch.
> > 
> > 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>
diff mbox series

Patch

diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
index 31f9ecae98df9..07fdbea7ea13b 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
@@ -3069,6 +3069,25 @@  void mlx5e_timestamp_init(struct mlx5e_priv *priv)
 	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)
 {
 	struct mlx5e_priv *priv = netdev_priv(netdev);
@@ -3101,7 +3120,7 @@  int mlx5e_open(struct net_device *netdev)
 	mutex_lock(&priv->state_lock);
 	err = mlx5e_open_locked(netdev);
 	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);
 
 	return err;
@@ -3135,7 +3154,7 @@  int mlx5e_close(struct net_device *netdev)
 		return -ENODEV;
 
 	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);
 	mutex_unlock(&priv->state_lock);
 
@@ -5182,7 +5201,7 @@  static void mlx5e_nic_enable(struct mlx5e_priv *priv)
 
 	/* Marking the link as currently not needed by the Driver */
 	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_dev_port_mtu(priv);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
index 8c294ab43f908..9519a61bd8ec5 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
@@ -1081,6 +1081,8 @@  static void mlx5e_uplink_rep_enable(struct mlx5e_priv *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);
 	priv->events_nb.notifier_call = uplink_rep_async_event;
 	mlx5_notifier_register(mdev, &priv->events_nb);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
index d9376627584e9..71d01143c4556 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
@@ -1826,6 +1826,8 @@  int mlx5_eswitch_set_vport_state(struct mlx5_eswitch *esw,
 				 u16 vport, int link_state)
 {
 	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;
 
 	if (!ESW_ALLOWED(esw))
@@ -1833,15 +1835,17 @@  int mlx5_eswitch_set_vport_state(struct mlx5_eswitch *esw,
 	if (IS_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);
 
-	err = mlx5_modify_vport_admin_state(esw->dev,
-					    MLX5_VPORT_STATE_OP_MOD_ESW_VPORT,
-					    vport, 1, link_state);
+	err = mlx5_modify_vport_admin_state(esw->dev, opmod, vport, other_vport, link_state);
 	if (err) {
-		mlx5_core_warn(esw->dev,
-			       "Failed to set vport %d link state, err = %d",
-			       vport, err);
+		mlx5_core_warn(esw->dev, "Failed to set vport %d link state, opmod = %d, err = %d",
+			       vport, opmod, err);
 		goto unlock;
 	}
 
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
index a5175e98c0b34..5785596f13f5b 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
@@ -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 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
+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)
 {
 	return ERR_PTR(-EOPNOTSUPP);
diff --git a/include/linux/mlx5/mlx5_ifc.h b/include/linux/mlx5/mlx5_ifc.h
index 073b79eacc991..1340e02b14ef2 100644
--- a/include/linux/mlx5/mlx5_ifc.h
+++ b/include/linux/mlx5/mlx5_ifc.h
@@ -4381,6 +4381,7 @@  struct mlx5_ifc_query_vport_state_out_bits {
 enum {
 	MLX5_VPORT_STATE_OP_MOD_VNIC_VPORT  = 0x0,
 	MLX5_VPORT_STATE_OP_MOD_ESW_VPORT   = 0x1,
+	MLX5_VPORT_STATE_OP_MOD_UPLINK      = 0x2,
 };
 
 struct mlx5_ifc_arm_monitor_counter_in_bits {