| From 21acdcac664d9f4b7c3dafbfddd41ed8f69873cd Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Mon, 15 Jun 2020 12:48:47 +0300 |
| Subject: net/mlx5e: Fix 50G per lane indication |
| |
| From: Aya Levin <ayal@mellanox.com> |
| |
| [ Upstream commit 6a1cf4e443a3b0a4d690d3c93b84b1e9cbfcb1bd ] |
| |
| Some released FW versions mistakenly don't set the capability that 50G |
| per lane link-modes are supported for VFs (ptys_extended_ethernet |
| capability bit). When the capability is unset, read |
| PTYS.ext_eth_proto_capability (always reliable). |
| If PTYS.ext_eth_proto_capability is valid (has a non-zero value) |
| conclude that the HCA supports 50G per lane. Otherwise, conclude that |
| the HCA doesn't support 50G per lane. |
| |
| Fixes: a08b4ed1373d ("net/mlx5: Add support to ext_* fields introduced in Port Type and Speed register") |
| Signed-off-by: Aya Levin <ayal@mellanox.com> |
| Reviewed-by: Eran Ben Elisha <eranbe@mellanox.com> |
| Signed-off-by: Saeed Mahameed <saeedm@mellanox.com> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| .../net/ethernet/mellanox/mlx5/core/en/port.c | 21 ++++++++++++++++--- |
| .../net/ethernet/mellanox/mlx5/core/en/port.h | 2 +- |
| .../ethernet/mellanox/mlx5/core/en_ethtool.c | 8 +++---- |
| 3 files changed, 23 insertions(+), 8 deletions(-) |
| |
| diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/port.c b/drivers/net/ethernet/mellanox/mlx5/core/en/port.c |
| index fce6eccdcf8b2..fa81a97f6ba9e 100644 |
| --- a/drivers/net/ethernet/mellanox/mlx5/core/en/port.c |
| +++ b/drivers/net/ethernet/mellanox/mlx5/core/en/port.c |
| @@ -78,11 +78,26 @@ static const u32 mlx5e_ext_link_speed[MLX5E_EXT_LINK_MODES_NUMBER] = { |
| [MLX5E_400GAUI_8] = 400000, |
| }; |
| |
| +bool mlx5e_ptys_ext_supported(struct mlx5_core_dev *mdev) |
| +{ |
| + struct mlx5e_port_eth_proto eproto; |
| + int err; |
| + |
| + if (MLX5_CAP_PCAM_FEATURE(mdev, ptys_extended_ethernet)) |
| + return true; |
| + |
| + err = mlx5_port_query_eth_proto(mdev, 1, true, &eproto); |
| + if (err) |
| + return false; |
| + |
| + return !!eproto.cap; |
| +} |
| + |
| static void mlx5e_port_get_speed_arr(struct mlx5_core_dev *mdev, |
| const u32 **arr, u32 *size, |
| bool force_legacy) |
| { |
| - bool ext = force_legacy ? false : MLX5_CAP_PCAM_FEATURE(mdev, ptys_extended_ethernet); |
| + bool ext = force_legacy ? false : mlx5e_ptys_ext_supported(mdev); |
| |
| *size = ext ? ARRAY_SIZE(mlx5e_ext_link_speed) : |
| ARRAY_SIZE(mlx5e_link_speed); |
| @@ -177,7 +192,7 @@ int mlx5e_port_linkspeed(struct mlx5_core_dev *mdev, u32 *speed) |
| bool ext; |
| int err; |
| |
| - ext = MLX5_CAP_PCAM_FEATURE(mdev, ptys_extended_ethernet); |
| + ext = mlx5e_ptys_ext_supported(mdev); |
| err = mlx5_port_query_eth_proto(mdev, 1, ext, &eproto); |
| if (err) |
| goto out; |
| @@ -205,7 +220,7 @@ int mlx5e_port_max_linkspeed(struct mlx5_core_dev *mdev, u32 *speed) |
| int err; |
| int i; |
| |
| - ext = MLX5_CAP_PCAM_FEATURE(mdev, ptys_extended_ethernet); |
| + ext = mlx5e_ptys_ext_supported(mdev); |
| err = mlx5_port_query_eth_proto(mdev, 1, ext, &eproto); |
| if (err) |
| return err; |
| diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/port.h b/drivers/net/ethernet/mellanox/mlx5/core/en/port.h |
| index 4a7f4497692bc..e196888f7056b 100644 |
| --- a/drivers/net/ethernet/mellanox/mlx5/core/en/port.h |
| +++ b/drivers/net/ethernet/mellanox/mlx5/core/en/port.h |
| @@ -54,7 +54,7 @@ int mlx5e_port_linkspeed(struct mlx5_core_dev *mdev, u32 *speed); |
| int mlx5e_port_max_linkspeed(struct mlx5_core_dev *mdev, u32 *speed); |
| u32 mlx5e_port_speed2linkmodes(struct mlx5_core_dev *mdev, u32 speed, |
| bool force_legacy); |
| - |
| +bool mlx5e_ptys_ext_supported(struct mlx5_core_dev *mdev); |
| int mlx5e_port_query_pbmc(struct mlx5_core_dev *mdev, void *out); |
| int mlx5e_port_set_pbmc(struct mlx5_core_dev *mdev, void *in); |
| int mlx5e_port_query_priority2buffer(struct mlx5_core_dev *mdev, u8 *buffer); |
| diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c |
| index 39ee32518b106..8cd529556b214 100644 |
| --- a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c |
| +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c |
| @@ -200,7 +200,7 @@ static void mlx5e_ethtool_get_speed_arr(struct mlx5_core_dev *mdev, |
| struct ptys2ethtool_config **arr, |
| u32 *size) |
| { |
| - bool ext = MLX5_CAP_PCAM_FEATURE(mdev, ptys_extended_ethernet); |
| + bool ext = mlx5e_ptys_ext_supported(mdev); |
| |
| *arr = ext ? ptys2ext_ethtool_table : ptys2legacy_ethtool_table; |
| *size = ext ? ARRAY_SIZE(ptys2ext_ethtool_table) : |
| @@ -871,7 +871,7 @@ static void get_lp_advertising(struct mlx5_core_dev *mdev, u32 eth_proto_lp, |
| struct ethtool_link_ksettings *link_ksettings) |
| { |
| unsigned long *lp_advertising = link_ksettings->link_modes.lp_advertising; |
| - bool ext = MLX5_CAP_PCAM_FEATURE(mdev, ptys_extended_ethernet); |
| + bool ext = mlx5e_ptys_ext_supported(mdev); |
| |
| ptys2ethtool_adver_link(lp_advertising, eth_proto_lp, ext); |
| } |
| @@ -900,7 +900,7 @@ int mlx5e_ethtool_get_link_ksettings(struct mlx5e_priv *priv, |
| __func__, err); |
| goto err_query_regs; |
| } |
| - ext = MLX5_CAP_PCAM_FEATURE(mdev, ptys_extended_ethernet); |
| + ext = !!MLX5_GET_ETH_PROTO(ptys_reg, out, true, eth_proto_capability); |
| eth_proto_cap = MLX5_GET_ETH_PROTO(ptys_reg, out, ext, |
| eth_proto_capability); |
| eth_proto_admin = MLX5_GET_ETH_PROTO(ptys_reg, out, ext, |
| @@ -1052,7 +1052,7 @@ int mlx5e_ethtool_set_link_ksettings(struct mlx5e_priv *priv, |
| autoneg = link_ksettings->base.autoneg; |
| speed = link_ksettings->base.speed; |
| |
| - ext_supported = MLX5_CAP_PCAM_FEATURE(mdev, ptys_extended_ethernet); |
| + ext_supported = mlx5e_ptys_ext_supported(mdev); |
| ext = ext_requested(autoneg, adver, ext_supported); |
| if (!ext_supported && ext) |
| return -EOPNOTSUPP; |
| -- |
| 2.25.1 |
| |