FreeBSD/sys/dev/e1000/if_em.c
/*********************************************************************
 *
 *  Initialize the hardware to a configuration
 *  as specified by the adapter structure.
 *
 **********************************************************************/
Initialize the hardware to a configuration
as specified by the adapter structure.
Initialize the hardware to a configuration as specified by the adapter structure .
static void
em_reset(struct adapter *adapter)
{
	device_t	dev = adapter->dev;
	if_t ifp = adapter->ifp;
	struct e1000_hw	*hw = &adapter->hw;
	u16		rx_buffer_size;
	u32		pba;
	INIT_DEBUGOUT("em_reset: begin");
	if (!em_smart_pwr_down && (hw->mac.type == e1000_82571 ||
	    hw->mac.type == e1000_82572)) {
		u16 phy_tmp = 0;
		e1000_read_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT, &phy_tmp);
		phy_tmp &= ~IGP02E1000_PM_SPD;
		e1000_write_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT, phy_tmp);
	}
	switch (hw->mac.type) {
	case e1000_82571:
	case e1000_82572:
	case e1000_80003es2lan:
			pba = E1000_PBA_32K; 
		break;
	case e1000_82573: 
			pba = E1000_PBA_12K; 
		break;
	case e1000_82574:
	case e1000_82583:
			pba = E1000_PBA_20K; 
		break;
	case e1000_ich8lan:
		pba = E1000_PBA_8K;
		break;
	case e1000_ich9lan:
	case e1000_ich10lan:
		if (adapter->hw.mac.max_frame_size > 4096)
			pba = E1000_PBA_14K;
		else
			pba = E1000_PBA_10K;
		break;
	case e1000_pchlan:
	case e1000_pch2lan:
	case e1000_pch_lpt:
	case e1000_pch_spt:
		pba = E1000_PBA_26K;
		break;
	default:
		if (adapter->hw.mac.max_frame_size > 8192)
			pba = E1000_PBA_40K; 
		else
			pba = E1000_PBA_48K; 
	}
	E1000_WRITE_REG(&adapter->hw, E1000_PBA, pba);
	rx_buffer_size = ((E1000_READ_REG(hw, E1000_PBA) & 0xffff) << 10 );
	hw->fc.high_water = rx_buffer_size -
	    roundup2(adapter->hw.mac.max_frame_size, 1024);
	hw->fc.low_water = hw->fc.high_water - 1500;
	if (adapter->fc) 
		hw->fc.requested_mode = adapter->fc;
	else
		hw->fc.requested_mode = e1000_fc_full;
	if (hw->mac.type == e1000_80003es2lan)
		hw->fc.pause_time = 0xFFFF;
	else
		hw->fc.pause_time = EM_FC_PAUSE_TIME;
	hw->fc.send_xon = TRUE;
	switch (hw->mac.type) {
	case e1000_pchlan:
                hw->fc.requested_mode = e1000_fc_rx_pause;
		hw->fc.pause_time = 0xFFFF; 
		if (if_getmtu(ifp) > ETHERMTU) {
			hw->fc.high_water = 0x3500;
			hw->fc.low_water = 0x1500;
		} else {
			hw->fc.high_water = 0x5000;
			hw->fc.low_water = 0x3000;
		}
		hw->fc.refresh_time = 0x1000;
		break;
	case e1000_pch2lan:
	case e1000_pch_lpt:
	case e1000_pch_spt:
		hw->fc.high_water = 0x5C20;
		hw->fc.low_water = 0x5048;
		hw->fc.pause_time = 0x0650;
		hw->fc.refresh_time = 0x0400;
		if (if_getmtu(ifp) > ETHERMTU)
			E1000_WRITE_REG(hw, E1000_PBA, 12);
		else
			E1000_WRITE_REG(hw, E1000_PBA, 26);
		break;
        case e1000_ich9lan:
        case e1000_ich10lan:
		if (if_getmtu(ifp) > ETHERMTU) {
			hw->fc.high_water = 0x2800;
			hw->fc.low_water = hw->fc.high_water - 8;
			break;
		} 
	default:
		if (hw->mac.type == e1000_80003es2lan)
			hw->fc.pause_time = 0xFFFF;
		break;
	}
	if (hw->mac.type == e1000_pch_spt)
		em_flush_desc_rings(adapter);
	e1000_reset_hw(hw);
	E1000_WRITE_REG(hw, E1000_WUC, 0);
	em_disable_aspm(adapter);
	if (e1000_init_hw(hw) < 0) {
		device_printf(dev, "Hardware Initialization Failed\n");
		return;
	}
	E1000_WRITE_REG(hw, E1000_VET, ETHERTYPE_VLAN);
	e1000_get_phy_info(hw);
	e1000_check_for_link(hw);
	return;
}
static void em_reset ( struct adapter * adapter ) { device_t dev = adapter -> dev ; if_t ifp = adapter -> ifp ; struct e1000_hw * hw = & adapter -> hw ; u16 rx_buffer_size ; u32 pba ; INIT_DEBUGOUT ( " " ) ; if ( ! em_smart_pwr_down && ( hw -> mac . type == e1000_82571 || hw -> mac . type == e1000_82572 ) ) { u16 phy_tmp = 0 ; e1000_read_phy_reg ( hw , IGP02E1000_PHY_POWER_MGMT , & phy_tmp ) ; phy_tmp &= ~ IGP02E1000_PM_SPD ; e1000_write_phy_reg ( hw , IGP02E1000_PHY_POWER_MGMT , phy_tmp ) ; } switch ( hw -> mac . type ) { case e1000_82571 : case e1000_82572 : case e1000_80003es2lan : pba = E1000_PBA_32K ; break ; case e1000_82573 : pba = E1000_PBA_12K ; break ; case e1000_82574 : case e1000_82583 : pba = E1000_PBA_20K ; break ; case e1000_ich8lan : pba = E1000_PBA_8K ; break ; case e1000_ich9lan : case e1000_ich10lan : if ( adapter -> hw . mac . max_frame_size > 4096 ) pba = E1000_PBA_14K ; else pba = E1000_PBA_10K ; break ; case e1000_pchlan : case e1000_pch2lan : case e1000_pch_lpt : case e1000_pch_spt : pba = E1000_PBA_26K ; break ; default : if ( adapter -> hw . mac . max_frame_size > 8192 ) pba = E1000_PBA_40K ; else pba = E1000_PBA_48K ; } E1000_WRITE_REG ( & adapter -> hw , E1000_PBA , pba ) ; rx_buffer_size = ( ( E1000_READ_REG ( hw , E1000_PBA ) & 0xffff ) << 10 ) ; hw -> fc . high_water = rx_buffer_size - roundup2 ( adapter -> hw . mac . max_frame_size , 1024 ) ; hw -> fc . low_water = hw -> fc . high_water - 1500 ; if ( adapter -> fc ) hw -> fc . requested_mode = adapter -> fc ; else hw -> fc . requested_mode = e1000_fc_full ; if ( hw -> mac . type == e1000_80003es2lan ) hw -> fc . pause_time = 0xFFFF ; else hw -> fc . pause_time = EM_FC_PAUSE_TIME ; hw -> fc . send_xon = TRUE ; switch ( hw -> mac . type ) { case e1000_pchlan : hw -> fc . requested_mode = e1000_fc_rx_pause ; hw -> fc . pause_time = 0xFFFF ; if ( if_getmtu ( ifp ) > ETHERMTU ) { hw -> fc . high_water = 0x3500 ; hw -> fc . low_water = 0x1500 ; } else { hw -> fc . high_water = 0x5000 ; hw -> fc . low_water = 0x3000 ; } hw -> fc . refresh_time = 0x1000 ; break ; case e1000_pch2lan : case e1000_pch_lpt : case e1000_pch_spt : hw -> fc . high_water = 0x5C20 ; hw -> fc . low_water = 0x5048 ; hw -> fc . pause_time = 0x0650 ; hw -> fc . refresh_time = 0x0400 ; if ( if_getmtu ( ifp ) > ETHERMTU ) E1000_WRITE_REG ( hw , E1000_PBA , 12 ) ; else E1000_WRITE_REG ( hw , E1000_PBA , 26 ) ; break ; case e1000_ich9lan : case e1000_ich10lan : if ( if_getmtu ( ifp ) > ETHERMTU ) { hw -> fc . high_water = 0x2800 ; hw -> fc . low_water = hw -> fc . high_water - 8 ; break ; } default : if ( hw -> mac . type == e1000_80003es2lan ) hw -> fc . pause_time = 0xFFFF ; break ; } if ( hw -> mac . type == e1000_pch_spt ) em_flush_desc_rings ( adapter ) ; e1000_reset_hw ( hw ) ; E1000_WRITE_REG ( hw , E1000_WUC , 0 ) ; em_disable_aspm ( adapter ) ; if ( e1000_init_hw ( hw ) < 0 ) { device_printf ( dev , " \n " ) ; return ; } E1000_WRITE_REG ( hw , E1000_VET , ETHERTYPE_VLAN ) ; e1000_get_phy_info ( hw ) ; e1000_check_for_link ( hw ) ; return ; }
Initialize the hardware to a configuration
  as specified by the adapter structure.
Initialize the hardware to a configuration as specified by the adapter structure .
/* Set up smart power down as default off on newer adapters. */ /* Speed up time to link by disabling smart power down. */ /*
	 * Packet Buffer Allocation (PBA)
	 * Writing PBA sets the receive portion of the buffer
	 * the remainder is used for the transmit buffer.
	 */ /* Total Packet Buffer on these is 48K */ /* 32K for Rx, 16K for Tx */ /* 82573: Total Packet Buffer is 32K */ /* 12K for Rx, 20K for Tx */ /* 20K for Rx, 20K for Tx */ /* Boost Receive side for jumbo frames */ /* 40K for Rx, 24K for Tx */ /* 48K for Rx, 16K for Tx */ /*
	 * These parameters control the automatic generation (Tx) and
	 * response (Rx) to Ethernet PAUSE frames.
	 * - High water mark should allow for at least two frames to be
	 *   received after sending an XOFF.
	 * - Low water mark works best when it is very near the high water mark.
	 *   This allows the receiver to restart by sending XON when it has
	 *   drained a bit. Here we use an arbitrary value of 1500 which will
	 *   restart after one full frame is pulled from the buffer. There
	 *   could be several smaller frames in the buffer and if so they will
	 *   not trigger the XON until their total number reduces the buffer
	 *   by 1500.
	 * - The pause time is fairly large at 1000 x 512ns = 512 usec.
	 */ /* locally set flow control value? */ /* Device specific overrides/settings */ /* Workaround: no TX flow ctrl for PCH */ /* override */ /* Jumbos need adjusted PBA */ /* else fall thru */ /* I219 needs some special flushing to avoid hangs */ /* Issue a global reset */ /* and a re-init */