/*******************************************************************************
Intel PRO/1000 Linux driver
/*******************************************************************************
Intel PRO/1000 Linux driver
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
* @hw: pointer to the HW structure
* @offset: register offset to be read
* @data: pointer to the read data
* @hw: pointer to the HW structure
* @offset: register offset to be read
* @data: pointer to the read data
* Control register. The MAC will take care of interfacing with the
* PHY to retrieve the desired data.
*/
* Control register. The MAC will take care of interfacing with the
* PHY to retrieve the desired data.
*/
- /* Poll the ready bit to see if the MDI read completed */
- for (i = 0; i < 64; i++) {
+ /*
+ * Poll the ready bit to see if the MDI read completed
+ * Increasing the time out as testing showed failures with
+ * the lower time out
+ */
+ for (i = 0; i < (E1000_GEN_POLL_TIMEOUT * 3); i++) {
* @hw: pointer to the HW structure
* @offset: register offset to write to
* @data: data to write to register at offset
*
* Writes data to MDI control register in the PHY at offset.
**/
* @hw: pointer to the HW structure
* @offset: register offset to write to
* @data: data to write to register at offset
*
* Writes data to MDI control register in the PHY at offset.
**/
* Control register. The MAC will take care of interfacing with the
* PHY to retrieve the desired data.
*/
* Control register. The MAC will take care of interfacing with the
* PHY to retrieve the desired data.
*/
- /* Poll the ready bit to see if the MDI read completed */
- for (i = 0; i < E1000_GEN_POLL_TIMEOUT; i++) {
- udelay(5);
+ /*
+ * Poll the ready bit to see if the MDI read completed
+ * Increasing the time out as testing showed failures with
+ * the lower time out
+ */
+ for (i = 0; i < (E1000_GEN_POLL_TIMEOUT * 3); i++) {
+ udelay(50);
- ret_val = e1000_read_phy_reg_mdic(hw,
- MAX_PHY_REG_ADDRESS & offset,
- data);
+ ret_val = e1000e_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
+ data);
- ret_val = e1000_write_phy_reg_mdic(hw,
- MAX_PHY_REG_ADDRESS & offset,
- data);
+ ret_val = e1000e_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
+ data);
- ret_val = e1000_write_phy_reg_mdic(hw,
- IGP01E1000_PHY_PAGE_SELECT,
- (u16)offset);
+ ret_val = e1000e_write_phy_reg_mdic(hw,
+ IGP01E1000_PHY_PAGE_SELECT,
+ (u16)offset);
- ret_val = e1000_read_phy_reg_mdic(hw,
- MAX_PHY_REG_ADDRESS & offset,
- data);
+ ret_val = e1000e_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
+ data);
- ret_val = e1000_write_phy_reg_mdic(hw,
- IGP01E1000_PHY_PAGE_SELECT,
- (u16)offset);
+ ret_val = e1000e_write_phy_reg_mdic(hw,
+ IGP01E1000_PHY_PAGE_SELECT,
+ (u16)offset);
- ret_val = e1000_write_phy_reg_mdic(hw,
- MAX_PHY_REG_ADDRESS & offset,
- data);
+ ret_val = e1000e_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
+ data);
- if (phy->revision < 4) {
- /* Force TX_CLK in the Extended PHY Specific Control Register
+ if ((phy->type == e1000_phy_m88) && (phy->revision < 4)) {
+ /*
+ * Force TX_CLK in the Extended PHY Specific Control Register
/* disable lplu d0 during driver init */
ret_val = e1000_set_d0_lplu_state(hw, 0);
/* disable lplu d0 during driver init */
ret_val = e1000_set_d0_lplu_state(hw, 0);
if (phy->autoneg_advertised == ADVERTISE_1000_FULL) {
/* Disable SmartSpeed */
ret_val = e1e_rphy(hw, IGP01E1000_PHY_PORT_CONFIG,
if (phy->autoneg_advertised == ADVERTISE_1000_FULL) {
/* Disable SmartSpeed */
ret_val = e1e_rphy(hw, IGP01E1000_PHY_PORT_CONFIG,
if (ret_val)
return ret_val;
data &= ~IGP01E1000_PSCFR_SMART_SPEED;
ret_val = e1e_wphy(hw, IGP01E1000_PHY_PORT_CONFIG,
if (ret_val)
return ret_val;
data &= ~IGP01E1000_PSCFR_SMART_SPEED;
ret_val = e1e_wphy(hw, IGP01E1000_PHY_PORT_CONFIG,
* 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.
*/
* 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.
*/
* Advertisement Register (Address 4) and the 1000 mb speed bits in
* the 1000Base-T Control Register (Address 9).
*/
* Advertisement Register (Address 4) and the 1000 mb speed bits in
* the 1000Base-T Control Register (Address 9).
*/
* 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
* 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
* but not send pause frames).
* 2: Tx flow control is enabled (we can send pause frames
* but we do not support receiving 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).
- */
- /* 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
+ *
+ * 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 e1000e_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:
* (in e1000e_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:
* 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:
* 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:
* Performs initial bounds checking on autoneg advertisement parameter, then
* configure to advertise the full capability. Setup the PHY to autoneg
* and restart the negotiation process between the link partner. If
* Performs initial bounds checking on autoneg advertisement parameter, then
* configure to advertise the full capability. Setup the PHY to autoneg
* and restart the negotiation process between the link partner. If
* the Auto Neg Restart bit in the PHY control register.
*/
ret_val = e1e_rphy(hw, PHY_CONTROL, &phy_ctrl);
* the Auto Neg Restart bit in the PHY control register.
*/
ret_val = e1e_rphy(hw, PHY_CONTROL, &phy_ctrl);
ret_val = e1000_wait_autoneg(hw);
if (ret_val) {
hw_dbg(hw, "Error while waiting for "
ret_val = e1000_wait_autoneg(hw);
if (ret_val) {
hw_dbg(hw, "Error while waiting for "
- /* PHY will be set to 10H, 10F, 100H or 100F
- * depending on user settings. */
+ /*
+ * PHY will be set to 10H, 10F, 100H or 100F
+ * depending on user settings.
+ */
hw_dbg(hw, "Forcing Speed and Duplex\n");
ret_val = e1000_phy_force_speed_duplex(hw);
if (ret_val) {
hw_dbg(hw, "Forcing Speed and Duplex\n");
ret_val = e1000_phy_force_speed_duplex(hw);
if (ret_val) {
* forced whenever speed and duplex are forced.
*/
ret_val = e1e_rphy(hw, IGP01E1000_PHY_PORT_CTRL, &phy_data);
* forced whenever speed and duplex are forced.
*/
ret_val = e1e_rphy(hw, IGP01E1000_PHY_PORT_CTRL, &phy_data);
hw_dbg(hw, "Waiting for forced speed/duplex link on IGP phy.\n");
ret_val = e1000e_phy_has_link_generic(hw,
hw_dbg(hw, "Waiting for forced speed/duplex link on IGP phy.\n");
ret_val = e1000e_phy_has_link_generic(hw,
* Calls the PHY setup function to force speed and duplex. Clears the
* auto-crossover to force MDI manually. Resets the PHY to commit the
* changes. If time expires while waiting for link up, we reset the DSP.
* Calls the PHY setup function to force speed and duplex. Clears the
* auto-crossover to force MDI manually. Resets the PHY to commit the
* changes. If time expires while waiting for link up, we reset the DSP.
* successful completion, else return corresponding error code.
**/
s32 e1000e_phy_force_speed_duplex_m88(struct e1000_hw *hw)
* successful completion, else return corresponding error code.
**/
s32 e1000e_phy_force_speed_duplex_m88(struct e1000_hw *hw)
* forced whenever speed and duplex are forced.
*/
ret_val = e1e_rphy(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
* forced whenever speed and duplex are forced.
*/
ret_val = e1e_rphy(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
hw_dbg(hw, "Waiting for forced speed/duplex link on M88 phy.\n");
ret_val = e1000e_phy_has_link_generic(hw, PHY_FORCE_LIMIT,
hw_dbg(hw, "Waiting for forced speed/duplex link on M88 phy.\n");
ret_val = e1000e_phy_has_link_generic(hw, PHY_FORCE_LIMIT,
* during Dx states where the power conservation is most
* important. During driver activity we should enable
* during Dx states where the power conservation is most
* important. During driver activity we should enable
if (phy->smart_speed == e1000_smart_speed_on) {
ret_val = e1e_rphy(hw, IGP01E1000_PHY_PORT_CONFIG,
if (phy->smart_speed == e1000_smart_speed_on) {
ret_val = e1e_rphy(hw, IGP01E1000_PHY_PORT_CONFIG,
if (ret_val)
return ret_val;
data |= IGP01E1000_PSCFR_SMART_SPEED;
ret_val = e1e_wphy(hw, IGP01E1000_PHY_PORT_CONFIG,
if (ret_val)
return ret_val;
data |= IGP01E1000_PSCFR_SMART_SPEED;
ret_val = e1e_wphy(hw, IGP01E1000_PHY_PORT_CONFIG,
if (ret_val)
return ret_val;
} else if (phy->smart_speed == e1000_smart_speed_off) {
ret_val = e1e_rphy(hw, IGP01E1000_PHY_PORT_CONFIG,
if (ret_val)
return ret_val;
} else if (phy->smart_speed == e1000_smart_speed_off) {
ret_val = e1e_rphy(hw, IGP01E1000_PHY_PORT_CONFIG,
if (ret_val)
return ret_val;
data &= ~IGP01E1000_PSCFR_SMART_SPEED;
ret_val = e1e_wphy(hw, IGP01E1000_PHY_PORT_CONFIG,
if (ret_val)
return ret_val;
data &= ~IGP01E1000_PSCFR_SMART_SPEED;
ret_val = e1e_wphy(hw, IGP01E1000_PHY_PORT_CONFIG,
* @hw: pointer to the HW structure
*
* Waits for auto-negotiation to complete or for the auto-negotiation time
* @hw: pointer to the HW structure
*
* Waits for auto-negotiation to complete or for the auto-negotiation time
* course and fine gain values. The result is a number
* that can be put into the lookup table to obtain the
* course and fine gain values. The result is a number
* that can be put into the lookup table to obtain the
hw_dbg(hw, "Phy info is only valid for copper media\n");
return -E1000_ERR_CONFIG;
}
hw_dbg(hw, "Phy info is only valid for copper media\n");
return -E1000_ERR_CONFIG;
}