|
@@ -35,7 +35,6 @@
|
|
|
#include <linux/slab.h>
|
|
|
#include <linux/delay.h>
|
|
|
#include <linux/vmalloc.h>
|
|
|
-#include <linux/mdio.h>
|
|
|
#include <linux/pm_runtime.h>
|
|
|
|
|
|
#include "e1000.h"
|
|
@@ -2076,23 +2075,20 @@ static int e1000e_get_eee(struct net_device *netdev, struct ethtool_eee *edata)
|
|
|
{
|
|
|
struct e1000_adapter *adapter = netdev_priv(netdev);
|
|
|
struct e1000_hw *hw = &adapter->hw;
|
|
|
- u16 cap_addr, adv_addr, lpa_addr, pcs_stat_addr, phy_data, lpi_ctrl;
|
|
|
- u32 status, ret_val;
|
|
|
+ u16 cap_addr, lpa_addr, pcs_stat_addr, phy_data;
|
|
|
+ u32 ret_val;
|
|
|
|
|
|
- if (!(adapter->flags & FLAG_IS_ICH) ||
|
|
|
- !(adapter->flags2 & FLAG2_HAS_EEE))
|
|
|
+ if (!(adapter->flags2 & FLAG2_HAS_EEE))
|
|
|
return -EOPNOTSUPP;
|
|
|
|
|
|
switch (hw->phy.type) {
|
|
|
case e1000_phy_82579:
|
|
|
cap_addr = I82579_EEE_CAPABILITY;
|
|
|
- adv_addr = I82579_EEE_ADVERTISEMENT;
|
|
|
lpa_addr = I82579_EEE_LP_ABILITY;
|
|
|
pcs_stat_addr = I82579_EEE_PCS_STATUS;
|
|
|
break;
|
|
|
case e1000_phy_i217:
|
|
|
cap_addr = I217_EEE_CAPABILITY;
|
|
|
- adv_addr = I217_EEE_ADVERTISEMENT;
|
|
|
lpa_addr = I217_EEE_LP_ABILITY;
|
|
|
pcs_stat_addr = I217_EEE_PCS_STATUS;
|
|
|
break;
|
|
@@ -2111,10 +2107,7 @@ static int e1000e_get_eee(struct net_device *netdev, struct ethtool_eee *edata)
|
|
|
edata->supported = mmd_eee_cap_to_ethtool_sup_t(phy_data);
|
|
|
|
|
|
/* EEE Advertised */
|
|
|
- ret_val = e1000_read_emi_reg_locked(hw, adv_addr, &phy_data);
|
|
|
- if (ret_val)
|
|
|
- goto release;
|
|
|
- edata->advertised = mmd_eee_adv_to_ethtool_adv_t(phy_data);
|
|
|
+ edata->advertised = mmd_eee_adv_to_ethtool_adv_t(adapter->eee_advert);
|
|
|
|
|
|
/* EEE Link Partner Advertised */
|
|
|
ret_val = e1000_read_emi_reg_locked(hw, lpa_addr, &phy_data);
|
|
@@ -2132,25 +2125,11 @@ release:
|
|
|
if (ret_val)
|
|
|
return -ENODATA;
|
|
|
|
|
|
- e1e_rphy(hw, I82579_LPI_CTRL, &lpi_ctrl);
|
|
|
- status = er32(STATUS);
|
|
|
-
|
|
|
/* Result of the EEE auto negotiation - there is no register that
|
|
|
* has the status of the EEE negotiation so do a best-guess based
|
|
|
- * on whether both Tx and Rx LPI indications have been received or
|
|
|
- * base it on the link speed, the EEE advertised speeds on both ends
|
|
|
- * and the speeds on which EEE is enabled locally.
|
|
|
+ * on whether Tx or Rx LPI indications have been received.
|
|
|
*/
|
|
|
- if (((phy_data & E1000_EEE_TX_LPI_RCVD) &&
|
|
|
- (phy_data & E1000_EEE_RX_LPI_RCVD)) ||
|
|
|
- ((status & E1000_STATUS_SPEED_100) &&
|
|
|
- (edata->advertised & ADVERTISED_100baseT_Full) &&
|
|
|
- (edata->lp_advertised & ADVERTISED_100baseT_Full) &&
|
|
|
- (lpi_ctrl & I82579_LPI_CTRL_100_ENABLE)) ||
|
|
|
- ((status & E1000_STATUS_SPEED_1000) &&
|
|
|
- (edata->advertised & ADVERTISED_1000baseT_Full) &&
|
|
|
- (edata->lp_advertised & ADVERTISED_1000baseT_Full) &&
|
|
|
- (lpi_ctrl & I82579_LPI_CTRL_1000_ENABLE)))
|
|
|
+ if (phy_data & (E1000_EEE_TX_LPI_RCVD | E1000_EEE_RX_LPI_RCVD))
|
|
|
edata->eee_active = true;
|
|
|
|
|
|
edata->eee_enabled = !hw->dev_spec.ich8lan.eee_disable;
|
|
@@ -2167,19 +2146,10 @@ static int e1000e_set_eee(struct net_device *netdev, struct ethtool_eee *edata)
|
|
|
struct ethtool_eee eee_curr;
|
|
|
s32 ret_val;
|
|
|
|
|
|
- if (!(adapter->flags & FLAG_IS_ICH) ||
|
|
|
- !(adapter->flags2 & FLAG2_HAS_EEE))
|
|
|
- return -EOPNOTSUPP;
|
|
|
-
|
|
|
ret_val = e1000e_get_eee(netdev, &eee_curr);
|
|
|
if (ret_val)
|
|
|
return ret_val;
|
|
|
|
|
|
- if (eee_curr.advertised != edata->advertised) {
|
|
|
- e_err("Setting EEE advertisement is not supported\n");
|
|
|
- return -EINVAL;
|
|
|
- }
|
|
|
-
|
|
|
if (eee_curr.tx_lpi_enabled != edata->tx_lpi_enabled) {
|
|
|
e_err("Setting EEE tx-lpi is not supported\n");
|
|
|
return -EINVAL;
|
|
@@ -2190,16 +2160,21 @@ static int e1000e_set_eee(struct net_device *netdev, struct ethtool_eee *edata)
|
|
|
return -EINVAL;
|
|
|
}
|
|
|
|
|
|
- if (hw->dev_spec.ich8lan.eee_disable != !edata->eee_enabled) {
|
|
|
- hw->dev_spec.ich8lan.eee_disable = !edata->eee_enabled;
|
|
|
-
|
|
|
- /* reset the link */
|
|
|
- if (netif_running(netdev))
|
|
|
- e1000e_reinit_locked(adapter);
|
|
|
- else
|
|
|
- e1000e_reset(adapter);
|
|
|
+ if (edata->advertised & ~(ADVERTISE_100_FULL | ADVERTISE_1000_FULL)) {
|
|
|
+ e_err("EEE advertisement supports only 100TX and/or 1000T full-duplex\n");
|
|
|
+ return -EINVAL;
|
|
|
}
|
|
|
|
|
|
+ adapter->eee_advert = ethtool_adv_to_mmd_eee_adv_t(edata->advertised);
|
|
|
+
|
|
|
+ hw->dev_spec.ich8lan.eee_disable = !edata->eee_enabled;
|
|
|
+
|
|
|
+ /* reset the link */
|
|
|
+ if (netif_running(netdev))
|
|
|
+ e1000e_reinit_locked(adapter);
|
|
|
+ else
|
|
|
+ e1000e_reset(adapter);
|
|
|
+
|
|
|
return 0;
|
|
|
}
|
|
|
|