aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/tg3.c
diff options
context:
space:
mode:
authorMichael Chan <mchan@broadcom.com>2006-12-07 03:21:48 -0500
committerDavid S. Miller <davem@davemloft.net>2006-12-07 03:21:48 -0500
commit3600d918d870456ea8e7bb9d47f327de5c20f3d6 (patch)
tree535cef03d0a422741b4c361048f7dda54df30622 /drivers/net/tg3.c
parent9d26e213423923c9e033ccd373705118131827c9 (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.c39
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
1710static int tg3_copper_is_advertising_all(struct tg3 *tp) 1704static 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))