Commit 218d8c4b authored by Jeff Garzik's avatar Jeff Garzik

[netdrver e1000] wol updates:

* Get WOL settings from EEPROM
* Remove PHY WOL support as device downshofts from 1GbE to 10/100 during
  suspend, which causes a PHY event, which causes the system to wake up!
  The downshifting to 10/100 is to reduce power.

Contributed by Scott Feldman @ Intel
parent 59275b0d
...@@ -113,6 +113,7 @@ struct e1000_adapter; ...@@ -113,6 +113,7 @@ struct e1000_adapter;
#define E1000_DEFAULT_PBA 0x00000030 #define E1000_DEFAULT_PBA 0x00000030
#define AUTO_ALL_MODES 0 #define AUTO_ALL_MODES 0
#define E1000_EEPROM_APME 4
/* only works for sizes that are powers of 2 */ /* only works for sizes that are powers of 2 */
#define E1000_ROUNDUP(i, size) ((i) = (((i) + (size) - 1) & ~((size) - 1))) #define E1000_ROUNDUP(i, size) ((i) = (((i) + (size) - 1) & ~((size) - 1)))
......
...@@ -306,12 +306,10 @@ e1000_ethtool_gwol(struct e1000_adapter *adapter, struct ethtool_wolinfo *wol) ...@@ -306,12 +306,10 @@ e1000_ethtool_gwol(struct e1000_adapter *adapter, struct ethtool_wolinfo *wol)
/* Fall Through */ /* Fall Through */
default: default:
wol->supported = WAKE_PHY | WAKE_UCAST | wol->supported = WAKE_UCAST | WAKE_MCAST
WAKE_MCAST | WAKE_BCAST | WAKE_MAGIC; | WAKE_BCAST | WAKE_MAGIC;
wol->wolopts = 0; wol->wolopts = 0;
if(adapter->wol & E1000_WUFC_LNKC)
wol->wolopts |= WAKE_PHY;
if(adapter->wol & E1000_WUFC_EX) if(adapter->wol & E1000_WUFC_EX)
wol->wolopts |= WAKE_UCAST; wol->wolopts |= WAKE_UCAST;
if(adapter->wol & E1000_WUFC_MC) if(adapter->wol & E1000_WUFC_MC)
...@@ -343,13 +341,11 @@ e1000_ethtool_swol(struct e1000_adapter *adapter, struct ethtool_wolinfo *wol) ...@@ -343,13 +341,11 @@ e1000_ethtool_swol(struct e1000_adapter *adapter, struct ethtool_wolinfo *wol)
/* Fall Through */ /* Fall Through */
default: default:
if(wol->wolopts & (WAKE_ARP | WAKE_MAGICSECURE)) if(wol->wolopts & (WAKE_ARP | WAKE_MAGICSECURE | WAKE_PHY))
return -EOPNOTSUPP; return -EOPNOTSUPP;
adapter->wol = 0; adapter->wol = 0;
if(wol->wolopts & WAKE_PHY)
adapter->wol |= E1000_WUFC_LNKC;
if(wol->wolopts & WAKE_UCAST) if(wol->wolopts & WAKE_UCAST)
adapter->wol |= E1000_WUFC_EX; adapter->wol |= E1000_WUFC_EX;
if(wol->wolopts & WAKE_MCAST) if(wol->wolopts & WAKE_MCAST)
......
...@@ -349,6 +349,7 @@ e1000_probe(struct pci_dev *pdev, ...@@ -349,6 +349,7 @@ e1000_probe(struct pci_dev *pdev,
int mmio_len; int mmio_len;
int pci_using_dac; int pci_using_dac;
int i; int i;
uint16_t eeprom_data;
if((i = pci_enable_device(pdev))) if((i = pci_enable_device(pdev)))
return i; return i;
...@@ -501,8 +502,9 @@ e1000_probe(struct pci_dev *pdev, ...@@ -501,8 +502,9 @@ e1000_probe(struct pci_dev *pdev,
* enable the ACPI Magic Packet filter * enable the ACPI Magic Packet filter
*/ */
e1000_read_eeprom(&adapter->hw, EEPROM_INIT_CONTROL2_REG, &eeprom_data);
if((adapter->hw.mac_type >= e1000_82544) && if((adapter->hw.mac_type >= e1000_82544) &&
(E1000_READ_REG(&adapter->hw, WUC) & E1000_WUC_APME)) (eeprom_data & E1000_EEPROM_APME))
adapter->wol |= E1000_WUFC_MAG; adapter->wol |= E1000_WUFC_MAG;
/* reset the hardware with the new settings */ /* reset the hardware with the new settings */
...@@ -2437,14 +2439,19 @@ e1000_suspend(struct pci_dev *pdev, uint32_t state) ...@@ -2437,14 +2439,19 @@ e1000_suspend(struct pci_dev *pdev, uint32_t state)
{ {
struct net_device *netdev = pci_get_drvdata(pdev); struct net_device *netdev = pci_get_drvdata(pdev);
struct e1000_adapter *adapter = netdev->priv; struct e1000_adapter *adapter = netdev->priv;
uint32_t ctrl, ctrl_ext, rctl, manc; uint32_t ctrl, ctrl_ext, rctl, manc, status;
uint32_t wufc = adapter->wol;
netif_device_detach(netdev); netif_device_detach(netdev);
if(netif_running(netdev)) if(netif_running(netdev))
e1000_down(adapter); e1000_down(adapter);
if(adapter->wol) { status = E1000_READ_REG(&adapter->hw, STATUS);
if(status & E1000_STATUS_LU)
wufc &= ~E1000_WUFC_LNKC;
if(wufc) {
e1000_setup_rctl(adapter); e1000_setup_rctl(adapter);
e1000_set_multi(netdev); e1000_set_multi(netdev);
...@@ -2474,7 +2481,7 @@ e1000_suspend(struct pci_dev *pdev, uint32_t state) ...@@ -2474,7 +2481,7 @@ e1000_suspend(struct pci_dev *pdev, uint32_t state)
} }
E1000_WRITE_REG(&adapter->hw, WUC, E1000_WUC_PME_EN); E1000_WRITE_REG(&adapter->hw, WUC, E1000_WUC_PME_EN);
E1000_WRITE_REG(&adapter->hw, WUFC, adapter->wol); E1000_WRITE_REG(&adapter->hw, WUFC, wufc);
pci_enable_wake(pdev, 3, 1); pci_enable_wake(pdev, 3, 1);
pci_enable_wake(pdev, 4, 1); /* 4 == D3 cold */ pci_enable_wake(pdev, 4, 1); /* 4 == D3 cold */
} else { } else {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment