aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/tg3.c31
-rw-r--r--drivers/net/tg3.h10
2 files changed, 33 insertions, 8 deletions
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index e64721b185d1..d0f314c6dbb0 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -1963,7 +1963,7 @@ static int tg3_halt_cpu(struct tg3 *, u32);
1963static int tg3_nvram_lock(struct tg3 *); 1963static int tg3_nvram_lock(struct tg3 *);
1964static void tg3_nvram_unlock(struct tg3 *); 1964static void tg3_nvram_unlock(struct tg3 *);
1965 1965
1966static void tg3_power_down_phy(struct tg3 *tp) 1966static void tg3_power_down_phy(struct tg3 *tp, bool do_low_power)
1967{ 1967{
1968 u32 val; 1968 u32 val;
1969 1969
@@ -1986,10 +1986,15 @@ static void tg3_power_down_phy(struct tg3 *tp)
1986 tw32_f(GRC_MISC_CFG, val | GRC_MISC_CFG_EPHY_IDDQ); 1986 tw32_f(GRC_MISC_CFG, val | GRC_MISC_CFG_EPHY_IDDQ);
1987 udelay(40); 1987 udelay(40);
1988 return; 1988 return;
1989 } else if (!(tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB)) { 1989 } else if (do_low_power) {
1990 tg3_writephy(tp, MII_TG3_EXT_CTRL, 1990 tg3_writephy(tp, MII_TG3_EXT_CTRL,
1991 MII_TG3_EXT_CTRL_FORCE_LED_OFF); 1991 MII_TG3_EXT_CTRL_FORCE_LED_OFF);
1992 tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x01b2); 1992
1993 tg3_writephy(tp, MII_TG3_AUX_CTRL,
1994 MII_TG3_AUXCTL_SHDWSEL_PWRCTL |
1995 MII_TG3_AUXCTL_PCTL_100TX_LPWR |
1996 MII_TG3_AUXCTL_PCTL_SPR_ISOLATE |
1997 MII_TG3_AUXCTL_PCTL_VREG_11V);
1993 } 1998 }
1994 1999
1995 /* The PHY should not be powered down on some chips because 2000 /* The PHY should not be powered down on some chips because
@@ -2052,7 +2057,7 @@ static void __tg3_set_mac_addr(struct tg3 *tp, int skip_mac_1)
2052static int tg3_set_power_state(struct tg3 *tp, pci_power_t state) 2057static int tg3_set_power_state(struct tg3 *tp, pci_power_t state)
2053{ 2058{
2054 u32 misc_host_ctrl; 2059 u32 misc_host_ctrl;
2055 bool device_should_wake; 2060 bool device_should_wake, do_low_power;
2056 2061
2057 /* Make sure register accesses (indirect or otherwise) 2062 /* Make sure register accesses (indirect or otherwise)
2058 * will function correctly. 2063 * will function correctly.
@@ -2091,10 +2096,11 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state)
2091 (tp->tg3_flags & TG3_FLAG_WOL_ENABLE); 2096 (tp->tg3_flags & TG3_FLAG_WOL_ENABLE);
2092 2097
2093 if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) { 2098 if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) {
2099 do_low_power = false;
2094 if ((tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED) && 2100 if ((tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED) &&
2095 !tp->link_config.phy_is_low_power) { 2101 !tp->link_config.phy_is_low_power) {
2096 struct phy_device *phydev; 2102 struct phy_device *phydev;
2097 u32 advertising; 2103 u32 phyid, advertising;
2098 2104
2099 phydev = tp->mdio_bus->phy_map[PHY_ADDR]; 2105 phydev = tp->mdio_bus->phy_map[PHY_ADDR];
2100 2106
@@ -2124,8 +2130,19 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state)
2124 phydev->advertising = advertising; 2130 phydev->advertising = advertising;
2125 2131
2126 phy_start_aneg(phydev); 2132 phy_start_aneg(phydev);
2133
2134 phyid = phydev->drv->phy_id & phydev->drv->phy_id_mask;
2135 if (phyid != TG3_PHY_ID_BCMAC131) {
2136 phyid &= TG3_PHY_OUI_MASK;
2137 if (phyid == TG3_PHY_OUI_1 &&
2138 phyid == TG3_PHY_OUI_2 &&
2139 phyid == TG3_PHY_OUI_3)
2140 do_low_power = true;
2141 }
2127 } 2142 }
2128 } else { 2143 } else {
2144 do_low_power = false;
2145
2129 if (tp->link_config.phy_is_low_power == 0) { 2146 if (tp->link_config.phy_is_low_power == 0) {
2130 tp->link_config.phy_is_low_power = 1; 2147 tp->link_config.phy_is_low_power = 1;
2131 tp->link_config.orig_speed = tp->link_config.speed; 2148 tp->link_config.orig_speed = tp->link_config.speed;
@@ -2169,7 +2186,7 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state)
2169 u32 mac_mode; 2186 u32 mac_mode;
2170 2187
2171 if (!(tp->tg3_flags2 & TG3_FLG2_PHY_SERDES)) { 2188 if (!(tp->tg3_flags2 & TG3_FLG2_PHY_SERDES)) {
2172 if (!(tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB)) { 2189 if (do_low_power) {
2173 tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x5a); 2190 tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x5a);
2174 udelay(40); 2191 udelay(40);
2175 } 2192 }
@@ -2277,7 +2294,7 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state)
2277 if (!(device_should_wake) && 2294 if (!(device_should_wake) &&
2278 !(tp->tg3_flags & TG3_FLAG_ENABLE_ASF) && 2295 !(tp->tg3_flags & TG3_FLAG_ENABLE_ASF) &&
2279 !(tp->tg3_flags3 & TG3_FLG3_ENABLE_APE)) 2296 !(tp->tg3_flags3 & TG3_FLG3_ENABLE_APE))
2280 tg3_power_down_phy(tp); 2297 tg3_power_down_phy(tp, do_low_power);
2281 2298
2282 tg3_frob_aux_power(tp); 2299 tg3_frob_aux_power(tp);
2283 2300
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h
index 417de07ca895..d7ce3a05a3e4 100644
--- a/drivers/net/tg3.h
+++ b/drivers/net/tg3.h
@@ -1795,6 +1795,11 @@
1795 1795
1796#define MII_TG3_AUX_CTRL 0x18 /* auxilliary control register */ 1796#define MII_TG3_AUX_CTRL 0x18 /* auxilliary control register */
1797 1797
1798#define MII_TG3_AUXCTL_PCTL_100TX_LPWR 0x0010
1799#define MII_TG3_AUXCTL_PCTL_SPR_ISOLATE 0x0020
1800#define MII_TG3_AUXCTL_PCTL_VREG_11V 0x0180
1801#define MII_TG3_AUXCTL_SHDWSEL_PWRCTL 0x0002
1802
1798#define MII_TG3_AUXCTL_MISC_WREN 0x8000 1803#define MII_TG3_AUXCTL_MISC_WREN 0x8000
1799#define MII_TG3_AUXCTL_MISC_FORCE_AMDIX 0x0200 1804#define MII_TG3_AUXCTL_MISC_FORCE_AMDIX 0x0200
1800#define MII_TG3_AUXCTL_MISC_RDSEL_MISC 0x7000 1805#define MII_TG3_AUXCTL_MISC_RDSEL_MISC 0x7000
@@ -2590,7 +2595,10 @@ struct tg3 {
2590#define PHY_REV_BCM5411_X0 0x1 /* Found on Netgear GA302T */ 2595#define PHY_REV_BCM5411_X0 0x1 /* Found on Netgear GA302T */
2591#define TG3_PHY_ID_BCM50610 0x143bd60 2596#define TG3_PHY_ID_BCM50610 0x143bd60
2592#define TG3_PHY_ID_BCMAC131 0x143bc70 2597#define TG3_PHY_ID_BCMAC131 0x143bc70
2593 2598#define TG3_PHY_OUI_MASK 0xfffffc00
2599#define TG3_PHY_OUI_1 0x00206000
2600#define TG3_PHY_OUI_2 0x0143bc00
2601#define TG3_PHY_OUI_3 0x03625c00
2594 2602
2595 u32 led_ctrl; 2603 u32 led_ctrl;
2596 u32 phy_otp; 2604 u32 phy_otp;