FreeBSD/sys/dev/e1000/if_em.c
/*
** WOL in the newer chipset interfaces (pchlan)
** require thing to be copied into the phy
*/
WOL in the newer chipset interfaces (pchlan)
require thing to be copied into the phy
WOL in the newer chipset interfaces ( pchlan ) require thing to be copied into the phy
static int
em_enable_phy_wakeup(struct adapter *adapter)
{
	struct e1000_hw *hw = &adapter->hw;
	u32 mreg, ret = 0;
	u16 preg;
	e1000_copy_rx_addrs_to_phy_ich8lan(hw);
	for (int i = 0; i < adapter->hw.mac.mta_reg_count; i++) {
		mreg = E1000_READ_REG_ARRAY(hw, E1000_MTA, i);
		e1000_write_phy_reg(hw, BM_MTA(i), (u16)(mreg & 0xFFFF));
		e1000_write_phy_reg(hw, BM_MTA(i) + 1,
		    (u16)((mreg >> 16) & 0xFFFF));
	}
	e1000_read_phy_reg(&adapter->hw, BM_RCTL, &preg);
	mreg = E1000_READ_REG(hw, E1000_RCTL);
	if (mreg & E1000_RCTL_UPE)
		preg |= BM_RCTL_UPE;
	if (mreg & E1000_RCTL_MPE)
		preg |= BM_RCTL_MPE;
	preg &= ~(BM_RCTL_MO_MASK);
	if (mreg & E1000_RCTL_MO_3)
		preg |= (((mreg & E1000_RCTL_MO_3) >> E1000_RCTL_MO_SHIFT)
				<< BM_RCTL_MO_SHIFT);
	if (mreg & E1000_RCTL_BAM)
		preg |= BM_RCTL_BAM;
	if (mreg & E1000_RCTL_PMCF)
		preg |= BM_RCTL_PMCF;
	mreg = E1000_READ_REG(hw, E1000_CTRL);
	if (mreg & E1000_CTRL_RFCE)
		preg |= BM_RCTL_RFCE;
	e1000_write_phy_reg(&adapter->hw, BM_RCTL, preg);
	E1000_WRITE_REG(hw, E1000_WUC,
	    E1000_WUC_PHY_WAKE | E1000_WUC_PME_EN);
	E1000_WRITE_REG(hw, E1000_WUFC, adapter->wol);
	e1000_write_phy_reg(&adapter->hw, BM_WUFC, adapter->wol);
	e1000_write_phy_reg(&adapter->hw, BM_WUC, E1000_WUC_PME_EN);
	ret = hw->phy.ops.acquire(hw);
	if (ret) {
		printf("Could not acquire PHY\n");
		return ret;
	}
	e1000_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT,
	                         (BM_WUC_ENABLE_PAGE << IGP_PAGE_SHIFT));
	ret = e1000_read_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, &preg);
	if (ret) {
		printf("Could not read PHY page 769\n");
		goto out;
	}
	preg |= BM_WUC_ENABLE_BIT | BM_WUC_HOST_WU_BIT;
	ret = e1000_write_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, preg);
	if (ret)
		printf("Could not set PHY Host Wakeup bit\n");
out:
	hw->phy.ops.release(hw);
	return ret;
}
static int em_enable_phy_wakeup ( struct adapter * adapter ) { struct e1000_hw * hw = & adapter -> hw ; u32 mreg , ret = 0 ; u16 preg ; e1000_copy_rx_addrs_to_phy_ich8lan ( hw ) ; for ( int i = 0 ; i < adapter -> hw . mac . mta_reg_count ; i ++ ) { mreg = E1000_READ_REG_ARRAY ( hw , E1000_MTA , i ) ; e1000_write_phy_reg ( hw , BM_MTA ( i ) , ( u16 ) ( mreg & 0xFFFF ) ) ; e1000_write_phy_reg ( hw , BM_MTA ( i ) + 1 , ( u16 ) ( ( mreg >> 16 ) & 0xFFFF ) ) ; } e1000_read_phy_reg ( & adapter -> hw , BM_RCTL , & preg ) ; mreg = E1000_READ_REG ( hw , E1000_RCTL ) ; if ( mreg & E1000_RCTL_UPE ) preg |= BM_RCTL_UPE ; if ( mreg & E1000_RCTL_MPE ) preg |= BM_RCTL_MPE ; preg &= ~ ( BM_RCTL_MO_MASK ) ; if ( mreg & E1000_RCTL_MO_3 ) preg |= ( ( ( mreg & E1000_RCTL_MO_3 ) >> E1000_RCTL_MO_SHIFT ) << BM_RCTL_MO_SHIFT ) ; if ( mreg & E1000_RCTL_BAM ) preg |= BM_RCTL_BAM ; if ( mreg & E1000_RCTL_PMCF ) preg |= BM_RCTL_PMCF ; mreg = E1000_READ_REG ( hw , E1000_CTRL ) ; if ( mreg & E1000_CTRL_RFCE ) preg |= BM_RCTL_RFCE ; e1000_write_phy_reg ( & adapter -> hw , BM_RCTL , preg ) ; E1000_WRITE_REG ( hw , E1000_WUC , E1000_WUC_PHY_WAKE | E1000_WUC_PME_EN ) ; E1000_WRITE_REG ( hw , E1000_WUFC , adapter -> wol ) ; e1000_write_phy_reg ( & adapter -> hw , BM_WUFC , adapter -> wol ) ; e1000_write_phy_reg ( & adapter -> hw , BM_WUC , E1000_WUC_PME_EN ) ; ret = hw -> phy . ops . acquire ( hw ) ; if ( ret ) { printf ( " \n " ) ; return ret ; } e1000_write_phy_reg_mdic ( hw , IGP01E1000_PHY_PAGE_SELECT , ( BM_WUC_ENABLE_PAGE << IGP_PAGE_SHIFT ) ) ; ret = e1000_read_phy_reg_mdic ( hw , BM_WUC_ENABLE_REG , & preg ) ; if ( ret ) { printf ( " \n " ) ; goto out ; } preg |= BM_WUC_ENABLE_BIT | BM_WUC_HOST_WU_BIT ; ret = e1000_write_phy_reg_mdic ( hw , BM_WUC_ENABLE_REG , preg ) ; if ( ret ) printf ( " \n " ) ; out : hw -> phy . ops . release ( hw ) ; return ret ; }
WOL in the newer chipset interfaces (pchlan)
require thing to be copied into the phy
WOL in the newer chipset interfaces ( pchlan ) require thing to be copied into the phy
/* copy MAC RARs to PHY RARs */ /* copy MAC MTA to PHY MTA */ /* configure PHY Rx Control register */ /* enable PHY wakeup in MAC register */ /* configure and enable PHY wakeup in PHY registers */ /* activate PHY wakeup */