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

📄 e1000_82543.c

📁 linux系统的网卡驱动包
💻 C
📖 第 1 页 / 共 4 页
字号:
		goto out;	ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0000);	if (ret_val)		goto out;	/*	 * This loop will early-out if the NO link condition has been met.	 * In other words, DO NOT use e1000_phy_has_link_generic() here.	 */	for (i = PHY_FORCE_TIME; i > 0; i--) {		/*		 * Read the MII Status Register and wait for Link Status bit		 * to be clear.		 */		ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);		if (ret_val)			goto out;		ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);		if (ret_val)			goto out;		if ((mii_status_reg & ~MII_SR_LINK_STATUS) == 0)			break;		msec_delay_irq(100);	}	/* Recommended delay time after link has been lost */	msec_delay_irq(1000);	/* Now we will re-enable the transmitter on the PHY */	ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0019);	if (ret_val)		goto out;	msec_delay_irq(50);	ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, 0xFFF0);	if (ret_val)		goto out;	msec_delay_irq(50);	ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, 0xFF00);	if (ret_val)		goto out;	msec_delay_irq(50);	ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, 0x0000);	if (ret_val)		goto out;	ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0000);	if (ret_val)		goto out;	/*	 * Read the MII Status Register and wait for Link Status bit	 * to be set.	 */	ret_val = e1000_phy_has_link_generic(hw, PHY_FORCE_TIME, 100000, &link);	if (ret_val)		goto out;out:	return ret_val;}/** *  e1000_phy_hw_reset_82543 - PHY hardware reset *  @hw: pointer to the HW structure * *  Sets the PHY_RESET_DIR bit in the extended device control register *  to put the PHY into a reset and waits for completion.  Once the reset *  has been accomplished, clear the PHY_RESET_DIR bit to take the PHY out *  of reset.  This is a function pointer entry point called by the api module. **/static s32 e1000_phy_hw_reset_82543(struct e1000_hw *hw){	struct e1000_functions *func = &hw->func;	u32 ctrl_ext;	s32 ret_val;	DEBUGFUNC("e1000_phy_hw_reset_82543");	/*	 * Read the Extended Device Control Register, assert the PHY_RESET_DIR	 * bit to put the PHY into reset...	 */	ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT);	ctrl_ext |= E1000_CTRL_EXT_SDP4_DIR;	ctrl_ext &= ~E1000_CTRL_EXT_SDP4_DATA;	E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext);	E1000_WRITE_FLUSH(hw);	msec_delay(10);	/* ...then take it out of reset. */	ctrl_ext |= E1000_CTRL_EXT_SDP4_DATA;	E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext);	E1000_WRITE_FLUSH(hw);	usec_delay(150);	ret_val = func->get_cfg_done(hw);	return ret_val;}/** *  e1000_reset_hw_82543 - Reset hardware *  @hw: pointer to the HW structure * *  This resets the hardware into a known state.  This is a *  function pointer entry point called by the api module. **/static s32 e1000_reset_hw_82543(struct e1000_hw *hw){	u32 ctrl, icr;	s32 ret_val = E1000_SUCCESS;	DEBUGFUNC("e1000_reset_hw_82543");	DEBUGOUT("Masking off all interrupts\n");	E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff);	E1000_WRITE_REG(hw, E1000_RCTL, 0);	E1000_WRITE_REG(hw, E1000_TCTL, E1000_TCTL_PSP);	E1000_WRITE_FLUSH(hw);	e1000_set_tbi_sbp_82543(hw, FALSE);	/*	 * Delay to allow any outstanding PCI transactions to complete before	 * resetting the device	 */	msec_delay(10);	ctrl = E1000_READ_REG(hw, E1000_CTRL);	DEBUGOUT("Issuing a global reset to 82543/82544 MAC\n");	if (hw->mac.type == e1000_82543) {		E1000_WRITE_REG(hw, E1000_CTRL, ctrl | E1000_CTRL_RST);	} else {		/*		 * The 82544 can't ACK the 64-bit write when issuing the		 * reset, so use IO-mapping as a workaround.		 */		E1000_WRITE_REG_IO(hw, E1000_CTRL, ctrl | E1000_CTRL_RST);	}	/*	 * After MAC reset, force reload of NVM to restore power-on	 * settings to device.	 */	e1000_reload_nvm(hw);	msec_delay(2);	/* Masking off and clearing any pending interrupts */	E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff);	icr = E1000_READ_REG(hw, E1000_ICR);	return ret_val;}/** *  e1000_init_hw_82543 - Initialize hardware *  @hw: pointer to the HW structure * *  This inits the hardware readying it for operation. **/static s32 e1000_init_hw_82543(struct e1000_hw *hw){	struct e1000_mac_info *mac = &hw->mac;	struct e1000_dev_spec_82543 *dev_spec;	u32 ctrl;	s32 ret_val;	u16 i;	DEBUGFUNC("e1000_init_hw_82543");	dev_spec = (struct e1000_dev_spec_82543 *)hw->dev_spec;	if (!dev_spec) {		DEBUGOUT("dev_spec pointer is set to NULL.\n");		ret_val = -E1000_ERR_CONFIG;		goto out;	}	/* Disabling VLAN filtering */	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);		E1000_WRITE_FLUSH(hw);	}	/*	 * Set the PCI priority bit correctly in the CTRL register.  This	 * determines if the adapter gives priority to receives, or if it	 * gives equal priority to transmits and receives.	 */	if (hw->mac.type == e1000_82543 && dev_spec->dma_fairness) {		ctrl = E1000_READ_REG(hw, E1000_CTRL);		E1000_WRITE_REG(hw, E1000_CTRL, ctrl | E1000_CTRL_PRIOR);	}	e1000_pcix_mmrbc_workaround_generic(hw);	/* Setup link and flow control */	ret_val = e1000_setup_link(hw);	/*	 * 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_82543(hw);out:	return ret_val;}/** *  e1000_setup_link_82543 - Setup flow control and link settings *  @hw: pointer to the HW structure * *  Read the EEPROM to determine the initial polarity value and write the *  extended device control register with the information before calling *  the generic setup link function, which does the following: *  Determines which flow control settings to use, then configures flow *  control.  Calls the appropriate media-specific link configuration *  function.  Assuming the adapter has a valid link partner, a valid link *  should be established.  Assumes the hardware has previously been reset *  and the transmitter and receiver are not enabled. **/static s32 e1000_setup_link_82543(struct e1000_hw *hw){	u32 ctrl_ext;	s32  ret_val;	u16 data;	DEBUGFUNC("e1000_setup_link_82543");	/*	 * Take the 4 bits from NVM word 0xF that determine the initial	 * polarity value for the SW controlled pins, and setup the	 * Extended Device Control reg with that info.	 * This is needed because one of the SW controlled pins is used for	 * signal detection.  So this should be done before phy setup.	 */	if (hw->mac.type == e1000_82543) {		ret_val = e1000_read_nvm(hw, NVM_INIT_CONTROL2_REG, 1, &data);		if (ret_val) {			DEBUGOUT("NVM Read Error\n");			ret_val = -E1000_ERR_NVM;			goto out;		}		ctrl_ext = ((data & NVM_WORD0F_SWPDIO_EXT_MASK) <<		            NVM_SWDPIO_EXT_SHIFT);		E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext);	}	ret_val = e1000_setup_link_generic(hw);out:	return ret_val;}/** *  e1000_setup_copper_link_82543 - Configure copper link settings *  @hw: pointer to the HW structure * *  Configures 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. **/static s32 e1000_setup_copper_link_82543(struct e1000_hw *hw){	u32 ctrl;	s32 ret_val;	bool link;	DEBUGFUNC("e1000_setup_copper_link_82543");	ctrl = E1000_READ_REG(hw, E1000_CTRL) | E1000_CTRL_SLU;	/*	 * With 82543, we need to force speed and duplex on the MAC	 * equal to what the PHY speed and duplex configuration is.	 * In addition, we need to perform a hardware reset on the	 * PHY to take it out of reset.	 */	if (hw->mac.type == e1000_82543) {		ctrl |= (E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);		E1000_WRITE_REG(hw, E1000_CTRL, ctrl);		ret_val = e1000_phy_hw_reset(hw);		if (ret_val)			goto out;		hw->phy.reset_disable = FALSE;	} else {		ctrl &= ~(E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);		E1000_WRITE_REG(hw, E1000_CTRL, ctrl);	}	/* Set MDI/MDI-X, Polarity Reversal, and downshift settings */	ret_val = e1000_copper_link_setup_m88(hw);	if (ret_val)		goto out;	if (hw->mac.autoneg) {		/*		 * Setup autoneg and flow control advertisement and perform		 * autonegotiation.		 */		ret_val = e1000_copper_link_autoneg(hw);		if (ret_val)			goto out;	} else {		/*		 * PHY will be set to 10H, 10F, 100H or 100F		 * depending on user settings.		 */		DEBUGOUT("Forcing Speed and Duplex\n");		ret_val = e1000_phy_force_speed_duplex_82543(hw);		if (ret_val) {			DEBUGOUT("Error Forcing Speed and Duplex\n");			goto out;		}	}	/*	 * Check link status. Wait up to 100 microseconds for link to become	 * valid.	 */	ret_val = e1000_phy_has_link_generic(hw,	                                     COPPER_LINK_UP_LIMIT,	                                     10,	                                     &link);	if (ret_val)		goto out;	if (link) {		DEBUGOUT("Valid link established!!!\n");		/* Config the MAC and PHY after link is up */		if (hw->mac.type == e1000_82544) {			e1000_config_collision_dist_generic(hw);		} else {			ret_val = e1000_config_mac_to_phy_82543(hw);			if (ret_val)				goto out;		}		ret_val = e1000_config_fc_after_link_up_generic(hw);	} else {		DEBUGOUT("Unable to establish link!!!\n");	}out:	return ret_val;}/** *  e1000_setup_fiber_link_82543 - Setup link for fiber *  @hw: pointer to the HW structure * *  Configures collision distance and flow control for fiber links.  Upon *  successful setup, poll for link. **/static s32 e1000_setup_fiber_link_82543(struct e1000_hw *hw){	u32 ctrl;	s32 ret_val;	DEBUGFUNC("e1000_setup_fiber_link_82543");	ctrl = E1000_READ_REG(hw, E1000_CTRL);	/* Take the link out of reset */	ctrl &= ~E1000_CTRL_LRST;	e1000_config_collision_dist_generic(hw);	ret_val = e1000_commit_fc_settings_generic(hw);	if (ret_val)		goto out;	DEBUGOUT("Auto-negotiation enabled\n");	E1000_WRITE_REG(hw, E1000_CTRL, ctrl);	E1000_WRITE_FLUSH(hw);	msec_delay(1);	/*	 * For these adapters, the SW defineable pin 1 is cleared when the	 * optics detect a signal.  If we have a signal, then poll for a	 * "Link-Up" indication.	 */	if (!(E1000_READ_REG(hw, E1000_CTRL) & E1000_CTRL_SWDPIN1)) {		ret_val = e1000_poll_fiber_serdes_link_generic(hw);	} else {		DEBUGOUT("No signal detected\n");	}out:	return ret_val;}/** *  e1000_check_for_copper_link_82543 - Check for link (Copper)

⌨️ 快捷键说明

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