+static void
+jme_set_10m_half(struct jme_adapter *jme)
+{
+ __u32 bmcr, tmp;
+
+ bmcr = jme_mdio_read(jme->dev, jme->mii_if.phy_id, MII_BMCR);
+ tmp = bmcr & ~(BMCR_ANENABLE | BMCR_SPEED100 |
+ BMCR_SPEED1000 | BMCR_FULLDPLX);
+
+ if (bmcr != tmp)
+ jme_mdio_write(jme->dev, jme->mii_if.phy_id, MII_BMCR, tmp);
+
+ jwrite32(jme, JME_GHC, GHC_SPEED_10M);
+}
+
+static int
+jme_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+ struct net_device *netdev = pci_get_drvdata(pdev);
+ struct jme_adapter *jme = netdev_priv(netdev);
+ int timeout = 100;
+
+ atomic_dec(&jme->link_changing);
+
+ netif_device_detach(netdev);
+ netif_stop_queue(netdev);
+ jme_stop_irq(jme);
+ jme_free_irq(jme);
+
+ while(--timeout > 0 &&
+ (
+ atomic_read(&jme->rx_cleaning) != 1 ||
+ atomic_read(&jme->tx_cleaning) != 1
+ )) {
+ mdelay(1);
+ }
+ if(!timeout) {
+ jeprintk(netdev->name, "Waiting tasklets timeout.\n");
+ return -EBUSY;
+ }
+ jme_disable_shadow(jme);
+
+ if(netif_carrier_ok(netdev)) {
+ jme_stop_pcc_timer(jme);
+ jme_reset_mac_processor(jme);
+ jme_free_rx_resources(jme);
+ jme_free_tx_resources(jme);
+ netif_carrier_off(netdev);
+ jme->phylink = 0;
+ }
+
+ jme_set_10m_half(jme);
+
+ pci_save_state(pdev);
+ if(jme->reg_pmcs) {
+ jwrite32(jme, JME_PMCS, jme->reg_pmcs);
+ pci_enable_wake(pdev, PCI_D3cold, 1);
+ }
+ else {
+ pci_enable_wake(pdev, PCI_D3cold, 0);
+ }
+ pci_set_power_state(pdev, pci_choose_state(pdev, state));
+
+ return 0;
+}
+
+static int
+jme_resume(struct pci_dev *pdev)
+{
+ struct net_device *netdev = pci_get_drvdata(pdev);
+ struct jme_adapter *jme = netdev_priv(netdev);
+
+ jme_clear_pm(jme);
+ pci_restore_state(pdev);
+
+ if(jme->flags & JME_FLAG_SSET)
+ jme_set_settings(netdev, &jme->old_ecmd);
+ else
+ jme_reset_phy_processor(jme);
+
+ jme_reset_mac_processor(jme);
+ jme_enable_shadow(jme);
+ jme_request_irq(jme);
+ jme_start_irq(jme);
+ netif_device_attach(netdev);
+
+ atomic_inc(&jme->link_changing);
+
+ jme_reset_link(jme);
+
+ return 0;
+}
+