napi_enable(&ugeth->napi);
        netif_start_queue(dev);
 
+       device_set_wakeup_capable(&dev->dev,
+                       qe_alive_during_sleep() || ugeth->phydev->irq);
+       device_set_wakeup_enable(&dev->dev, ugeth->wol_en);
+
        return err;
 
 err:
        schedule_work(&ugeth->timeout_work);
 }
 
+
+#ifdef CONFIG_PM
+
+static int ucc_geth_suspend(struct of_device *ofdev, pm_message_t state)
+{
+       struct net_device *ndev = dev_get_drvdata(&ofdev->dev);
+       struct ucc_geth_private *ugeth = netdev_priv(ndev);
+
+       if (!netif_running(ndev))
+               return 0;
+
+       napi_disable(&ugeth->napi);
+
+       /*
+        * Disable the controller, otherwise we'll wakeup on any network
+        * activity.
+        */
+       ugeth_disable(ugeth, COMM_DIR_RX_AND_TX);
+
+       if (ugeth->wol_en & WAKE_MAGIC) {
+               setbits32(ugeth->uccf->p_uccm, UCC_GETH_UCCE_MPD);
+               setbits32(&ugeth->ug_regs->maccfg2, MACCFG2_MPE);
+               ucc_fast_enable(ugeth->uccf, COMM_DIR_RX_AND_TX);
+       } else if (!(ugeth->wol_en & WAKE_PHY)) {
+               phy_stop(ugeth->phydev);
+       }
+
+       return 0;
+}
+
+static int ucc_geth_resume(struct of_device *ofdev)
+{
+       struct net_device *ndev = dev_get_drvdata(&ofdev->dev);
+       struct ucc_geth_private *ugeth = netdev_priv(ndev);
+       int err;
+
+       if (!netif_running(ndev))
+               return 0;
+
+       if (qe_alive_during_sleep()) {
+               if (ugeth->wol_en & WAKE_MAGIC) {
+                       ucc_fast_disable(ugeth->uccf, COMM_DIR_RX_AND_TX);
+                       clrbits32(&ugeth->ug_regs->maccfg2, MACCFG2_MPE);
+                       clrbits32(ugeth->uccf->p_uccm, UCC_GETH_UCCE_MPD);
+               }
+               ugeth_enable(ugeth, COMM_DIR_RX_AND_TX);
+       } else {
+               /*
+                * Full reinitialization is required if QE shuts down
+                * during sleep.
+                */
+               ucc_geth_memclean(ugeth);
+
+               err = ucc_geth_init_mac(ugeth);
+               if (err) {
+                       ugeth_err("%s: Cannot initialize MAC, aborting.",
+                                 ndev->name);
+                       return err;
+               }
+       }
+
+       ugeth->oldlink = 0;
+       ugeth->oldspeed = 0;
+       ugeth->oldduplex = -1;
+
+       phy_stop(ugeth->phydev);
+       phy_start(ugeth->phydev);
+
+       napi_enable(&ugeth->napi);
+       netif_start_queue(ndev);
+
+       return 0;
+}
+
+#else
+#define ucc_geth_suspend NULL
+#define ucc_geth_resume NULL
+#endif
+
 static phy_interface_t to_phy_interface(const char *phy_connection_type)
 {
        if (strcasecmp(phy_connection_type, "mii") == 0)
        .match_table    = ucc_geth_match,
        .probe          = ucc_geth_probe,
        .remove         = ucc_geth_remove,
+       .suspend        = ucc_geth_suspend,
+       .resume         = ucc_geth_resume,
 };
 
 static int __init ucc_geth_init(void)
 
        drvinfo->regdump_len = uec_get_regs_len(netdev);
 }
 
+#ifdef CONFIG_PM
+
+static void uec_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
+{
+       struct ucc_geth_private *ugeth = netdev_priv(netdev);
+       struct phy_device *phydev = ugeth->phydev;
+
+       if (phydev && phydev->irq)
+               wol->supported |= WAKE_PHY;
+       if (qe_alive_during_sleep())
+               wol->supported |= WAKE_MAGIC;
+
+       wol->wolopts = ugeth->wol_en;
+}
+
+static int uec_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
+{
+       struct ucc_geth_private *ugeth = netdev_priv(netdev);
+       struct phy_device *phydev = ugeth->phydev;
+
+       if (wol->wolopts & ~(WAKE_PHY | WAKE_MAGIC))
+               return -EINVAL;
+       else if (wol->wolopts & WAKE_PHY && (!phydev || !phydev->irq))
+               return -EINVAL;
+       else if (wol->wolopts & WAKE_MAGIC && !qe_alive_during_sleep())
+               return -EINVAL;
+
+       ugeth->wol_en = wol->wolopts;
+       device_set_wakeup_enable(&netdev->dev, ugeth->wol_en);
+
+       return 0;
+}
+
+#else
+#define uec_get_wol NULL
+#define uec_set_wol NULL
+#endif /* CONFIG_PM */
+
 static const struct ethtool_ops uec_ethtool_ops = {
        .get_settings           = uec_get_settings,
        .set_settings           = uec_set_settings,
        .get_sset_count         = uec_get_sset_count,
        .get_strings            = uec_get_strings,
        .get_ethtool_stats      = uec_get_ethtool_stats,
+       .get_wol                = uec_get_wol,
+       .set_wol                = uec_set_wol,
 };
 
 void uec_set_ethtool_ops(struct net_device *netdev)