From b11218c750ab92cfab4408a0328f1b36ceec3f33 Mon Sep 17 00:00:00 2001 From: Jonas Gorski <jonas.gorski@gmail.com> Date: Fri, 6 Jan 2012 12:24:18 +0100 Subject: [PATCH 19/63] NET: bcm63xx_enet: move phy_(dis)connect into probe/remove Only connect/disconnect the phy during probe and remove, not during any open/close. The phy seldom changes during the runtime, and disconnecting the phy during close will prevent it from keeping any configuration over a down/up cycle. Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com> --- drivers/net/ethernet/broadcom/bcm63xx_enet.c | 84 +++++++++++++------------- 1 files changed, 41 insertions(+), 43 deletions(-) --- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c +++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c @@ -870,10 +870,8 @@ static int bcm_enet_open(struct net_devi struct bcm_enet_priv *priv; struct sockaddr addr; struct device *kdev; - struct phy_device *phydev; int i, ret; unsigned int size; - char phy_id[MII_BUS_ID_SIZE + 3]; void *p; u32 val; @@ -881,40 +879,10 @@ static int bcm_enet_open(struct net_devi kdev = &priv->pdev->dev; if (priv->has_phy) { - /* connect to PHY */ - snprintf(phy_id, sizeof(phy_id), PHY_ID_FMT, - priv->mii_bus->id, priv->phy_id); - - phydev = phy_connect(dev, phy_id, bcm_enet_adjust_phy_link, - PHY_INTERFACE_MODE_MII); - - if (IS_ERR(phydev)) { - dev_err(kdev, "could not attach to PHY\n"); - return PTR_ERR(phydev); - } - - /* mask with MAC supported features */ - phydev->supported &= (SUPPORTED_10baseT_Half | - SUPPORTED_10baseT_Full | - SUPPORTED_100baseT_Half | - SUPPORTED_100baseT_Full | - SUPPORTED_Autoneg | - SUPPORTED_Pause | - SUPPORTED_MII); - phydev->advertising = phydev->supported; - - if (priv->pause_auto && priv->pause_rx && priv->pause_tx) - phydev->advertising |= SUPPORTED_Pause; - else - phydev->advertising &= ~SUPPORTED_Pause; - - dev_info(kdev, "attached PHY at address %d [%s]\n", - phydev->addr, phydev->drv->name); - + /* Reset state */ priv->old_link = 0; priv->old_duplex = -1; priv->old_pause = -1; - priv->phydev = phydev; } /* mask all interrupts and request them */ @@ -924,7 +892,7 @@ static int bcm_enet_open(struct net_devi ret = request_irq(dev->irq, bcm_enet_isr_mac, 0, dev->name, dev); if (ret) - goto out_phy_disconnect; + return ret; ret = request_irq(priv->irq_rx, bcm_enet_isr_dma, 0, dev->name, dev); @@ -1127,9 +1095,6 @@ out_freeirq_rx: out_freeirq: free_irq(dev->irq, dev); -out_phy_disconnect: - phy_disconnect(priv->phydev); - return ret; } @@ -1234,12 +1199,6 @@ static int bcm_enet_stop(struct net_devi free_irq(priv->irq_rx, dev); free_irq(dev->irq, dev); - /* release phy */ - if (priv->has_phy) { - phy_disconnect(priv->phydev); - priv->phydev = NULL; - } - return 0; } @@ -1834,6 +1793,8 @@ static int bcm_enet_probe(struct platfor /* MII bus registration */ if (priv->has_phy) { + struct phy_device *phydev; + char phy_id[MII_BUS_ID_SIZE + 3]; priv->mii_bus = mdiobus_alloc(); if (!priv->mii_bus) { @@ -1871,6 +1832,38 @@ static int bcm_enet_probe(struct platfor dev_err(&pdev->dev, "unable to register mdio bus\n"); goto out_free_mdio; } + + /* connect to PHY */ + snprintf(phy_id, sizeof(phy_id), PHY_ID_FMT, + priv->mii_bus->id, priv->phy_id); + + phydev = phy_connect(dev, phy_id, bcm_enet_adjust_phy_link, + PHY_INTERFACE_MODE_MII); + + if (IS_ERR(phydev)) { + dev_err(&pdev->dev, "could not attach to PHY\n"); + goto out_unregister_mdio; + } + + /* mask with MAC supported features */ + phydev->supported &= (SUPPORTED_10baseT_Half | + SUPPORTED_10baseT_Full | + SUPPORTED_100baseT_Half | + SUPPORTED_100baseT_Full | + SUPPORTED_Autoneg | + SUPPORTED_Pause | + SUPPORTED_MII); + phydev->advertising = phydev->supported; + + if (priv->pause_auto && priv->pause_rx && priv->pause_tx) + phydev->advertising |= SUPPORTED_Pause; + else + phydev->advertising &= ~SUPPORTED_Pause; + + dev_info(&pdev->dev, "attached PHY at address %d [%s]\n", + phydev->addr, phydev->drv->name); + + priv->phydev = phydev; } else { /* run platform code to initialize PHY device */ @@ -1916,6 +1909,9 @@ static int bcm_enet_probe(struct platfor return 0; out_unregister_mdio: + if (priv->phydev) + phy_disconnect(priv->phydev); + if (priv->mii_bus) mdiobus_unregister(priv->mii_bus); @@ -1957,6 +1953,8 @@ static int bcm_enet_remove(struct platfo enet_writel(priv, 0, ENET_MIISC_REG); if (priv->has_phy) { + phy_disconnect(priv->phydev); + priv->phydev = NULL; mdiobus_unregister(priv->mii_bus); mdiobus_free(priv->mii_bus); } else {