aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/tg3.c68
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;