mlxsw: ethtool: Pass link mode in use to ethtool
authorDanielle Ratson <danieller@nvidia.com>
Tue, 2 Feb 2021 18:06:11 +0000 (20:06 +0200)
committerJakub Kicinski <kuba@kernel.org>
Thu, 4 Feb 2021 02:37:29 +0000 (18:37 -0800)
Currently, when user space queries the link's parameters, as speed and
duplex, each parameter is passed from the driver to ethtool.

Instead, pass the link mode bit in use.
In Spectrum-1, simply pass the bit that is set to '1' from PTYS register.
In Spectrum-2, pass the first link mode bit in the mask of the used
link mode.

Signed-off-by: Danielle Ratson <danieller@nvidia.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ethernet/mellanox/mlxsw/spectrum.h
drivers/net/ethernet/mellanox/mlxsw/spectrum_ethtool.c

index 9ded4d1..d9d9e1f 100644 (file)
@@ -330,9 +330,9 @@ struct mlxsw_sp_port_type_speed_ops {
        void (*from_ptys_link)(struct mlxsw_sp *mlxsw_sp, u32 ptys_eth_proto,
                               unsigned long *mode);
        u32 (*from_ptys_speed)(struct mlxsw_sp *mlxsw_sp, u32 ptys_eth_proto);
-       void (*from_ptys_speed_duplex)(struct mlxsw_sp *mlxsw_sp,
-                                      bool carrier_ok, u32 ptys_eth_proto,
-                                      struct ethtool_link_ksettings *cmd);
+       void (*from_ptys_link_mode)(struct mlxsw_sp *mlxsw_sp,
+                                   bool carrier_ok, u32 ptys_eth_proto,
+                                   struct ethtool_link_ksettings *cmd);
        int (*ptys_max_speed)(struct mlxsw_sp_port *mlxsw_sp_port, u32 *p_max_speed);
        u32 (*to_ptys_advert_link)(struct mlxsw_sp *mlxsw_sp,
                                   const struct ethtool_link_ksettings *cmd);
index 15c6e5a..bd7f873 100644 (file)
@@ -966,8 +966,8 @@ static int mlxsw_sp_port_get_link_ksettings(struct net_device *dev,
 
        cmd->base.autoneg = autoneg ? AUTONEG_ENABLE : AUTONEG_DISABLE;
        cmd->base.port = mlxsw_sp_port_connector_port(connector_type);
-       ops->from_ptys_speed_duplex(mlxsw_sp, netif_carrier_ok(dev),
-                                   eth_proto_oper, cmd);
+       ops->from_ptys_link_mode(mlxsw_sp, netif_carrier_ok(dev),
+                                eth_proto_oper, cmd);
 
        return 0;
 }
@@ -1221,19 +1221,21 @@ mlxsw_sp1_from_ptys_speed(struct mlxsw_sp *mlxsw_sp, u32 ptys_eth_proto)
 }
 
 static void
-mlxsw_sp1_from_ptys_speed_duplex(struct mlxsw_sp *mlxsw_sp, bool carrier_ok,
-                                u32 ptys_eth_proto,
-                                struct ethtool_link_ksettings *cmd)
+mlxsw_sp1_from_ptys_link_mode(struct mlxsw_sp *mlxsw_sp, bool carrier_ok,
+                             u32 ptys_eth_proto,
+                             struct ethtool_link_ksettings *cmd)
 {
-       cmd->base.speed = SPEED_UNKNOWN;
-       cmd->base.duplex = DUPLEX_UNKNOWN;
+       int i;
+
+       cmd->link_mode = -1;
 
        if (!carrier_ok)
                return;
 
-       cmd->base.speed = mlxsw_sp1_from_ptys_speed(mlxsw_sp, ptys_eth_proto);
-       if (cmd->base.speed != SPEED_UNKNOWN)
-               cmd->base.duplex = DUPLEX_FULL;
+       for (i = 0; i < MLXSW_SP1_PORT_LINK_MODE_LEN; i++) {
+               if (ptys_eth_proto & mlxsw_sp1_port_link_mode[i].mask)
+                       cmd->link_mode = mlxsw_sp1_port_link_mode[i].mask_ethtool;
+       }
 }
 
 static int mlxsw_sp1_ptys_max_speed(struct mlxsw_sp_port *mlxsw_sp_port, u32 *p_max_speed)
@@ -1322,7 +1324,7 @@ const struct mlxsw_sp_port_type_speed_ops mlxsw_sp1_port_type_speed_ops = {
        .from_ptys_supported_port       = mlxsw_sp1_from_ptys_supported_port,
        .from_ptys_link                 = mlxsw_sp1_from_ptys_link,
        .from_ptys_speed                = mlxsw_sp1_from_ptys_speed,
-       .from_ptys_speed_duplex         = mlxsw_sp1_from_ptys_speed_duplex,
+       .from_ptys_link_mode            = mlxsw_sp1_from_ptys_link_mode,
        .ptys_max_speed                 = mlxsw_sp1_ptys_max_speed,
        .to_ptys_advert_link            = mlxsw_sp1_to_ptys_advert_link,
        .to_ptys_speed_lanes            = mlxsw_sp1_to_ptys_speed_lanes,
@@ -1658,19 +1660,24 @@ mlxsw_sp2_from_ptys_speed(struct mlxsw_sp *mlxsw_sp, u32 ptys_eth_proto)
 }
 
 static void
-mlxsw_sp2_from_ptys_speed_duplex(struct mlxsw_sp *mlxsw_sp, bool carrier_ok,
-                                u32 ptys_eth_proto,
-                                struct ethtool_link_ksettings *cmd)
+mlxsw_sp2_from_ptys_link_mode(struct mlxsw_sp *mlxsw_sp, bool carrier_ok,
+                             u32 ptys_eth_proto,
+                             struct ethtool_link_ksettings *cmd)
 {
-       cmd->base.speed = SPEED_UNKNOWN;
-       cmd->base.duplex = DUPLEX_UNKNOWN;
+       struct mlxsw_sp2_port_link_mode link;
+       int i;
+
+       cmd->link_mode = -1;
 
        if (!carrier_ok)
                return;
 
-       cmd->base.speed = mlxsw_sp2_from_ptys_speed(mlxsw_sp, ptys_eth_proto);
-       if (cmd->base.speed != SPEED_UNKNOWN)
-               cmd->base.duplex = DUPLEX_FULL;
+       for (i = 0; i < MLXSW_SP2_PORT_LINK_MODE_LEN; i++) {
+               if (ptys_eth_proto & mlxsw_sp2_port_link_mode[i].mask) {
+                       link = mlxsw_sp2_port_link_mode[i];
+                       cmd->link_mode = link.mask_ethtool[1];
+               }
+       }
 }
 
 static int mlxsw_sp2_ptys_max_speed(struct mlxsw_sp_port *mlxsw_sp_port, u32 *p_max_speed)
@@ -1793,7 +1800,7 @@ const struct mlxsw_sp_port_type_speed_ops mlxsw_sp2_port_type_speed_ops = {
        .from_ptys_supported_port       = mlxsw_sp2_from_ptys_supported_port,
        .from_ptys_link                 = mlxsw_sp2_from_ptys_link,
        .from_ptys_speed                = mlxsw_sp2_from_ptys_speed,
-       .from_ptys_speed_duplex         = mlxsw_sp2_from_ptys_speed_duplex,
+       .from_ptys_link_mode            = mlxsw_sp2_from_ptys_link_mode,
        .ptys_max_speed                 = mlxsw_sp2_ptys_max_speed,
        .to_ptys_advert_link            = mlxsw_sp2_to_ptys_advert_link,
        .to_ptys_speed_lanes            = mlxsw_sp2_to_ptys_speed_lanes,