Commit 2aca31e7 authored by Stephen Hemminger's avatar Stephen Hemminger Committed by David S. Miller

sky2: fix limited auto negotiation

The sky2 driver would always try all possible supported speeds even
if the user only asked for a limited set of speed/duplex combinations.
Reported-by: default avatarMohsen Hariri <m.hariri@gmail.com>
Signed-off-by: default avatarStephen Hemminger <shemminger@vyatta.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 9bcb8018
......@@ -3411,8 +3411,7 @@ static u32 sky2_supported_modes(const struct sky2_hw *hw)
u32 modes = SUPPORTED_10baseT_Half
| SUPPORTED_10baseT_Full
| SUPPORTED_100baseT_Half
| SUPPORTED_100baseT_Full
| SUPPORTED_Autoneg | SUPPORTED_TP;
| SUPPORTED_100baseT_Full;
if (hw->flags & SKY2_HW_GIGABIT)
modes |= SUPPORTED_1000baseT_Half
......@@ -3420,9 +3419,7 @@ static u32 sky2_supported_modes(const struct sky2_hw *hw)
return modes;
} else
return SUPPORTED_1000baseT_Half
| SUPPORTED_1000baseT_Full
| SUPPORTED_Autoneg
| SUPPORTED_FIBRE;
| SUPPORTED_1000baseT_Full;
}
static int sky2_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
......@@ -3436,9 +3433,11 @@ static int sky2_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
if (sky2_is_copper(hw)) {
ecmd->port = PORT_TP;
ecmd->speed = sky2->speed;
ecmd->supported |= SUPPORTED_Autoneg | SUPPORTED_TP;
} else {
ecmd->speed = SPEED_1000;
ecmd->port = PORT_FIBRE;
ecmd->supported |= SUPPORTED_Autoneg | SUPPORTED_FIBRE;
}
ecmd->advertising = sky2->advertising;
......@@ -3455,8 +3454,19 @@ static int sky2_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
u32 supported = sky2_supported_modes(hw);
if (ecmd->autoneg == AUTONEG_ENABLE) {
if (ecmd->advertising & ~supported)
return -EINVAL;
if (sky2_is_copper(hw))
sky2->advertising = ecmd->advertising |
ADVERTISED_TP |
ADVERTISED_Autoneg;
else
sky2->advertising = ecmd->advertising |
ADVERTISED_FIBRE |
ADVERTISED_Autoneg;
sky2->flags |= SKY2_FLAG_AUTO_SPEED;
ecmd->advertising = supported;
sky2->duplex = -1;
sky2->speed = -1;
} else {
......@@ -3500,8 +3510,6 @@ static int sky2_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
sky2->flags &= ~SKY2_FLAG_AUTO_SPEED;
}
sky2->advertising = ecmd->advertising;
if (netif_running(dev)) {
sky2_phy_reinit(sky2);
sky2_set_multicast(dev);
......
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