On 26.11.2018 09:07, Harini Katakam wrote: > When macb device is suspended and system is powered down, the clocks > are removed and hence macb should be closed gracefully and restored > upon resume. This patch does the same by switching off the net device, > suspending phy and performing necessary cleanup of interrupts and BDs. > Upon resume, all these are reinitialized again. > > Reset of macb device is done only when GEM is not a wake device. > Even when gem is a wake device, tx queues can be stopped and ptp device > can be closed (tsu clock will be disabled in pm_runtime_suspend) as > wake event detection has no dependency on this. > > Signed-off-by: Kedareswara rao Appana <appa...@xilinx.com> > Signed-off-by: Harini Katakam <harini.kata...@xilinx.com> > --- > v2 changes: > Fixed parameter passed to phy calls. > > drivers/net/ethernet/cadence/macb_main.c | 38 > ++++++++++++++++++++++++++++++-- > 1 file changed, 36 insertions(+), 2 deletions(-) > > diff --git a/drivers/net/ethernet/cadence/macb_main.c > b/drivers/net/ethernet/cadence/macb_main.c > index 4b85ad7..dcb0194 100644 > --- a/drivers/net/ethernet/cadence/macb_main.c > +++ b/drivers/net/ethernet/cadence/macb_main.c > @@ -4249,16 +4249,33 @@ static int __maybe_unused macb_suspend(struct device > *dev) > { > struct net_device *netdev = dev_get_drvdata(dev); > struct macb *bp = netdev_priv(netdev); > + struct macb_queue *queue = bp->queues; > + unsigned long flags; > + unsigned int q; > + > + if (!netif_running(netdev)) > + return 0; > > - netif_carrier_off(netdev); > - netif_device_detach(netdev);
Is it necessary to remove this from here and have it on every if branch? > > if (bp->wol & MACB_WOL_ENABLED) { > macb_writel(bp, IER, MACB_BIT(WOL)); > macb_writel(bp, WOL, MACB_BIT(MAG)); > enable_irq_wake(bp->queues[0].irq); > + netif_device_detach(netdev); > + } else { > + netif_device_detach(netdev); > + for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, > ++queue) > + napi_disable(&queue->napi); > + phy_stop(netdev->phydev); > + phy_suspend(netdev->phydev); > + spin_lock_irqsave(&bp->lock, flags); > + macb_reset_hw(bp); > + spin_unlock_irqrestore(&bp->lock, flags); In the previous version you said you encountered some crashes while stressing this part if macb_open()/macb_close() was used in here. Could you share the tests so that I can debug it on my side? > } > > + netif_carrier_off(netdev); > + if (bp->ptp_info) > + bp->ptp_info->ptp_remove(netdev); > pm_runtime_force_suspend(dev); > > return 0; > @@ -4268,6 +4285,11 @@ static int __maybe_unused macb_resume(struct device > *dev) > { > struct net_device *netdev = dev_get_drvdata(dev); > struct macb *bp = netdev_priv(netdev); > + struct macb_queue *queue = bp->queues; > + unsigned int q; > + > + if (!netif_running(netdev)) > + return 0; > > pm_runtime_force_resume(dev); > > @@ -4275,9 +4297,21 @@ static int __maybe_unused macb_resume(struct device > *dev) > macb_writel(bp, IDR, MACB_BIT(WOL)); > macb_writel(bp, WOL, 0); > disable_irq_wake(bp->queues[0].irq); > + } else { > + macb_writel(bp, NCR, MACB_BIT(MPE)); Just asking... shouldn't other registers be restored here after SoC power is cut off? Thank you, Claudiu Beznea > + for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, > ++queue) > + napi_enable(&queue->napi); > + phy_resume(netdev->phydev); > + phy_init_hw(netdev->phydev); > + phy_start(netdev->phydev); > } > > + bp->macbgem_ops.mog_init_rings(bp); > + macb_init_hw(bp); > + macb_set_rx_mode(netdev); > netif_device_attach(netdev); > + if (bp->ptp_info) > + bp->ptp_info->ptp_init(netdev); > > return 0; > } >