@@ -1517,6 +1517,35 @@ static void macb_tx_restart(struct macb_queue *queue)
15171517 macb_writel (bp , NCR , macb_readl (bp , NCR ) | MACB_BIT (TSTART ));
15181518}
15191519
1520+ static irqreturn_t gem_wol_interrupt (int irq , void * dev_id )
1521+ {
1522+ struct macb_queue * queue = dev_id ;
1523+ struct macb * bp = queue -> bp ;
1524+ u32 status ;
1525+
1526+ status = queue_readl (queue , ISR );
1527+
1528+ if (unlikely (!status ))
1529+ return IRQ_NONE ;
1530+
1531+ spin_lock (& bp -> lock );
1532+
1533+ if (status & GEM_BIT (WOL )) {
1534+ queue_writel (queue , IDR , GEM_BIT (WOL ));
1535+ gem_writel (bp , WOL , 0 );
1536+ netdev_vdbg (bp -> dev , "GEM WoL: queue = %u, isr = 0x%08lx\n" ,
1537+ (unsigned int )(queue - bp -> queues ),
1538+ (unsigned long )status );
1539+ if (bp -> caps & MACB_CAPS_ISR_CLEAR_ON_WRITE )
1540+ queue_writel (queue , ISR , GEM_BIT (WOL ));
1541+ pm_wakeup_event (& bp -> pdev -> dev , 0 );
1542+ }
1543+
1544+ spin_unlock (& bp -> lock );
1545+
1546+ return IRQ_HANDLED ;
1547+ }
1548+
15201549static irqreturn_t macb_interrupt (int irq , void * dev_id )
15211550{
15221551 struct macb_queue * queue = dev_id ;
@@ -3316,6 +3345,8 @@ static const struct ethtool_ops macb_ethtool_ops = {
33163345static const struct ethtool_ops gem_ethtool_ops = {
33173346 .get_regs_len = macb_get_regs_len ,
33183347 .get_regs = macb_get_regs ,
3348+ .get_wol = macb_get_wol ,
3349+ .set_wol = macb_set_wol ,
33193350 .get_link = ethtool_op_get_link ,
33203351 .get_ts_info = macb_get_ts_info ,
33213352 .get_ethtool_stats = gem_get_ethtool_stats ,
@@ -4567,33 +4598,68 @@ static int __maybe_unused macb_suspend(struct device *dev)
45674598 struct macb_queue * queue = bp -> queues ;
45684599 unsigned long flags ;
45694600 unsigned int q ;
4601+ int err ;
45704602
45714603 if (!netif_running (netdev ))
45724604 return 0 ;
45734605
45744606 if (bp -> wol & MACB_WOL_ENABLED ) {
4575- macb_writel (bp , IER , MACB_BIT (WOL ));
4576- macb_writel (bp , WOL , MACB_BIT (MAG ));
4577- enable_irq_wake (bp -> queues [0 ].irq );
4578- netif_device_detach (netdev );
4579- } else {
4580- netif_device_detach (netdev );
4607+ spin_lock_irqsave (& bp -> lock , flags );
4608+ /* Flush all status bits */
4609+ macb_writel (bp , TSR , -1 );
4610+ macb_writel (bp , RSR , -1 );
45814611 for (q = 0 , queue = bp -> queues ; q < bp -> num_queues ;
4582- ++ q , ++ queue )
4583- napi_disable (& queue -> napi );
4612+ ++ q , ++ queue ) {
4613+ /* Disable all interrupts */
4614+ queue_writel (queue , IDR , -1 );
4615+ queue_readl (queue , ISR );
4616+ if (bp -> caps & MACB_CAPS_ISR_CLEAR_ON_WRITE )
4617+ queue_writel (queue , ISR , -1 );
4618+ }
4619+ /* Change interrupt handler and
4620+ * Enable WoL IRQ on queue 0
4621+ */
4622+ if (macb_is_gem (bp )) {
4623+ devm_free_irq (dev , bp -> queues [0 ].irq , bp -> queues );
4624+ err = devm_request_irq (dev , bp -> queues [0 ].irq , gem_wol_interrupt ,
4625+ IRQF_SHARED , netdev -> name , bp -> queues );
4626+ if (err ) {
4627+ dev_err (dev ,
4628+ "Unable to request IRQ %d (error %d)\n" ,
4629+ bp -> queues [0 ].irq , err );
4630+ spin_unlock_irqrestore (& bp -> lock , flags );
4631+ return err ;
4632+ }
4633+ queue_writel (bp -> queues , IER , GEM_BIT (WOL ));
4634+ gem_writel (bp , WOL , MACB_BIT (MAG ));
4635+ } else {
4636+ queue_writel (bp -> queues , IER , MACB_BIT (WOL ));
4637+ macb_writel (bp , WOL , MACB_BIT (MAG ));
4638+ }
4639+ spin_unlock_irqrestore (& bp -> lock , flags );
4640+
4641+ enable_irq_wake (bp -> queues [0 ].irq );
4642+ }
4643+
4644+ netif_device_detach (netdev );
4645+ for (q = 0 , queue = bp -> queues ; q < bp -> num_queues ;
4646+ ++ q , ++ queue )
4647+ napi_disable (& queue -> napi );
4648+
4649+ if (!(bp -> wol & MACB_WOL_ENABLED )) {
45844650 rtnl_lock ();
45854651 phylink_stop (bp -> phylink );
45864652 rtnl_unlock ();
45874653 spin_lock_irqsave (& bp -> lock , flags );
45884654 macb_reset_hw (bp );
45894655 spin_unlock_irqrestore (& bp -> lock , flags );
4656+ }
45904657
4591- if (!(bp -> caps & MACB_CAPS_USRIO_DISABLED ))
4592- bp -> pm_data .usrio = macb_or_gem_readl (bp , USRIO );
4658+ if (!(bp -> caps & MACB_CAPS_USRIO_DISABLED ))
4659+ bp -> pm_data .usrio = macb_or_gem_readl (bp , USRIO );
45934660
4594- if (netdev -> hw_features & NETIF_F_NTUPLE )
4595- bp -> pm_data .scrt2 = gem_readl_n (bp , ETHT , SCRT2_ETHT );
4596- }
4661+ if (netdev -> hw_features & NETIF_F_NTUPLE )
4662+ bp -> pm_data .scrt2 = gem_readl_n (bp , ETHT , SCRT2_ETHT );
45974663
45984664 if (bp -> ptp_info )
45994665 bp -> ptp_info -> ptp_remove (netdev );
@@ -4608,7 +4674,9 @@ static int __maybe_unused macb_resume(struct device *dev)
46084674 struct net_device * netdev = dev_get_drvdata (dev );
46094675 struct macb * bp = netdev_priv (netdev );
46104676 struct macb_queue * queue = bp -> queues ;
4677+ unsigned long flags ;
46114678 unsigned int q ;
4679+ int err ;
46124680
46134681 if (!netif_running (netdev ))
46144682 return 0 ;
@@ -4617,29 +4685,60 @@ static int __maybe_unused macb_resume(struct device *dev)
46174685 pm_runtime_force_resume (dev );
46184686
46194687 if (bp -> wol & MACB_WOL_ENABLED ) {
4620- macb_writel (bp , IDR , MACB_BIT (WOL ));
4621- macb_writel (bp , WOL , 0 );
4622- disable_irq_wake (bp -> queues [0 ].irq );
4623- } else {
4624- macb_writel (bp , NCR , MACB_BIT (MPE ));
4625-
4626- if (netdev -> hw_features & NETIF_F_NTUPLE )
4627- gem_writel_n (bp , ETHT , SCRT2_ETHT , bp -> pm_data .scrt2 );
4688+ spin_lock_irqsave (& bp -> lock , flags );
4689+ /* Disable WoL */
4690+ if (macb_is_gem (bp )) {
4691+ queue_writel (bp -> queues , IDR , GEM_BIT (WOL ));
4692+ gem_writel (bp , WOL , 0 );
4693+ } else {
4694+ queue_writel (bp -> queues , IDR , MACB_BIT (WOL ));
4695+ macb_writel (bp , WOL , 0 );
4696+ }
4697+ /* Clear ISR on queue 0 */
4698+ queue_readl (bp -> queues , ISR );
4699+ if (bp -> caps & MACB_CAPS_ISR_CLEAR_ON_WRITE )
4700+ queue_writel (bp -> queues , ISR , -1 );
4701+ /* Replace interrupt handler on queue 0 */
4702+ devm_free_irq (dev , bp -> queues [0 ].irq , bp -> queues );
4703+ err = devm_request_irq (dev , bp -> queues [0 ].irq , macb_interrupt ,
4704+ IRQF_SHARED , netdev -> name , bp -> queues );
4705+ if (err ) {
4706+ dev_err (dev ,
4707+ "Unable to request IRQ %d (error %d)\n" ,
4708+ bp -> queues [0 ].irq , err );
4709+ spin_unlock_irqrestore (& bp -> lock , flags );
4710+ return err ;
4711+ }
4712+ spin_unlock_irqrestore (& bp -> lock , flags );
46284713
4629- if (!(bp -> caps & MACB_CAPS_USRIO_DISABLED ))
4630- macb_or_gem_writel (bp , USRIO , bp -> pm_data .usrio );
4714+ disable_irq_wake (bp -> queues [0 ].irq );
46314715
4632- for ( q = 0 , queue = bp -> queues ; q < bp -> num_queues ;
4633- ++ q , ++ queue )
4634- napi_enable ( & queue -> napi );
4716+ /* Now make sure we disable phy before moving
4717+ * to common restore path
4718+ */
46354719 rtnl_lock ();
4636- phylink_start (bp -> phylink );
4720+ phylink_stop (bp -> phylink );
46374721 rtnl_unlock ();
46384722 }
46394723
4724+ for (q = 0 , queue = bp -> queues ; q < bp -> num_queues ;
4725+ ++ q , ++ queue )
4726+ napi_enable (& queue -> napi );
4727+
4728+ if (netdev -> hw_features & NETIF_F_NTUPLE )
4729+ gem_writel_n (bp , ETHT , SCRT2_ETHT , bp -> pm_data .scrt2 );
4730+
4731+ if (!(bp -> caps & MACB_CAPS_USRIO_DISABLED ))
4732+ macb_or_gem_writel (bp , USRIO , bp -> pm_data .usrio );
4733+
4734+ macb_writel (bp , NCR , MACB_BIT (MPE ));
46404735 macb_init_hw (bp );
46414736 macb_set_rx_mode (netdev );
46424737 macb_restore_features (bp );
4738+ rtnl_lock ();
4739+ phylink_start (bp -> phylink );
4740+ rtnl_unlock ();
4741+
46434742 netif_device_attach (netdev );
46444743 if (bp -> ptp_info )
46454744 bp -> ptp_info -> ptp_init (netdev );
0 commit comments