--- sys/dev/e1000/if_igb.c (revision 316540) +++ sys/dev/e1000/if_igb.c (working copy) @@ -1231,6 +1231,14 @@ ifp->if_capenable ^= IFCAP_LRO; reinit = 1; } + if (mask & IFCAP_WOL) { + if (mask & IFCAP_WOL_MCAST) + ifp->if_capenable ^= IFCAP_WOL_MCAST; + if (mask & IFCAP_WOL_UCAST) + ifp->if_capenable ^= IFCAP_WOL_UCAST; + if (mask & IFCAP_WOL_MAGIC) + ifp->if_capenable ^= IFCAP_WOL_MAGIC; + } if (reinit && (ifp->if_drv_flags & IFF_DRV_RUNNING)) igb_init(adapter); VLAN_CAPABILITIES(ifp); @@ -3196,6 +3204,7 @@ #endif ifp->if_capabilities |= IFCAP_TSO; ifp->if_capabilities |= IFCAP_JUMBO_MTU; + ifp->if_capabilities |= IFCAP_WOL; ifp->if_capenable = ifp->if_capabilities; /* Don't enable LRO by default */ @@ -3206,6 +3215,14 @@ #endif /* + * Enable only WOL MAGIC by default + * if WOL is enabled by EEPROM. + */ + if( adapter->wol ) { + ifp->if_capenable |= IFCAP_WOL_MAGIC; + } + + /* * Tell the upper layer(s) we * support full VLAN capability. */ @@ -5498,21 +5515,47 @@ static void igb_enable_wakeup(device_t dev) { + struct adapter *adapter = device_get_softc(dev); + struct ifnet *ifp = adapter->ifp; + u32 wuc; u16 cap, status; u8 id; - /* First find the capabilities pointer*/ - cap = pci_read_config(dev, PCIR_CAP_PTR, 2); - /* Read the PM Capabilities */ - id = pci_read_config(dev, cap, 1); - if (id != PCIY_PMG) /* Something wrong */ - return; - /* OK, we have the power capabilities, so - now get the status register */ - cap += PCIR_POWER_STATUS; - status = pci_read_config(dev, cap, 2); - status |= PCIM_PSTAT_PME | PCIM_PSTAT_PMEENABLE; - pci_write_config(dev, cap, status, 2); + adapter->wol = E1000_READ_REG(&adapter->hw, E1000_WUFC); + if (ifp->if_capenable & IFCAP_WOL_MAGIC) { + adapter->wol |= E1000_WUFC_MAG; + } else { + adapter->wol &= ~E1000_WUFC_MAG; + } + if (ifp->if_capenable & IFCAP_WOL_MCAST) { + adapter->wol |= E1000_WUFC_MC; + } else { + adapter->wol &= ~E1000_WUFC_MC; + } + if (ifp->if_capenable & IFCAP_WOL_UCAST) { + adapter->wol |= E1000_WUFC_EX; + } else { + adapter->wol &= ~E1000_WUFC_EX; + } + if(adapter->wol & + ( E1000_WUFC_EX | E1000_WUFC_MC | E1000_WUFC_MAG) ) { + wuc = E1000_READ_REG(&adapter->hw, E1000_WUC); + wuc |= (E1000_WUC_PME_EN | E1000_WUC_APME) ; + E1000_WRITE_REG(&adapter->hw, E1000_WUC, wuc); + E1000_WRITE_REG(&adapter->hw, E1000_WUFC, adapter->wol); + /* First find the capabilities pointer*/ + cap = pci_read_config(dev, PCIR_CAP_PTR, 2); + /* Read the PM Capabilities */ + id = pci_read_config(dev, cap, 1); + if (id != PCIY_PMG) /* Something wrong */ + return; + /* OK, we have the power capabilities, so + now get the status register */ + cap += PCIR_POWER_STATUS; + status = pci_read_config(dev, cap, 2); + status |= PCIM_PSTAT_PME | PCIM_PSTAT_PMEENABLE; + pci_write_config(dev, cap, status, 2); + } return; }