diff options
Diffstat (limited to 'drivers/net/ethernet/broadcom/genet/bcmgenet.c')
-rw-r--r-- | drivers/net/ethernet/broadcom/genet/bcmgenet.c | 41 |
1 files changed, 26 insertions, 15 deletions
diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c index 12cb77ef1081..0f138280315a 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c @@ -2018,6 +2018,8 @@ static void bcmgenet_link_intr_enable(struct bcmgenet_priv *priv) */ if (priv->internal_phy) { int0_enable |= UMAC_IRQ_LINK_EVENT; + if (GENET_IS_V1(priv) || GENET_IS_V2(priv) || GENET_IS_V3(priv)) + int0_enable |= UMAC_IRQ_PHY_DET_R; } else if (priv->ext_phy) { int0_enable |= UMAC_IRQ_LINK_EVENT; } else if (priv->phy_interface == PHY_INTERFACE_MODE_MOCA) { @@ -2611,11 +2613,14 @@ static void bcmgenet_irq_task(struct work_struct *work) priv->irq0_stat = 0; spin_unlock_irq(&priv->lock); + if (status & UMAC_IRQ_PHY_DET_R && + priv->dev->phydev->autoneg != AUTONEG_ENABLE) + phy_init_hw(priv->dev->phydev); + /* Link UP/DOWN event */ - if (status & UMAC_IRQ_LINK_EVENT) { - priv->dev->phydev->link = !!(status & UMAC_IRQ_LINK_UP); + if (status & UMAC_IRQ_LINK_EVENT) phy_mac_interrupt(priv->dev->phydev); - } + } /* bcmgenet_isr1: handle Rx and Tx priority queues */ @@ -2710,7 +2715,7 @@ static irqreturn_t bcmgenet_isr0(int irq, void *dev_id) } /* all other interested interrupts handled in bottom half */ - status &= UMAC_IRQ_LINK_EVENT; + status &= (UMAC_IRQ_LINK_EVENT | UMAC_IRQ_PHY_DET_R); if (status) { /* Save irq status for bottom-half processing. */ spin_lock_irqsave(&priv->lock, flags); @@ -2874,6 +2879,12 @@ static int bcmgenet_open(struct net_device *dev) if (priv->internal_phy) bcmgenet_power_up(priv, GENET_POWER_PASSIVE); + ret = bcmgenet_mii_connect(dev); + if (ret) { + netdev_err(dev, "failed to connect to PHY\n"); + goto err_clk_disable; + } + /* take MAC out of reset */ bcmgenet_umac_reset(priv); @@ -2883,6 +2894,12 @@ static int bcmgenet_open(struct net_device *dev) reg = bcmgenet_umac_readl(priv, UMAC_CMD); priv->crc_fwd_en = !!(reg & CMD_CRC_FWD); + ret = bcmgenet_mii_config(dev, true); + if (ret) { + netdev_err(dev, "unsupported PHY\n"); + goto err_disconnect_phy; + } + bcmgenet_set_hw_addr(priv, dev->dev_addr); if (priv->internal_phy) { @@ -2898,7 +2915,7 @@ static int bcmgenet_open(struct net_device *dev) ret = bcmgenet_init_dma(priv); if (ret) { netdev_err(dev, "failed to initialize DMA\n"); - goto err_clk_disable; + goto err_disconnect_phy; } /* Always enable ring 16 - descriptor ring */ @@ -2921,25 +2938,19 @@ static int bcmgenet_open(struct net_device *dev) goto err_irq0; } - ret = bcmgenet_mii_probe(dev); - if (ret) { - netdev_err(dev, "failed to connect to PHY\n"); - goto err_irq1; - } - bcmgenet_netif_start(dev); netif_tx_start_all_queues(dev); return 0; -err_irq1: - free_irq(priv->irq1, priv); err_irq0: free_irq(priv->irq0, priv); err_fini_dma: bcmgenet_dma_teardown(priv); bcmgenet_fini_dma(priv); +err_disconnect_phy: + phy_disconnect(dev->phydev); err_clk_disable: if (priv->internal_phy) bcmgenet_power_down(priv, GENET_POWER_PASSIVE); @@ -3620,6 +3631,8 @@ static int bcmgenet_resume(struct device *d) if (priv->internal_phy) bcmgenet_power_up(priv, GENET_POWER_PASSIVE); + phy_init_hw(dev->phydev); + bcmgenet_umac_reset(priv); init_umac(priv); @@ -3628,8 +3641,6 @@ static int bcmgenet_resume(struct device *d) if (priv->wolopts) clk_disable_unprepare(priv->clk_wol); - phy_init_hw(dev->phydev); - /* Speed settings must be restored */ bcmgenet_mii_config(priv->dev, false); |