diff -ur linux.orig/drivers/net/ibm_newemac/core.c linux/drivers/net/ibm_newemac/core.c --- linux.orig/drivers/net/ibm_newemac/core.c 2012-10-08 12:38:33.000000000 -0700 +++ linux/drivers/net/ibm_newemac/core.c 2012-10-08 14:31:35.797089192 -0700 @@ -106,6 +106,7 @@ */ static DECLARE_WAIT_QUEUE_HEAD(emac_probe_wait); +static int emac_init_phy(struct emac_instance *dev); /* Having stable interface names is a doomed idea. However, it would be nice * if we didn't have completely random interface names at boot too :-) It's * just a matter of making everybody's life easier. Since we are doing @@ -135,7 +136,7 @@ EMAC_FTR_440EP_PHY_CLK_FIX)) DBG(dev, "%s" NL, error); else if (net_ratelimit()) - printk(KERN_ERR "%s: %s\n", dev->ofdev->node->full_name, error); + printk(KERN_INFO "%s: %s\n", dev->ofdev->node->full_name, error); } /* EMAC PHY clock workaround: @@ -161,6 +162,7 @@ } /* PHY polling intervals */ +#define PHY_POLL_NO_PHY (5 * HZ) #define PHY_POLL_LINK_ON HZ #define PHY_POLL_LINK_OFF (HZ / 5) @@ -1156,8 +1158,12 @@ /* Start PHY polling now. */ - if (dev->phy.address >= 0) { + if (dev->phy.address >= 0 || dev->phy.address == -2) { int link_poll_interval; + if (dev->phy.address == -2) { + netif_carrier_off(dev->ndev); + link_poll_interval = PHY_POLL_NO_PHY; + }else if (dev->phy.def->ops->poll_link(&dev->phy)) { dev->phy.def->ops->read_link(&dev->phy); emac_rx_clk_default(dev); @@ -1243,7 +1249,17 @@ if (!dev->opened) goto bail; - if (dev->phy.def->ops->poll_link(&dev->phy)) { + + if (!dev->phy.def) { + /* If the reset finally clears, because the phy now + * has a link, then reprobe for the phy. + */ + if (emac_reset(dev) == 0) + { + emac_init_phy(dev); + } + link_poll_interval = PHY_POLL_NO_PHY; + }else if (dev->phy.def->ops->poll_link(&dev->phy)) { if (!netif_carrier_ok(dev->ndev)) { emac_rx_clk_default(dev); /* Get new link parameters */ @@ -2376,7 +2392,7 @@ return 0; } -static int __devinit emac_init_phy(struct emac_instance *dev) +static int emac_init_phy(struct emac_instance *dev) { struct device_node *np = dev->ofdev->node; struct net_device *ndev = dev->ndev; @@ -2470,7 +2486,9 @@ mutex_unlock(&emac_phy_map_lock); if (i == 0x20) { printk(KERN_WARNING "%s: can't find PHY!\n", np->full_name); - return -ENXIO; + busy_phy_map = 0; + dev->phy.address = -2; + return 0; } /* Init PHY */