diff options
author | Matthew Vick <matthew.vick@intel.com> | 2013-02-21 03:32:52 +0000 |
---|---|---|
committer | Jeff Kirsher <jeffrey.t.kirsher@intel.com> | 2013-04-18 16:40:28 -0700 |
commit | 87371b9de5becc32af2f9be84008b8a8a424c58a (patch) | |
tree | 58128b8de909c4fab1d389e70ed81464a4e20822 /drivers/net/ethernet/intel/igb/igb_ethtool.c | |
parent | igb: Fix code comments and whitespace (diff) | |
download | linux-dev-87371b9de5becc32af2f9be84008b8a8a424c58a.tar.xz linux-dev-87371b9de5becc32af2f9be84008b8a8a424c58a.zip |
igb: Enable EEE LP advertisement
On EEE-capable devices, query the PHY to determine what the link partner is
advertising.
Signed-off-by: Matthew Vick <matthew.vick@intel.com>
Tested-by: Aaron Brown <aaron.f.brown@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers/net/ethernet/intel/igb/igb_ethtool.c')
-rw-r--r-- | drivers/net/ethernet/intel/igb/igb_ethtool.c | 30 |
1 files changed, 29 insertions, 1 deletions
diff --git a/drivers/net/ethernet/intel/igb/igb_ethtool.c b/drivers/net/ethernet/intel/igb/igb_ethtool.c index 08195bd0a23a..8412f9746c78 100644 --- a/drivers/net/ethernet/intel/igb/igb_ethtool.c +++ b/drivers/net/ethernet/intel/igb/igb_ethtool.c @@ -38,6 +38,7 @@ #include <linux/slab.h> #include <linux/pm_runtime.h> #include <linux/highmem.h> +#include <linux/mdio.h> #include "igb.h" @@ -2533,7 +2534,8 @@ static int igb_get_eee(struct net_device *netdev, struct ethtool_eee *edata) { struct igb_adapter *adapter = netdev_priv(netdev); struct e1000_hw *hw = &adapter->hw; - u32 ipcnfg, eeer; + u32 ipcnfg, eeer, ret_val; + u16 phy_data; if ((hw->mac.type < e1000_i350) || (hw->phy.media_type != e1000_media_type_copper)) @@ -2552,6 +2554,32 @@ static int igb_get_eee(struct net_device *netdev, struct ethtool_eee *edata) if (ipcnfg & E1000_IPCNFG_EEE_100M_AN) edata->advertised |= ADVERTISED_100baseT_Full; + /* EEE Link Partner Advertised */ + switch (hw->mac.type) { + case e1000_i350: + ret_val = igb_read_emi_reg(hw, E1000_EEE_LP_ADV_ADDR_I350, + &phy_data); + if (ret_val) + return -ENODATA; + + edata->lp_advertised = mmd_eee_adv_to_ethtool_adv_t(phy_data); + + break; + case e1000_i210: + case e1000_i211: + ret_val = igb_read_xmdio_reg(hw, E1000_EEE_LP_ADV_ADDR_I210, + E1000_EEE_LP_ADV_DEV_I210, + &phy_data); + if (ret_val) + return -ENODATA; + + edata->lp_advertised = mmd_eee_adv_to_ethtool_adv_t(phy_data); + + break; + default: + break; + } + if (eeer & E1000_EEER_EEE_NEG) edata->eee_active = true; |