Skip to content

Commit de991c5

Browse files
harini-katakamdavem330
authored andcommitted
net: macb: Add support for suspend/resume with full power down
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 <[email protected]> Signed-off-by: Harini Katakam <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent d54f89a commit de991c5

File tree

1 file changed

+38
-2
lines changed

1 file changed

+38
-2
lines changed

drivers/net/ethernet/cadence/macb_main.c

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4283,16 +4283,34 @@ static int __maybe_unused macb_suspend(struct device *dev)
42834283
{
42844284
struct net_device *netdev = dev_get_drvdata(dev);
42854285
struct macb *bp = netdev_priv(netdev);
4286+
struct macb_queue *queue = bp->queues;
4287+
unsigned long flags;
4288+
unsigned int q;
4289+
4290+
if (!netif_running(netdev))
4291+
return 0;
42864292

4287-
netif_carrier_off(netdev);
4288-
netif_device_detach(netdev);
42894293

42904294
if (bp->wol & MACB_WOL_ENABLED) {
42914295
macb_writel(bp, IER, MACB_BIT(WOL));
42924296
macb_writel(bp, WOL, MACB_BIT(MAG));
42934297
enable_irq_wake(bp->queues[0].irq);
4298+
netif_device_detach(netdev);
4299+
} else {
4300+
netif_device_detach(netdev);
4301+
for (q = 0, queue = bp->queues; q < bp->num_queues;
4302+
++q, ++queue)
4303+
napi_disable(&queue->napi);
4304+
phy_stop(netdev->phydev);
4305+
phy_suspend(netdev->phydev);
4306+
spin_lock_irqsave(&bp->lock, flags);
4307+
macb_reset_hw(bp);
4308+
spin_unlock_irqrestore(&bp->lock, flags);
42944309
}
42954310

4311+
netif_carrier_off(netdev);
4312+
if (bp->ptp_info)
4313+
bp->ptp_info->ptp_remove(netdev);
42964314
pm_runtime_force_suspend(dev);
42974315

42984316
return 0;
@@ -4302,16 +4320,34 @@ static int __maybe_unused macb_resume(struct device *dev)
43024320
{
43034321
struct net_device *netdev = dev_get_drvdata(dev);
43044322
struct macb *bp = netdev_priv(netdev);
4323+
struct macb_queue *queue = bp->queues;
4324+
unsigned int q;
4325+
4326+
if (!netif_running(netdev))
4327+
return 0;
43054328

43064329
pm_runtime_force_resume(dev);
43074330

43084331
if (bp->wol & MACB_WOL_ENABLED) {
43094332
macb_writel(bp, IDR, MACB_BIT(WOL));
43104333
macb_writel(bp, WOL, 0);
43114334
disable_irq_wake(bp->queues[0].irq);
4335+
} else {
4336+
macb_writel(bp, NCR, MACB_BIT(MPE));
4337+
for (q = 0, queue = bp->queues; q < bp->num_queues;
4338+
++q, ++queue)
4339+
napi_enable(&queue->napi);
4340+
phy_resume(netdev->phydev);
4341+
phy_init_hw(netdev->phydev);
4342+
phy_start(netdev->phydev);
43124343
}
43134344

4345+
bp->macbgem_ops.mog_init_rings(bp);
4346+
macb_init_hw(bp);
4347+
macb_set_rx_mode(netdev);
43144348
netif_device_attach(netdev);
4349+
if (bp->ptp_info)
4350+
bp->ptp_info->ptp_init(netdev);
43154351

43164352
return 0;
43174353
}

0 commit comments

Comments
 (0)