Commit 0a459aac authored by Matt Carlson's avatar Matt Carlson Committed by David S. Miller

tg3: Allow WOL for phylib controlled Broadcom phys

This patch allows WOL to be enabled for Broadcom phys under phylib
control.  The only exception is the AC131, which has a completely
different register set.
Signed-off-by: default avatarMatt Carlson <mcarlson@broadcom.com>
Signed-off-by: default avatarMichael Chan <mchan@broadcom.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 05ac4cb7
...@@ -1963,7 +1963,7 @@ static int tg3_halt_cpu(struct tg3 *, u32); ...@@ -1963,7 +1963,7 @@ static int tg3_halt_cpu(struct tg3 *, u32);
static int tg3_nvram_lock(struct tg3 *); static int tg3_nvram_lock(struct tg3 *);
static void tg3_nvram_unlock(struct tg3 *); static void tg3_nvram_unlock(struct tg3 *);
static void tg3_power_down_phy(struct tg3 *tp) static void tg3_power_down_phy(struct tg3 *tp, bool do_low_power)
{ {
u32 val; u32 val;
...@@ -1986,10 +1986,15 @@ static void tg3_power_down_phy(struct tg3 *tp) ...@@ -1986,10 +1986,15 @@ static void tg3_power_down_phy(struct tg3 *tp)
tw32_f(GRC_MISC_CFG, val | GRC_MISC_CFG_EPHY_IDDQ); tw32_f(GRC_MISC_CFG, val | GRC_MISC_CFG_EPHY_IDDQ);
udelay(40); udelay(40);
return; return;
} else if (!(tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB)) { } else if (do_low_power) {
tg3_writephy(tp, MII_TG3_EXT_CTRL, tg3_writephy(tp, MII_TG3_EXT_CTRL,
MII_TG3_EXT_CTRL_FORCE_LED_OFF); MII_TG3_EXT_CTRL_FORCE_LED_OFF);
tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x01b2);
tg3_writephy(tp, MII_TG3_AUX_CTRL,
MII_TG3_AUXCTL_SHDWSEL_PWRCTL |
MII_TG3_AUXCTL_PCTL_100TX_LPWR |
MII_TG3_AUXCTL_PCTL_SPR_ISOLATE |
MII_TG3_AUXCTL_PCTL_VREG_11V);
} }
/* The PHY should not be powered down on some chips because /* 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) ...@@ -2052,7 +2057,7 @@ static void __tg3_set_mac_addr(struct tg3 *tp, int skip_mac_1)
static int tg3_set_power_state(struct tg3 *tp, pci_power_t state) static int tg3_set_power_state(struct tg3 *tp, pci_power_t state)
{ {
u32 misc_host_ctrl; u32 misc_host_ctrl;
bool device_should_wake; bool device_should_wake, do_low_power;
/* Make sure register accesses (indirect or otherwise) /* Make sure register accesses (indirect or otherwise)
* will function correctly. * will function correctly.
...@@ -2091,10 +2096,11 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state) ...@@ -2091,10 +2096,11 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state)
(tp->tg3_flags & TG3_FLAG_WOL_ENABLE); (tp->tg3_flags & TG3_FLAG_WOL_ENABLE);
if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) { if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) {
do_low_power = false;
if ((tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED) && if ((tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED) &&
!tp->link_config.phy_is_low_power) { !tp->link_config.phy_is_low_power) {
struct phy_device *phydev; struct phy_device *phydev;
u32 advertising; u32 phyid, advertising;
phydev = tp->mdio_bus->phy_map[PHY_ADDR]; phydev = tp->mdio_bus->phy_map[PHY_ADDR];
...@@ -2124,8 +2130,19 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state) ...@@ -2124,8 +2130,19 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state)
phydev->advertising = advertising; phydev->advertising = advertising;
phy_start_aneg(phydev); phy_start_aneg(phydev);
phyid = phydev->drv->phy_id & phydev->drv->phy_id_mask;
if (phyid != TG3_PHY_ID_BCMAC131) {
phyid &= TG3_PHY_OUI_MASK;
if (phyid == TG3_PHY_OUI_1 &&
phyid == TG3_PHY_OUI_2 &&
phyid == TG3_PHY_OUI_3)
do_low_power = true;
}
} }
} else { } else {
do_low_power = false;
if (tp->link_config.phy_is_low_power == 0) { if (tp->link_config.phy_is_low_power == 0) {
tp->link_config.phy_is_low_power = 1; tp->link_config.phy_is_low_power = 1;
tp->link_config.orig_speed = tp->link_config.speed; 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,7 +2186,7 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state)
u32 mac_mode; u32 mac_mode;
if (!(tp->tg3_flags2 & TG3_FLG2_PHY_SERDES)) { if (!(tp->tg3_flags2 & TG3_FLG2_PHY_SERDES)) {
if (!(tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB)) { if (do_low_power) {
tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x5a); tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x5a);
udelay(40); udelay(40);
} }
...@@ -2277,7 +2294,7 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state) ...@@ -2277,7 +2294,7 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state)
if (!(device_should_wake) && if (!(device_should_wake) &&
!(tp->tg3_flags & TG3_FLAG_ENABLE_ASF) && !(tp->tg3_flags & TG3_FLAG_ENABLE_ASF) &&
!(tp->tg3_flags3 & TG3_FLG3_ENABLE_APE)) !(tp->tg3_flags3 & TG3_FLG3_ENABLE_APE))
tg3_power_down_phy(tp); tg3_power_down_phy(tp, do_low_power);
tg3_frob_aux_power(tp); tg3_frob_aux_power(tp);
......
...@@ -1795,6 +1795,11 @@ ...@@ -1795,6 +1795,11 @@
#define MII_TG3_AUX_CTRL 0x18 /* auxilliary control register */ #define MII_TG3_AUX_CTRL 0x18 /* auxilliary control register */
#define MII_TG3_AUXCTL_PCTL_100TX_LPWR 0x0010
#define MII_TG3_AUXCTL_PCTL_SPR_ISOLATE 0x0020
#define MII_TG3_AUXCTL_PCTL_VREG_11V 0x0180
#define MII_TG3_AUXCTL_SHDWSEL_PWRCTL 0x0002
#define MII_TG3_AUXCTL_MISC_WREN 0x8000 #define MII_TG3_AUXCTL_MISC_WREN 0x8000
#define MII_TG3_AUXCTL_MISC_FORCE_AMDIX 0x0200 #define MII_TG3_AUXCTL_MISC_FORCE_AMDIX 0x0200
#define MII_TG3_AUXCTL_MISC_RDSEL_MISC 0x7000 #define MII_TG3_AUXCTL_MISC_RDSEL_MISC 0x7000
...@@ -2590,7 +2595,10 @@ struct tg3 { ...@@ -2590,7 +2595,10 @@ struct tg3 {
#define PHY_REV_BCM5411_X0 0x1 /* Found on Netgear GA302T */ #define PHY_REV_BCM5411_X0 0x1 /* Found on Netgear GA302T */
#define TG3_PHY_ID_BCM50610 0x143bd60 #define TG3_PHY_ID_BCM50610 0x143bd60
#define TG3_PHY_ID_BCMAC131 0x143bc70 #define TG3_PHY_ID_BCMAC131 0x143bc70
#define TG3_PHY_OUI_MASK 0xfffffc00
#define TG3_PHY_OUI_1 0x00206000
#define TG3_PHY_OUI_2 0x0143bc00
#define TG3_PHY_OUI_3 0x03625c00
u32 led_ctrl; u32 led_ctrl;
u32 phy_otp; u32 phy_otp;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment