diff options
author | Michael Chan <mchan@broadcom.com> | 2006-12-07 03:21:48 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2006-12-07 03:21:48 -0500 |
commit | 3600d918d870456ea8e7bb9d47f327de5c20f3d6 (patch) | |
tree | 535cef03d0a422741b4c361048f7dda54df30622 /drivers/net/tg3.c | |
parent | 9d26e213423923c9e033ccd373705118131827c9 (diff) |
[TG3]: Allow partial speed advertisement.
Honor the advertisement bitmask from ethtool. We used to always
advertise the full capability when autoneg was set to on.
Signed-off-by: Michael Chan <mchan@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/tg3.c')
-rw-r--r-- | drivers/net/tg3.c | 39 |
1 files changed, 24 insertions, 15 deletions
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 16bc05fe531f..576e9ea0a566 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c | |||
@@ -1558,12 +1558,6 @@ static void tg3_phy_copper_begin(struct tg3 *tp) | |||
1558 | 1558 | ||
1559 | tg3_writephy(tp, MII_ADVERTISE, new_adv); | 1559 | tg3_writephy(tp, MII_ADVERTISE, new_adv); |
1560 | } else if (tp->link_config.speed == SPEED_INVALID) { | 1560 | } else if (tp->link_config.speed == SPEED_INVALID) { |
1561 | tp->link_config.advertising = | ||
1562 | (ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full | | ||
1563 | ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full | | ||
1564 | ADVERTISED_1000baseT_Half | ADVERTISED_1000baseT_Full | | ||
1565 | ADVERTISED_Autoneg | ADVERTISED_MII); | ||
1566 | |||
1567 | if (tp->tg3_flags & TG3_FLAG_10_100_ONLY) | 1561 | if (tp->tg3_flags & TG3_FLAG_10_100_ONLY) |
1568 | tp->link_config.advertising &= | 1562 | tp->link_config.advertising &= |
1569 | ~(ADVERTISED_1000baseT_Half | | 1563 | ~(ADVERTISED_1000baseT_Half | |
@@ -1707,25 +1701,36 @@ static int tg3_init_5401phy_dsp(struct tg3 *tp) | |||
1707 | return err; | 1701 | return err; |
1708 | } | 1702 | } |
1709 | 1703 | ||
1710 | static int tg3_copper_is_advertising_all(struct tg3 *tp) | 1704 | static int tg3_copper_is_advertising_all(struct tg3 *tp, u32 mask) |
1711 | { | 1705 | { |
1712 | u32 adv_reg, all_mask; | 1706 | u32 adv_reg, all_mask = 0; |
1707 | |||
1708 | if (mask & ADVERTISED_10baseT_Half) | ||
1709 | all_mask |= ADVERTISE_10HALF; | ||
1710 | if (mask & ADVERTISED_10baseT_Full) | ||
1711 | all_mask |= ADVERTISE_10FULL; | ||
1712 | if (mask & ADVERTISED_100baseT_Half) | ||
1713 | all_mask |= ADVERTISE_100HALF; | ||
1714 | if (mask & ADVERTISED_100baseT_Full) | ||
1715 | all_mask |= ADVERTISE_100FULL; | ||
1713 | 1716 | ||
1714 | if (tg3_readphy(tp, MII_ADVERTISE, &adv_reg)) | 1717 | if (tg3_readphy(tp, MII_ADVERTISE, &adv_reg)) |
1715 | return 0; | 1718 | return 0; |
1716 | 1719 | ||
1717 | all_mask = (ADVERTISE_10HALF | ADVERTISE_10FULL | | ||
1718 | ADVERTISE_100HALF | ADVERTISE_100FULL); | ||
1719 | if ((adv_reg & all_mask) != all_mask) | 1720 | if ((adv_reg & all_mask) != all_mask) |
1720 | return 0; | 1721 | return 0; |
1721 | if (!(tp->tg3_flags & TG3_FLAG_10_100_ONLY)) { | 1722 | if (!(tp->tg3_flags & TG3_FLAG_10_100_ONLY)) { |
1722 | u32 tg3_ctrl; | 1723 | u32 tg3_ctrl; |
1723 | 1724 | ||
1725 | all_mask = 0; | ||
1726 | if (mask & ADVERTISED_1000baseT_Half) | ||
1727 | all_mask |= ADVERTISE_1000HALF; | ||
1728 | if (mask & ADVERTISED_1000baseT_Full) | ||
1729 | all_mask |= ADVERTISE_1000FULL; | ||
1730 | |||
1724 | if (tg3_readphy(tp, MII_TG3_CTRL, &tg3_ctrl)) | 1731 | if (tg3_readphy(tp, MII_TG3_CTRL, &tg3_ctrl)) |
1725 | return 0; | 1732 | return 0; |
1726 | 1733 | ||
1727 | all_mask = (MII_TG3_CTRL_ADV_1000_HALF | | ||
1728 | MII_TG3_CTRL_ADV_1000_FULL); | ||
1729 | if ((tg3_ctrl & all_mask) != all_mask) | 1734 | if ((tg3_ctrl & all_mask) != all_mask) |
1730 | return 0; | 1735 | return 0; |
1731 | } | 1736 | } |
@@ -1885,7 +1890,8 @@ static int tg3_setup_copper_phy(struct tg3 *tp, int force_reset) | |||
1885 | /* Force autoneg restart if we are exiting | 1890 | /* Force autoneg restart if we are exiting |
1886 | * low power mode. | 1891 | * low power mode. |
1887 | */ | 1892 | */ |
1888 | if (!tg3_copper_is_advertising_all(tp)) | 1893 | if (!tg3_copper_is_advertising_all(tp, |
1894 | tp->link_config.advertising)) | ||
1889 | current_link_up = 0; | 1895 | current_link_up = 0; |
1890 | } else { | 1896 | } else { |
1891 | current_link_up = 0; | 1897 | current_link_up = 0; |
@@ -10156,7 +10162,7 @@ static int __devinit tg3_phy_probe(struct tg3 *tp) | |||
10156 | 10162 | ||
10157 | if (!(tp->tg3_flags2 & TG3_FLG2_ANY_SERDES) && | 10163 | if (!(tp->tg3_flags2 & TG3_FLG2_ANY_SERDES) && |
10158 | !(tp->tg3_flags & TG3_FLAG_ENABLE_ASF)) { | 10164 | !(tp->tg3_flags & TG3_FLAG_ENABLE_ASF)) { |
10159 | u32 bmsr, adv_reg, tg3_ctrl; | 10165 | u32 bmsr, adv_reg, tg3_ctrl, mask; |
10160 | 10166 | ||
10161 | tg3_readphy(tp, MII_BMSR, &bmsr); | 10167 | tg3_readphy(tp, MII_BMSR, &bmsr); |
10162 | if (!tg3_readphy(tp, MII_BMSR, &bmsr) && | 10168 | if (!tg3_readphy(tp, MII_BMSR, &bmsr) && |
@@ -10180,7 +10186,10 @@ static int __devinit tg3_phy_probe(struct tg3 *tp) | |||
10180 | MII_TG3_CTRL_ENABLE_AS_MASTER); | 10186 | MII_TG3_CTRL_ENABLE_AS_MASTER); |
10181 | } | 10187 | } |
10182 | 10188 | ||
10183 | if (!tg3_copper_is_advertising_all(tp)) { | 10189 | mask = (ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full | |
10190 | ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full | | ||
10191 | ADVERTISED_1000baseT_Half | ADVERTISED_1000baseT_Full); | ||
10192 | if (!tg3_copper_is_advertising_all(tp, mask)) { | ||
10184 | tg3_writephy(tp, MII_ADVERTISE, adv_reg); | 10193 | tg3_writephy(tp, MII_ADVERTISE, adv_reg); |
10185 | 10194 | ||
10186 | if (!(tp->tg3_flags & TG3_FLAG_10_100_ONLY)) | 10195 | if (!(tp->tg3_flags & TG3_FLAG_10_100_ONLY)) |