Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 79f05bf0 authored by Auke Kok's avatar Auke Kok Committed by Auke Kok
Browse files

e1000: Make PHY powerup/down a function



In relation to the irq work done earlier we also move the PHY powerup
and powerdown functions into separate functions and move the calls to
_close and _open, making the PHY stay in it's power state as long as
the device is _up.

Signed-off-by: default avatarJesse Brandeburg <jesse.brandeburg@intel.com>
Signed-off-by: default avatarAuke Kok <auke-jan.h.kok@intel.com>
parent 2db10a08
Loading
Loading
Loading
Loading
+49 −27
Original line number Diff line number Diff line
@@ -428,14 +428,6 @@ e1000_up(struct e1000_adapter *adapter)

	/* hardware has been reset, we need to reload some things */

	/* Reset the PHY if it was previously powered down */
	if (adapter->hw.media_type == e1000_media_type_copper) {
		uint16_t mii_reg;
		e1000_read_phy_reg(&adapter->hw, PHY_CTRL, &mii_reg);
		if (mii_reg & MII_CR_POWER_DOWN)
			e1000_phy_hw_reset(&adapter->hw);
	}

	e1000_set_multi(netdev);

	e1000_restore_vlan(adapter);
@@ -464,12 +456,56 @@ e1000_up(struct e1000_adapter *adapter)
	return 0;
}

/**
 * e1000_power_up_phy - restore link in case the phy was powered down
 * @adapter: address of board private structure
 *
 * The phy may be powered down to save power and turn off link when the
 * driver is unloaded and wake on lan is not enabled (among others)
 * *** this routine MUST be followed by a call to e1000_reset ***
 *
 **/

static void e1000_power_up_phy(struct e1000_adapter *adapter)
{
	uint16_t mii_reg = 0;

	/* Just clear the power down bit to wake the phy back up */
	if (adapter->hw.media_type == e1000_media_type_copper) {
		/* according to the manual, the phy will retain its
		 * settings across a power-down/up cycle */
		e1000_read_phy_reg(&adapter->hw, PHY_CTRL, &mii_reg);
		mii_reg &= ~MII_CR_POWER_DOWN;
		e1000_write_phy_reg(&adapter->hw, PHY_CTRL, mii_reg);
	}
}

static void e1000_power_down_phy(struct e1000_adapter *adapter)
{
	boolean_t mng_mode_enabled = (adapter->hw.mac_type >= e1000_82571) &&
	                              e1000_check_mng_mode(&adapter->hw);
	/* Power down the PHY so no link is implied when interface is down
	 * The PHY cannot be powered down if any of the following is TRUE
	 * (a) WoL is enabled
	 * (b) AMT is active
	 * (c) SoL/IDER session is active */
	if (!adapter->wol && adapter->hw.mac_type >= e1000_82540 &&
	    adapter->hw.media_type == e1000_media_type_copper &&
	    !(E1000_READ_REG(&adapter->hw, MANC) & E1000_MANC_SMBUS_EN) &&
	    !mng_mode_enabled &&
	    !e1000_check_phy_reset_block(&adapter->hw)) {
		uint16_t mii_reg = 0;
		e1000_read_phy_reg(&adapter->hw, PHY_CTRL, &mii_reg);
		mii_reg |= MII_CR_POWER_DOWN;
		e1000_write_phy_reg(&adapter->hw, PHY_CTRL, mii_reg);
		mdelay(1);
	}
}

void
e1000_down(struct e1000_adapter *adapter)
{
	struct net_device *netdev = adapter->netdev;
	boolean_t mng_mode_enabled = (adapter->hw.mac_type >= e1000_82571) &&
	                              e1000_check_mng_mode(&adapter->hw);

	e1000_irq_disable(adapter);

@@ -489,23 +525,6 @@ e1000_down(struct e1000_adapter *adapter)
	e1000_reset(adapter);
	e1000_clean_all_tx_rings(adapter);
	e1000_clean_all_rx_rings(adapter);

	/* Power down the PHY so no link is implied when interface is down *
	 * The PHY cannot be powered down if any of the following is TRUE *
	 * (a) WoL is enabled
	 * (b) AMT is active
	 * (c) SoL/IDER session is active */
	if (!adapter->wol && adapter->hw.mac_type >= e1000_82540 &&
	   adapter->hw.media_type == e1000_media_type_copper &&
	   !(E1000_READ_REG(&adapter->hw, MANC) & E1000_MANC_SMBUS_EN) &&
	   !mng_mode_enabled &&
	   !e1000_check_phy_reset_block(&adapter->hw)) {
		uint16_t mii_reg;
		e1000_read_phy_reg(&adapter->hw, PHY_CTRL, &mii_reg);
		mii_reg |= MII_CR_POWER_DOWN;
		e1000_write_phy_reg(&adapter->hw, PHY_CTRL, mii_reg);
		mdelay(1);
	}
}

void
@@ -1117,6 +1136,8 @@ e1000_open(struct net_device *netdev)
	if (err)
		goto err_up;

	e1000_power_up_phy(adapter);

	if ((err = e1000_up(adapter)))
		goto err_up;
	adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
@@ -1162,6 +1183,7 @@ e1000_close(struct net_device *netdev)

	WARN_ON(test_bit(__E1000_RESETTING, &adapter->flags));
	e1000_down(adapter);
	e1000_power_down_phy(adapter);
	e1000_free_irq(adapter);

	e1000_free_all_tx_resources(adapter);