提交 2aca31e7 编写于 作者: S Stephen Hemminger 提交者: 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: NMohsen Hariri <m.hariri@gmail.com>
Signed-off-by: NStephen Hemminger <shemminger@vyatta.com>
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
上级 9bcb8018
...@@ -3411,8 +3411,7 @@ static u32 sky2_supported_modes(const struct sky2_hw *hw) ...@@ -3411,8 +3411,7 @@ static u32 sky2_supported_modes(const struct sky2_hw *hw)
u32 modes = SUPPORTED_10baseT_Half u32 modes = SUPPORTED_10baseT_Half
| SUPPORTED_10baseT_Full | SUPPORTED_10baseT_Full
| SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Half
| SUPPORTED_100baseT_Full | SUPPORTED_100baseT_Full;
| SUPPORTED_Autoneg | SUPPORTED_TP;
if (hw->flags & SKY2_HW_GIGABIT) if (hw->flags & SKY2_HW_GIGABIT)
modes |= SUPPORTED_1000baseT_Half modes |= SUPPORTED_1000baseT_Half
...@@ -3420,9 +3419,7 @@ static u32 sky2_supported_modes(const struct sky2_hw *hw) ...@@ -3420,9 +3419,7 @@ static u32 sky2_supported_modes(const struct sky2_hw *hw)
return modes; return modes;
} else } else
return SUPPORTED_1000baseT_Half return SUPPORTED_1000baseT_Half
| SUPPORTED_1000baseT_Full | SUPPORTED_1000baseT_Full;
| SUPPORTED_Autoneg
| SUPPORTED_FIBRE;
} }
static int sky2_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) 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) ...@@ -3436,9 +3433,11 @@ static int sky2_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
if (sky2_is_copper(hw)) { if (sky2_is_copper(hw)) {
ecmd->port = PORT_TP; ecmd->port = PORT_TP;
ecmd->speed = sky2->speed; ecmd->speed = sky2->speed;
ecmd->supported |= SUPPORTED_Autoneg | SUPPORTED_TP;
} else { } else {
ecmd->speed = SPEED_1000; ecmd->speed = SPEED_1000;
ecmd->port = PORT_FIBRE; ecmd->port = PORT_FIBRE;
ecmd->supported |= SUPPORTED_Autoneg | SUPPORTED_FIBRE;
} }
ecmd->advertising = sky2->advertising; ecmd->advertising = sky2->advertising;
...@@ -3455,8 +3454,19 @@ static int sky2_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd) ...@@ -3455,8 +3454,19 @@ static int sky2_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
u32 supported = sky2_supported_modes(hw); u32 supported = sky2_supported_modes(hw);
if (ecmd->autoneg == AUTONEG_ENABLE) { 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; sky2->flags |= SKY2_FLAG_AUTO_SPEED;
ecmd->advertising = supported;
sky2->duplex = -1; sky2->duplex = -1;
sky2->speed = -1; sky2->speed = -1;
} else { } else {
...@@ -3500,8 +3510,6 @@ static int sky2_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd) ...@@ -3500,8 +3510,6 @@ static int sky2_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
sky2->flags &= ~SKY2_FLAG_AUTO_SPEED; sky2->flags &= ~SKY2_FLAG_AUTO_SPEED;
} }
sky2->advertising = ecmd->advertising;
if (netif_running(dev)) { if (netif_running(dev)) {
sky2_phy_reinit(sky2); sky2_phy_reinit(sky2);
sky2_set_multicast(dev); sky2_set_multicast(dev);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册