diff mbox

[Wily,SRU] net/mlx5e: Ethtool link speed setting fixes

Message ID 1447967382-30283-1-git-send-email-tim.gardner@canonical.com
State New
Headers show

Commit Message

Tim Gardner Nov. 19, 2015, 9:09 p.m. UTC
From: Achiad Shochat <achiad@mellanox.com>

BugLink: http://bugs.launchpad.net/bugs/1517919

- Port speed settings are applied by the device only upon
  port admin status transition from DOWN to UP.
  So we enforce this transition regardless of the port's
  current operation state (which may be occasionally DOWN if
  for example the network cable is disconnected).
- Fix the PORT_UP/DOWN device interface enum
- Set the local_port bit in the device PAOS register
- EXPORT the PAOS (Port Administrative and Operational Status)
  register set/query access functions.

Signed-off-by: Achiad Shochat <achiad@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
(cherry picked from commit 6fa1bcab6be6e9bd93f80e345c7e9a4ec7861df9)
Signed-off-by: Tim Gardner <tim.gardner@canonical.com>
---
 .../net/ethernet/mellanox/mlx5/core/en_ethtool.c   | 25 ++++++----------------
 drivers/net/ethernet/mellanox/mlx5/core/port.c     | 14 ++++++++----
 include/linux/mlx5/driver.h                        | 11 +++++-----
 3 files changed, 23 insertions(+), 27 deletions(-)

Comments

Kamal Mostafa Nov. 19, 2015, 10:07 p.m. UTC | #1
ACK: upstream cherry-pick; builds fine in Wily.

 -Kamal
Andy Whitcroft Nov. 20, 2015, 3:37 p.m. UTC | #2
On Thu, Nov 19, 2015 at 02:09:42PM -0700, tim.gardner@canonical.com wrote:
> From: Achiad Shochat <achiad@mellanox.com>
> 
> BugLink: http://bugs.launchpad.net/bugs/1517919
> 
> - Port speed settings are applied by the device only upon
>   port admin status transition from DOWN to UP.
>   So we enforce this transition regardless of the port's
>   current operation state (which may be occasionally DOWN if
>   for example the network cable is disconnected).
> - Fix the PORT_UP/DOWN device interface enum
> - Set the local_port bit in the device PAOS register
> - EXPORT the PAOS (Port Administrative and Operational Status)
>   register set/query access functions.
> 
> Signed-off-by: Achiad Shochat <achiad@mellanox.com>
> Signed-off-by: David S. Miller <davem@davemloft.net>
> (cherry picked from commit 6fa1bcab6be6e9bd93f80e345c7e9a4ec7861df9)
> Signed-off-by: Tim Gardner <tim.gardner@canonical.com>
> ---
>  .../net/ethernet/mellanox/mlx5/core/en_ethtool.c   | 25 ++++++----------------
>  drivers/net/ethernet/mellanox/mlx5/core/port.c     | 14 ++++++++----
>  include/linux/mlx5/driver.h                        | 11 +++++-----
>  3 files changed, 23 insertions(+), 27 deletions(-)
> 
> diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
> index 14fd82c..2dcacfd 100644
> --- a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
> +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
> @@ -606,7 +606,7 @@ static int mlx5e_set_settings(struct net_device *netdev,
>  	u32 link_modes;
>  	u32 speed;
>  	u32 eth_proto_cap, eth_proto_admin;
> -	u8 port_status;
> +	enum mlx5_port_status ps;
>  	int err;
>  
>  	speed = ethtool_cmd_speed(cmd);
> @@ -640,24 +640,13 @@ static int mlx5e_set_settings(struct net_device *netdev,
>  	if (link_modes == eth_proto_admin)
>  		goto out;
>  
> -	err = mlx5_set_port_proto(mdev, link_modes, MLX5_PTYS_EN);
> -	if (err) {
> -		netdev_err(netdev, "%s: set port eth proto admin failed: %d\n",
> -			   __func__, err);
> -		goto out;
> -	}
> +	mlx5_query_port_admin_status(mdev, &ps);
> +	if (ps == MLX5_PORT_UP)
> +		mlx5_set_port_admin_status(mdev, MLX5_PORT_DOWN);
> +	mlx5_set_port_proto(mdev, link_modes, MLX5_PTYS_EN);
> +	if (ps == MLX5_PORT_UP)
> +		mlx5_set_port_admin_status(mdev, MLX5_PORT_UP);
>  
> -	err = mlx5_query_port_status(mdev, &port_status);
> -	if (err)
> -		goto out;
> -
> -	if (port_status == MLX5_PORT_DOWN)
> -		return 0;
> -
> -	err = mlx5_set_port_status(mdev, MLX5_PORT_DOWN);
> -	if (err)
> -		goto out;
> -	err = mlx5_set_port_status(mdev, MLX5_PORT_UP);
>  out:
>  	return err;
>  }
> diff --git a/drivers/net/ethernet/mellanox/mlx5/core/port.c b/drivers/net/ethernet/mellanox/mlx5/core/port.c
> index 7014799..f8db52b 100644
> --- a/drivers/net/ethernet/mellanox/mlx5/core/port.c
> +++ b/drivers/net/ethernet/mellanox/mlx5/core/port.c
> @@ -216,22 +216,25 @@ int mlx5_set_port_proto(struct mlx5_core_dev *dev, u32 proto_admin,
>  }
>  EXPORT_SYMBOL_GPL(mlx5_set_port_proto);
>  
> -int mlx5_set_port_status(struct mlx5_core_dev *dev,
> -			 enum mlx5_port_status status)
> +int mlx5_set_port_admin_status(struct mlx5_core_dev *dev,
> +			       enum mlx5_port_status status)
>  {
>  	u32 in[MLX5_ST_SZ_DW(paos_reg)];
>  	u32 out[MLX5_ST_SZ_DW(paos_reg)];
>  
>  	memset(in, 0, sizeof(in));
>  
> +	MLX5_SET(paos_reg, in, local_port, 1);
>  	MLX5_SET(paos_reg, in, admin_status, status);
>  	MLX5_SET(paos_reg, in, ase, 1);
>  
>  	return mlx5_core_access_reg(dev, in, sizeof(in), out,
>  				    sizeof(out), MLX5_REG_PAOS, 0, 1);
>  }
> +EXPORT_SYMBOL_GPL(mlx5_set_port_admin_status);
>  
> -int mlx5_query_port_status(struct mlx5_core_dev *dev, u8 *status)
> +int mlx5_query_port_admin_status(struct mlx5_core_dev *dev,
> +				 enum mlx5_port_status *status)
>  {
>  	u32 in[MLX5_ST_SZ_DW(paos_reg)];
>  	u32 out[MLX5_ST_SZ_DW(paos_reg)];
> @@ -239,14 +242,17 @@ int mlx5_query_port_status(struct mlx5_core_dev *dev, u8 *status)
>  
>  	memset(in, 0, sizeof(in));
>  
> +	MLX5_SET(paos_reg, in, local_port, 1);
> +
>  	err = mlx5_core_access_reg(dev, in, sizeof(in), out,
>  				   sizeof(out), MLX5_REG_PAOS, 0, 0);
>  	if (err)
>  		return err;
>  
> -	*status = MLX5_GET(paos_reg, out, oper_status);
> +	*status = MLX5_GET(paos_reg, out, admin_status);
>  	return err;
>  }
> +EXPORT_SYMBOL_GPL(mlx5_query_port_admin_status);
>  
>  static void mlx5_query_port_mtu(struct mlx5_core_dev *dev, int *admin_mtu,
>  				int *max_mtu, int *oper_mtu, u8 port)
> diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h
> index 5fe0cae..da2e71c 100644
> --- a/include/linux/mlx5/driver.h
> +++ b/include/linux/mlx5/driver.h
> @@ -151,8 +151,8 @@ enum mlx5_dev_event {
>  };
>  
>  enum mlx5_port_status {
> -	MLX5_PORT_UP        = 1 << 1,
> -	MLX5_PORT_DOWN      = 1 << 2,
> +	MLX5_PORT_UP        = 1,
> +	MLX5_PORT_DOWN      = 2,
>  };
>  
>  struct mlx5_uuar_info {
> @@ -760,9 +760,10 @@ int mlx5_query_port_proto_oper(struct mlx5_core_dev *dev,
>  			       u8 local_port);
>  int mlx5_set_port_proto(struct mlx5_core_dev *dev, u32 proto_admin,
>  			int proto_mask);
> -int mlx5_set_port_status(struct mlx5_core_dev *dev,
> -			 enum mlx5_port_status status);
> -int mlx5_query_port_status(struct mlx5_core_dev *dev, u8 *status);
> +int mlx5_set_port_admin_status(struct mlx5_core_dev *dev,
> +			       enum mlx5_port_status status);
> +int mlx5_query_port_admin_status(struct mlx5_core_dev *dev,
> +				 enum mlx5_port_status *status);
>  
>  int mlx5_set_port_mtu(struct mlx5_core_dev *dev, int mtu, u8 port);
>  void mlx5_query_port_max_mtu(struct mlx5_core_dev *dev, int *max_mtu, u8 port);

Looks to do what is claimed.  Clean cherry-pick.

Acked-by: Andy Whitcroft <apw@canonical.com>

-apw
Kamal Mostafa Nov. 20, 2015, 7:43 p.m. UTC | #3

diff mbox

Patch

diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
index 14fd82c..2dcacfd 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
@@ -606,7 +606,7 @@  static int mlx5e_set_settings(struct net_device *netdev,
 	u32 link_modes;
 	u32 speed;
 	u32 eth_proto_cap, eth_proto_admin;
-	u8 port_status;
+	enum mlx5_port_status ps;
 	int err;
 
 	speed = ethtool_cmd_speed(cmd);
@@ -640,24 +640,13 @@  static int mlx5e_set_settings(struct net_device *netdev,
 	if (link_modes == eth_proto_admin)
 		goto out;
 
-	err = mlx5_set_port_proto(mdev, link_modes, MLX5_PTYS_EN);
-	if (err) {
-		netdev_err(netdev, "%s: set port eth proto admin failed: %d\n",
-			   __func__, err);
-		goto out;
-	}
+	mlx5_query_port_admin_status(mdev, &ps);
+	if (ps == MLX5_PORT_UP)
+		mlx5_set_port_admin_status(mdev, MLX5_PORT_DOWN);
+	mlx5_set_port_proto(mdev, link_modes, MLX5_PTYS_EN);
+	if (ps == MLX5_PORT_UP)
+		mlx5_set_port_admin_status(mdev, MLX5_PORT_UP);
 
-	err = mlx5_query_port_status(mdev, &port_status);
-	if (err)
-		goto out;
-
-	if (port_status == MLX5_PORT_DOWN)
-		return 0;
-
-	err = mlx5_set_port_status(mdev, MLX5_PORT_DOWN);
-	if (err)
-		goto out;
-	err = mlx5_set_port_status(mdev, MLX5_PORT_UP);
 out:
 	return err;
 }
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/port.c b/drivers/net/ethernet/mellanox/mlx5/core/port.c
index 7014799..f8db52b 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/port.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/port.c
@@ -216,22 +216,25 @@  int mlx5_set_port_proto(struct mlx5_core_dev *dev, u32 proto_admin,
 }
 EXPORT_SYMBOL_GPL(mlx5_set_port_proto);
 
-int mlx5_set_port_status(struct mlx5_core_dev *dev,
-			 enum mlx5_port_status status)
+int mlx5_set_port_admin_status(struct mlx5_core_dev *dev,
+			       enum mlx5_port_status status)
 {
 	u32 in[MLX5_ST_SZ_DW(paos_reg)];
 	u32 out[MLX5_ST_SZ_DW(paos_reg)];
 
 	memset(in, 0, sizeof(in));
 
+	MLX5_SET(paos_reg, in, local_port, 1);
 	MLX5_SET(paos_reg, in, admin_status, status);
 	MLX5_SET(paos_reg, in, ase, 1);
 
 	return mlx5_core_access_reg(dev, in, sizeof(in), out,
 				    sizeof(out), MLX5_REG_PAOS, 0, 1);
 }
+EXPORT_SYMBOL_GPL(mlx5_set_port_admin_status);
 
-int mlx5_query_port_status(struct mlx5_core_dev *dev, u8 *status)
+int mlx5_query_port_admin_status(struct mlx5_core_dev *dev,
+				 enum mlx5_port_status *status)
 {
 	u32 in[MLX5_ST_SZ_DW(paos_reg)];
 	u32 out[MLX5_ST_SZ_DW(paos_reg)];
@@ -239,14 +242,17 @@  int mlx5_query_port_status(struct mlx5_core_dev *dev, u8 *status)
 
 	memset(in, 0, sizeof(in));
 
+	MLX5_SET(paos_reg, in, local_port, 1);
+
 	err = mlx5_core_access_reg(dev, in, sizeof(in), out,
 				   sizeof(out), MLX5_REG_PAOS, 0, 0);
 	if (err)
 		return err;
 
-	*status = MLX5_GET(paos_reg, out, oper_status);
+	*status = MLX5_GET(paos_reg, out, admin_status);
 	return err;
 }
+EXPORT_SYMBOL_GPL(mlx5_query_port_admin_status);
 
 static void mlx5_query_port_mtu(struct mlx5_core_dev *dev, int *admin_mtu,
 				int *max_mtu, int *oper_mtu, u8 port)
diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h
index 5fe0cae..da2e71c 100644
--- a/include/linux/mlx5/driver.h
+++ b/include/linux/mlx5/driver.h
@@ -151,8 +151,8 @@  enum mlx5_dev_event {
 };
 
 enum mlx5_port_status {
-	MLX5_PORT_UP        = 1 << 1,
-	MLX5_PORT_DOWN      = 1 << 2,
+	MLX5_PORT_UP        = 1,
+	MLX5_PORT_DOWN      = 2,
 };
 
 struct mlx5_uuar_info {
@@ -760,9 +760,10 @@  int mlx5_query_port_proto_oper(struct mlx5_core_dev *dev,
 			       u8 local_port);
 int mlx5_set_port_proto(struct mlx5_core_dev *dev, u32 proto_admin,
 			int proto_mask);
-int mlx5_set_port_status(struct mlx5_core_dev *dev,
-			 enum mlx5_port_status status);
-int mlx5_query_port_status(struct mlx5_core_dev *dev, u8 *status);
+int mlx5_set_port_admin_status(struct mlx5_core_dev *dev,
+			       enum mlx5_port_status status);
+int mlx5_query_port_admin_status(struct mlx5_core_dev *dev,
+				 enum mlx5_port_status *status);
 
 int mlx5_set_port_mtu(struct mlx5_core_dev *dev, int mtu, u8 port);
 void mlx5_query_port_max_mtu(struct mlx5_core_dev *dev, int *max_mtu, u8 port);