diff options
Diffstat (limited to 'target/linux/brcm63xx/patches-3.3/410-NET-bcm63xx_enet-move-phy_-dis-connect-into-probe-re.patch')
-rw-r--r-- | target/linux/brcm63xx/patches-3.3/410-NET-bcm63xx_enet-move-phy_-dis-connect-into-probe-re.patch | 169 |
1 files changed, 169 insertions, 0 deletions
diff --git a/target/linux/brcm63xx/patches-3.3/410-NET-bcm63xx_enet-move-phy_-dis-connect-into-probe-re.patch b/target/linux/brcm63xx/patches-3.3/410-NET-bcm63xx_enet-move-phy_-dis-connect-into-probe-re.patch new file mode 100644 index 0000000..2102db3 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/410-NET-bcm63xx_enet-move-phy_-dis-connect-into-probe-re.patch @@ -0,0 +1,169 @@ +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 +@@ -784,10 +784,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; + +@@ -795,40 +793,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, 0, +- 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 */ +@@ -838,7 +806,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, IRQF_DISABLED, + dev->name, dev); +@@ -1025,9 +993,6 @@ out_freeirq_rx: + out_freeirq: + free_irq(dev->irq, dev); + +-out_phy_disconnect: +- phy_disconnect(priv->phydev); +- + return ret; + } + +@@ -1132,12 +1097,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; + } + +@@ -1714,6 +1673,8 @@ static int __devinit bcm_enet_probe(stru + + /* 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) { +@@ -1750,6 +1711,38 @@ static int __devinit bcm_enet_probe(stru + 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, 0, ++ 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 */ +@@ -1795,6 +1788,9 @@ static int __devinit bcm_enet_probe(stru + return 0; + + out_unregister_mdio: ++ if (priv->phydev) ++ phy_disconnect(priv->phydev); ++ + if (priv->mii_bus) { + mdiobus_unregister(priv->mii_bus); + kfree(priv->mii_bus->irq); +@@ -1845,6 +1841,8 @@ static int __devexit bcm_enet_remove(str + enet_writel(priv, 0, ENET_MIISC_REG); + + if (priv->has_phy) { ++ phy_disconnect(priv->phydev); ++ priv->phydev = NULL; + mdiobus_unregister(priv->mii_bus); + kfree(priv->mii_bus->irq); + mdiobus_free(priv->mii_bus); |