Commit 961fac88 authored by Don Skidmore's avatar Don Skidmore Committed by Jeff Kirsher

ixgbe: Add a PHY power state method

This new method will control the PHY power state.  You pass in the
state you wish to change to (ether on or off).  For cases where this
method is not used the current PHY power state behavior is maintained.
Signed-off-by: default avatarDon Skidmore <donald.c.skidmore@intel.com>
Tested-by: default avatarKrishneil Singh <krishneil.k.singh@intel.com>
Signed-off-by: default avatarJeff Kirsher <jeffrey.t.kirsher@intel.com>
parent c2c78d5c
...@@ -4877,6 +4877,9 @@ static void ixgbe_up_complete(struct ixgbe_adapter *adapter) ...@@ -4877,6 +4877,9 @@ static void ixgbe_up_complete(struct ixgbe_adapter *adapter)
if (hw->mac.ops.enable_tx_laser) if (hw->mac.ops.enable_tx_laser)
hw->mac.ops.enable_tx_laser(hw); hw->mac.ops.enable_tx_laser(hw);
if (hw->phy.ops.set_phy_power)
hw->phy.ops.set_phy_power(hw, true);
smp_mb__before_atomic(); smp_mb__before_atomic();
clear_bit(__IXGBE_DOWN, &adapter->state); clear_bit(__IXGBE_DOWN, &adapter->state);
ixgbe_napi_enable_all(adapter); ixgbe_napi_enable_all(adapter);
...@@ -4996,6 +4999,13 @@ void ixgbe_reset(struct ixgbe_adapter *adapter) ...@@ -4996,6 +4999,13 @@ void ixgbe_reset(struct ixgbe_adapter *adapter)
if (test_bit(__IXGBE_PTP_RUNNING, &adapter->state)) if (test_bit(__IXGBE_PTP_RUNNING, &adapter->state))
ixgbe_ptp_reset(adapter); ixgbe_ptp_reset(adapter);
if (hw->phy.ops.set_phy_power) {
if (!netif_running(adapter->netdev) && !adapter->wol)
hw->phy.ops.set_phy_power(hw, false);
else
hw->phy.ops.set_phy_power(hw, true);
}
} }
/** /**
...@@ -5676,6 +5686,7 @@ static int ixgbe_change_mtu(struct net_device *netdev, int new_mtu) ...@@ -5676,6 +5686,7 @@ static int ixgbe_change_mtu(struct net_device *netdev, int new_mtu)
static int ixgbe_open(struct net_device *netdev) static int ixgbe_open(struct net_device *netdev)
{ {
struct ixgbe_adapter *adapter = netdev_priv(netdev); struct ixgbe_adapter *adapter = netdev_priv(netdev);
struct ixgbe_hw *hw = &adapter->hw;
int err, queues; int err, queues;
/* disallow open during test */ /* disallow open during test */
...@@ -5733,6 +5744,8 @@ static int ixgbe_open(struct net_device *netdev) ...@@ -5733,6 +5744,8 @@ static int ixgbe_open(struct net_device *netdev)
ixgbe_free_irq(adapter); ixgbe_free_irq(adapter);
err_req_irq: err_req_irq:
ixgbe_free_all_rx_resources(adapter); ixgbe_free_all_rx_resources(adapter);
if (hw->phy.ops.set_phy_power && !adapter->wol)
hw->phy.ops.set_phy_power(&adapter->hw, false);
err_setup_rx: err_setup_rx:
ixgbe_free_all_tx_resources(adapter); ixgbe_free_all_tx_resources(adapter);
err_setup_tx: err_setup_tx:
...@@ -5893,6 +5906,8 @@ static int __ixgbe_shutdown(struct pci_dev *pdev, bool *enable_wake) ...@@ -5893,6 +5906,8 @@ static int __ixgbe_shutdown(struct pci_dev *pdev, bool *enable_wake)
} }
*enable_wake = !!wufc; *enable_wake = !!wufc;
if (hw->phy.ops.set_phy_power && !*enable_wake)
hw->phy.ops.set_phy_power(hw, false);
ixgbe_release_hw_control(adapter); ixgbe_release_hw_control(adapter);
......
...@@ -2140,3 +2140,36 @@ s32 ixgbe_tn_check_overtemp(struct ixgbe_hw *hw) ...@@ -2140,3 +2140,36 @@ s32 ixgbe_tn_check_overtemp(struct ixgbe_hw *hw)
return IXGBE_ERR_OVERTEMP; return IXGBE_ERR_OVERTEMP;
} }
/** ixgbe_set_copper_phy_power - Control power for copper phy
* @hw: pointer to hardware structure
* @on: true for on, false for off
**/
s32 ixgbe_set_copper_phy_power(struct ixgbe_hw *hw, bool on)
{
u32 status;
u16 reg;
/* Bail if we don't have copper phy */
if (hw->mac.ops.get_media_type(hw) != ixgbe_media_type_copper)
return 0;
status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_VENDOR_SPECIFIC_1_CONTROL,
IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
&reg);
if (status)
return status;
if (on) {
reg &= ~IXGBE_MDIO_PHY_SET_LOW_POWER_MODE;
} else {
if (ixgbe_check_reset_blocked(hw))
return 0;
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);
return status;
}
...@@ -145,6 +145,7 @@ s32 ixgbe_get_phy_firmware_version_generic(struct ixgbe_hw *hw, ...@@ -145,6 +145,7 @@ s32 ixgbe_get_phy_firmware_version_generic(struct ixgbe_hw *hw,
u16 *firmware_version); u16 *firmware_version);
s32 ixgbe_reset_phy_nl(struct ixgbe_hw *hw); s32 ixgbe_reset_phy_nl(struct ixgbe_hw *hw);
s32 ixgbe_set_copper_phy_power(struct ixgbe_hw *hw, bool on);
s32 ixgbe_identify_module_generic(struct ixgbe_hw *hw); s32 ixgbe_identify_module_generic(struct ixgbe_hw *hw);
s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw); s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw);
s32 ixgbe_get_sfp_init_sequence_offsets(struct ixgbe_hw *hw, s32 ixgbe_get_sfp_init_sequence_offsets(struct ixgbe_hw *hw,
......
...@@ -1309,6 +1309,8 @@ struct ixgbe_thermal_sensor_data { ...@@ -1309,6 +1309,8 @@ struct ixgbe_thermal_sensor_data {
#define IXGBE_MDIO_AUTO_NEG_LP 0x13 /* AUTO_NEG LP Status Reg */ #define IXGBE_MDIO_AUTO_NEG_LP 0x13 /* AUTO_NEG LP Status Reg */
#define IXGBE_MDIO_AUTO_NEG_EEE_ADVT 0x3C /* AUTO_NEG EEE Advt Reg */ #define IXGBE_MDIO_AUTO_NEG_EEE_ADVT 0x3C /* AUTO_NEG EEE Advt Reg */
#define IXGBE_MDIO_PHY_SET_LOW_POWER_MODE 0x0800 /* Set low power mode */
#define IXGBE_MDIO_TX_VENDOR_ALARMS_3 0xCC02 /* Vendor Alarms 3 Reg */ #define IXGBE_MDIO_TX_VENDOR_ALARMS_3 0xCC02 /* Vendor Alarms 3 Reg */
#define IXGBE_MDIO_TX_VENDOR_ALARMS_3_RST_MASK 0x3 /* PHY Reset Complete Mask */ #define IXGBE_MDIO_TX_VENDOR_ALARMS_3_RST_MASK 0x3 /* PHY Reset Complete Mask */
#define IXGBE_MDIO_GLOBAL_RES_PR_10 0xC479 /* Global Resv Provisioning 10 Reg */ #define IXGBE_MDIO_GLOBAL_RES_PR_10 0xC479 /* Global Resv Provisioning 10 Reg */
...@@ -3277,6 +3279,7 @@ struct ixgbe_phy_operations { ...@@ -3277,6 +3279,7 @@ struct ixgbe_phy_operations {
s32 (*read_i2c_combined)(struct ixgbe_hw *, u8 addr, u16 reg, u16 *val); s32 (*read_i2c_combined)(struct ixgbe_hw *, u8 addr, u16 reg, u16 *val);
s32 (*write_i2c_combined)(struct ixgbe_hw *, u8 addr, u16 reg, u16 val); s32 (*write_i2c_combined)(struct ixgbe_hw *, u8 addr, u16 reg, u16 val);
s32 (*check_overtemp)(struct ixgbe_hw *); s32 (*check_overtemp)(struct ixgbe_hw *);
s32 (*set_phy_power)(struct ixgbe_hw *, bool on);
}; };
struct ixgbe_eeprom_info { struct ixgbe_eeprom_info {
......
...@@ -850,6 +850,7 @@ static struct ixgbe_phy_operations phy_ops_X540 = { ...@@ -850,6 +850,7 @@ static struct ixgbe_phy_operations phy_ops_X540 = {
.read_i2c_eeprom = &ixgbe_read_i2c_eeprom_generic, .read_i2c_eeprom = &ixgbe_read_i2c_eeprom_generic,
.write_i2c_eeprom = &ixgbe_write_i2c_eeprom_generic, .write_i2c_eeprom = &ixgbe_write_i2c_eeprom_generic,
.check_overtemp = &ixgbe_tn_check_overtemp, .check_overtemp = &ixgbe_tn_check_overtemp,
.set_phy_power = &ixgbe_set_copper_phy_power,
.get_firmware_version = &ixgbe_get_phy_firmware_version_generic, .get_firmware_version = &ixgbe_get_phy_firmware_version_generic,
}; };
......
...@@ -1530,6 +1530,7 @@ static struct ixgbe_phy_operations phy_ops_X550 = { ...@@ -1530,6 +1530,7 @@ static struct ixgbe_phy_operations phy_ops_X550 = {
.setup_link = &ixgbe_setup_phy_link_generic, .setup_link = &ixgbe_setup_phy_link_generic,
.read_i2c_combined = &ixgbe_read_i2c_combined_generic, .read_i2c_combined = &ixgbe_read_i2c_combined_generic,
.write_i2c_combined = &ixgbe_write_i2c_combined_generic, .write_i2c_combined = &ixgbe_write_i2c_combined_generic,
.set_phy_power = &ixgbe_set_copper_phy_power,
}; };
static struct ixgbe_phy_operations phy_ops_X550EM_x = { static struct ixgbe_phy_operations phy_ops_X550EM_x = {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment