{
u32 status;
u16 reg;
- u32 retries = 1;
-
- /* TODO: The number of attempts and delay between attempts is undefined */
- do {
- /* decrement retries counter and exit if we hit 0 */
- if (retries < 1) {
- ERROR_REPORT1(IXGBE_ERROR_INVALID_STATE,
- "External PHY not yet finished resetting.");
- return IXGBE_ERR_PHY;
- }
- retries--;
-
- usec_delay(0);
-
- status = hw->phy.ops.read_reg(hw,
- IXGBE_MDIO_TX_VENDOR_ALARMS_3,
- IXGBE_MDIO_PMA_PMD_DEV_TYPE,
- ®);
-
- if (status != IXGBE_SUCCESS)
- return status;
-
- /* Verify PHY FW reset has completed */
- } while ((reg & IXGBE_MDIO_TX_VENDOR_ALARMS_3_RST_MASK) != 1);
- /* Set port to low power mode */
status = hw->phy.ops.read_reg(hw,
- IXGBE_MDIO_VENDOR_SPECIFIC_1_CONTROL,
- IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
- ®);
-
- if (status != IXGBE_SUCCESS)
- return status;
-
- reg |= IXGBE_MDIO_PHY_SET_LOW_POWER_MODE;
-
- status = hw->phy.ops.write_reg(hw,
- IXGBE_MDIO_VENDOR_SPECIFIC_1_CONTROL,
- IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
- reg);
-
- if (status != IXGBE_SUCCESS)
- return status;
-
- /* Enable the transmitter */
- status = hw->phy.ops.read_reg(hw,
- IXGBE_MDIO_PMD_STD_TX_DISABLE_CNTR,
+ IXGBE_MDIO_TX_VENDOR_ALARMS_3,
IXGBE_MDIO_PMA_PMD_DEV_TYPE,
®);
if (status != IXGBE_SUCCESS)
return status;
- reg &= ~IXGBE_MDIO_PMD_GLOBAL_TX_DISABLE;
-
- status = hw->phy.ops.write_reg(hw,
- IXGBE_MDIO_PMD_STD_TX_DISABLE_CNTR,
- IXGBE_MDIO_PMA_PMD_DEV_TYPE,
- reg);
-
- if (status != IXGBE_SUCCESS)
- return status;
+ /* If PHY FW reset completed bit is set then this is the first
+ * SW instance after a power on so the PHY FW must be un-stalled.
+ */
+ if (reg & IXGBE_MDIO_TX_VENDOR_ALARMS_3_RST_MASK) {
+ status = hw->phy.ops.read_reg(hw,
+ IXGBE_MDIO_GLOBAL_RES_PR_10,
+ IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
+ ®);
- /* Un-stall the PHY FW */
- status = hw->phy.ops.read_reg(hw,
- IXGBE_MDIO_GLOBAL_RES_PR_10,
- IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
- ®);
+ if (status != IXGBE_SUCCESS)
+ return status;
- if (status != IXGBE_SUCCESS)
- return status;
+ reg &= ~IXGBE_MDIO_POWER_UP_STALL;
- reg &= ~IXGBE_MDIO_POWER_UP_STALL;
+ status = hw->phy.ops.write_reg(hw,
+ IXGBE_MDIO_GLOBAL_RES_PR_10,
+ IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
+ reg);
- status = hw->phy.ops.write_reg(hw,
- IXGBE_MDIO_GLOBAL_RES_PR_10,
- IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
- reg);
+ if (status != IXGBE_SUCCESS)
+ return status;
+ }
return status;
}