net/mlx5e: Fix 50G per lane indication
authorAya Levin <ayal@mellanox.com>
Mon, 15 Jun 2020 09:48:47 +0000 (12:48 +0300)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 16 Jul 2020 06:16:41 +0000 (08:16 +0200)
[ 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>
drivers/net/ethernet/mellanox/mlx5/core/en/port.c
drivers/net/ethernet/mellanox/mlx5/core/en/port.h
drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c

index fce6eccdcf8b2f3337655ddf26f634f465005e01..fa81a97f6ba9ed96b847314ec082a8c79ae0c257 100644 (file)
@@ -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;
index 4a7f4497692bc7655ce6852cc497807a935e6a59..e196888f7056bc2dcc27ae112d604139f37d2837 100644 (file)
@@ -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);
index 39ee32518b1060a228c29b52624c44c015dd7381..8cd529556b21424b0139ebb2d6fb46e46cddf22d 100644 (file)
@@ -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;