Commit 1c557819 authored by Guo-Fu Tseng's avatar Guo-Fu Tseng Committed by David S. Miller
Browse files

jme: Support WoL after shutdown



Adding shutdown function that setup wake if wol is enabled.
Add jme_phy_on in jme_set_100m_half in case it is shutting down
or suspending when interface is down(phy_off by default).

v2 updates:
Removed CONFIG_PM ifdef for jme_set_100m_half and jme_wait_link.
It would be nice if it can be applied to net-2.6 along with other patches
sent few days ago. If it is not appropriate, please ignore the net-2.6
request, and apply it to net-next-2.6 as previous patch. :)

Reported-and-helped-by: default avatarСtac <Taoga@yandex.ru>
Signed-off-by: default avatarGuo-Fu Tseng <cooldavid@cooldavid.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent b889416b
Loading
Loading
Loading
Loading
+30 −15
Original line number Diff line number Diff line
@@ -1623,12 +1623,12 @@ err_out:
	return rc;
}

#ifdef CONFIG_PM
static void
jme_set_100m_half(struct jme_adapter *jme)
{
	u32 bmcr, tmp;

	jme_phy_on(jme);
	bmcr = jme_mdio_read(jme->dev, jme->mii_if.phy_id, MII_BMCR);
	tmp = bmcr & ~(BMCR_ANENABLE | BMCR_SPEED100 |
		       BMCR_SPEED1000 | BMCR_FULLDPLX);
@@ -1656,7 +1656,6 @@ jme_wait_link(struct jme_adapter *jme)
		phylink = jme_linkstat_from_phy(jme);
	}
}
#endif

static inline void
jme_phy_off(struct jme_adapter *jme)
@@ -1664,6 +1663,21 @@ jme_phy_off(struct jme_adapter *jme)
	jme_mdio_write(jme->dev, jme->mii_if.phy_id, MII_BMCR, BMCR_PDOWN);
}

static void
jme_powersave_phy(struct jme_adapter *jme)
{
	if (jme->reg_pmcs) {
		jme_set_100m_half(jme);

		if (jme->reg_pmcs & (PMCS_LFEN | PMCS_LREN))
			jme_wait_link(jme);

		jwrite32(jme, JME_PMCS, jme->reg_pmcs);
	} else {
		jme_phy_off(jme);
	}
}

static int
jme_close(struct net_device *netdev)
{
@@ -2991,6 +3005,16 @@ jme_remove_one(struct pci_dev *pdev)

}

static void
jme_shutdown(struct pci_dev *pdev)
{
	struct net_device *netdev = pci_get_drvdata(pdev);
	struct jme_adapter *jme = netdev_priv(netdev);

	jme_powersave_phy(jme);
	pci_pme_active(pdev, true);
}

#ifdef CONFIG_PM
static int
jme_suspend(struct pci_dev *pdev, pm_message_t state)
@@ -3028,19 +3052,9 @@ jme_suspend(struct pci_dev *pdev, pm_message_t state)
	tasklet_hi_enable(&jme->rxempty_task);

	pci_save_state(pdev);
	if (jme->reg_pmcs) {
		jme_set_100m_half(jme);

		if (jme->reg_pmcs & (PMCS_LFEN | PMCS_LREN))
			jme_wait_link(jme);

		jwrite32(jme, JME_PMCS, jme->reg_pmcs);

		pci_enable_wake(pdev, PCI_D3cold, true);
	} else {
		jme_phy_off(jme);
	}
	pci_set_power_state(pdev, PCI_D3cold);
	jme_powersave_phy(jme);
	pci_enable_wake(jme->pdev, PCI_D3hot, true);
	pci_set_power_state(pdev, PCI_D3hot);

	return 0;
}
@@ -3087,6 +3101,7 @@ static struct pci_driver jme_driver = {
	.suspend        = jme_suspend,
	.resume         = jme_resume,
#endif /* CONFIG_PM */
	.shutdown       = jme_shutdown,
};

static int __init