ecsr = ravb_read(ndev, ECSR);
        ravb_write(ndev, ecsr, ECSR);   /* clear interrupt */
+
+       if (ecsr & ECSR_MPD)
+               pm_wakeup_event(&priv->pdev->dev, 0);
        if (ecsr & ECSR_ICD)
                ndev->stats.tx_carrier_errors++;
        if (ecsr & ECSR_LCHNG) {
        return 0;
 }
 
+static void ravb_get_wol(struct net_device *ndev, struct ethtool_wolinfo *wol)
+{
+       struct ravb_private *priv = netdev_priv(ndev);
+
+       wol->supported = 0;
+       wol->wolopts = 0;
+
+       if (priv->clk) {
+               wol->supported = WAKE_MAGIC;
+               wol->wolopts = priv->wol_enabled ? WAKE_MAGIC : 0;
+       }
+}
+
+static int ravb_set_wol(struct net_device *ndev, struct ethtool_wolinfo *wol)
+{
+       struct ravb_private *priv = netdev_priv(ndev);
+
+       if (!priv->clk || wol->wolopts & ~WAKE_MAGIC)
+               return -EOPNOTSUPP;
+
+       priv->wol_enabled = !!(wol->wolopts & WAKE_MAGIC);
+
+       device_set_wakeup_enable(&priv->pdev->dev, priv->wol_enabled);
+
+       return 0;
+}
+
 static const struct ethtool_ops ravb_ethtool_ops = {
        .nway_reset             = ravb_nway_reset,
        .get_msglevel           = ravb_get_msglevel,
        .get_ts_info            = ravb_get_ts_info,
        .get_link_ksettings     = ravb_get_link_ksettings,
        .set_link_ksettings     = ravb_set_link_ksettings,
+       .get_wol                = ravb_get_wol,
+       .set_wol                = ravb_set_wol,
 };
 
 static inline int ravb_hook_irq(unsigned int irq, irq_handler_t handler,
 
        priv->chip_id = chip_id;
 
+       /* Get clock, if not found that's OK but Wake-On-Lan is unavailable */
+       priv->clk = devm_clk_get(&pdev->dev, NULL);
+       if (IS_ERR(priv->clk))
+               priv->clk = NULL;
+
        /* Set function */
        ndev->netdev_ops = &ravb_netdev_ops;
        ndev->ethtool_ops = &ravb_ethtool_ops;
        if (error)
                goto out_napi_del;
 
+       if (priv->clk)
+               device_set_wakeup_capable(&pdev->dev, 1);
+
        /* Print device information */
        netdev_info(ndev, "Base address at %#x, %pM, IRQ %d.\n",
                    (u32)ndev->base_addr, ndev->dev_addr, ndev->irq);
        return 0;
 }
 
+static int ravb_wol_setup(struct net_device *ndev)
+{
+       struct ravb_private *priv = netdev_priv(ndev);
+
+       /* Disable interrupts by clearing the interrupt masks. */
+       ravb_write(ndev, 0, RIC0);
+       ravb_write(ndev, 0, RIC2);
+       ravb_write(ndev, 0, TIC);
+
+       /* Only allow ECI interrupts */
+       synchronize_irq(priv->emac_irq);
+       napi_disable(&priv->napi[RAVB_NC]);
+       napi_disable(&priv->napi[RAVB_BE]);
+       ravb_write(ndev, ECSIPR_MPDIP, ECSIPR);
+
+       /* Enable MagicPacket */
+       ravb_modify(ndev, ECMR, ECMR_MPDE, ECMR_MPDE);
+
+       /* Increased clock usage so device won't be suspended */
+       clk_enable(priv->clk);
+
+       return enable_irq_wake(priv->emac_irq);
+}
+
+static int ravb_wol_restore(struct net_device *ndev)
+{
+       struct ravb_private *priv = netdev_priv(ndev);
+       int ret;
+
+       napi_enable(&priv->napi[RAVB_NC]);
+       napi_enable(&priv->napi[RAVB_BE]);
+
+       /* Disable MagicPacket */
+       ravb_modify(ndev, ECMR, ECMR_MPDE, 0);
+
+       ret = ravb_close(ndev);
+       if (ret < 0)
+               return ret;
+
+       /* Restore clock usage count */
+       clk_disable(priv->clk);
+
+       return disable_irq_wake(priv->emac_irq);
+}
+
 static int __maybe_unused ravb_suspend(struct device *dev)
 {
        struct net_device *ndev = dev_get_drvdata(dev);
-       int ret = 0;
+       struct ravb_private *priv = netdev_priv(ndev);
+       int ret;
 
-       if (netif_running(ndev)) {
-               netif_device_detach(ndev);
+       if (!netif_running(ndev))
+               return 0;
+
+       netif_device_detach(ndev);
+
+       if (priv->wol_enabled)
+               ret = ravb_wol_setup(ndev);
+       else
                ret = ravb_close(ndev);
-       }
 
        return ret;
 }
        struct ravb_private *priv = netdev_priv(ndev);
        int ret = 0;
 
+       /* If WoL is enabled set reset mode to rearm the WoL logic */
+       if (priv->wol_enabled)
+               ravb_write(ndev, CCC_OPC_RESET, CCC);
+
        /* All register have been reset to default values.
         * Restore all registers which where setup at probe time and
         * reopen device if it was running before system suspended.
        ravb_write(ndev, priv->desc_bat_dma, DBAT);
 
        if (netif_running(ndev)) {
+               if (priv->wol_enabled) {
+                       ret = ravb_wol_restore(ndev);
+                       if (ret)
+                               return ret;
+               }
                ret = ravb_open(ndev);
                if (ret < 0)
                        return ret;