Skip to content

Commit d495bcb

Browse files
bwallanJeff Kirsher
authored andcommitted
e1000e: EEE capability advertisement not set/disabled as required
Devices supported by the driver which support EEE (currently 82579, I217 and I218) are advertising EEE capabilities during auto-negotiation even when EEE has been disabled. In addition to not acting as expected, this also caused the EEE status reported by 'ethtool --show-eee' to be wrong when two of these devices are connected back-to-back and EEE is disabled on one. In addition to fixing this issue, the ability for the user to specify which speeds (100 or 1000 full-duplex) to advertise EEE support has been added. Signed-off-by: Bruce Allan <[email protected]> Tested-by: Jeff Pieper <[email protected]> Signed-off-by: Jeff Kirsher <[email protected]>
1 parent ea8179a commit d495bcb

File tree

5 files changed

+88
-72
lines changed

5 files changed

+88
-72
lines changed

drivers/net/ethernet/intel/e1000e/e1000.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
#include <linux/ptp_clock_kernel.h>
4747
#include <linux/ptp_classify.h>
4848
#include <linux/mii.h>
49+
#include <linux/mdio.h>
4950
#include "hw.h"
5051

5152
struct e1000_info;
@@ -350,6 +351,8 @@ struct e1000_adapter {
350351
struct timecounter tc;
351352
struct ptp_clock *ptp_clock;
352353
struct ptp_clock_info ptp_clock_info;
354+
355+
u16 eee_advert;
353356
};
354357

355358
struct e1000_info {

drivers/net/ethernet/intel/e1000e/ethtool.c

Lines changed: 19 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@
3535
#include <linux/slab.h>
3636
#include <linux/delay.h>
3737
#include <linux/vmalloc.h>
38-
#include <linux/mdio.h>
3938
#include <linux/pm_runtime.h>
4039

4140
#include "e1000.h"
@@ -2076,23 +2075,20 @@ static int e1000e_get_eee(struct net_device *netdev, struct ethtool_eee *edata)
20762075
{
20772076
struct e1000_adapter *adapter = netdev_priv(netdev);
20782077
struct e1000_hw *hw = &adapter->hw;
2079-
u16 cap_addr, adv_addr, lpa_addr, pcs_stat_addr, phy_data, lpi_ctrl;
2080-
u32 status, ret_val;
2078+
u16 cap_addr, lpa_addr, pcs_stat_addr, phy_data;
2079+
u32 ret_val;
20812080

2082-
if (!(adapter->flags & FLAG_IS_ICH) ||
2083-
!(adapter->flags2 & FLAG2_HAS_EEE))
2081+
if (!(adapter->flags2 & FLAG2_HAS_EEE))
20842082
return -EOPNOTSUPP;
20852083

20862084
switch (hw->phy.type) {
20872085
case e1000_phy_82579:
20882086
cap_addr = I82579_EEE_CAPABILITY;
2089-
adv_addr = I82579_EEE_ADVERTISEMENT;
20902087
lpa_addr = I82579_EEE_LP_ABILITY;
20912088
pcs_stat_addr = I82579_EEE_PCS_STATUS;
20922089
break;
20932090
case e1000_phy_i217:
20942091
cap_addr = I217_EEE_CAPABILITY;
2095-
adv_addr = I217_EEE_ADVERTISEMENT;
20962092
lpa_addr = I217_EEE_LP_ABILITY;
20972093
pcs_stat_addr = I217_EEE_PCS_STATUS;
20982094
break;
@@ -2111,10 +2107,7 @@ static int e1000e_get_eee(struct net_device *netdev, struct ethtool_eee *edata)
21112107
edata->supported = mmd_eee_cap_to_ethtool_sup_t(phy_data);
21122108

21132109
/* EEE Advertised */
2114-
ret_val = e1000_read_emi_reg_locked(hw, adv_addr, &phy_data);
2115-
if (ret_val)
2116-
goto release;
2117-
edata->advertised = mmd_eee_adv_to_ethtool_adv_t(phy_data);
2110+
edata->advertised = mmd_eee_adv_to_ethtool_adv_t(adapter->eee_advert);
21182111

21192112
/* EEE Link Partner Advertised */
21202113
ret_val = e1000_read_emi_reg_locked(hw, lpa_addr, &phy_data);
@@ -2132,25 +2125,11 @@ static int e1000e_get_eee(struct net_device *netdev, struct ethtool_eee *edata)
21322125
if (ret_val)
21332126
return -ENODATA;
21342127

2135-
e1e_rphy(hw, I82579_LPI_CTRL, &lpi_ctrl);
2136-
status = er32(STATUS);
2137-
21382128
/* Result of the EEE auto negotiation - there is no register that
21392129
* has the status of the EEE negotiation so do a best-guess based
2140-
* on whether both Tx and Rx LPI indications have been received or
2141-
* base it on the link speed, the EEE advertised speeds on both ends
2142-
* and the speeds on which EEE is enabled locally.
2130+
* on whether Tx or Rx LPI indications have been received.
21432131
*/
2144-
if (((phy_data & E1000_EEE_TX_LPI_RCVD) &&
2145-
(phy_data & E1000_EEE_RX_LPI_RCVD)) ||
2146-
((status & E1000_STATUS_SPEED_100) &&
2147-
(edata->advertised & ADVERTISED_100baseT_Full) &&
2148-
(edata->lp_advertised & ADVERTISED_100baseT_Full) &&
2149-
(lpi_ctrl & I82579_LPI_CTRL_100_ENABLE)) ||
2150-
((status & E1000_STATUS_SPEED_1000) &&
2151-
(edata->advertised & ADVERTISED_1000baseT_Full) &&
2152-
(edata->lp_advertised & ADVERTISED_1000baseT_Full) &&
2153-
(lpi_ctrl & I82579_LPI_CTRL_1000_ENABLE)))
2132+
if (phy_data & (E1000_EEE_TX_LPI_RCVD | E1000_EEE_RX_LPI_RCVD))
21542133
edata->eee_active = true;
21552134

21562135
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)
21672146
struct ethtool_eee eee_curr;
21682147
s32 ret_val;
21692148

2170-
if (!(adapter->flags & FLAG_IS_ICH) ||
2171-
!(adapter->flags2 & FLAG2_HAS_EEE))
2172-
return -EOPNOTSUPP;
2173-
21742149
ret_val = e1000e_get_eee(netdev, &eee_curr);
21752150
if (ret_val)
21762151
return ret_val;
21772152

2178-
if (eee_curr.advertised != edata->advertised) {
2179-
e_err("Setting EEE advertisement is not supported\n");
2180-
return -EINVAL;
2181-
}
2182-
21832153
if (eee_curr.tx_lpi_enabled != edata->tx_lpi_enabled) {
21842154
e_err("Setting EEE tx-lpi is not supported\n");
21852155
return -EINVAL;
@@ -2190,16 +2160,21 @@ static int e1000e_set_eee(struct net_device *netdev, struct ethtool_eee *edata)
21902160
return -EINVAL;
21912161
}
21922162

2193-
if (hw->dev_spec.ich8lan.eee_disable != !edata->eee_enabled) {
2194-
hw->dev_spec.ich8lan.eee_disable = !edata->eee_enabled;
2195-
2196-
/* reset the link */
2197-
if (netif_running(netdev))
2198-
e1000e_reinit_locked(adapter);
2199-
else
2200-
e1000e_reset(adapter);
2163+
if (edata->advertised & ~(ADVERTISE_100_FULL | ADVERTISE_1000_FULL)) {
2164+
e_err("EEE advertisement supports only 100TX and/or 1000T full-duplex\n");
2165+
return -EINVAL;
22012166
}
22022167

2168+
adapter->eee_advert = ethtool_adv_to_mmd_eee_adv_t(edata->advertised);
2169+
2170+
hw->dev_spec.ich8lan.eee_disable = !edata->eee_enabled;
2171+
2172+
/* reset the link */
2173+
if (netif_running(netdev))
2174+
e1000e_reinit_locked(adapter);
2175+
else
2176+
e1000e_reset(adapter);
2177+
22032178
return 0;
22042179
}
22052180

drivers/net/ethernet/intel/e1000e/ich8lan.c

Lines changed: 28 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -695,7 +695,7 @@ s32 e1000_read_emi_reg_locked(struct e1000_hw *hw, u16 addr, u16 *data)
695695
*
696696
* Assumes the SW/FW/HW Semaphore is already acquired.
697697
**/
698-
static s32 e1000_write_emi_reg_locked(struct e1000_hw *hw, u16 addr, u16 data)
698+
s32 e1000_write_emi_reg_locked(struct e1000_hw *hw, u16 addr, u16 data)
699699
{
700700
return __e1000_access_emi_reg_locked(hw, addr, &data, false);
701701
}
@@ -712,11 +712,22 @@ static s32 e1000_set_eee_pchlan(struct e1000_hw *hw)
712712
{
713713
struct e1000_dev_spec_ich8lan *dev_spec = &hw->dev_spec.ich8lan;
714714
s32 ret_val;
715-
u16 lpi_ctrl;
715+
u16 lpa, pcs_status, adv, adv_addr, lpi_ctrl, data;
716716

717-
if ((hw->phy.type != e1000_phy_82579) &&
718-
(hw->phy.type != e1000_phy_i217))
717+
switch (hw->phy.type) {
718+
case e1000_phy_82579:
719+
lpa = I82579_EEE_LP_ABILITY;
720+
pcs_status = I82579_EEE_PCS_STATUS;
721+
adv_addr = I82579_EEE_ADVERTISEMENT;
722+
break;
723+
case e1000_phy_i217:
724+
lpa = I217_EEE_LP_ABILITY;
725+
pcs_status = I217_EEE_PCS_STATUS;
726+
adv_addr = I217_EEE_ADVERTISEMENT;
727+
break;
728+
default:
719729
return 0;
730+
}
720731

721732
ret_val = hw->phy.ops.acquire(hw);
722733
if (ret_val)
@@ -731,34 +742,24 @@ static s32 e1000_set_eee_pchlan(struct e1000_hw *hw)
731742

732743
/* Enable EEE if not disabled by user */
733744
if (!dev_spec->eee_disable) {
734-
u16 lpa, pcs_status, data;
735-
736745
/* Save off link partner's EEE ability */
737-
switch (hw->phy.type) {
738-
case e1000_phy_82579:
739-
lpa = I82579_EEE_LP_ABILITY;
740-
pcs_status = I82579_EEE_PCS_STATUS;
741-
break;
742-
case e1000_phy_i217:
743-
lpa = I217_EEE_LP_ABILITY;
744-
pcs_status = I217_EEE_PCS_STATUS;
745-
break;
746-
default:
747-
ret_val = -E1000_ERR_PHY;
748-
goto release;
749-
}
750746
ret_val = e1000_read_emi_reg_locked(hw, lpa,
751747
&dev_spec->eee_lp_ability);
752748
if (ret_val)
753749
goto release;
754750

751+
/* Read EEE advertisement */
752+
ret_val = e1000_read_emi_reg_locked(hw, adv_addr, &adv);
753+
if (ret_val)
754+
goto release;
755+
755756
/* Enable EEE only for speeds in which the link partner is
756-
* EEE capable.
757+
* EEE capable and for which we advertise EEE.
757758
*/
758-
if (dev_spec->eee_lp_ability & I82579_EEE_1000_SUPPORTED)
759+
if (adv & dev_spec->eee_lp_ability & I82579_EEE_1000_SUPPORTED)
759760
lpi_ctrl |= I82579_LPI_CTRL_1000_ENABLE;
760761

761-
if (dev_spec->eee_lp_ability & I82579_EEE_100_SUPPORTED) {
762+
if (adv & dev_spec->eee_lp_ability & I82579_EEE_100_SUPPORTED) {
762763
e1e_rphy_locked(hw, MII_LPA, &data);
763764
if (data & LPA_100FULL)
764765
lpi_ctrl |= I82579_LPI_CTRL_100_ENABLE;
@@ -770,13 +771,13 @@ static s32 e1000_set_eee_pchlan(struct e1000_hw *hw)
770771
dev_spec->eee_lp_ability &=
771772
~I82579_EEE_100_SUPPORTED;
772773
}
773-
774-
/* R/Clr IEEE MMD 3.1 bits 11:10 - Tx/Rx LPI Received */
775-
ret_val = e1000_read_emi_reg_locked(hw, pcs_status, &data);
776-
if (ret_val)
777-
goto release;
778774
}
779775

776+
/* R/Clr IEEE MMD 3.1 bits 11:10 - Tx/Rx LPI Received */
777+
ret_val = e1000_read_emi_reg_locked(hw, pcs_status, &data);
778+
if (ret_val)
779+
goto release;
780+
780781
ret_val = e1e_wphy_locked(hw, I82579_LPI_CTRL, lpi_ctrl);
781782
release:
782783
hw->phy.ops.release(hw);

drivers/net/ethernet/intel/e1000e/ich8lan.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,7 @@
212212
#define I82577_MSE_THRESHOLD 0x0887 /* 82577 Mean Square Error Threshold */
213213
#define I82579_MSE_LINK_DOWN 0x2411 /* MSE count before dropping link */
214214
#define I82579_RX_CONFIG 0x3412 /* Receive configuration */
215-
#define I82579_EEE_PCS_STATUS 0x182D /* IEEE MMD Register 3.1 >> 8 */
215+
#define I82579_EEE_PCS_STATUS 0x182E /* IEEE MMD Register 3.1 >> 8 */
216216
#define I82579_EEE_CAPABILITY 0x0410 /* IEEE MMD Register 3.20 */
217217
#define I82579_EEE_ADVERTISEMENT 0x040E /* IEEE MMD Register 7.60 */
218218
#define I82579_EEE_LP_ABILITY 0x040F /* IEEE MMD Register 7.61 */
@@ -268,4 +268,5 @@ s32 e1000_configure_k1_ich8lan(struct e1000_hw *hw, bool k1_enable);
268268
void e1000_copy_rx_addrs_to_phy_ich8lan(struct e1000_hw *hw);
269269
s32 e1000_lv_jumbo_workaround_ich8lan(struct e1000_hw *hw, bool enable);
270270
s32 e1000_read_emi_reg_locked(struct e1000_hw *hw, u16 addr, u16 *data);
271+
s32 e1000_write_emi_reg_locked(struct e1000_hw *hw, u16 addr, u16 data);
271272
#endif /* _E1000E_ICH8LAN_H_ */

drivers/net/ethernet/intel/e1000e/netdev.c

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3875,6 +3875,38 @@ void e1000e_reset(struct e1000_adapter *adapter)
38753875
/* initialize systim and reset the ns time counter */
38763876
e1000e_config_hwtstamp(adapter);
38773877

3878+
/* Set EEE advertisement as appropriate */
3879+
if (adapter->flags2 & FLAG2_HAS_EEE) {
3880+
s32 ret_val;
3881+
u16 adv_addr;
3882+
3883+
switch (hw->phy.type) {
3884+
case e1000_phy_82579:
3885+
adv_addr = I82579_EEE_ADVERTISEMENT;
3886+
break;
3887+
case e1000_phy_i217:
3888+
adv_addr = I217_EEE_ADVERTISEMENT;
3889+
break;
3890+
default:
3891+
dev_err(&adapter->pdev->dev,
3892+
"Invalid PHY type setting EEE advertisement\n");
3893+
return;
3894+
}
3895+
3896+
ret_val = hw->phy.ops.acquire(hw);
3897+
if (ret_val) {
3898+
dev_err(&adapter->pdev->dev,
3899+
"EEE advertisement - unable to acquire PHY\n");
3900+
return;
3901+
}
3902+
3903+
e1000_write_emi_reg_locked(hw, adv_addr,
3904+
hw->dev_spec.ich8lan.eee_disable ?
3905+
0 : adapter->eee_advert);
3906+
3907+
hw->phy.ops.release(hw);
3908+
}
3909+
38783910
if (!netif_running(adapter->netdev) &&
38793911
!test_bit(__E1000_TESTING, &adapter->state)) {
38803912
e1000_power_down_phy(adapter);
@@ -6540,6 +6572,10 @@ static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
65406572
goto err_flashmap;
65416573
}
65426574

6575+
/* Set default EEE advertisement */
6576+
if (adapter->flags2 & FLAG2_HAS_EEE)
6577+
adapter->eee_advert = MDIO_EEE_100TX | MDIO_EEE_1000T;
6578+
65436579
/* construct the net_device struct */
65446580
netdev->netdev_ops = &e1000e_netdev_ops;
65456581
e1000e_set_ethtool_ops(netdev);

0 commit comments

Comments
 (0)