@@ -1076,15 +1076,16 @@ static void ptys2ethtool_supported_advertised_port(struct mlx5_core_dev *mdev,
}
}
-static void get_speed_duplex(struct net_device *netdev,
- u32 eth_proto_oper, bool force_legacy,
- u16 data_rate_oper,
- struct ethtool_link_ksettings *link_ksettings)
+static void get_link_properties(struct net_device *netdev,
+ u32 eth_proto_oper, bool force_legacy,
+ u16 data_rate_oper,
+ struct ethtool_link_ksettings *link_ksettings)
{
struct mlx5e_priv *priv = netdev_priv(netdev);
const struct mlx5_link_info *info;
u8 duplex = DUPLEX_UNKNOWN;
u32 speed = SPEED_UNKNOWN;
+ u32 lanes = LANES_UNKNOWN;
if (!netif_carrier_ok(netdev))
goto out;
@@ -1092,14 +1093,17 @@ static void get_speed_duplex(struct net_device *netdev,
info = mlx5_port_ptys2info(priv->mdev, eth_proto_oper, force_legacy);
if (info) {
speed = info->speed;
+ lanes = info->lanes;
duplex = DUPLEX_FULL;
} else if (data_rate_oper) {
speed = 100 * data_rate_oper;
+ lanes = MAX_LANES;
}
out:
- link_ksettings->base.speed = speed;
link_ksettings->base.duplex = duplex;
+ link_ksettings->base.speed = speed;
+ link_ksettings->lanes = lanes;
}
static void get_supported(struct mlx5_core_dev *mdev, u32 eth_proto_cap,
@@ -1236,8 +1240,8 @@ static int mlx5e_ethtool_get_link_ksettings(struct mlx5e_priv *priv,
get_supported(mdev, eth_proto_cap, link_ksettings);
get_advertising(eth_proto_admin, tx_pause, rx_pause, link_ksettings,
admin_ext);
- get_speed_duplex(priv->netdev, eth_proto_oper, !admin_ext,
- data_rate_oper, link_ksettings);
+ get_link_properties(priv->netdev, eth_proto_oper, !admin_ext,
+ data_rate_oper, link_ksettings);
eth_proto_oper = eth_proto_oper ? eth_proto_oper : eth_proto_cap;
connector_type = connector_type < MLX5E_CONNECTOR_TYPE_NUMBER ?
@@ -1366,6 +1370,7 @@ static int mlx5e_ethtool_set_link_ksettings(struct mlx5e_priv *priv,
adver = link_ksettings->link_modes.advertising;
autoneg = link_ksettings->base.autoneg;
info.speed = link_ksettings->base.speed;
+ info.lanes = link_ksettings->lanes;
ext_supported = mlx5_ptys_ext_supported(mdev);
ext_requested = ext_link_mode_requested(adver);
@@ -2613,6 +2618,7 @@ static void mlx5e_get_ts_stats(struct net_device *netdev,
}
const struct ethtool_ops mlx5e_ethtool_ops = {
+ .cap_link_lanes_supported = true,
.cap_rss_ctx_supported = true,
.rxfh_per_ctx_key = true,
.supported_coalesce_params = ETHTOOL_COALESCE_USECS |
@@ -131,6 +131,7 @@ struct mlx5_module_eeprom_query_params {
struct mlx5_link_info {
u32 speed;
+ u32 lanes;
};
static inline void mlx5_printk(struct mlx5_core_dev *dev, int level, const char *format, ...)
@@ -1039,56 +1039,56 @@ int mlx5_query_dscp2prio(struct mlx5_core_dev *mdev, u8 *dscp2prio)
/* speed in units of 1Mb */
static const struct mlx5_link_info mlx5e_link_info[MLX5E_LINK_MODES_NUMBER] = {
- [MLX5E_1000BASE_CX_SGMII] = {.speed = 1000},
- [MLX5E_1000BASE_KX] = {.speed = 1000},
- [MLX5E_10GBASE_CX4] = {.speed = 10000},
- [MLX5E_10GBASE_KX4] = {.speed = 10000},
- [MLX5E_10GBASE_KR] = {.speed = 10000},
- [MLX5E_20GBASE_KR2] = {.speed = 20000},
- [MLX5E_40GBASE_CR4] = {.speed = 40000},
- [MLX5E_40GBASE_KR4] = {.speed = 40000},
- [MLX5E_56GBASE_R4] = {.speed = 56000},
- [MLX5E_10GBASE_CR] = {.speed = 10000},
- [MLX5E_10GBASE_SR] = {.speed = 10000},
- [MLX5E_10GBASE_ER] = {.speed = 10000},
- [MLX5E_40GBASE_SR4] = {.speed = 40000},
- [MLX5E_40GBASE_LR4] = {.speed = 40000},
- [MLX5E_50GBASE_SR2] = {.speed = 50000},
- [MLX5E_100GBASE_CR4] = {.speed = 100000},
- [MLX5E_100GBASE_SR4] = {.speed = 100000},
- [MLX5E_100GBASE_KR4] = {.speed = 100000},
- [MLX5E_100GBASE_LR4] = {.speed = 100000},
- [MLX5E_100BASE_TX] = {.speed = 100},
- [MLX5E_1000BASE_T] = {.speed = 1000},
- [MLX5E_10GBASE_T] = {.speed = 10000},
- [MLX5E_25GBASE_CR] = {.speed = 25000},
- [MLX5E_25GBASE_KR] = {.speed = 25000},
- [MLX5E_25GBASE_SR] = {.speed = 25000},
- [MLX5E_50GBASE_CR2] = {.speed = 50000},
- [MLX5E_50GBASE_KR2] = {.speed = 50000},
+ [MLX5E_1000BASE_CX_SGMII] = {.speed = 1000, .lanes = 1},
+ [MLX5E_1000BASE_KX] = {.speed = 1000, .lanes = 1},
+ [MLX5E_10GBASE_CX4] = {.speed = 10000, .lanes = 4},
+ [MLX5E_10GBASE_KX4] = {.speed = 10000, .lanes = 4},
+ [MLX5E_10GBASE_KR] = {.speed = 10000, .lanes = 1},
+ [MLX5E_20GBASE_KR2] = {.speed = 20000, .lanes = 2},
+ [MLX5E_40GBASE_CR4] = {.speed = 40000, .lanes = 4},
+ [MLX5E_40GBASE_KR4] = {.speed = 40000, .lanes = 4},
+ [MLX5E_56GBASE_R4] = {.speed = 56000, .lanes = 4},
+ [MLX5E_10GBASE_CR] = {.speed = 10000, .lanes = 1},
+ [MLX5E_10GBASE_SR] = {.speed = 10000, .lanes = 1},
+ [MLX5E_10GBASE_ER] = {.speed = 10000, .lanes = 1},
+ [MLX5E_40GBASE_SR4] = {.speed = 40000, .lanes = 4},
+ [MLX5E_40GBASE_LR4] = {.speed = 40000, .lanes = 4},
+ [MLX5E_50GBASE_SR2] = {.speed = 50000, .lanes = 2},
+ [MLX5E_100GBASE_CR4] = {.speed = 100000, .lanes = 4},
+ [MLX5E_100GBASE_SR4] = {.speed = 100000, .lanes = 4},
+ [MLX5E_100GBASE_KR4] = {.speed = 100000, .lanes = 4},
+ [MLX5E_100GBASE_LR4] = {.speed = 100000, .lanes = 4},
+ [MLX5E_100BASE_TX] = {.speed = 100, .lanes = 1},
+ [MLX5E_1000BASE_T] = {.speed = 1000, .lanes = 1},
+ [MLX5E_10GBASE_T] = {.speed = 10000, .lanes = 1},
+ [MLX5E_25GBASE_CR] = {.speed = 25000, .lanes = 1},
+ [MLX5E_25GBASE_KR] = {.speed = 25000, .lanes = 1},
+ [MLX5E_25GBASE_SR] = {.speed = 25000, .lanes = 1},
+ [MLX5E_50GBASE_CR2] = {.speed = 50000, .lanes = 2},
+ [MLX5E_50GBASE_KR2] = {.speed = 50000, .lanes = 2},
};
static const struct mlx5_link_info
mlx5e_ext_link_info[MLX5E_EXT_LINK_MODES_NUMBER] = {
- [MLX5E_SGMII_100M] = {.speed = 100},
- [MLX5E_1000BASE_X_SGMII] = {.speed = 1000},
- [MLX5E_5GBASE_R] = {.speed = 5000},
- [MLX5E_10GBASE_XFI_XAUI_1] = {.speed = 10000},
- [MLX5E_40GBASE_XLAUI_4_XLPPI_4] = {.speed = 40000},
- [MLX5E_25GAUI_1_25GBASE_CR_KR] = {.speed = 25000},
- [MLX5E_50GAUI_2_LAUI_2_50GBASE_CR2_KR2] = {.speed = 50000},
- [MLX5E_50GAUI_1_LAUI_1_50GBASE_CR_KR] = {.speed = 50000},
- [MLX5E_CAUI_4_100GBASE_CR4_KR4] = {.speed = 100000},
- [MLX5E_100GAUI_2_100GBASE_CR2_KR2] = {.speed = 100000},
- [MLX5E_200GAUI_4_200GBASE_CR4_KR4] = {.speed = 200000},
- [MLX5E_400GAUI_8_400GBASE_CR8] = {.speed = 400000},
- [MLX5E_100GAUI_1_100GBASE_CR_KR] = {.speed = 100000},
- [MLX5E_200GAUI_2_200GBASE_CR2_KR2] = {.speed = 200000},
- [MLX5E_400GAUI_4_400GBASE_CR4_KR4] = {.speed = 400000},
- [MLX5E_800GAUI_8_800GBASE_CR8_KR8] = {.speed = 800000},
- [MLX5E_200GAUI_1_200GBASE_CR1_KR1] = {.speed = 200000},
- [MLX5E_400GAUI_2_400GBASE_CR2_KR2] = {.speed = 400000},
- [MLX5E_800GAUI_4_800GBASE_CR4_KR4] = {.speed = 800000},
+ [MLX5E_SGMII_100M] = {.speed = 100, .lanes = 1},
+ [MLX5E_1000BASE_X_SGMII] = {.speed = 1000, .lanes = 1},
+ [MLX5E_5GBASE_R] = {.speed = 5000, .lanes = 1},
+ [MLX5E_10GBASE_XFI_XAUI_1] = {.speed = 10000, .lanes = 1},
+ [MLX5E_40GBASE_XLAUI_4_XLPPI_4] = {.speed = 40000, .lanes = 4},
+ [MLX5E_25GAUI_1_25GBASE_CR_KR] = {.speed = 25000, .lanes = 1},
+ [MLX5E_50GAUI_2_LAUI_2_50GBASE_CR2_KR2] = {.speed = 50000, .lanes = 2},
+ [MLX5E_50GAUI_1_LAUI_1_50GBASE_CR_KR] = {.speed = 50000, .lanes = 1},
+ [MLX5E_CAUI_4_100GBASE_CR4_KR4] = {.speed = 100000, .lanes = 4},
+ [MLX5E_100GAUI_2_100GBASE_CR2_KR2] = {.speed = 100000, .lanes = 2},
+ [MLX5E_200GAUI_4_200GBASE_CR4_KR4] = {.speed = 200000, .lanes = 4},
+ [MLX5E_400GAUI_8_400GBASE_CR8] = {.speed = 400000, .lanes = 8},
+ [MLX5E_100GAUI_1_100GBASE_CR_KR] = {.speed = 100000, .lanes = 1},
+ [MLX5E_200GAUI_2_200GBASE_CR2_KR2] = {.speed = 200000, .lanes = 2},
+ [MLX5E_400GAUI_4_400GBASE_CR4_KR4] = {.speed = 400000, .lanes = 4},
+ [MLX5E_800GAUI_8_800GBASE_CR8_KR8] = {.speed = 800000, .lanes = 8},
+ [MLX5E_200GAUI_1_200GBASE_CR1_KR1] = {.speed = 200000, .lanes = 1},
+ [MLX5E_400GAUI_2_400GBASE_CR2_KR2] = {.speed = 400000, .lanes = 2},
+ [MLX5E_800GAUI_4_800GBASE_CR4_KR4] = {.speed = 800000, .lanes = 4},
};
int mlx5_port_query_eth_proto(struct mlx5_core_dev *dev, u8 port, bool ext,
@@ -1168,8 +1168,10 @@ u32 mlx5_port_info2linkmodes(struct mlx5_core_dev *mdev,
mlx5e_port_get_link_mode_info_arr(mdev, &table, &max_size,
force_legacy);
for (i = 0; i < max_size; ++i) {
- if (table[i].speed == info->speed)
- link_modes |= MLX5E_PROT_MASK(i);
+ if (table[i].speed == info->speed) {
+ if (!info->lanes || table[i].lanes == info->lanes)
+ link_modes |= MLX5E_PROT_MASK(i);
+ }
}
return link_modes;
}
@@ -2192,6 +2192,8 @@ enum ethtool_link_mode_bit_indices {
#define SPEED_800000 800000
#define SPEED_UNKNOWN -1
+#define LANES_UNKNOWN 0
+#define MAX_LANES 8
static inline int ethtool_validate_speed(__u32 speed)
{