aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/ethernet/broadcom/genet/bcmgenet.c34
-rw-r--r--drivers/net/ethernet/broadcom/genet/bcmgenet.h2
-rw-r--r--drivers/net/ethernet/broadcom/genet/bcmmii.c29
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. */
850static void bcmgenet_power_down(struct bcmgenet_priv *priv, 850static 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
878static void bcmgenet_power_up(struct bcmgenet_priv *priv, 883static 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
2617static void bcmgenet_timeout(struct net_device *dev) 2625static 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
3110static int bcmgenet_resume(struct device *d) 3120static 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);
663int bcmgenet_mii_config(struct net_device *dev, bool init); 664int bcmgenet_mii_config(struct net_device *dev, bool init);
664void bcmgenet_mii_exit(struct net_device *dev); 665void bcmgenet_mii_exit(struct net_device *dev);
665void bcmgenet_mii_reset(struct net_device *dev); 666void bcmgenet_mii_reset(struct net_device *dev);
667void bcmgenet_phy_power_set(struct net_device *dev, bool enable);
666void bcmgenet_mii_setup(struct net_device *dev); 668void 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
171static void bcmgenet_ephy_power_up(struct net_device *dev) 171void 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
191static void bcmgenet_internal_phy_setup(struct net_device *dev) 202static 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;