[PATCH] skge: cleanup ethtool mode support
Unify mapping of supported modes based on hardware. Signed-off-by: Stephen Hemminger <shemminger@osdl.org>
This commit is contained in:
parent
89bf5f231f
commit
31b619c5ab
|
@ -179,6 +179,36 @@ static int skge_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Determine supported/adverised modes based on hardware.
|
||||||
|
* Note: ethtoool ADVERTISED_xxx == SUPPORTED_xxx
|
||||||
|
*/
|
||||||
|
static u32 skge_supported_modes(const struct skge_hw *hw)
|
||||||
|
{
|
||||||
|
u32 supported;
|
||||||
|
|
||||||
|
if (iscopper(hw)) {
|
||||||
|
supported = SUPPORTED_10baseT_Half
|
||||||
|
| SUPPORTED_10baseT_Full
|
||||||
|
| SUPPORTED_100baseT_Half
|
||||||
|
| SUPPORTED_100baseT_Full
|
||||||
|
| SUPPORTED_1000baseT_Half
|
||||||
|
| SUPPORTED_1000baseT_Full
|
||||||
|
| SUPPORTED_Autoneg| SUPPORTED_TP;
|
||||||
|
|
||||||
|
if (hw->chip_id == CHIP_ID_GENESIS)
|
||||||
|
supported &= ~(SUPPORTED_10baseT_Half
|
||||||
|
| SUPPORTED_10baseT_Full
|
||||||
|
| SUPPORTED_100baseT_Half
|
||||||
|
| SUPPORTED_100baseT_Full);
|
||||||
|
|
||||||
|
else if (hw->chip_id == CHIP_ID_YUKON)
|
||||||
|
supported &= ~SUPPORTED_1000baseT_Half;
|
||||||
|
} else
|
||||||
|
supported = SUPPORTED_1000baseT_Full | SUPPORTED_FIBRE
|
||||||
|
| SUPPORTED_Autoneg;
|
||||||
|
|
||||||
|
return supported;
|
||||||
|
}
|
||||||
|
|
||||||
static int skge_get_settings(struct net_device *dev,
|
static int skge_get_settings(struct net_device *dev,
|
||||||
struct ethtool_cmd *ecmd)
|
struct ethtool_cmd *ecmd)
|
||||||
|
@ -187,35 +217,13 @@ static int skge_get_settings(struct net_device *dev,
|
||||||
struct skge_hw *hw = skge->hw;
|
struct skge_hw *hw = skge->hw;
|
||||||
|
|
||||||
ecmd->transceiver = XCVR_INTERNAL;
|
ecmd->transceiver = XCVR_INTERNAL;
|
||||||
|
ecmd->supported = skge_supported_modes(hw);
|
||||||
|
|
||||||
if (iscopper(hw)) {
|
if (iscopper(hw)) {
|
||||||
if (hw->chip_id == CHIP_ID_GENESIS)
|
|
||||||
ecmd->supported = SUPPORTED_1000baseT_Full
|
|
||||||
| SUPPORTED_1000baseT_Half
|
|
||||||
| SUPPORTED_Autoneg | SUPPORTED_TP;
|
|
||||||
else {
|
|
||||||
ecmd->supported = SUPPORTED_10baseT_Half
|
|
||||||
| SUPPORTED_10baseT_Full
|
|
||||||
| SUPPORTED_100baseT_Half
|
|
||||||
| SUPPORTED_100baseT_Full
|
|
||||||
| SUPPORTED_1000baseT_Half
|
|
||||||
| SUPPORTED_1000baseT_Full
|
|
||||||
| SUPPORTED_Autoneg| SUPPORTED_TP;
|
|
||||||
|
|
||||||
if (hw->chip_id == CHIP_ID_YUKON)
|
|
||||||
ecmd->supported &= ~SUPPORTED_1000baseT_Half;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
ecmd->port = PORT_TP;
|
ecmd->port = PORT_TP;
|
||||||
ecmd->phy_address = hw->phy_addr;
|
ecmd->phy_address = hw->phy_addr;
|
||||||
} else {
|
} else
|
||||||
ecmd->supported = SUPPORTED_1000baseT_Full
|
|
||||||
| SUPPORTED_FIBRE
|
|
||||||
| SUPPORTED_Autoneg;
|
|
||||||
|
|
||||||
ecmd->port = PORT_FIBRE;
|
ecmd->port = PORT_FIBRE;
|
||||||
}
|
|
||||||
|
|
||||||
ecmd->advertising = skge->advertising;
|
ecmd->advertising = skge->advertising;
|
||||||
ecmd->autoneg = skge->autoneg;
|
ecmd->autoneg = skge->autoneg;
|
||||||
|
@ -224,60 +232,57 @@ static int skge_get_settings(struct net_device *dev,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static u32 skge_modes(const struct skge_hw *hw)
|
|
||||||
{
|
|
||||||
u32 modes = ADVERTISED_Autoneg
|
|
||||||
| ADVERTISED_1000baseT_Full | ADVERTISED_1000baseT_Half
|
|
||||||
| ADVERTISED_100baseT_Full | ADVERTISED_100baseT_Half
|
|
||||||
| ADVERTISED_10baseT_Full | ADVERTISED_10baseT_Half;
|
|
||||||
|
|
||||||
if (iscopper(hw)) {
|
|
||||||
modes |= ADVERTISED_TP;
|
|
||||||
switch (hw->chip_id) {
|
|
||||||
case CHIP_ID_GENESIS:
|
|
||||||
modes &= ~(ADVERTISED_100baseT_Full
|
|
||||||
| ADVERTISED_100baseT_Half
|
|
||||||
| ADVERTISED_10baseT_Full
|
|
||||||
| ADVERTISED_10baseT_Half);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CHIP_ID_YUKON:
|
|
||||||
modes &= ~ADVERTISED_1000baseT_Half;
|
|
||||||
break;
|
|
||||||
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
modes |= ADVERTISED_FIBRE;
|
|
||||||
modes &= ~ADVERTISED_1000baseT_Half;
|
|
||||||
}
|
|
||||||
return modes;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int skge_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
|
static int skge_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
|
||||||
{
|
{
|
||||||
struct skge_port *skge = netdev_priv(dev);
|
struct skge_port *skge = netdev_priv(dev);
|
||||||
const struct skge_hw *hw = skge->hw;
|
const struct skge_hw *hw = skge->hw;
|
||||||
|
u32 supported = skge_supported_modes(hw);
|
||||||
|
|
||||||
if (ecmd->autoneg == AUTONEG_ENABLE) {
|
if (ecmd->autoneg == AUTONEG_ENABLE) {
|
||||||
if (ecmd->advertising & skge_modes(hw))
|
ecmd->advertising = supported;
|
||||||
return -EINVAL;
|
skge->duplex = -1;
|
||||||
|
skge->speed = -1;
|
||||||
} else {
|
} else {
|
||||||
switch (ecmd->speed) {
|
u32 setting;
|
||||||
|
|
||||||
|
switch(ecmd->speed) {
|
||||||
case SPEED_1000:
|
case SPEED_1000:
|
||||||
|
if (ecmd->duplex == DUPLEX_FULL)
|
||||||
|
setting = SUPPORTED_1000baseT_Full;
|
||||||
|
else if (ecmd->duplex == DUPLEX_HALF)
|
||||||
|
setting = SUPPORTED_1000baseT_Half;
|
||||||
|
else
|
||||||
|
return -EINVAL;
|
||||||
break;
|
break;
|
||||||
case SPEED_100:
|
case SPEED_100:
|
||||||
|
if (ecmd->duplex == DUPLEX_FULL)
|
||||||
|
setting = SUPPORTED_100baseT_Full;
|
||||||
|
else if (ecmd->duplex == DUPLEX_HALF)
|
||||||
|
setting = SUPPORTED_100baseT_Half;
|
||||||
|
else
|
||||||
|
return -EINVAL;
|
||||||
|
break;
|
||||||
|
|
||||||
case SPEED_10:
|
case SPEED_10:
|
||||||
if (iscopper(hw) || hw->chip_id == CHIP_ID_GENESIS)
|
if (ecmd->duplex == DUPLEX_FULL)
|
||||||
|
setting = SUPPORTED_10baseT_Full;
|
||||||
|
else if (ecmd->duplex == DUPLEX_HALF)
|
||||||
|
setting = SUPPORTED_10baseT_Half;
|
||||||
|
else
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((setting & supported) == 0)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
skge->speed = ecmd->speed;
|
||||||
|
skge->duplex = ecmd->duplex;
|
||||||
}
|
}
|
||||||
|
|
||||||
skge->autoneg = ecmd->autoneg;
|
skge->autoneg = ecmd->autoneg;
|
||||||
skge->speed = ecmd->speed;
|
|
||||||
skge->duplex = ecmd->duplex;
|
|
||||||
skge->advertising = ecmd->advertising;
|
skge->advertising = ecmd->advertising;
|
||||||
|
|
||||||
if (netif_running(dev)) {
|
if (netif_running(dev)) {
|
||||||
|
@ -2973,7 +2978,7 @@ static struct net_device *skge_devinit(struct skge_hw *hw, int port,
|
||||||
skge->flow_control = FLOW_MODE_SYMMETRIC;
|
skge->flow_control = FLOW_MODE_SYMMETRIC;
|
||||||
skge->duplex = -1;
|
skge->duplex = -1;
|
||||||
skge->speed = -1;
|
skge->speed = -1;
|
||||||
skge->advertising = skge_modes(hw);
|
skge->advertising = skge_supported_modes(hw);
|
||||||
|
|
||||||
hw->dev[port] = dev;
|
hw->dev[port] = dev;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue