Message ID | 1364350323-2488-1-git-send-email-Frank.Li@freescale.com |
---|---|
State | Accepted, archived |
Delegated to: | David Miller |
Headers | show |
From: Frank Li <Frank.Li@freescale.com> Date: Wed, 27 Mar 2013 10:12:03 +0800 > Without this patch > 1. boot with nfs (no_console_suspend) > 2. echo mem >/sys/power/state > 3. wakeup by wakesource > 4. print "eth0: tx queue full" > > This fix above problem by reinit bd queue at restart function > > Signed-off-by: Frank Li <Frank.Li@freescale.com> Applied. -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Hi Frank, On Tue, Mar 26, 2013 at 11:12 PM, Frank Li <Frank.Li@freescale.com> wrote: > Without this patch > 1. boot with nfs (no_console_suspend) > 2. echo mem >/sys/power/state > 3. wakeup by wakesource > 4. print "eth0: tx queue full" I still have issues with suspend/resume with your patch applied: $ echo enabled > /sys/devices/80000000.apb/80040000.apbx/80074000.serial/tty/ttyAMA0/power/wakeup $ echo mem > /sys/power/state [ 31.577857] PM: Syncing filesystems ... done. [ 31.604332] Freezing user space processes ... (elapsed 0.01 seconds) done. [ 31.622160] Freezing remaining freezable tasks ... (elapsed 0.01 seconds) do. [ 31.642018] Suspending console(s) (use no_console_suspend to debug) [ 31.666914] PM: suspend of devices complete after 12.672 msecs [ 31.671975] PM: late suspend of devices complete after 5.007 msecs [ 31.678542] PM: noirq suspend of devices complete after 6.521 msecs [ 31.682147] PM: noirq resume of devices complete after 3.186 msecs [ 31.687396] PM: early resume of devices complete after 3.464 msecs [ 31.759982] PM: resume of devices complete after 2432.562 msecs (Then send any char via DUART to wakeup the system) [ 31.802673] Restarting tasks ... done. [ 33.829493] libphy: 800f0000.etherne:00 - Link is Down [ 36.859102] FEC: MDIO read timeout [ 38.889180] FEC: MDIO read timeout It does not fail 100%: there are times that suspend works just fine. -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Hello, Am 12.04.2013 15:23, wrote Fabio Estevam: > Hi Frank, > > On Tue, Mar 26, 2013 at 11:12 PM, Frank Li <Frank.Li@freescale.com> wrote: >> Without this patch >> 1. boot with nfs (no_console_suspend) >> 2. echo mem >/sys/power/state >> 3. wakeup by wakesource >> 4. print "eth0: tx queue full" > > I still have issues with suspend/resume with your patch applied: > > $ echo enabled > > /sys/devices/80000000.apb/80040000.apbx/80074000.serial/tty/ttyAMA0/power/wakeup > $ echo mem > /sys/power/state > > [ 31.577857] PM: Syncing filesystems ... done. > [ 31.604332] Freezing user space processes ... (elapsed 0.01 seconds) done. > [ 31.622160] Freezing remaining freezable tasks ... (elapsed 0.01 seconds) do. > [ 31.642018] Suspending console(s) (use no_console_suspend to debug) > [ 31.666914] PM: suspend of devices complete after 12.672 msecs > [ 31.671975] PM: late suspend of devices complete after 5.007 msecs > [ 31.678542] PM: noirq suspend of devices complete after 6.521 msecs > [ 31.682147] PM: noirq resume of devices complete after 3.186 msecs > [ 31.687396] PM: early resume of devices complete after 3.464 msecs > [ 31.759982] PM: resume of devices complete after 2432.562 msecs > > (Then send any char via DUART to wakeup the system) > > [ 31.802673] Restarting tasks ... done. > [ 33.829493] libphy: 800f0000.etherne:00 - Link is Down > [ 36.859102] FEC: MDIO read timeout > [ 38.889180] FEC: MDIO read timeout > Which clock is connected to the PHY? Is it the enet_clock generated by i.MX28? Is the connection between PHY and i.MX28 RMII? If the FEC goes through a reset the clock generated by i.MX28 may switched to MII (25 MHz). Maybe the PHY gets confused if it is working in RMII mode. > It does not fail 100%: there are times that suspend works just fine. > -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Hi Markus, On Fri, Apr 12, 2013 at 12:32 PM, Markus Niebel <list-09@tqsc.de> wrote: > Which clock is connected to the PHY? Is it the enet_clock generated by i.MX28? Is the connection between PHY and i.MX28 RMII? Yes, on mx28evk it is the ENET_CLK pin on mx28 that drives the LAN8270 PHY clock. The connection is RMII. > If the FEC goes through a reset the clock generated by i.MX28 may switched to MII (25 MHz). Maybe the PHY gets confused if it is working in RMII mode. > Thanks for the suggestion, but I also tried not to turn off/on the enet_clk and the issue also happens when enet_clk is kept constantly at 50MHz. -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/drivers/net/ethernet/freescale/fec.c b/drivers/net/ethernet/freescale/fec.c index 911d025..f292c3a 100644 --- a/drivers/net/ethernet/freescale/fec.c +++ b/drivers/net/ethernet/freescale/fec.c @@ -345,6 +345,53 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *ndev) return NETDEV_TX_OK; } +/* Init RX & TX buffer descriptors + */ +static void fec_enet_bd_init(struct net_device *dev) +{ + struct fec_enet_private *fep = netdev_priv(dev); + struct bufdesc *bdp; + unsigned int i; + + /* Initialize the receive buffer descriptors. */ + bdp = fep->rx_bd_base; + for (i = 0; i < RX_RING_SIZE; i++) { + + /* Initialize the BD for every fragment in the page. */ + if (bdp->cbd_bufaddr) + bdp->cbd_sc = BD_ENET_RX_EMPTY; + else + bdp->cbd_sc = 0; + bdp = fec_enet_get_nextdesc(bdp, fep->bufdesc_ex); + } + + /* Set the last buffer to wrap */ + bdp = fec_enet_get_prevdesc(bdp, fep->bufdesc_ex); + bdp->cbd_sc |= BD_SC_WRAP; + + fep->cur_rx = fep->rx_bd_base; + + /* ...and the same for transmit */ + bdp = fep->tx_bd_base; + fep->cur_tx = bdp; + for (i = 0; i < TX_RING_SIZE; i++) { + + /* Initialize the BD for every fragment in the page. */ + bdp->cbd_sc = 0; + if (bdp->cbd_bufaddr && fep->tx_skbuff[i]) { + dev_kfree_skb_any(fep->tx_skbuff[i]); + fep->tx_skbuff[i] = NULL; + } + bdp->cbd_bufaddr = 0; + bdp = fec_enet_get_nextdesc(bdp, fep->bufdesc_ex); + } + + /* Set the last buffer to wrap */ + bdp = fec_enet_get_prevdesc(bdp, fep->bufdesc_ex); + bdp->cbd_sc |= BD_SC_WRAP; + fep->dirty_tx = bdp; +} + /* This function is called to start or restart the FEC during a link * change. This only happens when switching between half and full * duplex. @@ -388,6 +435,8 @@ fec_restart(struct net_device *ndev, int duplex) /* Set maximum receive buffer size. */ writel(PKT_MAXBLR_SIZE, fep->hwp + FEC_R_BUFF_SIZE); + fec_enet_bd_init(ndev); + /* Set receive and transmit descriptor base. */ writel(fep->bd_dma, fep->hwp + FEC_R_DES_START); if (fep->bufdesc_ex) @@ -397,7 +446,6 @@ fec_restart(struct net_device *ndev, int duplex) writel((unsigned long)fep->bd_dma + sizeof(struct bufdesc) * RX_RING_SIZE, fep->hwp + FEC_X_DES_START); - fep->cur_rx = fep->rx_bd_base; for (i = 0; i <= TX_RING_MOD_MASK; i++) { if (fep->tx_skbuff[i]) { @@ -1597,8 +1645,6 @@ static int fec_enet_init(struct net_device *ndev) { struct fec_enet_private *fep = netdev_priv(ndev); struct bufdesc *cbd_base; - struct bufdesc *bdp; - unsigned int i; /* Allocate memory for buffer descriptors. */ cbd_base = dma_alloc_coherent(NULL, PAGE_SIZE, &fep->bd_dma, @@ -1608,6 +1654,7 @@ static int fec_enet_init(struct net_device *ndev) return -ENOMEM; } + memset(cbd_base, 0, PAGE_SIZE); spin_lock_init(&fep->hw_lock); fep->netdev = ndev; @@ -1631,35 +1678,6 @@ static int fec_enet_init(struct net_device *ndev) writel(FEC_RX_DISABLED_IMASK, fep->hwp + FEC_IMASK); netif_napi_add(ndev, &fep->napi, fec_enet_rx_napi, FEC_NAPI_WEIGHT); - /* Initialize the receive buffer descriptors. */ - bdp = fep->rx_bd_base; - for (i = 0; i < RX_RING_SIZE; i++) { - - /* Initialize the BD for every fragment in the page. */ - bdp->cbd_sc = 0; - bdp = fec_enet_get_nextdesc(bdp, fep->bufdesc_ex); - } - - /* Set the last buffer to wrap */ - bdp = fec_enet_get_prevdesc(bdp, fep->bufdesc_ex); - bdp->cbd_sc |= BD_SC_WRAP; - - /* ...and the same for transmit */ - bdp = fep->tx_bd_base; - fep->cur_tx = bdp; - for (i = 0; i < TX_RING_SIZE; i++) { - - /* Initialize the BD for every fragment in the page. */ - bdp->cbd_sc = 0; - bdp->cbd_bufaddr = 0; - bdp = fec_enet_get_nextdesc(bdp, fep->bufdesc_ex); - } - - /* Set the last buffer to wrap */ - bdp = fec_enet_get_prevdesc(bdp, fep->bufdesc_ex); - bdp->cbd_sc |= BD_SC_WRAP; - fep->dirty_tx = bdp; - fec_restart(ndev, 0); return 0;
Without this patch 1. boot with nfs (no_console_suspend) 2. echo mem >/sys/power/state 3. wakeup by wakesource 4. print "eth0: tx queue full" This fix above problem by reinit bd queue at restart function Signed-off-by: Frank Li <Frank.Li@freescale.com> --- Change from v1 to v2 * rebase to net/master drivers/net/ethernet/freescale/fec.c | 82 ++++++++++++++++++++------------- 1 files changed, 50 insertions(+), 32 deletions(-)