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

📄 e1000.c

📁 F:worksip2440a board可启动u-boot-like.tar.gz F:worksip2440a board可启动u-boot-like.tar.gz
💻 C
📖 第 1 页 / 共 5 页
字号:
	default:		DEBUGOUT("Flow control param set incorrectly\n");		return -E1000_ERR_CONFIG;	}	/* Disable TX Flow Control for 82542 (rev 2.0) */	if (hw->mac_type == e1000_82542_rev2_0)		ctrl &= (~E1000_CTRL_TFCE);	E1000_WRITE_REG(hw, CTRL, ctrl);	return 0;}/****************************************************************************** * Configures flow control settings after link is established * * hw - Struct containing variables accessed by shared code * * Should be called immediately after a valid link has been established. * Forces MAC flow control settings if link was forced. When in MII/GMII mode * and autonegotiation is enabled, the MAC flow control settings will be set * based on the flow control negotiated by the PHY. In TBI mode, the TFCE * and RFCE bits will be automaticaly set to the negotiated flow control mode. *****************************************************************************/static inte1000_config_fc_after_link_up(struct e1000_hw *hw){	int32_t ret_val;	uint16_t mii_status_reg;	uint16_t mii_nway_adv_reg;	uint16_t mii_nway_lp_ability_reg;	uint16_t speed;	uint16_t duplex;	DEBUGFUNC();	/* Check for the case where we have fiber media and auto-neg failed	 * so we had to force link.  In this case, we need to force the	 * configuration of the MAC to match the "fc" parameter.	 */	if ((hw->media_type == e1000_media_type_fiber) && (hw->autoneg_failed)) {		ret_val = e1000_force_mac_fc(hw);		if (ret_val < 0) {			DEBUGOUT("Error forcing flow control settings\n");			return ret_val;		}	}	/* Check for the case where we have copper media and auto-neg is	 * enabled.  In this case, we need to check and see if Auto-Neg	 * has completed, and if so, how the PHY and link partner has	 * flow control configured.	 */	if (hw->media_type == e1000_media_type_copper) {		/* Read the MII Status Register and check to see if AutoNeg		 * has completed.  We read this twice because this reg has		 * some "sticky" (latched) bits.		 */		if (e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg) < 0) {			DEBUGOUT("PHY Read Error \n");			return -E1000_ERR_PHY;		}		if (e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg) < 0) {			DEBUGOUT("PHY Read Error \n");			return -E1000_ERR_PHY;		}		if (mii_status_reg & MII_SR_AUTONEG_COMPLETE) {			/* The AutoNeg process has completed, so we now need to			 * read both the Auto Negotiation Advertisement Register			 * (Address 4) and the Auto_Negotiation Base Page Ability			 * Register (Address 5) to determine how flow control was			 * negotiated.			 */			if (e1000_read_phy_reg			    (hw, PHY_AUTONEG_ADV, &mii_nway_adv_reg) < 0) {				DEBUGOUT("PHY Read Error\n");				return -E1000_ERR_PHY;			}			if (e1000_read_phy_reg			    (hw, PHY_LP_ABILITY,			     &mii_nway_lp_ability_reg) < 0) {				DEBUGOUT("PHY Read Error\n");				return -E1000_ERR_PHY;			}			/* Two bits in the Auto Negotiation Advertisement Register			 * (Address 4) and two bits in the Auto Negotiation Base			 * Page Ability Register (Address 5) determine flow control			 * for both the PHY and the link partner.  The following			 * table, taken out of the IEEE 802.3ab/D6.0 dated March 25,			 * 1999, describes these PAUSE resolution bits and how flow			 * control is determined based upon these settings.			 * NOTE:  DC = Don't Care			 *			 *   LOCAL DEVICE  |   LINK PARTNER			 * PAUSE | ASM_DIR | PAUSE | ASM_DIR | NIC Resolution			 *-------|---------|-------|---------|--------------------			 *   0   |    0    |  DC   |   DC    | e1000_fc_none			 *   0   |    1    |   0   |   DC    | e1000_fc_none			 *   0   |    1    |   1   |    0    | e1000_fc_none			 *   0   |    1    |   1   |    1    | e1000_fc_tx_pause			 *   1   |    0    |   0   |   DC    | e1000_fc_none			 *   1   |   DC    |   1   |   DC    | e1000_fc_full			 *   1   |    1    |   0   |    0    | e1000_fc_none			 *   1   |    1    |   0   |    1    | e1000_fc_rx_pause			 *			 */			/* Are both PAUSE bits set to 1?  If so, this implies			 * Symmetric Flow Control is enabled at both ends.  The			 * ASM_DIR bits are irrelevant per the spec.			 *			 * For Symmetric Flow Control:			 *			 *   LOCAL DEVICE  |   LINK PARTNER			 * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result			 *-------|---------|-------|---------|--------------------			 *   1   |   DC    |   1   |   DC    | e1000_fc_full			 *			 */			if ((mii_nway_adv_reg & NWAY_AR_PAUSE) &&			    (mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE)) {				/* Now we need to check if the user selected RX ONLY				 * of pause frames.  In this case, we had to advertise				 * FULL flow control because we could not advertise RX				 * ONLY. Hence, we must now check to see if we need to				 * turn OFF  the TRANSMISSION of PAUSE frames.				 */				if (hw->original_fc == e1000_fc_full) {					hw->fc = e1000_fc_full;					DEBUGOUT("Flow Control = FULL.\r\n");				} else {					hw->fc = e1000_fc_rx_pause;					DEBUGOUT					    ("Flow Control = RX PAUSE frames only.\r\n");				}			}			/* For receiving PAUSE frames ONLY.			 *			 *   LOCAL DEVICE  |   LINK PARTNER			 * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result			 *-------|---------|-------|---------|--------------------			 *   0   |    1    |   1   |    1    | e1000_fc_tx_pause			 *			 */			else if (!(mii_nway_adv_reg & NWAY_AR_PAUSE) &&				 (mii_nway_adv_reg & NWAY_AR_ASM_DIR) &&				 (mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) &&				 (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR))			{				hw->fc = e1000_fc_tx_pause;				DEBUGOUT				    ("Flow Control = TX PAUSE frames only.\r\n");			}			/* For transmitting PAUSE frames ONLY.			 *			 *   LOCAL DEVICE  |   LINK PARTNER			 * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result			 *-------|---------|-------|---------|--------------------			 *   1   |    1    |   0   |    1    | e1000_fc_rx_pause			 *			 */			else if ((mii_nway_adv_reg & NWAY_AR_PAUSE) &&				 (mii_nway_adv_reg & NWAY_AR_ASM_DIR) &&				 !(mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) &&				 (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR))			{				hw->fc = e1000_fc_rx_pause;				DEBUGOUT				    ("Flow Control = RX PAUSE frames only.\r\n");			}			/* Per the IEEE spec, at this point flow control should be			 * disabled.  However, we want to consider that we could			 * be connected to a legacy switch that doesn't advertise			 * desired flow control, but can be forced on the link			 * partner.  So if we advertised no flow control, that is			 * what we will resolve to.  If we advertised some kind of			 * receive capability (Rx Pause Only or Full Flow Control)			 * and the link partner advertised none, we will configure			 * ourselves to enable Rx Flow Control only.  We can do			 * this safely for two reasons:  If the link partner really			 * didn't want flow control enabled, and we enable Rx, no			 * harm done since we won't be receiving any PAUSE frames			 * anyway.  If the intent on the link partner was to have			 * flow control enabled, then by us enabling RX only, we			 * can at least receive pause frames and process them.			 * This is a good idea because in most cases, since we are			 * predominantly a server NIC, more times than not we will			 * be asked to delay transmission of packets than asking			 * our link partner to pause transmission of frames.			 */			else if (hw->original_fc == e1000_fc_none ||				 hw->original_fc == e1000_fc_tx_pause) {				hw->fc = e1000_fc_none;				DEBUGOUT("Flow Control = NONE.\r\n");			} else {				hw->fc = e1000_fc_rx_pause;				DEBUGOUT				    ("Flow Control = RX PAUSE frames only.\r\n");			}			/* Now we need to do one last check...  If we auto-			 * negotiated to HALF DUPLEX, flow control should not be			 * enabled per IEEE 802.3 spec.			 */			e1000_get_speed_and_duplex(hw, &speed, &duplex);			if (duplex == HALF_DUPLEX)				hw->fc = e1000_fc_none;			/* Now we call a subroutine to actually force the MAC			 * controller to use the correct flow control settings.			 */			ret_val = e1000_force_mac_fc(hw);			if (ret_val < 0) {				DEBUGOUT				    ("Error forcing flow control settings\n");				return ret_val;			}		} else {			DEBUGOUT			    ("Copper PHY and Auto Neg has not completed.\r\n");		}	}	return 0;}/****************************************************************************** * Checks to see if the link status of the hardware has changed. * * hw - Struct containing variables accessed by shared code * * Called by any function that needs to check the link status of the adapter. *****************************************************************************/static inte1000_check_for_link(struct eth_device *nic){	struct e1000_hw *hw = nic->priv;	uint32_t rxcw;	uint32_t ctrl;	uint32_t status;	uint32_t rctl;	uint32_t signal;	int32_t ret_val;	uint16_t phy_data;	uint16_t lp_capability;	DEBUGFUNC();	/* On adapters with a MAC newer that 82544, SW Defineable pin 1 will be	 * set when the optics detect a signal. On older adapters, it will be	 * cleared when there is a signal	 */	ctrl = E1000_READ_REG(hw, CTRL);	if ((hw->mac_type > e1000_82544) && !(ctrl & E1000_CTRL_ILOS))		signal = E1000_CTRL_SWDPIN1;	else		signal = 0;	status = E1000_READ_REG(hw, STATUS);	rxcw = E1000_READ_REG(hw, RXCW);	DEBUGOUT("ctrl: %#08x status %#08x rxcw %#08x\n", ctrl, status, rxcw);	/* If we have a copper PHY then we only want to go out to the PHY	 * registers to see if Auto-Neg has completed and/or if our link	 * status has changed.  The get_link_status flag will be set if we	 * receive a Link Status Change interrupt or we have Rx Sequence	 * Errors.	 */	if ((hw->media_type == e1000_media_type_copper) && hw->get_link_status) {		/* First we want to see if the MII Status Register reports		 * link.  If so, then we want to get the current speed/duplex		 * of the PHY.		 * Read the register twice since the link bit is sticky.		 */		if (e1000_read_phy_reg(hw, PHY_STATUS, &phy_data) < 0) {			DEBUGOUT("PHY Read Error\n");			return -E1000_ERR_PHY;		}		if (e1000_read_phy_reg(hw, PHY_STATUS, &phy_data) < 0) {			DEBUGOUT("PHY Read Error\n");			return -E1000_ERR_PHY;		}		if (phy_data & MII_SR_LINK_STATUS) {			hw->get_link_status = FALSE;		} else {			/* No link detected */			return -E1000_ERR_NOLINK;		}		/* We have a M88E1000 PHY and Auto-Neg is enabled.  If we		 * have Si on board that is 82544 or newer, Auto		 * Speed Detection takes care of MAC speed/duplex		 * configuration.  So we only need to configure Collision		 * Distance in the MAC.  Otherwise, we need to force		 * speed/duplex on the MAC to the current PHY speed/duplex		 * settings.		 */		if (hw->mac_type >= e1000_82544)			e1000_config_collision_dist(hw);		else {			ret_val = e1000_config_mac_to_phy(hw);			if (ret_val < 0) {				DEBUGOUT				    ("Error configuring MAC to PHY settings\n");				return ret_val;			}		}		/* Configure Flow Control now that Auto-Neg has completed. First, we		 * need to restore the desired flow control settings because we may		 * have had to re-autoneg with a different link partner.		 */		ret_val = e1000_config_fc_after_link_up(hw);		if (ret_val < 0) {			DEBUGOUT("Error configuring flow control\n");			return ret_val;		}		/* At this point we know that we are on copper and we have		 * auto-negotiated link.  These are conditions for checking the link		 * parter capability register.  We use the link partner capability to		 * determine if TBI Compatibility needs to be turned on or off.  If		 * the link partner advertises any speed in addition to Gigabit, then		 * we assume that they are GMII-based, and TBI compatibility is not		 * needed. If no other speeds are advertised, we assume the link		 * partner is TBI-based, and we turn on TBI Compatibility.		 */		if (hw->tbi_compatibility_en) {			if (e1000_read_phy_reg			    (hw, PHY_LP_ABILITY, &lp_capability) < 0) {				DEBUGOUT("PHY Read Error\n");				return -E1000_ERR_PHY;			}			if (lp_capability & (NWAY_LPAR_10T_HD_CAPS |					     NWAY_LPAR_10T_FD_CAPS |					     NWAY_LPAR_100TX_HD_CAPS |					     NWAY_LPAR_100TX_FD_CAPS |					     NWAY_LPAR_100T4_CAPS)) {				/* If our link partner advertises anything in addition to				 * gigabit, we do not need to enable TBI compatibility.				 */				if (hw->tbi_compatibility_on) {					/* If we previously were in the mode, turn it off. */					rctl = E1000_READ_REG(hw, RCTL);					rctl &= ~E1000_RCTL_SBP;					E1000_WRITE_REG(hw, RCTL, rctl);					hw->tbi_compatibility_on = FALSE;				}			} else {				/* If TBI compatibility is was previously off, turn it on. For				 * compatibility with a TBI link partner, we will store bad				 * packets. Some frames have an additional byte on the end and				 * will look like CRC errors to to the hardware.				 */				if (!hw->tbi_compatibility_on) {					hw->tbi_compatibility_on = TRUE;					rctl = E1000_READ_REG(hw, RCTL);					rctl |= E1000_RCTL_SBP;					E1000_WRITE_REG(hw, RCTL, rctl);				}			}		}	}	/* If we don't have link (auto-negotiation failed or link partner cannot	 * auto-negotiate), the cable is plugged in (we have signal), 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, in case the cable was just plugged	 * in. The autoneg_failed flag does this.	 */	else if ((hw->media_type == e1000_media_type_fiber) &&		 (!(status & E1000_STATUS_LU)) &&		 ((ctrl & E1000_CTRL_SWDPIN1) == signal) &&		 (!(rxcw & E1000_RXCW_C))) {		if (hw->autoneg_failed == 0) {			hw->autoneg_failed = 1;			return 0;		}		DEBUGOUT("NOT RXing /C/, disable AutoNeg and force link.\r\n");		/* Disable auto-negotiation in the TXCW register */		E1000_WRITE_REG(hw, TXCW, (hw->txcw & ~E1000_TXCW_ANE));		/* Force link-up and also force full-duplex. */		ctrl = E1000_READ_REG(hw, CTRL);		ctrl |= (E1000_CTRL_SLU | E1000_CTRL_FD);		E1000_WRITE_REG(hw, CTRL, ctrl);		/* Configure Flow Control after forcing link up. */		ret_val = e1000_config_fc_after_link_up(hw);		if (ret_val < 0) {			DEBUGOUT("Error configuring flow control\n");			return ret_val;		}	}	/* If we are forcing link and we are receiving /C/ ordered sets, re-enable	 * auto-negoti

⌨️ 快捷键说明

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