Commit 763ece86 authored by Danielle Ratson's avatar Danielle Ratson Committed by Jakub Kicinski

mlxsw: ethtool: Add support for setting lanes when autoneg is off

Currently, when auto negotiation is set to off, the user can force a
specific speed or both speed and duplex. The user cannot influence the
number of lanes that will be forced.

Add support for setting speed along with lanes so one would be able
to choose how many lanes will be forced.

When lanes parameter is passed from user space, choose the link mode
that its actual width equals to it.
Otherwise, the default link mode will be the one that supports the width
of the port.
Signed-off-by: default avatarDanielle Ratson <danieller@nvidia.com>
Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 5fc4053d
...@@ -336,7 +336,8 @@ struct mlxsw_sp_port_type_speed_ops { ...@@ -336,7 +336,8 @@ struct mlxsw_sp_port_type_speed_ops {
int (*ptys_max_speed)(struct mlxsw_sp_port *mlxsw_sp_port, u32 *p_max_speed); 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, u32 (*to_ptys_advert_link)(struct mlxsw_sp *mlxsw_sp,
const struct ethtool_link_ksettings *cmd); const struct ethtool_link_ksettings *cmd);
u32 (*to_ptys_speed)(struct mlxsw_sp *mlxsw_sp, u8 width, u32 speed); u32 (*to_ptys_speed_lanes)(struct mlxsw_sp *mlxsw_sp, u8 width,
const struct ethtool_link_ksettings *cmd);
void (*reg_ptys_eth_pack)(struct mlxsw_sp *mlxsw_sp, char *payload, void (*reg_ptys_eth_pack)(struct mlxsw_sp *mlxsw_sp, char *payload,
u8 local_port, u32 proto_admin, bool autoneg); u8 local_port, u32 proto_admin, bool autoneg);
void (*reg_ptys_eth_unpack)(struct mlxsw_sp *mlxsw_sp, char *payload, void (*reg_ptys_eth_unpack)(struct mlxsw_sp *mlxsw_sp, char *payload,
......
...@@ -996,12 +996,12 @@ mlxsw_sp_port_set_link_ksettings(struct net_device *dev, ...@@ -996,12 +996,12 @@ mlxsw_sp_port_set_link_ksettings(struct net_device *dev,
autoneg = cmd->base.autoneg == AUTONEG_ENABLE; autoneg = cmd->base.autoneg == AUTONEG_ENABLE;
eth_proto_new = autoneg ? eth_proto_new = autoneg ?
ops->to_ptys_advert_link(mlxsw_sp, cmd) : ops->to_ptys_advert_link(mlxsw_sp, cmd) :
ops->to_ptys_speed(mlxsw_sp, mlxsw_sp_port->mapping.width, ops->to_ptys_speed_lanes(mlxsw_sp, mlxsw_sp_port->mapping.width,
cmd->base.speed); cmd);
eth_proto_new = eth_proto_new & eth_proto_cap; eth_proto_new = eth_proto_new & eth_proto_cap;
if (!eth_proto_new) { if (!eth_proto_new) {
netdev_err(dev, "No supported speed requested\n"); netdev_err(dev, "No supported speed or lanes requested\n");
return -EINVAL; return -EINVAL;
} }
...@@ -1060,20 +1060,21 @@ mlxsw_sp_get_ts_info(struct net_device *netdev, struct ethtool_ts_info *info) ...@@ -1060,20 +1060,21 @@ mlxsw_sp_get_ts_info(struct net_device *netdev, struct ethtool_ts_info *info)
} }
const struct ethtool_ops mlxsw_sp_port_ethtool_ops = { const struct ethtool_ops mlxsw_sp_port_ethtool_ops = {
.get_drvinfo = mlxsw_sp_port_get_drvinfo, .cap_link_lanes_supported = true,
.get_link = ethtool_op_get_link, .get_drvinfo = mlxsw_sp_port_get_drvinfo,
.get_link_ext_state = mlxsw_sp_port_get_link_ext_state, .get_link = ethtool_op_get_link,
.get_pauseparam = mlxsw_sp_port_get_pauseparam, .get_link_ext_state = mlxsw_sp_port_get_link_ext_state,
.set_pauseparam = mlxsw_sp_port_set_pauseparam, .get_pauseparam = mlxsw_sp_port_get_pauseparam,
.get_strings = mlxsw_sp_port_get_strings, .set_pauseparam = mlxsw_sp_port_set_pauseparam,
.set_phys_id = mlxsw_sp_port_set_phys_id, .get_strings = mlxsw_sp_port_get_strings,
.get_ethtool_stats = mlxsw_sp_port_get_stats, .set_phys_id = mlxsw_sp_port_set_phys_id,
.get_sset_count = mlxsw_sp_port_get_sset_count, .get_ethtool_stats = mlxsw_sp_port_get_stats,
.get_link_ksettings = mlxsw_sp_port_get_link_ksettings, .get_sset_count = mlxsw_sp_port_get_sset_count,
.set_link_ksettings = mlxsw_sp_port_set_link_ksettings, .get_link_ksettings = mlxsw_sp_port_get_link_ksettings,
.get_module_info = mlxsw_sp_get_module_info, .set_link_ksettings = mlxsw_sp_port_set_link_ksettings,
.get_module_eeprom = mlxsw_sp_get_module_eeprom, .get_module_info = mlxsw_sp_get_module_info,
.get_ts_info = mlxsw_sp_get_ts_info, .get_module_eeprom = mlxsw_sp_get_module_eeprom,
.get_ts_info = mlxsw_sp_get_ts_info,
}; };
struct mlxsw_sp1_port_link_mode { struct mlxsw_sp1_port_link_mode {
...@@ -1271,14 +1272,17 @@ mlxsw_sp1_to_ptys_advert_link(struct mlxsw_sp *mlxsw_sp, ...@@ -1271,14 +1272,17 @@ mlxsw_sp1_to_ptys_advert_link(struct mlxsw_sp *mlxsw_sp,
return ptys_proto; return ptys_proto;
} }
static u32 mlxsw_sp1_to_ptys_speed(struct mlxsw_sp *mlxsw_sp, u8 width, static u32 mlxsw_sp1_to_ptys_speed_lanes(struct mlxsw_sp *mlxsw_sp, u8 width,
u32 speed) const struct ethtool_link_ksettings *cmd)
{ {
u32 ptys_proto = 0; u32 ptys_proto = 0;
int i; int i;
if (cmd->lanes > width)
return ptys_proto;
for (i = 0; i < MLXSW_SP1_PORT_LINK_MODE_LEN; i++) { for (i = 0; i < MLXSW_SP1_PORT_LINK_MODE_LEN; i++) {
if (speed == mlxsw_sp1_port_link_mode[i].speed) if (cmd->base.speed == mlxsw_sp1_port_link_mode[i].speed)
ptys_proto |= mlxsw_sp1_port_link_mode[i].mask; ptys_proto |= mlxsw_sp1_port_link_mode[i].mask;
} }
return ptys_proto; return ptys_proto;
...@@ -1321,7 +1325,7 @@ const struct mlxsw_sp_port_type_speed_ops mlxsw_sp1_port_type_speed_ops = { ...@@ -1321,7 +1325,7 @@ const struct mlxsw_sp_port_type_speed_ops mlxsw_sp1_port_type_speed_ops = {
.from_ptys_speed_duplex = mlxsw_sp1_from_ptys_speed_duplex, .from_ptys_speed_duplex = mlxsw_sp1_from_ptys_speed_duplex,
.ptys_max_speed = mlxsw_sp1_ptys_max_speed, .ptys_max_speed = mlxsw_sp1_ptys_max_speed,
.to_ptys_advert_link = mlxsw_sp1_to_ptys_advert_link, .to_ptys_advert_link = mlxsw_sp1_to_ptys_advert_link,
.to_ptys_speed = mlxsw_sp1_to_ptys_speed, .to_ptys_speed_lanes = mlxsw_sp1_to_ptys_speed_lanes,
.reg_ptys_eth_pack = mlxsw_sp1_reg_ptys_eth_pack, .reg_ptys_eth_pack = mlxsw_sp1_reg_ptys_eth_pack,
.reg_ptys_eth_unpack = mlxsw_sp1_reg_ptys_eth_unpack, .reg_ptys_eth_unpack = mlxsw_sp1_reg_ptys_eth_unpack,
.ptys_proto_cap_masked_get = mlxsw_sp1_ptys_proto_cap_masked_get, .ptys_proto_cap_masked_get = mlxsw_sp1_ptys_proto_cap_masked_get,
...@@ -1483,7 +1487,8 @@ struct mlxsw_sp2_port_link_mode { ...@@ -1483,7 +1487,8 @@ struct mlxsw_sp2_port_link_mode {
int m_ethtool_len; int m_ethtool_len;
u32 mask; u32 mask;
u32 speed; u32 speed;
u8 mask_width; u32 width;
u8 mask_sup_width;
}; };
static const struct mlxsw_sp2_port_link_mode mlxsw_sp2_port_link_mode[] = { static const struct mlxsw_sp2_port_link_mode mlxsw_sp2_port_link_mode[] = {
...@@ -1491,105 +1496,117 @@ static const struct mlxsw_sp2_port_link_mode mlxsw_sp2_port_link_mode[] = { ...@@ -1491,105 +1496,117 @@ static const struct mlxsw_sp2_port_link_mode mlxsw_sp2_port_link_mode[] = {
.mask = MLXSW_REG_PTYS_EXT_ETH_SPEED_SGMII_100M, .mask = MLXSW_REG_PTYS_EXT_ETH_SPEED_SGMII_100M,
.mask_ethtool = mlxsw_sp2_mask_ethtool_sgmii_100m, .mask_ethtool = mlxsw_sp2_mask_ethtool_sgmii_100m,
.m_ethtool_len = MLXSW_SP2_MASK_ETHTOOL_SGMII_100M_LEN, .m_ethtool_len = MLXSW_SP2_MASK_ETHTOOL_SGMII_100M_LEN,
.mask_width = MLXSW_SP_PORT_MASK_WIDTH_1X | .mask_sup_width = MLXSW_SP_PORT_MASK_WIDTH_1X |
MLXSW_SP_PORT_MASK_WIDTH_2X | MLXSW_SP_PORT_MASK_WIDTH_2X |
MLXSW_SP_PORT_MASK_WIDTH_4X | MLXSW_SP_PORT_MASK_WIDTH_4X |
MLXSW_SP_PORT_MASK_WIDTH_8X, MLXSW_SP_PORT_MASK_WIDTH_8X,
.speed = SPEED_100, .speed = SPEED_100,
.width = 1,
}, },
{ {
.mask = MLXSW_REG_PTYS_EXT_ETH_SPEED_1000BASE_X_SGMII, .mask = MLXSW_REG_PTYS_EXT_ETH_SPEED_1000BASE_X_SGMII,
.mask_ethtool = mlxsw_sp2_mask_ethtool_1000base_x_sgmii, .mask_ethtool = mlxsw_sp2_mask_ethtool_1000base_x_sgmii,
.m_ethtool_len = MLXSW_SP2_MASK_ETHTOOL_1000BASE_X_SGMII_LEN, .m_ethtool_len = MLXSW_SP2_MASK_ETHTOOL_1000BASE_X_SGMII_LEN,
.mask_width = MLXSW_SP_PORT_MASK_WIDTH_1X | .mask_sup_width = MLXSW_SP_PORT_MASK_WIDTH_1X |
MLXSW_SP_PORT_MASK_WIDTH_2X | MLXSW_SP_PORT_MASK_WIDTH_2X |
MLXSW_SP_PORT_MASK_WIDTH_4X | MLXSW_SP_PORT_MASK_WIDTH_4X |
MLXSW_SP_PORT_MASK_WIDTH_8X, MLXSW_SP_PORT_MASK_WIDTH_8X,
.speed = SPEED_1000, .speed = SPEED_1000,
.width = 1,
}, },
{ {
.mask = MLXSW_REG_PTYS_EXT_ETH_SPEED_5GBASE_R, .mask = MLXSW_REG_PTYS_EXT_ETH_SPEED_5GBASE_R,
.mask_ethtool = mlxsw_sp2_mask_ethtool_5gbase_r, .mask_ethtool = mlxsw_sp2_mask_ethtool_5gbase_r,
.m_ethtool_len = MLXSW_SP2_MASK_ETHTOOL_5GBASE_R_LEN, .m_ethtool_len = MLXSW_SP2_MASK_ETHTOOL_5GBASE_R_LEN,
.mask_width = MLXSW_SP_PORT_MASK_WIDTH_1X | .mask_sup_width = MLXSW_SP_PORT_MASK_WIDTH_1X |
MLXSW_SP_PORT_MASK_WIDTH_2X | MLXSW_SP_PORT_MASK_WIDTH_2X |
MLXSW_SP_PORT_MASK_WIDTH_4X | MLXSW_SP_PORT_MASK_WIDTH_4X |
MLXSW_SP_PORT_MASK_WIDTH_8X, MLXSW_SP_PORT_MASK_WIDTH_8X,
.speed = SPEED_5000, .speed = SPEED_5000,
.width = 1,
}, },
{ {
.mask = MLXSW_REG_PTYS_EXT_ETH_SPEED_XFI_XAUI_1_10G, .mask = MLXSW_REG_PTYS_EXT_ETH_SPEED_XFI_XAUI_1_10G,
.mask_ethtool = mlxsw_sp2_mask_ethtool_xfi_xaui_1_10g, .mask_ethtool = mlxsw_sp2_mask_ethtool_xfi_xaui_1_10g,
.m_ethtool_len = MLXSW_SP2_MASK_ETHTOOL_XFI_XAUI_1_10G_LEN, .m_ethtool_len = MLXSW_SP2_MASK_ETHTOOL_XFI_XAUI_1_10G_LEN,
.mask_width = MLXSW_SP_PORT_MASK_WIDTH_1X | .mask_sup_width = MLXSW_SP_PORT_MASK_WIDTH_1X |
MLXSW_SP_PORT_MASK_WIDTH_2X | MLXSW_SP_PORT_MASK_WIDTH_2X |
MLXSW_SP_PORT_MASK_WIDTH_4X | MLXSW_SP_PORT_MASK_WIDTH_4X |
MLXSW_SP_PORT_MASK_WIDTH_8X, MLXSW_SP_PORT_MASK_WIDTH_8X,
.speed = SPEED_10000, .speed = SPEED_10000,
.width = 1,
}, },
{ {
.mask = MLXSW_REG_PTYS_EXT_ETH_SPEED_XLAUI_4_XLPPI_4_40G, .mask = MLXSW_REG_PTYS_EXT_ETH_SPEED_XLAUI_4_XLPPI_4_40G,
.mask_ethtool = mlxsw_sp2_mask_ethtool_xlaui_4_xlppi_4_40g, .mask_ethtool = mlxsw_sp2_mask_ethtool_xlaui_4_xlppi_4_40g,
.m_ethtool_len = MLXSW_SP2_MASK_ETHTOOL_XLAUI_4_XLPPI_4_40G_LEN, .m_ethtool_len = MLXSW_SP2_MASK_ETHTOOL_XLAUI_4_XLPPI_4_40G_LEN,
.mask_width = MLXSW_SP_PORT_MASK_WIDTH_4X | .mask_sup_width = MLXSW_SP_PORT_MASK_WIDTH_4X |
MLXSW_SP_PORT_MASK_WIDTH_8X, MLXSW_SP_PORT_MASK_WIDTH_8X,
.speed = SPEED_40000, .speed = SPEED_40000,
.width = 4,
}, },
{ {
.mask = MLXSW_REG_PTYS_EXT_ETH_SPEED_25GAUI_1_25GBASE_CR_KR, .mask = MLXSW_REG_PTYS_EXT_ETH_SPEED_25GAUI_1_25GBASE_CR_KR,
.mask_ethtool = mlxsw_sp2_mask_ethtool_25gaui_1_25gbase_cr_kr, .mask_ethtool = mlxsw_sp2_mask_ethtool_25gaui_1_25gbase_cr_kr,
.m_ethtool_len = MLXSW_SP2_MASK_ETHTOOL_25GAUI_1_25GBASE_CR_KR_LEN, .m_ethtool_len = MLXSW_SP2_MASK_ETHTOOL_25GAUI_1_25GBASE_CR_KR_LEN,
.mask_width = MLXSW_SP_PORT_MASK_WIDTH_1X | .mask_sup_width = MLXSW_SP_PORT_MASK_WIDTH_1X |
MLXSW_SP_PORT_MASK_WIDTH_2X | MLXSW_SP_PORT_MASK_WIDTH_2X |
MLXSW_SP_PORT_MASK_WIDTH_4X | MLXSW_SP_PORT_MASK_WIDTH_4X |
MLXSW_SP_PORT_MASK_WIDTH_8X, MLXSW_SP_PORT_MASK_WIDTH_8X,
.speed = SPEED_25000, .speed = SPEED_25000,
.width = 1,
}, },
{ {
.mask = MLXSW_REG_PTYS_EXT_ETH_SPEED_50GAUI_2_LAUI_2_50GBASE_CR2_KR2, .mask = MLXSW_REG_PTYS_EXT_ETH_SPEED_50GAUI_2_LAUI_2_50GBASE_CR2_KR2,
.mask_ethtool = mlxsw_sp2_mask_ethtool_50gaui_2_laui_2_50gbase_cr2_kr2, .mask_ethtool = mlxsw_sp2_mask_ethtool_50gaui_2_laui_2_50gbase_cr2_kr2,
.m_ethtool_len = MLXSW_SP2_MASK_ETHTOOL_50GAUI_2_LAUI_2_50GBASE_CR2_KR2_LEN, .m_ethtool_len = MLXSW_SP2_MASK_ETHTOOL_50GAUI_2_LAUI_2_50GBASE_CR2_KR2_LEN,
.mask_width = MLXSW_SP_PORT_MASK_WIDTH_2X | .mask_sup_width = MLXSW_SP_PORT_MASK_WIDTH_2X |
MLXSW_SP_PORT_MASK_WIDTH_4X | MLXSW_SP_PORT_MASK_WIDTH_4X |
MLXSW_SP_PORT_MASK_WIDTH_8X, MLXSW_SP_PORT_MASK_WIDTH_8X,
.speed = SPEED_50000, .speed = SPEED_50000,
.width = 2,
}, },
{ {
.mask = MLXSW_REG_PTYS_EXT_ETH_SPEED_50GAUI_1_LAUI_1_50GBASE_CR_KR, .mask = MLXSW_REG_PTYS_EXT_ETH_SPEED_50GAUI_1_LAUI_1_50GBASE_CR_KR,
.mask_ethtool = mlxsw_sp2_mask_ethtool_50gaui_1_laui_1_50gbase_cr_kr, .mask_ethtool = mlxsw_sp2_mask_ethtool_50gaui_1_laui_1_50gbase_cr_kr,
.m_ethtool_len = MLXSW_SP2_MASK_ETHTOOL_50GAUI_1_LAUI_1_50GBASE_CR_KR_LEN, .m_ethtool_len = MLXSW_SP2_MASK_ETHTOOL_50GAUI_1_LAUI_1_50GBASE_CR_KR_LEN,
.mask_width = MLXSW_SP_PORT_MASK_WIDTH_1X, .mask_sup_width = MLXSW_SP_PORT_MASK_WIDTH_1X,
.speed = SPEED_50000, .speed = SPEED_50000,
.width = 1,
}, },
{ {
.mask = MLXSW_REG_PTYS_EXT_ETH_SPEED_CAUI_4_100GBASE_CR4_KR4, .mask = MLXSW_REG_PTYS_EXT_ETH_SPEED_CAUI_4_100GBASE_CR4_KR4,
.mask_ethtool = mlxsw_sp2_mask_ethtool_caui_4_100gbase_cr4_kr4, .mask_ethtool = mlxsw_sp2_mask_ethtool_caui_4_100gbase_cr4_kr4,
.m_ethtool_len = MLXSW_SP2_MASK_ETHTOOL_CAUI_4_100GBASE_CR4_KR4_LEN, .m_ethtool_len = MLXSW_SP2_MASK_ETHTOOL_CAUI_4_100GBASE_CR4_KR4_LEN,
.mask_width = MLXSW_SP_PORT_MASK_WIDTH_4X | .mask_sup_width = MLXSW_SP_PORT_MASK_WIDTH_4X |
MLXSW_SP_PORT_MASK_WIDTH_8X, MLXSW_SP_PORT_MASK_WIDTH_8X,
.speed = SPEED_100000, .speed = SPEED_100000,
.width = 4,
}, },
{ {
.mask = MLXSW_REG_PTYS_EXT_ETH_SPEED_100GAUI_2_100GBASE_CR2_KR2, .mask = MLXSW_REG_PTYS_EXT_ETH_SPEED_100GAUI_2_100GBASE_CR2_KR2,
.mask_ethtool = mlxsw_sp2_mask_ethtool_100gaui_2_100gbase_cr2_kr2, .mask_ethtool = mlxsw_sp2_mask_ethtool_100gaui_2_100gbase_cr2_kr2,
.m_ethtool_len = MLXSW_SP2_MASK_ETHTOOL_100GAUI_2_100GBASE_CR2_KR2_LEN, .m_ethtool_len = MLXSW_SP2_MASK_ETHTOOL_100GAUI_2_100GBASE_CR2_KR2_LEN,
.mask_width = MLXSW_SP_PORT_MASK_WIDTH_2X, .mask_sup_width = MLXSW_SP_PORT_MASK_WIDTH_2X,
.speed = SPEED_100000, .speed = SPEED_100000,
.width = 2,
}, },
{ {
.mask = MLXSW_REG_PTYS_EXT_ETH_SPEED_200GAUI_4_200GBASE_CR4_KR4, .mask = MLXSW_REG_PTYS_EXT_ETH_SPEED_200GAUI_4_200GBASE_CR4_KR4,
.mask_ethtool = mlxsw_sp2_mask_ethtool_200gaui_4_200gbase_cr4_kr4, .mask_ethtool = mlxsw_sp2_mask_ethtool_200gaui_4_200gbase_cr4_kr4,
.m_ethtool_len = MLXSW_SP2_MASK_ETHTOOL_200GAUI_4_200GBASE_CR4_KR4_LEN, .m_ethtool_len = MLXSW_SP2_MASK_ETHTOOL_200GAUI_4_200GBASE_CR4_KR4_LEN,
.mask_width = MLXSW_SP_PORT_MASK_WIDTH_4X | .mask_sup_width = MLXSW_SP_PORT_MASK_WIDTH_4X |
MLXSW_SP_PORT_MASK_WIDTH_8X, MLXSW_SP_PORT_MASK_WIDTH_8X,
.speed = SPEED_200000, .speed = SPEED_200000,
.width = 4,
}, },
{ {
.mask = MLXSW_REG_PTYS_EXT_ETH_SPEED_400GAUI_8, .mask = MLXSW_REG_PTYS_EXT_ETH_SPEED_400GAUI_8,
.mask_ethtool = mlxsw_sp2_mask_ethtool_400gaui_8, .mask_ethtool = mlxsw_sp2_mask_ethtool_400gaui_8,
.m_ethtool_len = MLXSW_SP2_MASK_ETHTOOL_400GAUI_8_LEN, .m_ethtool_len = MLXSW_SP2_MASK_ETHTOOL_400GAUI_8_LEN,
.mask_width = MLXSW_SP_PORT_MASK_WIDTH_8X, .mask_sup_width = MLXSW_SP_PORT_MASK_WIDTH_8X,
.speed = SPEED_400000, .speed = SPEED_400000,
.width = 8,
}, },
}; };
...@@ -1707,17 +1724,36 @@ mlxsw_sp2_to_ptys_advert_link(struct mlxsw_sp *mlxsw_sp, ...@@ -1707,17 +1724,36 @@ mlxsw_sp2_to_ptys_advert_link(struct mlxsw_sp *mlxsw_sp,
return ptys_proto; return ptys_proto;
} }
static u32 mlxsw_sp2_to_ptys_speed(struct mlxsw_sp *mlxsw_sp, static u32 mlxsw_sp2_to_ptys_speed_lanes(struct mlxsw_sp *mlxsw_sp, u8 width,
u8 width, u32 speed) const struct ethtool_link_ksettings *cmd)
{ {
u8 mask_width = mlxsw_sp_port_mask_width_get(width); u8 mask_width = mlxsw_sp_port_mask_width_get(width);
struct mlxsw_sp2_port_link_mode link_mode;
u32 ptys_proto = 0; u32 ptys_proto = 0;
int i; int i;
if (cmd->lanes > width)
return ptys_proto;
for (i = 0; i < MLXSW_SP2_PORT_LINK_MODE_LEN; i++) { for (i = 0; i < MLXSW_SP2_PORT_LINK_MODE_LEN; i++) {
if ((speed == mlxsw_sp2_port_link_mode[i].speed) && if (cmd->base.speed == mlxsw_sp2_port_link_mode[i].speed) {
(mask_width & mlxsw_sp2_port_link_mode[i].mask_width)) link_mode = mlxsw_sp2_port_link_mode[i];
ptys_proto |= mlxsw_sp2_port_link_mode[i].mask;
if (!cmd->lanes) {
/* If number of lanes was not set by user space,
* choose the link mode that supports the width
* of the port.
*/
if (mask_width & link_mode.mask_sup_width)
ptys_proto |= link_mode.mask;
} else if (cmd->lanes == link_mode.width) {
/* Else if the number of lanes was set, choose
* the link mode that its actual width equals to
* it.
*/
ptys_proto |= link_mode.mask;
}
}
} }
return ptys_proto; return ptys_proto;
} }
...@@ -1760,7 +1796,7 @@ const struct mlxsw_sp_port_type_speed_ops mlxsw_sp2_port_type_speed_ops = { ...@@ -1760,7 +1796,7 @@ const struct mlxsw_sp_port_type_speed_ops mlxsw_sp2_port_type_speed_ops = {
.from_ptys_speed_duplex = mlxsw_sp2_from_ptys_speed_duplex, .from_ptys_speed_duplex = mlxsw_sp2_from_ptys_speed_duplex,
.ptys_max_speed = mlxsw_sp2_ptys_max_speed, .ptys_max_speed = mlxsw_sp2_ptys_max_speed,
.to_ptys_advert_link = mlxsw_sp2_to_ptys_advert_link, .to_ptys_advert_link = mlxsw_sp2_to_ptys_advert_link,
.to_ptys_speed = mlxsw_sp2_to_ptys_speed, .to_ptys_speed_lanes = mlxsw_sp2_to_ptys_speed_lanes,
.reg_ptys_eth_pack = mlxsw_sp2_reg_ptys_eth_pack, .reg_ptys_eth_pack = mlxsw_sp2_reg_ptys_eth_pack,
.reg_ptys_eth_unpack = mlxsw_sp2_reg_ptys_eth_unpack, .reg_ptys_eth_unpack = mlxsw_sp2_reg_ptys_eth_unpack,
.ptys_proto_cap_masked_get = mlxsw_sp2_ptys_proto_cap_masked_get, .ptys_proto_cap_masked_get = mlxsw_sp2_ptys_proto_cap_masked_get,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment