⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 e1000_82540.c

📁 linux系统的网卡驱动包
💻 C
📖 第 1 页 / 共 2 页
字号:
	DEBUGOUT("Initializing the IEEE VLAN\n");	if (mac->type < e1000_82545_rev_3)		E1000_WRITE_REG(hw, E1000_VET, 0);	e1000_clear_vfta(hw);	/* Setup the receive address. */	e1000_init_rx_addrs_generic(hw, mac->rar_entry_count);	/* Zero out the Multicast HASH table */	DEBUGOUT("Zeroing the MTA\n");	for (i = 0; i < mac->mta_reg_count; i++) {		E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, 0);		/*		 * Avoid back to back register writes by adding the register		 * read (flush).  This is to protect against some strange		 * bridge configurations that may issue Memory Write Block		 * (MWB) to our register space.  The *_rev_3 hardware at		 * least doesn't respond correctly to every other dword in an		 * MWB to our register space.		 */		E1000_WRITE_FLUSH(hw);	}	if (mac->type < e1000_82545_rev_3)		e1000_pcix_mmrbc_workaround_generic(hw);	/* Setup link and flow control */	ret_val = e1000_setup_link(hw);	txdctl = E1000_READ_REG(hw, E1000_TXDCTL(0));	txdctl = (txdctl & ~E1000_TXDCTL_WTHRESH) |	         E1000_TXDCTL_FULL_TX_DESC_WB;	E1000_WRITE_REG(hw, E1000_TXDCTL(0), txdctl);	/*	 * Clear all of the statistics registers (clear on read).  It is	 * important that we do this after we have tried to establish link	 * because the symbol error count will increment wildly if there	 * is no link.	 */	e1000_clear_hw_cntrs_82540(hw);	if ((hw->device_id == E1000_DEV_ID_82546GB_QUAD_COPPER) ||	    (hw->device_id == E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3)) {		ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT);		/*		 * Relaxed ordering must be disabled to avoid a parity		 * error crash in a PCI slot.		 */		ctrl_ext |= E1000_CTRL_EXT_RO_DIS;		E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext);	}	return ret_val;}/** *  e1000_setup_copper_link_82540 - Configure copper link settings *  @hw: pointer to the HW structure * *  Calls the appropriate function to configure the link for auto-neg or forced *  speed and duplex.  Then we check for link, once link is established calls *  to configure collision distance and flow control are called.  If link is *  not established, we return -E1000_ERR_PHY (-2).  This is a function *  pointer entry point called by the api module. **/static s32 e1000_setup_copper_link_82540(struct e1000_hw *hw){	u32 ctrl;	s32 ret_val = E1000_SUCCESS;	u16 data;	DEBUGFUNC("e1000_setup_copper_link_82540");	ctrl = E1000_READ_REG(hw, E1000_CTRL);	ctrl |= E1000_CTRL_SLU;	ctrl &= ~(E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);	E1000_WRITE_REG(hw, E1000_CTRL, ctrl);	ret_val = e1000_set_phy_mode_82540(hw);	if (ret_val)		goto out;	if (hw->mac.type == e1000_82545_rev_3 ||	    hw->mac.type == e1000_82546_rev_3) {		ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &data);		if (ret_val)			goto out;		data |= 0x00000008;		ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, data);		if (ret_val)			goto out;	}	ret_val = e1000_copper_link_setup_m88(hw);	if (ret_val)		goto out;	ret_val = e1000_setup_copper_link_generic(hw);out:	return ret_val;}/** *  e1000_setup_fiber_serdes_link_82540 - Setup link for fiber/serdes *  @hw: pointer to the HW structure * *  Set the output amplitude to the value in the EEPROM and adjust the VCO *  speed to improve Bit Error Rate (BER) performance.  Configures collision *  distance and flow control for fiber and serdes links.  Upon successful *  setup, poll for link.  This is a function pointer entry point called by *  the api module. **/static s32 e1000_setup_fiber_serdes_link_82540(struct e1000_hw *hw){	struct e1000_mac_info *mac = &hw->mac;	s32 ret_val = E1000_SUCCESS;	DEBUGFUNC("e1000_setup_fiber_serdes_link_82540");	switch (mac->type) {	case e1000_82545_rev_3:	case e1000_82546_rev_3:		if (hw->phy.media_type == e1000_media_type_internal_serdes) {			/*			 * If we're on serdes media, adjust the output			 * amplitude to value set in the EEPROM.			 */			ret_val = e1000_adjust_serdes_amplitude_82540(hw);			if (ret_val)				goto out;		}		/* Adjust VCO speed to improve BER performance */		ret_val = e1000_set_vco_speed_82540(hw);		if (ret_val)			goto out;	default:		break;	}	ret_val = e1000_setup_fiber_serdes_link_generic(hw);out:	return ret_val;}/** *  e1000_adjust_serdes_amplitude_82540 - Adjust amplitude based on EEPROM *  @hw: pointer to the HW structure * *  Adjust the SERDES ouput amplitude based on the EEPROM settings. **/static s32 e1000_adjust_serdes_amplitude_82540(struct e1000_hw *hw){	s32 ret_val = E1000_SUCCESS;	u16 nvm_data;	DEBUGFUNC("e1000_adjust_serdes_amplitude_82540");	ret_val = e1000_read_nvm(hw, NVM_SERDES_AMPLITUDE, 1, &nvm_data);	if (ret_val)		goto out;	if (nvm_data != NVM_RESERVED_WORD) {		/* Adjust serdes output amplitude only. */		nvm_data &= NVM_SERDES_AMPLITUDE_MASK;		ret_val = e1000_write_phy_reg(hw,		                             M88E1000_PHY_EXT_CTRL,		                             nvm_data);		if (ret_val)			goto out;	}out:	return ret_val;}/** *  e1000_set_vco_speed_82540 - Set VCO speed for better performance *  @hw: pointer to the HW structure * *  Set the VCO speed to improve Bit Error Rate (BER) performance. **/static s32 e1000_set_vco_speed_82540(struct e1000_hw *hw){	s32  ret_val = E1000_SUCCESS;	u16 default_page = 0;	u16 phy_data;	DEBUGFUNC("e1000_set_vco_speed_82540");	/* Set PHY register 30, page 5, bit 8 to 0 */	ret_val = e1000_read_phy_reg(hw,	                            M88E1000_PHY_PAGE_SELECT,	                            &default_page);	if (ret_val)		goto out;	ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0005);	if (ret_val)		goto out;	ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, &phy_data);	if (ret_val)		goto out;	phy_data &= ~M88E1000_PHY_VCO_REG_BIT8;	ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, phy_data);	if (ret_val)		goto out;	/* Set PHY register 30, page 4, bit 11 to 1 */	ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0004);	if (ret_val)		goto out;	ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, &phy_data);	if (ret_val)		goto out;	phy_data |= M88E1000_PHY_VCO_REG_BIT11;	ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, phy_data);	if (ret_val)		goto out;	ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT,	                              default_page);out:	return ret_val;}/** *  e1000_set_phy_mode_82540 - Set PHY to class A mode *  @hw: pointer to the HW structure * *  Sets the PHY to class A mode and assumes the following operations will *  follow to enable the new class mode: *    1.  Do a PHY soft reset. *    2.  Restart auto-negotiation or force link. **/static s32 e1000_set_phy_mode_82540(struct e1000_hw *hw){	struct e1000_phy_info *phy = &hw->phy;	s32 ret_val = E1000_SUCCESS;	u16 nvm_data;	DEBUGFUNC("e1000_set_phy_mode_82540");	if (hw->mac.type != e1000_82545_rev_3)		goto out;	ret_val = e1000_read_nvm(hw, NVM_PHY_CLASS_WORD, 1, &nvm_data);	if (ret_val) {		ret_val = -E1000_ERR_PHY;		goto out;	}	if ((nvm_data != NVM_RESERVED_WORD) && (nvm_data & NVM_PHY_CLASS_A)) {		ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT,		                              0x000B);		if (ret_val) {			ret_val = -E1000_ERR_PHY;			goto out;		}		ret_val = e1000_write_phy_reg(hw,		                              M88E1000_PHY_GEN_CONTROL,		                              0x8104);		if (ret_val) {			ret_val = -E1000_ERR_PHY;			goto out;		}		phy->reset_disable = FALSE;	}out:	return ret_val;}/** * e1000_power_down_phy_copper_82540 - Remove link in case of PHY power down * @hw: pointer to the HW structure * * In the case of a PHY power down to save power, or to turn off link during a * driver unload, or wake on lan is not enabled, remove the link. **/static void e1000_power_down_phy_copper_82540(struct e1000_hw *hw){	/* If the management interface is not enabled, then power down */	if (!(E1000_READ_REG(hw, E1000_MANC) & E1000_MANC_SMBUS_EN))		e1000_power_down_phy_copper(hw);	return;}/** *  e1000_clear_hw_cntrs_82540 - Clear device specific hardware counters *  @hw: pointer to the HW structure * *  Clears the hardware counters by reading the counter registers. **/static void e1000_clear_hw_cntrs_82540(struct e1000_hw *hw){	volatile u32 temp;	DEBUGFUNC("e1000_clear_hw_cntrs_82540");	e1000_clear_hw_cntrs_base_generic(hw);	temp = E1000_READ_REG(hw, E1000_PRC64);	temp = E1000_READ_REG(hw, E1000_PRC127);	temp = E1000_READ_REG(hw, E1000_PRC255);	temp = E1000_READ_REG(hw, E1000_PRC511);	temp = E1000_READ_REG(hw, E1000_PRC1023);	temp = E1000_READ_REG(hw, E1000_PRC1522);	temp = E1000_READ_REG(hw, E1000_PTC64);	temp = E1000_READ_REG(hw, E1000_PTC127);	temp = E1000_READ_REG(hw, E1000_PTC255);	temp = E1000_READ_REG(hw, E1000_PTC511);	temp = E1000_READ_REG(hw, E1000_PTC1023);	temp = E1000_READ_REG(hw, E1000_PTC1522);	temp = E1000_READ_REG(hw, E1000_ALGNERRC);	temp = E1000_READ_REG(hw, E1000_RXERRC);	temp = E1000_READ_REG(hw, E1000_TNCRS);	temp = E1000_READ_REG(hw, E1000_CEXTERR);	temp = E1000_READ_REG(hw, E1000_TSCTC);	temp = E1000_READ_REG(hw, E1000_TSCTFC);	temp = E1000_READ_REG(hw, E1000_MGTPRC);	temp = E1000_READ_REG(hw, E1000_MGTPDC);	temp = E1000_READ_REG(hw, E1000_MGTPTC);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -