Gitweb: http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=911b23... Commit: 911b237d7d327db5371a762f4d8d8cd9ea763662 Parent: 968530643a0685caced9dfd6f72f20d5e7bc8fbb Author: Benjamin Herrenschmidt <benh@kernel.crashing.org> AuthorDate: Wed Dec 5 11:14:27 2007 +1100 Committer: Jeff Garzik <jeff@garzik.org> CommitDate: Fri Dec 7 15:09:05 2007 -0500 ibm_newemac: Workaround reset timeout when no link With some PHYs, when the link goes away, the EMAC reset fails due to the loss of the RX clock I believe. The old EMAC driver worked around that using some internal chip-specific clock force bits that are different on various 44x implementations. This is an attempt at doing it differently, by avoiding the reset when there is no link, but forcing loopback mode instead. It seems to work on my Taishan 440GX based board so far. Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Acked-by: Stefan Roese <sr@denx.de> Signed-off-by: Jeff Garzik <jeff@garzik.org> --- drivers/net/ibm_newemac/core.c | 20 ++++++++++++++------ 1 files changed, 14 insertions(+), 6 deletions(-) diff --git a/drivers/net/ibm_newemac/core.c b/drivers/net/ibm_newemac/core.c index eb0718b..e0eae09 100644 --- a/drivers/net/ibm_newemac/core.c +++ b/drivers/net/ibm_newemac/core.c @@ -464,26 +464,34 @@ static int emac_configure(struct emac_instance *dev) { struct emac_regs __iomem *p = dev->emacp; struct net_device *ndev = dev->ndev; - int tx_size, rx_size; + int tx_size, rx_size, link = netif_carrier_ok(dev->ndev); u32 r, mr1 = 0; DBG(dev, "configure" NL); - if (emac_reset(dev) < 0) + if (!link) { + out_be32(&p->mr1, in_be32(&p->mr1) + | EMAC_MR1_FDE | EMAC_MR1_ILE); + udelay(100); + } else if (emac_reset(dev) < 0) return -ETIMEDOUT; if (emac_has_feature(dev, EMAC_FTR_HAS_TAH)) tah_reset(dev->tah_dev); - DBG(dev, " duplex = %d, pause = %d, asym_pause = %d\n", - dev->phy.duplex, dev->phy.pause, dev->phy.asym_pause); + DBG(dev, " link = %d duplex = %d, pause = %d, asym_pause = %d\n", + link, dev->phy.duplex, dev->phy.pause, dev->phy.asym_pause); /* Default fifo sizes */ tx_size = dev->tx_fifo_size; rx_size = dev->rx_fifo_size; + /* No link, force loopback */ + if (!link) + mr1 = EMAC_MR1_FDE | EMAC_MR1_ILE; + /* Check for full duplex */ - if (dev->phy.duplex == DUPLEX_FULL) + else if (dev->phy.duplex == DUPLEX_FULL) mr1 |= EMAC_MR1_FDE | EMAC_MR1_MWSW_001; /* Adjust fifo sizes, mr1 and timeouts based on link speed */ @@ -1165,9 +1173,9 @@ static void emac_link_timer(struct work_struct *work) link_poll_interval = PHY_POLL_LINK_ON; } else { if (netif_carrier_ok(dev->ndev)) { - emac_reinitialize(dev); netif_carrier_off(dev->ndev); netif_tx_disable(dev->ndev); + emac_reinitialize(dev); emac_print_link_status(dev); } link_poll_interval = PHY_POLL_LINK_OFF; - To unsubscribe from this list: send the line "unsubscribe git-commits-head" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
| david | Re: Dual-Licensing Linux Kernel with GPL V2 and GPL V3 |
| Eric Sandeen | Re: [RFC] Heads up on sys_fallocate() |
| Filippos Papadopoulos | Re: INITIO scsi driver fails to work properly |
| Greg KH | [GIT PATCH] driver core patches against 2.6.24 |
git: | |
| Gerrit Renker | [PATCH 27/37] dccp: Integration of dynamic feature activation - part 2 (server side) |
| David Miller | [GIT]: Networking |
| Jarek Poplawski | [PATCH take 2] pkt_sched: Protect gen estimators under est_lock. |
| Natalie Protasevich | [BUG] New Kernel Bugs |
