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

📄 lib.c

📁 grub源码分析文档
💻 C
📖 第 1 页 / 共 5 页
字号:
		ew32(CTRL, ctrl);		/* Configure Flow Control after forcing link up. */		ret_val = e1000e_config_fc_after_link_up(hw);		if (ret_val) {			hw_dbg(hw, "Error configuring flow control\n");			return ret_val;		}	} else if ((ctrl & E1000_CTRL_SLU) && (rxcw & E1000_RXCW_C)) {		/*		 * If we are forcing link and we are receiving /C/ ordered		 * sets, re-enable auto-negotiation in the TXCW register		 * and disable forced link in the Device Control register		 * in an attempt to auto-negotiate with our link partner.		 */		hw_dbg(hw, "RXing /C/, enable AutoNeg and stop forcing link.\n");		ew32(TXCW, mac->txcw);		ew32(CTRL, (ctrl & ~E1000_CTRL_SLU));		mac->serdes_has_link = 1;	}	return 0;}/** *  e1000e_check_for_serdes_link - Check for link (Serdes) *  @hw: pointer to the HW structure * *  Checks for link up on the hardware.  If link is not up and we have *  a signal, then we need to force link up. **/s32 e1000e_check_for_serdes_link(struct e1000_hw *hw){	struct e1000_mac_info *mac = &hw->mac;	u32 rxcw;	u32 ctrl;	u32 status;	s32 ret_val;	ctrl = er32(CTRL);	status = er32(STATUS);	rxcw = er32(RXCW);	/*	 * If we don't have link (auto-negotiation failed or link partner	 * cannot auto-negotiate), and our link partner is not trying to	 * auto-negotiate with us (we are receiving idles or data),	 * we need to force link up. We also need to give auto-negotiation	 * time to complete.	 */	/* (ctrl & E1000_CTRL_SWDPIN1) == 1 == have signal */	if ((!(status & E1000_STATUS_LU)) && (!(rxcw & E1000_RXCW_C))) {		if (mac->autoneg_failed == 0) {			mac->autoneg_failed = 1;			return 0;		}		hw_dbg(hw, "NOT RXing /C/, disable AutoNeg and force link.\n");		/* Disable auto-negotiation in the TXCW register */		ew32(TXCW, (mac->txcw & ~E1000_TXCW_ANE));		/* Force link-up and also force full-duplex. */		ctrl = er32(CTRL);		ctrl |= (E1000_CTRL_SLU | E1000_CTRL_FD);		ew32(CTRL, ctrl);		/* Configure Flow Control after forcing link up. */		ret_val = e1000e_config_fc_after_link_up(hw);		if (ret_val) {			hw_dbg(hw, "Error configuring flow control\n");			return ret_val;		}	} else if ((ctrl & E1000_CTRL_SLU) && (rxcw & E1000_RXCW_C)) {		/*		 * If we are forcing link and we are receiving /C/ ordered		 * sets, re-enable auto-negotiation in the TXCW register		 * and disable forced link in the Device Control register		 * in an attempt to auto-negotiate with our link partner.		 */		hw_dbg(hw, "RXing /C/, enable AutoNeg and stop forcing link.\n");		ew32(TXCW, mac->txcw);		ew32(CTRL, (ctrl & ~E1000_CTRL_SLU));		mac->serdes_has_link = 1;	} else if (!(E1000_TXCW_ANE & er32(TXCW))) {		/*		 * If we force link for non-auto-negotiation switch, check		 * link status based on MAC synchronization for internal		 * serdes media type.		 */		/* SYNCH bit and IV bit are sticky. */		udelay(10);		if (E1000_RXCW_SYNCH & er32(RXCW)) {			if (!(rxcw & E1000_RXCW_IV)) {				mac->serdes_has_link = 1;				hw_dbg(hw, "SERDES: Link is up.\n");			}		} else {			mac->serdes_has_link = 0;			hw_dbg(hw, "SERDES: Link is down.\n");		}	}	if (E1000_TXCW_ANE & er32(TXCW)) {		status = er32(STATUS);		mac->serdes_has_link = (status & E1000_STATUS_LU);	}	return 0;}/** *  e1000_set_default_fc_generic - Set flow control default values *  @hw: pointer to the HW structure * *  Read the EEPROM for the default values for flow control and store the *  values. **/static s32 e1000_set_default_fc_generic(struct e1000_hw *hw){	s32 ret_val;	u16 nvm_data;	/*	 * Read and store word 0x0F of the EEPROM. This word contains bits	 * that determine the hardware's default PAUSE (flow control) mode,	 * a bit that determines whether the HW defaults to enabling or	 * disabling auto-negotiation, and the direction of the	 * SW defined pins. If there is no SW over-ride of the flow	 * control setting, then the variable hw->fc will	 * be initialized based on a value in the EEPROM.	 */	ret_val = e1000_read_nvm(hw, NVM_INIT_CONTROL2_REG, 1, &nvm_data);	if (ret_val) {		hw_dbg(hw, "NVM Read Error\n");		return ret_val;	}	if ((nvm_data & NVM_WORD0F_PAUSE_MASK) == 0)		hw->fc.type = e1000_fc_none;	else if ((nvm_data & NVM_WORD0F_PAUSE_MASK) ==		 NVM_WORD0F_ASM_DIR)		hw->fc.type = e1000_fc_tx_pause;	else		hw->fc.type = e1000_fc_full;	return 0;}/** *  e1000e_setup_link - Setup flow control and link settings *  @hw: pointer to the HW structure * *  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. **/s32 e1000e_setup_link(struct e1000_hw *hw){	struct e1000_mac_info *mac = &hw->mac;	s32 ret_val;	/*	 * In the case of the phy reset being blocked, we already have a link.	 * We do not need to set it up again.	 */	if (e1000_check_reset_block(hw))		return 0;	/*	 * If flow control is set to default, set flow control based on	 * the EEPROM flow control settings.	 */	if (hw->fc.type == e1000_fc_default) {		ret_val = e1000_set_default_fc_generic(hw);		if (ret_val)			return ret_val;	}	/*	 * We want to save off the original Flow Control configuration just	 * in case we get disconnected and then reconnected into a different	 * hub or switch with different Flow Control capabilities.	 */	hw->fc.original_type = hw->fc.type;	hw_dbg(hw, "After fix-ups FlowControl is now = %x\n", hw->fc.type);	/* Call the necessary media_type subroutine to configure the link. */	ret_val = mac->ops.setup_physical_interface(hw);	if (ret_val)		return ret_val;	/*	 * Initialize the flow control address, type, and PAUSE timer	 * registers to their default values.  This is done even if flow	 * control is disabled, because it does not hurt anything to	 * initialize these registers.	 */	hw_dbg(hw, "Initializing the Flow Control address, type and timer regs\n");	ew32(FCT, FLOW_CONTROL_TYPE);	ew32(FCAH, FLOW_CONTROL_ADDRESS_HIGH);	ew32(FCAL, FLOW_CONTROL_ADDRESS_LOW);	ew32(FCTTV, hw->fc.pause_time);	return e1000e_set_fc_watermarks(hw);}/** *  e1000_commit_fc_settings_generic - Configure flow control *  @hw: pointer to the HW structure * *  Write the flow control settings to the Transmit Config Word Register (TXCW) *  base on the flow control settings in e1000_mac_info. **/static s32 e1000_commit_fc_settings_generic(struct e1000_hw *hw){	struct e1000_mac_info *mac = &hw->mac;	u32 txcw;	/*	 * Check for a software override of the flow control settings, and	 * setup the device accordingly.  If auto-negotiation is enabled, then	 * software will have to set the "PAUSE" bits to the correct value in	 * the Transmit Config Word Register (TXCW) and re-start auto-	 * negotiation.  However, if auto-negotiation is disabled, then	 * software will have to manually configure the two flow control enable	 * bits in the CTRL register.	 *	 * The possible values of the "fc" parameter are:	 *      0:  Flow control is completely disabled	 *      1:  Rx flow control is enabled (we can receive pause frames,	 *	  but not send pause frames).	 *      2:  Tx flow control is enabled (we can send pause frames but we	 *	  do not support receiving pause frames).	 *      3:  Both Rx and Tx flow control (symmetric) are enabled.	 */	switch (hw->fc.type) {	case e1000_fc_none:		/* Flow control completely disabled by a software over-ride. */		txcw = (E1000_TXCW_ANE | E1000_TXCW_FD);		break;	case e1000_fc_rx_pause:		/*		 * Rx Flow control is enabled and Tx Flow control is disabled		 * by a software over-ride. Since there really isn't a way to		 * advertise that we are capable of Rx Pause ONLY, we will		 * advertise that we support both symmetric and asymmetric Rx		 * PAUSE.  Later, we will disable the adapter's ability to send		 * PAUSE frames.		 */		txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_PAUSE_MASK);		break;	case e1000_fc_tx_pause:		/*		 * Tx Flow control is enabled, and Rx Flow control is disabled,		 * by a software over-ride.		 */		txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_ASM_DIR);		break;	case e1000_fc_full:		/*		 * Flow control (both Rx and Tx) is enabled by a software		 * over-ride.		 */		txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_PAUSE_MASK);		break;	default:		hw_dbg(hw, "Flow control param set incorrectly\n");		return -E1000_ERR_CONFIG;		break;	}	ew32(TXCW, txcw);	mac->txcw = txcw;	return 0;}/** *  e1000_poll_fiber_serdes_link_generic - Poll for link up *  @hw: pointer to the HW structure * *  Polls for link up by reading the status register, if link fails to come *  up with auto-negotiation, then the link is forced if a signal is detected. **/static s32 e1000_poll_fiber_serdes_link_generic(struct e1000_hw *hw){	struct e1000_mac_info *mac = &hw->mac;	u32 i, status;	s32 ret_val;	/*	 * If we have a signal (the cable is plugged in, or assumed true for	 * serdes media) then poll for a "Link-Up" indication in the Device	 * Status Register.  Time-out if a link isn't seen in 500 milliseconds	 * seconds (Auto-negotiation should complete in less than 500	 * milliseconds even if the other end is doing it in SW).	 */	for (i = 0; i < FIBER_LINK_UP_LIMIT; i++) {		msleep(10);		status = er32(STATUS);		if (status & E1000_STATUS_LU)			break;	}	if (i == FIBER_LINK_UP_LIMIT) {		hw_dbg(hw, "Never got a valid link from auto-neg!!!\n");		mac->autoneg_failed = 1;		/*		 * AutoNeg failed to achieve a link, so we'll call		 * mac->check_for_link. This routine will force the		 * link up if we detect a signal. This will allow us to		 * communicate with non-autonegotiating link partners.		 */		ret_val = mac->ops.check_for_link(hw);		if (ret_val) {			hw_dbg(hw, "Error while checking for link\n");			return ret_val;		}		mac->autoneg_failed = 0;	} else {		mac->autoneg_failed = 0;		hw_dbg(hw, "Valid Link Found\n");	}	return 0;}/** *  e1000e_setup_fiber_serdes_link - Setup link for fiber/serdes *  @hw: pointer to the HW structure * *  Configures collision distance and flow control for fiber and serdes *  links.  Upon successful setup, poll for link. **/s32 e1000e_setup_fiber_serdes_link(struct e1000_hw *hw){	u32 ctrl;	s32 ret_val;	ctrl = er32(CTRL);	/* Take the link out of reset */	ctrl &= ~E1000_CTRL_LRST;	e1000e_config_collision_dist(hw);	ret_val = e1000_commit_fc_settings_generic(hw);	if (ret_val)		return ret_val;	/*	 * Since auto-negotiation is enabled, take the link out of reset (the	 * link will be in reset, because we previously reset the chip). This	 * will restart auto-negotiation.  If auto-negotiation is successful	 * then the link-up status bit will be set and the flow control enable	 * bits (RFCE and TFCE) will be set according to their negotiated value.	 */	hw_dbg(hw, "Auto-negotiation enabled\n");	ew32(CTRL, ctrl);	e1e_flush();	msleep(1);	/*	 * For these adapters, the SW definable pin 1 is set when the optics	 * detect a signal.  If we have a signal, then poll for a "Link-Up"	 * indication.	 */	if (hw->phy.media_type == e1000_media_type_internal_serdes ||	    (er32(CTRL) & E1000_CTRL_SWDPIN1)) {		ret_val = e1000_poll_fiber_serdes_link_generic(hw);	} else {		hw_dbg(hw, "No signal detected\n");	}	return 0;}/** *  e1000e_config_collision_dist - Configure collision distance *  @hw: pointer to the HW structure * *  Configures the collision distance to the default value and is used *  during link setup. Currently no func pointer exists and all *  implementations are handled in the generic version of this function. **/void e1000e_config_collision_dist(struct e1000_hw *hw){	u32 tctl;	tctl = er32(TCTL);	tctl &= ~E1000_TCTL_COLD;	tctl |= E1000_COLLISION_DISTANCE << E1000_COLD_SHIFT;	ew32(TCTL, tctl);	e1e_flush();}/** *  e1000e_set_fc_watermarks - Set flow control high/low watermarks *  @hw: pointer to the HW structure * *  Sets the flow control high/low threshold (watermark) registers.  If *  flow control XON frame transmission is enabled, then set XON frame *  transmission as well. **/s32 e1000e_set_fc_watermarks(struct e1000_hw *hw){	u32 fcrtl = 0, fcrth = 0;	/*	 * Set the flow control receive threshold registers.  Normally,	 * these registers will be set to a default threshold that may be	 * adjusted later by the driver's runtime code.  However, if the	 * ability to transmit pause frames is not enabled, then these	 * registers will be set to 0.	 */	if (hw->fc.type & e1000_fc_tx_pause) {		/*		 * We need to set up the Receive Threshold high and low water		 * marks as well as (optionally) enabling the transmission of		 * XON frames.		 */		fcrtl = hw->fc.low_water;		fcrtl |= E1000_FCRTL_XONE;		fcrth = hw->fc.high_water;	}	ew32(FCRTL, fcrtl);	ew32(FCRTH, fcrth);	return 0;}/** *  e1000e_force_mac_fc - Force the MAC's flow control settings *  @hw: pointer to the HW structure * *  Force the MAC's flow control settings.  Sets the TFCE and RFCE bits in the *  device control register to reflect the adapter settings.  TFCE and RFCE *  need to be explicitly set by software when a copper PHY is used because *  autonegotiation is managed by the PHY rather than the MAC.  Software must *  also configure these bits when link is forced on a fiber connection. **/s32 e1000e_force_mac_fc(struct e1000_hw *hw){	u32 ctrl;	ctrl = er32(CTRL);	/*	 * Because we didn't get link via the internal auto-negotiation	 * mechanism (we either forced link or we got link via PHY	 * auto-neg), we have to manually enable/disable transmit an	 * receive flow control.	 *	 * The "Case" statement below enables/disable flow control	 * according to the "hw->fc.type" parameter.	 *	 * The possible values of the "fc" parameter are:	 *      0:  Flow control is completely disabled	 *      1:  Rx flow control is enabled (we can receive pause	 *	  frames but not send pause frames).	 *      2:  Tx flow control is enabled (we can send pause frames	 *	  frames but we do not receive pause frames).	 *      3:  Both Rx and Tx flow control (symmetric) is enabled.	 *  other:  No other values should be possible at this point.	 */	hw_dbg(hw, "hw->fc.type = %u\n", hw->fc.type);	switch (hw->fc.type) {	case e1000_fc_none:		ctrl &= (~(E1000_CTRL_TFCE | E1000_CTRL_RFCE));		break;	case e1000_fc_rx_pause:		ctrl &= (~E1000_CTRL_TFCE);		ctrl |= E1000_CTRL_RFCE;		break;

⌨️ 快捷键说明

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