diff options
-rw-r--r-- | drivers/net/tg3.c | 68 |
1 files changed, 50 insertions, 18 deletions
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 774a01ab03be..0ea61f7f6203 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c | |||
@@ -8552,7 +8552,7 @@ static int tg3_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) | |||
8552 | cmd->duplex = tp->link_config.active_duplex; | 8552 | cmd->duplex = tp->link_config.active_duplex; |
8553 | } | 8553 | } |
8554 | cmd->phy_address = PHY_ADDR; | 8554 | cmd->phy_address = PHY_ADDR; |
8555 | cmd->transceiver = 0; | 8555 | cmd->transceiver = XCVR_INTERNAL; |
8556 | cmd->autoneg = tp->link_config.autoneg; | 8556 | cmd->autoneg = tp->link_config.autoneg; |
8557 | cmd->maxtxpkt = 0; | 8557 | cmd->maxtxpkt = 0; |
8558 | cmd->maxrxpkt = 0; | 8558 | cmd->maxrxpkt = 0; |
@@ -8569,26 +8569,58 @@ static int tg3_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) | |||
8569 | return phy_ethtool_sset(tp->mdio_bus->phy_map[PHY_ADDR], cmd); | 8569 | return phy_ethtool_sset(tp->mdio_bus->phy_map[PHY_ADDR], cmd); |
8570 | } | 8570 | } |
8571 | 8571 | ||
8572 | if (tp->tg3_flags2 & TG3_FLG2_ANY_SERDES) { | 8572 | if (cmd->autoneg != AUTONEG_ENABLE && |
8573 | /* These are the only valid advertisement bits allowed. */ | 8573 | cmd->autoneg != AUTONEG_DISABLE) |
8574 | if (cmd->autoneg == AUTONEG_ENABLE && | ||
8575 | (cmd->advertising & ~(ADVERTISED_1000baseT_Half | | ||
8576 | ADVERTISED_1000baseT_Full | | ||
8577 | ADVERTISED_Autoneg | | ||
8578 | ADVERTISED_FIBRE))) | ||
8579 | return -EINVAL; | ||
8580 | /* Fiber can only do SPEED_1000. */ | ||
8581 | else if ((cmd->autoneg != AUTONEG_ENABLE) && | ||
8582 | (cmd->speed != SPEED_1000)) | ||
8583 | return -EINVAL; | ||
8584 | /* Copper cannot force SPEED_1000. */ | ||
8585 | } else if ((cmd->autoneg != AUTONEG_ENABLE) && | ||
8586 | (cmd->speed == SPEED_1000)) | ||
8587 | return -EINVAL; | 8574 | return -EINVAL; |
8588 | else if ((cmd->speed == SPEED_1000) && | 8575 | |
8589 | (tp->tg3_flags & TG3_FLAG_10_100_ONLY)) | 8576 | if (cmd->autoneg == AUTONEG_DISABLE && |
8577 | cmd->duplex != DUPLEX_FULL && | ||
8578 | cmd->duplex != DUPLEX_HALF) | ||
8590 | return -EINVAL; | 8579 | return -EINVAL; |
8591 | 8580 | ||
8581 | if (cmd->autoneg == AUTONEG_ENABLE) { | ||
8582 | u32 mask = ADVERTISED_Autoneg | | ||
8583 | ADVERTISED_Pause | | ||
8584 | ADVERTISED_Asym_Pause; | ||
8585 | |||
8586 | if (!(tp->tg3_flags2 & TG3_FLAG_10_100_ONLY)) | ||
8587 | mask |= ADVERTISED_1000baseT_Half | | ||
8588 | ADVERTISED_1000baseT_Full; | ||
8589 | |||
8590 | if (!(tp->tg3_flags2 & TG3_FLG2_ANY_SERDES)) | ||
8591 | mask |= ADVERTISED_100baseT_Half | | ||
8592 | ADVERTISED_100baseT_Full | | ||
8593 | ADVERTISED_10baseT_Half | | ||
8594 | ADVERTISED_10baseT_Full | | ||
8595 | ADVERTISED_TP; | ||
8596 | else | ||
8597 | mask |= ADVERTISED_FIBRE; | ||
8598 | |||
8599 | if (cmd->advertising & ~mask) | ||
8600 | return -EINVAL; | ||
8601 | |||
8602 | mask &= (ADVERTISED_1000baseT_Half | | ||
8603 | ADVERTISED_1000baseT_Full | | ||
8604 | ADVERTISED_100baseT_Half | | ||
8605 | ADVERTISED_100baseT_Full | | ||
8606 | ADVERTISED_10baseT_Half | | ||
8607 | ADVERTISED_10baseT_Full); | ||
8608 | |||
8609 | cmd->advertising &= mask; | ||
8610 | } else { | ||
8611 | if (tp->tg3_flags2 & TG3_FLG2_ANY_SERDES) { | ||
8612 | if (cmd->speed != SPEED_1000) | ||
8613 | return -EINVAL; | ||
8614 | |||
8615 | if (cmd->duplex != DUPLEX_FULL) | ||
8616 | return -EINVAL; | ||
8617 | } else { | ||
8618 | if (cmd->speed != SPEED_100 && | ||
8619 | cmd->speed != SPEED_10) | ||
8620 | return -EINVAL; | ||
8621 | } | ||
8622 | } | ||
8623 | |||
8592 | tg3_full_lock(tp, 0); | 8624 | tg3_full_lock(tp, 0); |
8593 | 8625 | ||
8594 | tp->link_config.autoneg = cmd->autoneg; | 8626 | tp->link_config.autoneg = cmd->autoneg; |