Skip to content
Snippets Groups Projects
e1000.c 155 KiB
Newer Older
  • Learn to ignore specific revisions
  • 	ret_val = e1000_copper_link_autoneg(hw);
    	if (ret_val)
    		return ret_val;
    
    
    	/* Check link status. Wait up to 100 microseconds for link to become
    	 * valid.
    	 */
    	for (i = 0; i < 10; i++) {
    
    		ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data);
    		if (ret_val)
    			return ret_val;
    		ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data);
    		if (ret_val)
    			return ret_val;
    
    
    		if (phy_data & MII_SR_LINK_STATUS) {
    
    			/* Config the MAC and PHY after link is up */
    			ret_val = e1000_copper_link_postconfig(hw);
    			if (ret_val)
    
    				return ret_val;
    
    			DEBUGOUT("Valid link established!!!\n");
    
    			return E1000_SUCCESS;
    
    		}
    		udelay(10);
    	}
    
    	DEBUGOUT("Unable to establish link!!!\n");
    
    	return E1000_SUCCESS;
    
    }
    
    /******************************************************************************
    * Configures PHY autoneg and flow control advertisement settings
    *
    * hw - Struct containing variables accessed by shared code
    ******************************************************************************/
    
    int32_t
    
    e1000_phy_setup_autoneg(struct e1000_hw *hw)
    {
    
    	int32_t ret_val;
    
    	uint16_t mii_autoneg_adv_reg;
    	uint16_t mii_1000t_ctrl_reg;
    
    	DEBUGFUNC();
    
    	/* Read the MII Auto-Neg Advertisement Register (Address 4). */
    
    	ret_val = e1000_read_phy_reg(hw, PHY_AUTONEG_ADV, &mii_autoneg_adv_reg);
    	if (ret_val)
    		return ret_val;
    
    	if (hw->phy_type != e1000_phy_ife) {
    		/* Read the MII 1000Base-T Control Register (Address 9). */
    		ret_val = e1000_read_phy_reg(hw, PHY_1000T_CTRL,
    				&mii_1000t_ctrl_reg);
    		if (ret_val)
    			return ret_val;
    	} else
    		mii_1000t_ctrl_reg = 0;
    
    
    	/* Need to parse both autoneg_advertised and fc and set up
    	 * the appropriate PHY registers.  First we will parse for
    	 * autoneg_advertised software override.  Since we can advertise
    	 * a plethora of combinations, we need to check each bit
    	 * individually.
    	 */
    
    	/* First we clear all the 10/100 mb speed bits in the Auto-Neg
    	 * Advertisement Register (Address 4) and the 1000 mb speed bits in
    
    	 * the  1000Base-T Control Register (Address 9).
    
    	 */
    	mii_autoneg_adv_reg &= ~REG4_SPEED_MASK;
    	mii_1000t_ctrl_reg &= ~REG9_SPEED_MASK;
    
    	DEBUGOUT("autoneg_advertised %x\n", hw->autoneg_advertised);
    
    	/* Do we want to advertise 10 Mb Half Duplex? */
    	if (hw->autoneg_advertised & ADVERTISE_10_HALF) {
    		DEBUGOUT("Advertise 10mb Half duplex\n");
    		mii_autoneg_adv_reg |= NWAY_AR_10T_HD_CAPS;
    	}
    
    	/* Do we want to advertise 10 Mb Full Duplex? */
    	if (hw->autoneg_advertised & ADVERTISE_10_FULL) {
    		DEBUGOUT("Advertise 10mb Full duplex\n");
    		mii_autoneg_adv_reg |= NWAY_AR_10T_FD_CAPS;
    	}
    
    	/* Do we want to advertise 100 Mb Half Duplex? */
    	if (hw->autoneg_advertised & ADVERTISE_100_HALF) {
    		DEBUGOUT("Advertise 100mb Half duplex\n");
    		mii_autoneg_adv_reg |= NWAY_AR_100TX_HD_CAPS;
    	}
    
    	/* Do we want to advertise 100 Mb Full Duplex? */
    	if (hw->autoneg_advertised & ADVERTISE_100_FULL) {
    		DEBUGOUT("Advertise 100mb Full duplex\n");
    		mii_autoneg_adv_reg |= NWAY_AR_100TX_FD_CAPS;
    	}
    
    	/* We do not allow the Phy to advertise 1000 Mb Half Duplex */
    	if (hw->autoneg_advertised & ADVERTISE_1000_HALF) {
    		DEBUGOUT
    		    ("Advertise 1000mb Half duplex requested, request denied!\n");
    	}
    
    	/* Do we want to advertise 1000 Mb Full Duplex? */
    	if (hw->autoneg_advertised & ADVERTISE_1000_FULL) {
    		DEBUGOUT("Advertise 1000mb Full duplex\n");
    		mii_1000t_ctrl_reg |= CR_1000T_FD_CAPS;
    	}
    
    	/* Check for a software override of the flow control settings, and
    	 * setup the PHY advertisement registers accordingly.  If
    	 * auto-negotiation is enabled, then software will have to set the
    	 * "PAUSE" bits to the correct value in the Auto-Negotiation
    	 * Advertisement Register (PHY_AUTONEG_ADV) and re-start auto-negotiation.
    	 *
    	 * 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.
    
    	 *  other:  No software override.  The flow control configuration
    
    	 *	    in the EEPROM is used.
    
    	 */
    	switch (hw->fc) {
    	case e1000_fc_none:	/* 0 */
    		/* Flow control (RX & TX) is completely disabled by a
    		 * software over-ride.
    		 */
    		mii_autoneg_adv_reg &= ~(NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
    		break;
    	case e1000_fc_rx_pause:	/* 1 */
    		/* 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
    		 * (in e1000_config_fc_after_link_up) we will disable the
    		 *hw's ability to send PAUSE frames.
    		 */
    		mii_autoneg_adv_reg |= (NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
    		break;
    	case e1000_fc_tx_pause:	/* 2 */
    		/* TX Flow control is enabled, and RX Flow control is
    		 * disabled, by a software over-ride.
    		 */
    		mii_autoneg_adv_reg |= NWAY_AR_ASM_DIR;
    		mii_autoneg_adv_reg &= ~NWAY_AR_PAUSE;
    		break;
    	case e1000_fc_full:	/* 3 */
    		/* Flow control (both RX and TX) is enabled by a software
    		 * over-ride.
    		 */
    		mii_autoneg_adv_reg |= (NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
    		break;
    	default:
    		DEBUGOUT("Flow control param set incorrectly\n");
    		return -E1000_ERR_CONFIG;
    	}
    
    
    	ret_val = e1000_write_phy_reg(hw, PHY_AUTONEG_ADV, mii_autoneg_adv_reg);
    	if (ret_val)
    		return ret_val;
    
    
    	DEBUGOUT("Auto-Neg Advertising %x\n", mii_autoneg_adv_reg);
    
    
    	if (hw->phy_type != e1000_phy_ife) {
    		ret_val = e1000_write_phy_reg(hw, PHY_1000T_CTRL,
    				mii_1000t_ctrl_reg);
    		if (ret_val)
    			return ret_val;
    
    
    	return E1000_SUCCESS;
    
    }
    
    /******************************************************************************
    * Sets the collision distance in the Transmit Control register
    *
    * hw - Struct containing variables accessed by shared code
    *
    * Link should have been established previously. Reads the speed and duplex
    * information from the Device Status register.
    ******************************************************************************/
    static void
    e1000_config_collision_dist(struct e1000_hw *hw)
    {
    
    	uint32_t tctl, coll_dist;
    
    	DEBUGFUNC();
    
    	if (hw->mac_type < e1000_82543)
    		coll_dist = E1000_COLLISION_DISTANCE_82542;
    	else
    		coll_dist = E1000_COLLISION_DISTANCE;
    
    
    	tctl = E1000_READ_REG(hw, TCTL);
    
    	tctl &= ~E1000_TCTL_COLD;
    
    	tctl |= coll_dist << E1000_COLD_SHIFT;
    
    
    	E1000_WRITE_REG(hw, TCTL, tctl);
    	E1000_WRITE_FLUSH(hw);
    }
    
    /******************************************************************************
    * Sets MAC speed and duplex settings to reflect the those in the PHY
    *
    * hw - Struct containing variables accessed by shared code
    * mii_reg - data to write to the MII control register
    *
    * The contents of the PHY register containing the needed information need to
    * be passed in.
    ******************************************************************************/
    static int
    e1000_config_mac_to_phy(struct e1000_hw *hw)
    {
    	uint32_t ctrl;
    	uint16_t phy_data;
    
    	DEBUGFUNC();
    
    	/* Read the Device Control Register and set the bits to Force Speed
    	 * and Duplex.
    	 */
    	ctrl = E1000_READ_REG(hw, CTRL);
    	ctrl |= (E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);
    	ctrl &= ~(E1000_CTRL_SPD_SEL | E1000_CTRL_ILOS);
    
    	/* Set up duplex in the Device Control and Transmit Control
    	 * registers depending on negotiated values.
    	 */
    	if (e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data) < 0) {
    		DEBUGOUT("PHY Read Error\n");
    		return -E1000_ERR_PHY;
    	}
    	if (phy_data & M88E1000_PSSR_DPLX)
    		ctrl |= E1000_CTRL_FD;
    	else
    		ctrl &= ~E1000_CTRL_FD;
    
    	e1000_config_collision_dist(hw);
    
    	/* Set up speed in the Device Control register depending on
    	 * negotiated values.
    	 */
    	if ((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_1000MBS)
    		ctrl |= E1000_CTRL_SPD_1000;
    	else if ((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_100MBS)
    		ctrl |= E1000_CTRL_SPD_100;
    	/* Write the configured values back to the Device Control Reg. */
    	E1000_WRITE_REG(hw, CTRL, ctrl);
    	return 0;
    }
    
    /******************************************************************************
     * Forces the MAC's flow control settings.
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
     *
    
     * hw - Struct containing variables accessed by shared code
     *
     * 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.
     *****************************************************************************/
    static int
    e1000_force_mac_fc(struct e1000_hw *hw)
    {
    	uint32_t ctrl;
    
    	DEBUGFUNC();
    
    	/* Get the current configuration of the Device Control Register */
    	ctrl = E1000_READ_REG(hw, 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" 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.
    	 */
    
    	switch (hw->fc) {
    	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;
    	case e1000_fc_tx_pause:
    		ctrl &= (~E1000_CTRL_RFCE);
    		ctrl |= E1000_CTRL_TFCE;
    		break;
    	case e1000_fc_full:
    		ctrl |= (E1000_CTRL_TFCE | E1000_CTRL_RFCE);
    		break;
    	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
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
     *
    
     * 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 int32_t
    
    e1000_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))
    		|| ((hw->media_type == e1000_media_type_internal_serdes)
    		&& (hw->autoneg_failed))
    		|| ((hw->media_type == e1000_media_type_copper)
    		&& (!hw->autoneg))) {
    
    		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 E1000_SUCCESS;
    
    }
    
    /******************************************************************************
     * 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 int
    e1000_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();
    
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    	/* 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) {
    
    York Sun's avatar
    York Sun committed
    			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;
    			}
    		}
    
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    		/* 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)) {
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    				/* 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);
    
    York Sun's avatar
    York Sun committed
    					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) {
    
    York Sun's avatar
    York Sun committed
    					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-negotiation in the TXCW register and disable forced link in the
    	 * Device Control register in an attempt to auto-negotiate with our link
    	 * partner.
    	 */
    	else if ((hw->media_type == e1000_media_type_fiber) &&
    		 (ctrl & E1000_CTRL_SLU) && (rxcw & E1000_RXCW_C)) {
    		DEBUGOUT
    		    ("RXing /C/, enable AutoNeg and stop forcing link.\r\n");
    		E1000_WRITE_REG(hw, TXCW, hw->txcw);
    		E1000_WRITE_REG(hw, CTRL, (ctrl & ~E1000_CTRL_SLU));
    	}
    	return 0;
    }
    
    
    /******************************************************************************
    * Configure the MAC-to-PHY interface for 10/100Mbps
    *
    * hw - Struct containing variables accessed by shared code
    ******************************************************************************/
    static int32_t
    e1000_configure_kmrn_for_10_100(struct e1000_hw *hw, uint16_t duplex)
    {
    	int32_t ret_val = E1000_SUCCESS;
    	uint32_t tipg;
    	uint16_t reg_data;
    
    	DEBUGFUNC();
    
    	reg_data = E1000_KUMCTRLSTA_HD_CTRL_10_100_DEFAULT;
    	ret_val = e1000_write_kmrn_reg(hw,
    			E1000_KUMCTRLSTA_OFFSET_HD_CTRL, reg_data);
    	if (ret_val)
    		return ret_val;
    
    	/* Configure Transmit Inter-Packet Gap */
    	tipg = E1000_READ_REG(hw, TIPG);
    	tipg &= ~E1000_TIPG_IPGT_MASK;
    	tipg |= DEFAULT_80003ES2LAN_TIPG_IPGT_10_100;
    	E1000_WRITE_REG(hw, TIPG, tipg);
    
    	ret_val = e1000_read_phy_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, &reg_data);
    
    	if (ret_val)
    		return ret_val;
    
    	if (duplex == HALF_DUPLEX)
    		reg_data |= GG82563_KMCR_PASS_FALSE_CARRIER;
    	else
    		reg_data &= ~GG82563_KMCR_PASS_FALSE_CARRIER;
    
    	ret_val = e1000_write_phy_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, reg_data);
    
    	return ret_val;
    }
    
    static int32_t
    e1000_configure_kmrn_for_1000(struct e1000_hw *hw)
    {
    	int32_t ret_val = E1000_SUCCESS;
    	uint16_t reg_data;
    	uint32_t tipg;
    
    	DEBUGFUNC();
    
    	reg_data = E1000_KUMCTRLSTA_HD_CTRL_1000_DEFAULT;
    	ret_val = e1000_write_kmrn_reg(hw,
    			E1000_KUMCTRLSTA_OFFSET_HD_CTRL, reg_data);
    	if (ret_val)
    		return ret_val;
    
    	/* Configure Transmit Inter-Packet Gap */
    	tipg = E1000_READ_REG(hw, TIPG);
    	tipg &= ~E1000_TIPG_IPGT_MASK;
    	tipg |= DEFAULT_80003ES2LAN_TIPG_IPGT_1000;
    	E1000_WRITE_REG(hw, TIPG, tipg);
    
    	ret_val = e1000_read_phy_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, &reg_data);
    
    	if (ret_val)
    		return ret_val;
    
    	reg_data &= ~GG82563_KMCR_PASS_FALSE_CARRIER;
    	ret_val = e1000_write_phy_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, reg_data);
    
    	return ret_val;
    }
    
    
    /******************************************************************************
     * Detects the current speed and duplex settings of the hardware.
     *
     * hw - Struct containing variables accessed by shared code
     * speed - Speed of the connection
     * duplex - Duplex setting of the connection
     *****************************************************************************/
    
    static int
    e1000_get_speed_and_duplex(struct e1000_hw *hw, uint16_t *speed,
    		uint16_t *duplex)
    
    	int32_t ret_val;
    	uint16_t phy_data;
    
    
    	DEBUGFUNC();
    
    	if (hw->mac_type >= e1000_82543) {
    		status = E1000_READ_REG(hw, STATUS);
    		if (status & E1000_STATUS_SPEED_1000) {
    			*speed = SPEED_1000;
    			DEBUGOUT("1000 Mbs, ");
    		} else if (status & E1000_STATUS_SPEED_100) {
    			*speed = SPEED_100;
    			DEBUGOUT("100 Mbs, ");
    		} else {
    			*speed = SPEED_10;
    			DEBUGOUT("10 Mbs, ");
    		}
    
    		if (status & E1000_STATUS_FD) {
    			*duplex = FULL_DUPLEX;
    			DEBUGOUT("Full Duplex\r\n");
    		} else {
    			*duplex = HALF_DUPLEX;
    			DEBUGOUT(" Half Duplex\r\n");
    		}
    	} else {
    		DEBUGOUT("1000 Mbs, Full Duplex\r\n");
    		*speed = SPEED_1000;
    		*duplex = FULL_DUPLEX;
    	}
    
    
    	/* IGP01 PHY may advertise full duplex operation after speed downgrade
    	 * even if it is operating at half duplex.  Here we set the duplex
    	 * settings to match the duplex in the link partner's capabilities.
    	 */
    	if (hw->phy_type == e1000_phy_igp && hw->speed_downgraded) {
    		ret_val = e1000_read_phy_reg(hw, PHY_AUTONEG_EXP, &phy_data);
    		if (ret_val)
    			return ret_val;
    
    		if (!(phy_data & NWAY_ER_LP_NWAY_CAPS))
    			*duplex = HALF_DUPLEX;
    		else {
    			ret_val = e1000_read_phy_reg(hw,
    					PHY_LP_ABILITY, &phy_data);
    			if (ret_val)
    				return ret_val;
    			if ((*speed == SPEED_100 &&
    				!(phy_data & NWAY_LPAR_100TX_FD_CAPS))
    				|| (*speed == SPEED_10
    				&& !(phy_data & NWAY_LPAR_10T_FD_CAPS)))
    				*duplex = HALF_DUPLEX;
    		}
    	}
    
    	if ((hw->mac_type == e1000_80003es2lan) &&
    		(hw->media_type == e1000_media_type_copper)) {
    		if (*speed == SPEED_1000)
    			ret_val = e1000_configure_kmrn_for_1000(hw);
    		else
    			ret_val = e1000_configure_kmrn_for_10_100(hw, *duplex);
    		if (ret_val)
    			return ret_val;
    	}
    	return E1000_SUCCESS;
    
    }
    
    /******************************************************************************
    * Blocks until autoneg completes or times out (~4.5 seconds)
    *
    * hw - Struct containing variables accessed by shared code
    ******************************************************************************/
    static int
    e1000_wait_autoneg(struct e1000_hw *hw)
    {
    	uint16_t i;
    	uint16_t phy_data;
    
    	DEBUGFUNC();
    	DEBUGOUT("Waiting for Auto-Neg to complete.\n");
    
    	/* We will wait for autoneg to complete or 4.5 seconds to expire. */
    	for (i = PHY_AUTO_NEG_TIME; i > 0; i--) {
    		/* Read the MII Status Register and wait for Auto-Neg
    		 * Complete bit to be set.
    		 */
    		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_AUTONEG_COMPLETE) {
    			DEBUGOUT("Auto-Neg complete.\n");
    			return 0;
    		}
    		mdelay(100);
    	}
    	DEBUGOUT("Auto-Neg timedout.\n");
    	return -E1000_ERR_TIMEOUT;
    }
    
    /******************************************************************************
    * Raises the Management Data Clock
    *
    * hw - Struct containing variables accessed by shared code
    * ctrl - Device control register's current value
    ******************************************************************************/
    static void
    e1000_raise_mdi_clk(struct e1000_hw *hw, uint32_t * ctrl)
    {
    	/* Raise the clock input to the Management Data Clock (by setting the MDC
    	 * bit), and then delay 2 microseconds.
    	 */
    	E1000_WRITE_REG(hw, CTRL, (*ctrl | E1000_CTRL_MDC));
    	E1000_WRITE_FLUSH(hw);
    	udelay(2);
    }
    
    /******************************************************************************
    * Lowers the Management Data Clock
    *
    * hw - Struct containing variables accessed by shared code
    * ctrl - Device control register's current value
    ******************************************************************************/
    static void
    e1000_lower_mdi_clk(struct e1000_hw *hw, uint32_t * ctrl)
    {
    	/* Lower the clock input to the Management Data Clock (by clearing the MDC
    	 * bit), and then delay 2 microseconds.
    	 */
    	E1000_WRITE_REG(hw, CTRL, (*ctrl & ~E1000_CTRL_MDC));
    	E1000_WRITE_FLUSH(hw);
    	udelay(2);
    }
    
    /******************************************************************************
    * Shifts data bits out to the PHY
    *
    * hw - Struct containing variables accessed by shared code
    * data - Data to send out to the PHY
    * count - Number of bits to shift out
    *
    * Bits are shifted out in MSB to LSB order.
    ******************************************************************************/
    static void
    e1000_shift_out_mdi_bits(struct e1000_hw *hw, uint32_t data, uint16_t count)
    {
    	uint32_t ctrl;
    	uint32_t mask;
    
    	/* We need to shift "count" number of bits out to the PHY. So, the value
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    	 * in the "data" parameter will be shifted out to the PHY one bit at a
    
    	 * time. In order to do this, "data" must be broken down into bits.
    	 */
    	mask = 0x01;
    	mask <<= (count - 1);
    
    	ctrl = E1000_READ_REG(hw, CTRL);
    
    	/* Set MDIO_DIR and MDC_DIR direction bits to be used as output pins. */
    	ctrl |= (E1000_CTRL_MDIO_DIR | E1000_CTRL_MDC_DIR);
    
    	while (mask) {
    		/* A "1" is shifted out to the PHY by setting the MDIO bit to "1" and
    		 * then raising and lowering the Management Data Clock. A "0" is
    		 * shifted out to the PHY by setting the MDIO bit to "0" and then
    		 * raising and lowering the clock.
    		 */
    		if (data & mask)
    			ctrl |= E1000_CTRL_MDIO;
    		else
    			ctrl &= ~E1000_CTRL_MDIO;
    
    		E1000_WRITE_REG(hw, CTRL, ctrl);
    		E1000_WRITE_FLUSH(hw);
    
    		udelay(2);
    
    		e1000_raise_mdi_clk(hw, &ctrl);
    		e1000_lower_mdi_clk(hw, &ctrl);
    
    		mask = mask >> 1;
    	}