diff options
-rw-r--r-- | drivers/net/ethernet/broadcom/genet/bcmgenet.c | 34 | ||||
-rw-r--r-- | drivers/net/ethernet/broadcom/genet/bcmgenet.h | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/broadcom/genet/bcmmii.c | 29 |
3 files changed, 47 insertions, 18 deletions
diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c index 12956b143b11..c38d5429e27a 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c | |||
@@ -847,9 +847,10 @@ static struct ethtool_ops bcmgenet_ethtool_ops = { | |||
847 | }; | 847 | }; |
848 | 848 | ||
849 | /* Power down the unimac, based on mode. */ | 849 | /* Power down the unimac, based on mode. */ |
850 | static void bcmgenet_power_down(struct bcmgenet_priv *priv, | 850 | static int bcmgenet_power_down(struct bcmgenet_priv *priv, |
851 | enum bcmgenet_power_mode mode) | 851 | enum bcmgenet_power_mode mode) |
852 | { | 852 | { |
853 | int ret = 0; | ||
853 | u32 reg; | 854 | u32 reg; |
854 | 855 | ||
855 | switch (mode) { | 856 | switch (mode) { |
@@ -858,7 +859,7 @@ static void bcmgenet_power_down(struct bcmgenet_priv *priv, | |||
858 | break; | 859 | break; |
859 | 860 | ||
860 | case GENET_POWER_WOL_MAGIC: | 861 | case GENET_POWER_WOL_MAGIC: |
861 | bcmgenet_wol_power_down_cfg(priv, mode); | 862 | ret = bcmgenet_wol_power_down_cfg(priv, mode); |
862 | break; | 863 | break; |
863 | 864 | ||
864 | case GENET_POWER_PASSIVE: | 865 | case GENET_POWER_PASSIVE: |
@@ -868,11 +869,15 @@ static void bcmgenet_power_down(struct bcmgenet_priv *priv, | |||
868 | reg |= (EXT_PWR_DOWN_PHY | | 869 | reg |= (EXT_PWR_DOWN_PHY | |
869 | EXT_PWR_DOWN_DLL | EXT_PWR_DOWN_BIAS); | 870 | EXT_PWR_DOWN_DLL | EXT_PWR_DOWN_BIAS); |
870 | bcmgenet_ext_writel(priv, reg, EXT_EXT_PWR_MGMT); | 871 | bcmgenet_ext_writel(priv, reg, EXT_EXT_PWR_MGMT); |
872 | |||
873 | bcmgenet_phy_power_set(priv->dev, false); | ||
871 | } | 874 | } |
872 | break; | 875 | break; |
873 | default: | 876 | default: |
874 | break; | 877 | break; |
875 | } | 878 | } |
879 | |||
880 | return 0; | ||
876 | } | 881 | } |
877 | 882 | ||
878 | static void bcmgenet_power_up(struct bcmgenet_priv *priv, | 883 | static void bcmgenet_power_up(struct bcmgenet_priv *priv, |
@@ -2462,9 +2467,6 @@ static void bcmgenet_netif_start(struct net_device *dev) | |||
2462 | 2467 | ||
2463 | umac_enable_set(priv, CMD_TX_EN | CMD_RX_EN, true); | 2468 | umac_enable_set(priv, CMD_TX_EN | CMD_RX_EN, true); |
2464 | 2469 | ||
2465 | if (phy_is_internal(priv->phydev)) | ||
2466 | bcmgenet_power_up(priv, GENET_POWER_PASSIVE); | ||
2467 | |||
2468 | netif_tx_start_all_queues(dev); | 2470 | netif_tx_start_all_queues(dev); |
2469 | 2471 | ||
2470 | phy_start(priv->phydev); | 2472 | phy_start(priv->phydev); |
@@ -2483,6 +2485,12 @@ static int bcmgenet_open(struct net_device *dev) | |||
2483 | if (!IS_ERR(priv->clk)) | 2485 | if (!IS_ERR(priv->clk)) |
2484 | clk_prepare_enable(priv->clk); | 2486 | clk_prepare_enable(priv->clk); |
2485 | 2487 | ||
2488 | /* If this is an internal GPHY, power it back on now, before UniMAC is | ||
2489 | * brought out of reset as absolutely no UniMAC activity is allowed | ||
2490 | */ | ||
2491 | if (phy_is_internal(priv->phydev)) | ||
2492 | bcmgenet_power_up(priv, GENET_POWER_PASSIVE); | ||
2493 | |||
2486 | /* take MAC out of reset */ | 2494 | /* take MAC out of reset */ |
2487 | bcmgenet_umac_reset(priv); | 2495 | bcmgenet_umac_reset(priv); |
2488 | 2496 | ||
@@ -2606,12 +2614,12 @@ static int bcmgenet_close(struct net_device *dev) | |||
2606 | free_irq(priv->irq1, priv); | 2614 | free_irq(priv->irq1, priv); |
2607 | 2615 | ||
2608 | if (phy_is_internal(priv->phydev)) | 2616 | if (phy_is_internal(priv->phydev)) |
2609 | bcmgenet_power_down(priv, GENET_POWER_PASSIVE); | 2617 | ret = bcmgenet_power_down(priv, GENET_POWER_PASSIVE); |
2610 | 2618 | ||
2611 | if (!IS_ERR(priv->clk)) | 2619 | if (!IS_ERR(priv->clk)) |
2612 | clk_disable_unprepare(priv->clk); | 2620 | clk_disable_unprepare(priv->clk); |
2613 | 2621 | ||
2614 | return 0; | 2622 | return ret; |
2615 | } | 2623 | } |
2616 | 2624 | ||
2617 | static void bcmgenet_timeout(struct net_device *dev) | 2625 | static void bcmgenet_timeout(struct net_device *dev) |
@@ -3097,14 +3105,16 @@ static int bcmgenet_suspend(struct device *d) | |||
3097 | 3105 | ||
3098 | /* Prepare the device for Wake-on-LAN and switch to the slow clock */ | 3106 | /* Prepare the device for Wake-on-LAN and switch to the slow clock */ |
3099 | if (device_may_wakeup(d) && priv->wolopts) { | 3107 | if (device_may_wakeup(d) && priv->wolopts) { |
3100 | bcmgenet_power_down(priv, GENET_POWER_WOL_MAGIC); | 3108 | ret = bcmgenet_power_down(priv, GENET_POWER_WOL_MAGIC); |
3101 | clk_prepare_enable(priv->clk_wol); | 3109 | clk_prepare_enable(priv->clk_wol); |
3110 | } else if (phy_is_internal(priv->phydev)) { | ||
3111 | ret = bcmgenet_power_down(priv, GENET_POWER_PASSIVE); | ||
3102 | } | 3112 | } |
3103 | 3113 | ||
3104 | /* Turn off the clocks */ | 3114 | /* Turn off the clocks */ |
3105 | clk_disable_unprepare(priv->clk); | 3115 | clk_disable_unprepare(priv->clk); |
3106 | 3116 | ||
3107 | return 0; | 3117 | return ret; |
3108 | } | 3118 | } |
3109 | 3119 | ||
3110 | static int bcmgenet_resume(struct device *d) | 3120 | static int bcmgenet_resume(struct device *d) |
@@ -3123,6 +3133,12 @@ static int bcmgenet_resume(struct device *d) | |||
3123 | if (ret) | 3133 | if (ret) |
3124 | return ret; | 3134 | return ret; |
3125 | 3135 | ||
3136 | /* If this is an internal GPHY, power it back on now, before UniMAC is | ||
3137 | * brought out of reset as absolutely no UniMAC activity is allowed | ||
3138 | */ | ||
3139 | if (phy_is_internal(priv->phydev)) | ||
3140 | bcmgenet_power_up(priv, GENET_POWER_PASSIVE); | ||
3141 | |||
3126 | bcmgenet_umac_reset(priv); | 3142 | bcmgenet_umac_reset(priv); |
3127 | 3143 | ||
3128 | ret = init_umac(priv); | 3144 | ret = init_umac(priv); |
diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.h b/drivers/net/ethernet/broadcom/genet/bcmgenet.h index 1ea838946318..7a59879d441f 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.h +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.h | |||
@@ -354,6 +354,7 @@ struct bcmgenet_mib_counters { | |||
354 | #define EXT_GPHY_CTRL 0x1C | 354 | #define EXT_GPHY_CTRL 0x1C |
355 | #define EXT_CFG_IDDQ_BIAS (1 << 0) | 355 | #define EXT_CFG_IDDQ_BIAS (1 << 0) |
356 | #define EXT_CFG_PWR_DOWN (1 << 1) | 356 | #define EXT_CFG_PWR_DOWN (1 << 1) |
357 | #define EXT_CK25_DIS (1 << 4) | ||
357 | #define EXT_GPHY_RESET (1 << 5) | 358 | #define EXT_GPHY_RESET (1 << 5) |
358 | 359 | ||
359 | /* DMA rings size */ | 360 | /* DMA rings size */ |
@@ -663,6 +664,7 @@ int bcmgenet_mii_init(struct net_device *dev); | |||
663 | int bcmgenet_mii_config(struct net_device *dev, bool init); | 664 | int bcmgenet_mii_config(struct net_device *dev, bool init); |
664 | void bcmgenet_mii_exit(struct net_device *dev); | 665 | void bcmgenet_mii_exit(struct net_device *dev); |
665 | void bcmgenet_mii_reset(struct net_device *dev); | 666 | void bcmgenet_mii_reset(struct net_device *dev); |
667 | void bcmgenet_phy_power_set(struct net_device *dev, bool enable); | ||
666 | void bcmgenet_mii_setup(struct net_device *dev); | 668 | void bcmgenet_mii_setup(struct net_device *dev); |
667 | 669 | ||
668 | /* Wake-on-LAN routines */ | 670 | /* Wake-on-LAN routines */ |
diff --git a/drivers/net/ethernet/broadcom/genet/bcmmii.c b/drivers/net/ethernet/broadcom/genet/bcmmii.c index 446889cc3c6a..6d3b66a103cc 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmmii.c +++ b/drivers/net/ethernet/broadcom/genet/bcmmii.c | |||
@@ -168,7 +168,7 @@ void bcmgenet_mii_reset(struct net_device *dev) | |||
168 | } | 168 | } |
169 | } | 169 | } |
170 | 170 | ||
171 | static void bcmgenet_ephy_power_up(struct net_device *dev) | 171 | void bcmgenet_phy_power_set(struct net_device *dev, bool enable) |
172 | { | 172 | { |
173 | struct bcmgenet_priv *priv = netdev_priv(dev); | 173 | struct bcmgenet_priv *priv = netdev_priv(dev); |
174 | u32 reg = 0; | 174 | u32 reg = 0; |
@@ -178,14 +178,25 @@ static void bcmgenet_ephy_power_up(struct net_device *dev) | |||
178 | return; | 178 | return; |
179 | 179 | ||
180 | reg = bcmgenet_ext_readl(priv, EXT_GPHY_CTRL); | 180 | reg = bcmgenet_ext_readl(priv, EXT_GPHY_CTRL); |
181 | reg &= ~(EXT_CFG_IDDQ_BIAS | EXT_CFG_PWR_DOWN); | 181 | if (enable) { |
182 | reg |= EXT_GPHY_RESET; | 182 | reg &= ~EXT_CK25_DIS; |
183 | bcmgenet_ext_writel(priv, reg, EXT_GPHY_CTRL); | 183 | bcmgenet_ext_writel(priv, reg, EXT_GPHY_CTRL); |
184 | mdelay(2); | 184 | mdelay(1); |
185 | |||
186 | reg &= ~(EXT_CFG_IDDQ_BIAS | EXT_CFG_PWR_DOWN); | ||
187 | reg |= EXT_GPHY_RESET; | ||
188 | bcmgenet_ext_writel(priv, reg, EXT_GPHY_CTRL); | ||
189 | mdelay(1); | ||
185 | 190 | ||
186 | reg &= ~EXT_GPHY_RESET; | 191 | reg &= ~EXT_GPHY_RESET; |
192 | } else { | ||
193 | reg |= EXT_CFG_IDDQ_BIAS | EXT_CFG_PWR_DOWN | EXT_GPHY_RESET; | ||
194 | bcmgenet_ext_writel(priv, reg, EXT_GPHY_CTRL); | ||
195 | mdelay(1); | ||
196 | reg |= EXT_CK25_DIS; | ||
197 | } | ||
187 | bcmgenet_ext_writel(priv, reg, EXT_GPHY_CTRL); | 198 | bcmgenet_ext_writel(priv, reg, EXT_GPHY_CTRL); |
188 | udelay(20); | 199 | udelay(60); |
189 | } | 200 | } |
190 | 201 | ||
191 | static void bcmgenet_internal_phy_setup(struct net_device *dev) | 202 | static void bcmgenet_internal_phy_setup(struct net_device *dev) |
@@ -193,8 +204,8 @@ static void bcmgenet_internal_phy_setup(struct net_device *dev) | |||
193 | struct bcmgenet_priv *priv = netdev_priv(dev); | 204 | struct bcmgenet_priv *priv = netdev_priv(dev); |
194 | u32 reg; | 205 | u32 reg; |
195 | 206 | ||
196 | /* Power up EPHY */ | 207 | /* Power up PHY */ |
197 | bcmgenet_ephy_power_up(dev); | 208 | bcmgenet_phy_power_set(dev, true); |
198 | /* enable APD */ | 209 | /* enable APD */ |
199 | reg = bcmgenet_ext_readl(priv, EXT_EXT_PWR_MGMT); | 210 | reg = bcmgenet_ext_readl(priv, EXT_EXT_PWR_MGMT); |
200 | reg |= EXT_PWR_DN_EN_LD; | 211 | reg |= EXT_PWR_DN_EN_LD; |