struct mlx4_en_priv *priv = netdev_priv(dev);
struct mlx4_ptys_reg ptys_reg;
__be32 proto_admin;
+ u8 cur_autoneg;
int ret;
u32 ptys_adv = ethtool2ptys_link_modes(
return 0;
}
- proto_admin = link_ksettings->base.autoneg == AUTONEG_ENABLE ?
- cpu_to_be32(ptys_adv) :
- speed_set_ptys_admin(priv, speed,
- ptys_reg.eth_proto_cap);
+ cur_autoneg = ptys_reg.flags & MLX4_PTYS_AN_DISABLE_ADMIN ?
+ AUTONEG_DISABLE : AUTONEG_ENABLE;
+
+ if (link_ksettings->base.autoneg == AUTONEG_DISABLE) {
+ proto_admin = speed_set_ptys_admin(priv, speed,
+ ptys_reg.eth_proto_cap);
+ if ((be32_to_cpu(proto_admin) &
+ (MLX4_PROT_MASK(MLX4_1000BASE_CX_SGMII) |
+ MLX4_PROT_MASK(MLX4_1000BASE_KX))) &&
+ (ptys_reg.flags & MLX4_PTYS_AN_DISABLE_CAP))
+ ptys_reg.flags |= MLX4_PTYS_AN_DISABLE_ADMIN;
+ } else {
+ proto_admin = cpu_to_be32(ptys_adv);
+ ptys_reg.flags &= ~MLX4_PTYS_AN_DISABLE_ADMIN;
+ }
proto_admin &= ptys_reg.eth_proto_cap;
if (!proto_admin) {
return -EINVAL; /* nothing to change due to bad input */
}
- if (proto_admin == ptys_reg.eth_proto_admin)
+ if ((proto_admin == ptys_reg.eth_proto_admin) &&
+ ((ptys_reg.flags & MLX4_PTYS_AN_DISABLE_CAP) &&
+ (link_ksettings->base.autoneg == cur_autoneg)))
return 0; /* Nothing to change */
en_dbg(DRV, priv, "mlx4_ACCESS_PTYS_REG SET: ptys_reg.eth_proto_admin = 0x%x\n",