diff --git a/drivers/net/ethernet/mellanox/mlxsw/reg.h b/drivers/net/ethernet/mellanox/mlxsw/reg.h index b83d0a7a0b49b2f30bea1af97eea5dc093e2b97d..43ce27f8c4a75e49260dde0e00c6cc33efa4278a 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/reg.h +++ b/drivers/net/ethernet/mellanox/mlxsw/reg.h @@ -2138,6 +2138,18 @@ MLXSW_ITEM32(reg, ptys, local_port, 0x00, 16, 8); */ MLXSW_ITEM32(reg, ptys, proto_mask, 0x00, 0, 3); +enum { + MLXSW_REG_PTYS_AN_STATUS_NA, + MLXSW_REG_PTYS_AN_STATUS_OK, + MLXSW_REG_PTYS_AN_STATUS_FAIL, +}; + +/* reg_ptys_an_status + * Autonegotiation status. + * Access: RO + */ +MLXSW_ITEM32(reg, ptys, an_status, 0x04, 28, 4); + #define MLXSW_REG_PTYS_ETH_SPEED_SGMII BIT(0) #define MLXSW_REG_PTYS_ETH_SPEED_1000BASE_KX BIT(1) #define MLXSW_REG_PTYS_ETH_SPEED_10GBASE_CX4 BIT(2) @@ -2184,6 +2196,13 @@ MLXSW_ITEM32(reg, ptys, eth_proto_admin, 0x18, 0, 32); */ MLXSW_ITEM32(reg, ptys, eth_proto_oper, 0x24, 0, 32); +/* reg_ptys_eth_proto_lp_advertise + * The protocols that were advertised by the link partner during + * autonegotiation. + * Access: RO + */ +MLXSW_ITEM32(reg, ptys, eth_proto_lp_advertise, 0x30, 0, 32); + static inline void mlxsw_reg_ptys_pack(char *payload, u8 local_port, u32 proto_admin) { diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c index cbec5f3019397a31aa787076ea3b72267cc64bbe..07930cc1fa60c519035340a4992b6c965e90cd1b 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c @@ -1800,6 +1800,8 @@ static int mlxsw_sp_port_get_settings(struct net_device *dev, u32 eth_proto_cap; u32 eth_proto_admin; u32 eth_proto_oper; + u8 autoneg_status; + u32 eth_proto_lp; int err; mlxsw_reg_ptys_pack(ptys_pl, mlxsw_sp_port->local_port, 0); @@ -1810,6 +1812,8 @@ static int mlxsw_sp_port_get_settings(struct net_device *dev, } mlxsw_reg_ptys_unpack(ptys_pl, ð_proto_cap, ð_proto_admin, ð_proto_oper); + eth_proto_lp = mlxsw_reg_ptys_eth_proto_lp_advertise_get(ptys_pl); + autoneg_status = mlxsw_reg_ptys_an_status_get(ptys_pl); cmd->supported = mlxsw_sp_from_ptys_supported_port(eth_proto_cap) | mlxsw_sp_from_ptys_supported_link(eth_proto_cap) | @@ -1826,7 +1830,10 @@ static int mlxsw_sp_port_get_settings(struct net_device *dev, eth_proto_oper = eth_proto_oper ? eth_proto_oper : eth_proto_cap; cmd->port = mlxsw_sp_port_connector_port(eth_proto_oper); - cmd->lp_advertising = mlxsw_sp_from_ptys_advert_link(eth_proto_oper); + + if (autoneg_status == MLXSW_REG_PTYS_AN_STATUS_OK && eth_proto_lp) + cmd->lp_advertising = + mlxsw_sp_from_ptys_advert_link(eth_proto_lp); cmd->transceiver = XCVR_INTERNAL; return 0;