FreeBSD/sys/dev/e1000/if_lem.c
/*
 * Enable PCI Wake On Lan capability
 */
Enable PCI Wake On Lan capability
Enable PCI Wake On Lan capability
static void
lem_enable_wakeup(device_t dev)
{
	struct adapter	*adapter = device_get_softc(dev);
	if_t ifp = adapter->ifp;
	u32		pmc, ctrl, ctrl_ext, rctl;
	u16     	status;
	if ((pci_find_cap(dev, PCIY_PMG, &pmc) != 0))
		return;
	ctrl = E1000_READ_REG(&adapter->hw, E1000_CTRL);
	ctrl |= (E1000_CTRL_SWDPIN2 | E1000_CTRL_SWDPIN3);
	E1000_WRITE_REG(&adapter->hw, E1000_CTRL, ctrl);
	E1000_WRITE_REG(&adapter->hw, E1000_WUC, E1000_WUC_PME_EN);
	if (adapter->hw.phy.media_type == e1000_media_type_fiber ||
	    adapter->hw.phy.media_type == e1000_media_type_internal_serdes) {
		ctrl_ext = E1000_READ_REG(&adapter->hw, E1000_CTRL_EXT);
		ctrl_ext |= E1000_CTRL_EXT_SDP3_DATA;
		E1000_WRITE_REG(&adapter->hw, E1000_CTRL_EXT, ctrl_ext);
	}
	if ((if_getcapenable(ifp) & IFCAP_WOL_MAGIC) == 0)
		adapter->wol &= ~E1000_WUFC_MAG;
	if ((if_getcapenable(ifp) & IFCAP_WOL_MCAST) == 0)
		adapter->wol &= ~E1000_WUFC_MC;
	else {
		rctl = E1000_READ_REG(&adapter->hw, E1000_RCTL);
		rctl |= E1000_RCTL_MPE;
		E1000_WRITE_REG(&adapter->hw, E1000_RCTL, rctl);
	}
	if (adapter->hw.mac.type == e1000_pchlan) {
		if (lem_enable_phy_wakeup(adapter))
			return;
	} else {
		E1000_WRITE_REG(&adapter->hw, E1000_WUC, E1000_WUC_PME_EN);
		E1000_WRITE_REG(&adapter->hw, E1000_WUFC, adapter->wol);
	}
        status = pci_read_config(dev, pmc + PCIR_POWER_STATUS, 2);
	status &= ~(PCIM_PSTAT_PME | PCIM_PSTAT_PMEENABLE);
	if (if_getcapenable(ifp) & IFCAP_WOL)
		status |= PCIM_PSTAT_PME | PCIM_PSTAT_PMEENABLE;
        pci_write_config(dev, pmc + PCIR_POWER_STATUS, status, 2);
	return;
}
static void lem_enable_wakeup ( device_t dev ) { struct adapter * adapter = device_get_softc ( dev ) ; if_t ifp = adapter -> ifp ; u32 pmc , ctrl , ctrl_ext , rctl ; u16 status ; if ( ( pci_find_cap ( dev , PCIY_PMG , & pmc ) != 0 ) ) return ; ctrl = E1000_READ_REG ( & adapter -> hw , E1000_CTRL ) ; ctrl |= ( E1000_CTRL_SWDPIN2 | E1000_CTRL_SWDPIN3 ) ; E1000_WRITE_REG ( & adapter -> hw , E1000_CTRL , ctrl ) ; E1000_WRITE_REG ( & adapter -> hw , E1000_WUC , E1000_WUC_PME_EN ) ; if ( adapter -> hw . phy . media_type == e1000_media_type_fiber || adapter -> hw . phy . media_type == e1000_media_type_internal_serdes ) { ctrl_ext = E1000_READ_REG ( & adapter -> hw , E1000_CTRL_EXT ) ; ctrl_ext |= E1000_CTRL_EXT_SDP3_DATA ; E1000_WRITE_REG ( & adapter -> hw , E1000_CTRL_EXT , ctrl_ext ) ; } if ( ( if_getcapenable ( ifp ) & IFCAP_WOL_MAGIC ) == 0 ) adapter -> wol &= ~ E1000_WUFC_MAG ; if ( ( if_getcapenable ( ifp ) & IFCAP_WOL_MCAST ) == 0 ) adapter -> wol &= ~ E1000_WUFC_MC ; else { rctl = E1000_READ_REG ( & adapter -> hw , E1000_RCTL ) ; rctl |= E1000_RCTL_MPE ; E1000_WRITE_REG ( & adapter -> hw , E1000_RCTL , rctl ) ; } if ( adapter -> hw . mac . type == e1000_pchlan ) { if ( lem_enable_phy_wakeup ( adapter ) ) return ; } else { E1000_WRITE_REG ( & adapter -> hw , E1000_WUC , E1000_WUC_PME_EN ) ; E1000_WRITE_REG ( & adapter -> hw , E1000_WUFC , adapter -> wol ) ; } status = pci_read_config ( dev , pmc + PCIR_POWER_STATUS , 2 ) ; status &= ~ ( PCIM_PSTAT_PME | PCIM_PSTAT_PMEENABLE ) ; if ( if_getcapenable ( ifp ) & IFCAP_WOL ) status |= PCIM_PSTAT_PME | PCIM_PSTAT_PMEENABLE ; pci_write_config ( dev , pmc + PCIR_POWER_STATUS , status , 2 ) ; return ; }
Enable PCI Wake On Lan capability
Enable PCI Wake On Lan capability
/* Advertise the wakeup capability */ /* Keep the laser running on Fiber adapters */ /*
	** Determine type of Wakeup: note that wol
	** is set with all bits on by default.
	*/ /* Request PME */