Linux Archive

Linux Archive (http://www.linux-archive.org/)
-   Debian Kernel (http://www.linux-archive.org/debian-kernel/)
-   -   Bug#663533: please apply e1000e fixes up to some version supported upstream (e.g., 3.0.y) (http://www.linux-archive.org/debian-kernel/643406-bug-663533-please-apply-e1000e-fixes-up-some-version-supported-upstream-e-g-3-0-y.html)

Jonathan Nieder 03-12-2012 12:32 AM

Bug#663533: please apply e1000e fixes up to some version supported upstream (e.g., 3.0.y)
 
Source: linux-2.6
Version: 2.6.32-41
Severity: wishlist
Tags: patch squeeze

Hi,

Ben Hutchings wrote[1]:
> On Sun, 2012-03-11 at 14:36 -0500, Jonathan Nieder wrote:

>> Ben: it looks like there have been 31 commits to the e1000e driver
>> from 2.6.38 to 3.0.y. The patches marked with '+' seem like
>> candidates for inclusion in squeeze. '?' generally means I was
>> too lazy to think about that patch and it might or might not be a
>> candidate. What do you think?
> [...]
>
> You're probably right, but it'll take time to backport and properly test
> this lot. So for now I'll just apply the single fix.

Makes sense.

Here is a backport of the patches mentioned in the list from [1].
Backporting was straightforward for all of them. The most iffy is
probably the last one ("PCI/e1000e: Add and use
pci_disable_link_state_locked"), since it adds new ABI.

Untested. I don't have an e1000e.

Thoughts and test results welcome.
Jonathan

Bruce Allan (9):
e1000e: return appropriate errors for 'ethtool -r'
e1000e: use dev_kfree_skb_irq() instead of dev_kfree_skb()
e1000e: extend timeout for ethtool link test diagnostic
e1000e: extend EEE LPI timer to prevent dropped link
e1000e: do not toggle LANPHYPC value bit when PHY reset is blocked
e1000e: disable jumbo frames on 82579 when MACsec enabled in EEPROM
e1000e: do not suggest the driver supports Wake-on-ARP
e1000e: PCIe link speed in GT/s, not GB/s
e1000e: If ASPM L0s needs to be disabled, do it prior to enabling
device

David Decotigny (2):
ethtool: Use full 32 bit speed range in ethtool's set_settings
net/igb/e1000/e1000e: more robust ethtool duplex/speed configuration

Sergei Shtylyov (1):
net: use pci_dev->revision, again

Yinghai Lu (1):
PCI/e1000e: Add and use pci_disable_link_state_locked()

drivers/net/e1000e/82571.c | 10 +++----
drivers/net/e1000e/defines.h | 1 +
drivers/net/e1000e/e1000.h | 2 +-
drivers/net/e1000e/ethtool.c | 60 +++++++++++++++++++++++++-----------------
drivers/net/e1000e/ich8lan.c | 39 ++++++++++++++++++++++-----
drivers/net/e1000e/netdev.c | 37 +++++++++++++++++++-------
drivers/pci/pcie/aspm.c | 19 ++++++++++---
include/linux/pci-aspm.h | 1 +
8 files changed, 120 insertions(+), 49 deletions(-)

[1] http://bugs.debian.org/644906
From: Bruce Allan <bruce.w.allan@intel.com>
Date: Thu, 20 Jan 2011 06:58:07 +0000
Subject: e1000e: return appropriate errors for 'ethtool -r'

...when invoked while interface is not up or when auto-negotiation is
disabled as done by other drivers.

commit 5962bc21ceaaba81e04fa1bb5671c65251805d3e upstream.

Signed-off-by: Bruce Allan <bruce.w.allan@intel.com>
Tested-by: Jeff Pieper <jeffrey.e.pieper@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
drivers/net/e1000e/ethtool.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/drivers/net/e1000e/ethtool.c b/drivers/net/e1000e/ethtool.c
index 6f0f4153fb57..a9435c35b95d 100644
--- a/drivers/net/e1000e/ethtool.c
+++ b/drivers/net/e1000e/ethtool.c
@@ -1986,8 +1986,15 @@ static int e1000_set_coalesce(struct net_device *netdev,
static int e1000_nway_reset(struct net_device *netdev)
{
struct e1000_adapter *adapter = netdev_priv(netdev);
- if (netif_running(netdev))
- e1000e_reinit_locked(adapter);
+
+ if (!netif_running(netdev))
+ return -EAGAIN;
+
+ if (!adapter->hw.mac.autoneg)
+ return -EINVAL;
+
+ e1000e_reinit_locked(adapter);
+
return 0;
}

--
1.7.9.2

From: Sergei Shtylyov <sshtylyov@ru.mvista.com>
Date: Mon, 28 Feb 2011 11:57:33 -0800
Subject: net: use pci_dev->revision, again

commit ff938e43d39e926de74b32a3656c190f979ab642 upstream.

Several more network drivers that read the device's revision ID
from the PCI configuration register were merged after the commit
44c10138fd4bbc4b6d6bff0873c24902f2a9da65 (PCI: Change all drivers
to use pci_device->revision), so it's time to do another pass of
conversion to using the 'revision' field of 'struct pci_dev'...

[jn: restricted to drivers/net/e1000e/]

Signed-off-by: Sergei Shtylyov <sshtylyov@ru.mvista.com>
Acked-by: "John W. Linville" <linville@tuxdriver.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
drivers/net/e1000e/ethtool.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/net/e1000e/ethtool.c b/drivers/net/e1000e/ethtool.c
index a9435c35b95d..5e9aae1752ad 100644
--- a/drivers/net/e1000e/ethtool.c
+++ b/drivers/net/e1000e/ethtool.c
@@ -447,13 +447,11 @@ static void e1000_get_regs(struct net_device *netdev,
struct e1000_hw *hw = &adapter->hw;
u32 *regs_buff = p;
u16 phy_data;
- u8 revision_id;

memset(p, 0, E1000_REGS_LEN * sizeof(u32));

- pci_read_config_byte(adapter->pdev, PCI_REVISION_ID, &revision_id);
-
- regs->version = (1 << 24) | (revision_id << 16) | adapter->pdev->device;
+ regs->version = (1 << 24) | (adapter->pdev->revision << 16) |
+ adapter->pdev->device;

regs_buff[0] = er32(CTRL);
regs_buff[1] = er32(STATUS);
--
1.7.9.2

From: Bruce Allan <bruce.w.allan@intel.com>
Date: Thu, 10 Feb 2011 08:17:21 +0000
Subject: e1000e: use dev_kfree_skb_irq() instead of dev_kfree_skb()

commit ef5ab89cf7edc2e2cb996d62201a2b356d5e9286 upstream.

Based on a report and patch originally submitted by Prasanna Panchamukhi.

Use dev_kfree_skb_irq() in e1000_clean_jumbo_rx_irq() since this latter
function is called only in interrupt context. This avoids "Warning:
kfree_skb on hard IRQ" messages.

Cc: "Prasanna S. Panchamukhi" <prasanna.panchamukhi@riverbed.com>
Signed-off-by: Bruce Allan <bruce.w.allan@intel.com>
Tested-by: Jeff Pieper <jeffrey.e.pieper@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
drivers/net/e1000e/netdev.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
index dcdc472c363b..875aef6faa63 100644
--- a/drivers/net/e1000e/netdev.c
+++ b/drivers/net/e1000e/netdev.c
@@ -1327,7 +1327,7 @@ static bool e1000_clean_jumbo_rx_irq(struct e1000_adapter *adapter,
/* an error means any chain goes out the window
* too */
if (rx_ring->rx_skb_top)
- dev_kfree_skb(rx_ring->rx_skb_top);
+ dev_kfree_skb_irq(rx_ring->rx_skb_top);
rx_ring->rx_skb_top = NULL;
goto next_desc;
}
@@ -1400,7 +1400,7 @@ static bool e1000_clean_jumbo_rx_irq(struct e1000_adapter *adapter,
/* eth type trans needs skb->data to point to something */
if (!pskb_may_pull(skb, ETH_HLEN)) {
e_err("pskb_may_pull failed.
");
- dev_kfree_skb(skb);
+ dev_kfree_skb_irq(skb);
goto next_desc;
}

--
1.7.9.2

From: Bruce Allan <bruce.w.allan@intel.com>
Date: Fri, 25 Feb 2011 06:36:25 +0000
Subject: e1000e: extend timeout for ethtool link test diagnostic

commit 5661aeb08edcef6799861f92817f593c1fd7b272 upstream.

With some PHYs supported by this driver, link establishment can take a
little longer when connected to certain switches. Extend the timeout to
reduce the number of false diagnostic failures, and cleanup a code style
issue in the same function.

Signed-off-by: Bruce Allan <bruce.w.allan@intel.com>
Tested-by: Jeff Pieper <jeffrey.e.pieper@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
drivers/net/e1000e/ethtool.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/net/e1000e/ethtool.c b/drivers/net/e1000e/ethtool.c
index 5e9aae1752ad..301a2b4fe40d 100644
--- a/drivers/net/e1000e/ethtool.c
+++ b/drivers/net/e1000e/ethtool.c
@@ -1689,10 +1689,13 @@ static int e1000_link_test(struct e1000_adapter *adapter, u64 *data)
} else {
hw->mac.ops.check_for_link(hw);
if (hw->mac.autoneg)
- msleep(4000);
+ /*
+ * On some Phy/switch combinations, link establishment
+ * can take a few seconds more than expected.
+ */
+ msleep(5000);

- if (!(er32(STATUS) &
- E1000_STATUS_LU))
+ if (!(er32(STATUS) & E1000_STATUS_LU))
*data = 1;
}
return *data;
--
1.7.9.2

From: Bruce Allan <bruce.w.allan@intel.com>
Date: Fri, 25 Feb 2011 06:58:03 +0000
Subject: e1000e: extend EEE LPI timer to prevent dropped link

commit 1effb45cca29e22e4b2209bb567770b7e20a3a2b upstream.

The link can be unexpectedly dropped when the timer for entering EEE low-
power-idle quiet state expires too soon. The timer needs to be extended
from 196usec to 200usec after every LCD (PHY) reset to prevent this from
happening.

Signed-off-by: Bruce Allan <bruce.w.allan@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
drivers/net/e1000e/ich8lan.c | 29 ++++++++++++++++++++++++-----
1 file changed, 24 insertions(+), 5 deletions(-)

diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c
index 92812f439860..b4583015f567 100644
--- a/drivers/net/e1000e/ich8lan.c
+++ b/drivers/net/e1000e/ich8lan.c
@@ -141,6 +141,11 @@
#define I82579_LPI_CTRL_ENABLE_MASK 0x6000
#define I82579_LPI_CTRL_FORCE_PLL_LOCK_COUNT 0x80

+/* EMI Registers */
+#define I82579_EMI_ADDR 0x10
+#define I82579_EMI_DATA 0x11
+#define I82579_LPI_UPDATE_TIMER 0x4805 /* in 40ns units + 40 ns base value */
+
/* Strapping Option Register - RO */
#define E1000_STRAP 0x0000C
#define E1000_STRAP_SMBUS_ADDRESS_MASK 0x00FE0000
@@ -1732,11 +1737,25 @@ static s32 e1000_post_phy_reset_ich8lan(struct e1000_hw *hw)
/* Configure the LCD with the OEM bits in NVM */
ret_val = e1000_oem_bits_config_ich8lan(hw, true);

- /* Ungate automatic PHY configuration on non-managed 82579 */
- if ((hw->mac.type == e1000_pch2lan) &&
- !(er32(FWSM) & E1000_ICH_FWSM_FW_VALID)) {
- msleep(10);
- e1000_gate_hw_phy_config_ich8lan(hw, false);
+ if (hw->mac.type == e1000_pch2lan) {
+ /* Ungate automatic PHY configuration on non-managed 82579 */
+ if (!(er32(FWSM) & E1000_ICH_FWSM_FW_VALID)) {
+ msleep(10);
+ e1000_gate_hw_phy_config_ich8lan(hw, false);
+ }
+
+ /* Set EEE LPI Update Timer to 200usec */
+ ret_val = hw->phy.ops.acquire(hw);
+ if (ret_val)
+ goto out;
+ ret_val = hw->phy.ops.write_reg_locked(hw, I82579_EMI_ADDR,
+ I82579_LPI_UPDATE_TIMER);
+ if (ret_val)
+ goto release;
+ ret_val = hw->phy.ops.write_reg_locked(hw, I82579_EMI_DATA,
+ 0x1387);
+release:
+ hw->phy.ops.release(hw);
}

out:
--
1.7.9.2

From: Bruce Allan <bruce.w.allan@intel.com>
Date: Fri, 25 Feb 2011 06:25:18 +0000
Subject: e1000e: do not toggle LANPHYPC value bit when PHY reset is blocked

commit 6cc7aaed70c96c3933fbacbad582fc79b7d6e335 upstream.

When PHY reset is intentionally blocked on 82577/8/9, do not toggle the
LANPHYPC value bit (essentially performing a hard power reset of the
device) otherwise the PHY can be put into an unknown state.

[jn: with unrelated whitespace cleanup left out]

Signed-off-by: Bruce Allan <bruce.w.allan@intel.com>
Tested-by: Jeff Pieper <jeffrey.e.pieper@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
drivers/net/e1000e/ich8lan.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c
index b4583015f567..8a09f9d662e3 100644
--- a/drivers/net/e1000e/ich8lan.c
+++ b/drivers/net/e1000e/ich8lan.c
@@ -308,7 +308,7 @@ static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw)
* the interconnect to PCIe mode.
*/
fwsm = er32(FWSM);
- if (!(fwsm & E1000_ICH_FWSM_FW_VALID)) {
+ if (!(fwsm & E1000_ICH_FWSM_FW_VALID) && !e1000_check_reset_block(hw)) {
ctrl = er32(CTRL);
ctrl |= E1000_CTRL_LANPHYPC_OVERRIDE;
ctrl &= ~E1000_CTRL_LANPHYPC_VALUE;
--
1.7.9.2

From: Bruce Allan <bruce.w.allan@intel.com>
Date: Fri, 25 Feb 2011 07:44:51 +0000
Subject: e1000e: disable jumbo frames on 82579 when MACsec enabled in EEPROM

commit 23e4f061306798dfb1941bd2f399949b705822c6 upstream.

If/when an OEM enables MACsec in the 82579 EEPROM, disable jumbo frames
support in the driver due to an interoperability issue in hardware that
prevents jumbo packets from being transmitted or received.

Signed-off-by: Bruce Allan <bruce.w.allan@intel.com>
Tested-by: Jeff Pieper <jeffrey.e.pieper@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
drivers/net/e1000e/defines.h | 1 +
drivers/net/e1000e/ich8lan.c | 8 +++++++-
2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/net/e1000e/defines.h b/drivers/net/e1000e/defines.h
index 13149983d07e..c516a7440bec 100644
--- a/drivers/net/e1000e/defines.h
+++ b/drivers/net/e1000e/defines.h
@@ -86,6 +86,7 @@
#define E1000_CTRL_EXT_IAME 0x08000000 /* Interrupt acknowledge Auto-mask */
#define E1000_CTRL_EXT_INT_TIMER_CLR 0x20000000 /* Clear Interrupt timers after IMS clear */
#define E1000_CTRL_EXT_PBA_CLR 0x80000000 /* PBA Clear */
+#define E1000_CTRL_EXT_LSECCK 0x00001000
#define E1000_CTRL_EXT_PHYPDEN 0x00100000

/* Receive Descriptor bit definitions */
diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c
index 8a09f9d662e3..9e523b65161b 100644
--- a/drivers/net/e1000e/ich8lan.c
+++ b/drivers/net/e1000e/ich8lan.c
@@ -759,7 +759,13 @@ static s32 e1000_get_variants_ich8lan(struct e1000_adapter *adapter)
if (rc)
return rc;

- if (adapter->hw.phy.type == e1000_phy_ife) {
+ /*
+ * Disable Jumbo Frame support on parts with Intel 10/100 PHY or
+ * on parts with MACsec enabled in NVM (reflected in CTRL_EXT).
+ */
+ if ((adapter->hw.phy.type == e1000_phy_ife) ||
+ ((adapter->hw.mac.type >= e1000_pch2lan) &&
+ (!(er32(CTRL_EXT) & E1000_CTRL_EXT_LSECCK)))) {
adapter->flags &= ~FLAG_HAS_JUMBO_FRAMES;
adapter->max_hw_frame_size = ETH_FRAME_LEN + ETH_FCS_LEN;
}
--
1.7.9.2

From: Bruce Allan <bruce.w.allan@intel.com>
Date: Fri, 4 Mar 2011 09:07:01 +0000
Subject: e1000e: do not suggest the driver supports Wake-on-ARP

commit 4a29e15515ea56b8ec78ebb77529b1ad5c268bb9 upstream.

The driver doesn't support Wake-on-ARP, so don't advertise through ethtool
that it does.

[jn: leaving out unrelated coding style fix]

Signed-off-by: Bruce Allan <bruce.w.allan@intel.com>
Tested-by: Jeff Pieper <jeffrey.e.pieper@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
drivers/net/e1000e/ethtool.c | 9 ++-------
1 file changed, 2 insertions(+), 7 deletions(-)

diff --git a/drivers/net/e1000e/ethtool.c b/drivers/net/e1000e/ethtool.c
index 301a2b4fe40d..8c3bce6d5503 100644
--- a/drivers/net/e1000e/ethtool.c
+++ b/drivers/net/e1000e/ethtool.c
@@ -1822,8 +1822,7 @@ static void e1000_get_wol(struct net_device *netdev,
return;

wol->supported = WAKE_UCAST | WAKE_MCAST |
- WAKE_BCAST | WAKE_MAGIC |
- WAKE_PHY | WAKE_ARP;
+ WAKE_BCAST | WAKE_MAGIC | WAKE_PHY;

/* apply any specific unsupported masks here */
if (adapter->flags & FLAG_NO_WAKE_UCAST) {
@@ -1844,8 +1843,6 @@ static void e1000_get_wol(struct net_device *netdev,
wol->wolopts |= WAKE_MAGIC;
if (adapter->wol & E1000_WUFC_LNKC)
wol->wolopts |= WAKE_PHY;
- if (adapter->wol & E1000_WUFC_ARP)
- wol->wolopts |= WAKE_ARP;
}

static int e1000_set_wol(struct net_device *netdev,
@@ -1856,7 +1853,7 @@ static int e1000_set_wol(struct net_device *netdev,
if (!(adapter->flags & FLAG_HAS_WOL) ||
!device_can_wakeup(&adapter->pdev->dev) ||
(wol->wolopts & ~(WAKE_UCAST | WAKE_MCAST | WAKE_BCAST |
- WAKE_MAGIC | WAKE_PHY | WAKE_ARP)))
+ WAKE_MAGIC | WAKE_PHY)))
return -EOPNOTSUPP;

/* these settings will always override what we currently have */
@@ -1872,8 +1869,6 @@ static int e1000_set_wol(struct net_device *netdev,
adapter->wol |= E1000_WUFC_MAG;
if (wol->wolopts & WAKE_PHY)
adapter->wol |= E1000_WUFC_LNKC;
- if (wol->wolopts & WAKE_ARP)
- adapter->wol |= E1000_WUFC_ARP;

device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol);

--
1.7.9.2

From: Bruce Allan <bruce.w.allan@intel.com>
Date: Sat, 19 Mar 2011 00:31:23 +0000
Subject: e1000e: PCIe link speed in GT/s, not GB/s

commit a5cc764206a3d01dce8ebc17b4e1534afb53c495 upstream.

Correct the log message when driver loads.

Signed-off-by: Bruce Allan <bruce.w.allan@intel.com>
Tested-by: Aaron Brown <aaron.f.brown@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
drivers/net/e1000e/netdev.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
index 875aef6faa63..c7df32b97a49 100644
--- a/drivers/net/e1000e/netdev.c
+++ b/drivers/net/e1000e/netdev.c
@@ -5674,7 +5674,7 @@ static void e1000_print_device_info(struct e1000_adapter *adapter)
u8 pba_str[E1000_PBANUM_LENGTH];

/* print bus type/speed/width info */
- e_info("(PCI Express:2.5GB/s:%s) %pM
",
+ e_info("(PCI Express:2.5GT/s:%s) %pM
",
/* bus width */
((hw->bus.width == e1000_bus_width_pcie_x4) ? "Width x4" :
"Width x1"),
--
1.7.9.2

From: Bruce Allan <bruce.w.allan@intel.com>
Date: Thu, 24 Mar 2011 03:09:03 +0000
Subject: e1000e: If ASPM L0s needs to be disabled, do it prior to enabling device

commit 78cd29d5a92ae5067377ad42089f2c8781312f4a upstream.

Based on a patch from Naga Chumbalkar <nagananda.chumbalkar@hp.com>:

If ASPM L0s needs to be disabled due to HW errata, do it prior to
"enabling" the device. This way if the kernel ever defaults its
aspm_policy to POLICY_POWERSAVE, then the e1000e driver will get a
chance to disable ASPM on the misbehaving device *prior* to calling
pci_enable_device_mem(). This will be useful in situations
where the BIOS indicates ASPM support on the server by clearing the
ACPI FADT "ASPM Controls" bit.

Note:
The kernel (2.6.38) currently uses the BIOS "default" as its aspm_policy.
However, Linux distros can diverge from that and set the default to
"powersave".

v2: o cleanup namespace pollution of e1000e_disable_aspm(),
o fix type and initialization of the new aspm_disable_flag in a few
functions, and
o redefine FLAG2_DISABLE_ASPM_L0S to the first unused bit in
adapter->flags2.

Signed-off-by: Bruce Allan <bruce.w.allan@intel.com>
Cc: Naga Chumbalkar <nagananda.chumbalkar@hp.com>
Tested-by: Aaron Brown <aaron.f.brown@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
drivers/net/e1000e/82571.c | 10 +++++-----
drivers/net/e1000e/e1000.h | 2 +-
drivers/net/e1000e/netdev.c | 29 ++++++++++++++++++++++++-----
3 files changed, 30 insertions(+), 11 deletions(-)

diff --git a/drivers/net/e1000e/82571.c b/drivers/net/e1000e/82571.c
index 89a69035e538..5fddc940dcda 100644
--- a/drivers/net/e1000e/82571.c
+++ b/drivers/net/e1000e/82571.c
@@ -431,9 +431,6 @@ static s32 e1000_get_variants_82571(struct e1000_adapter *adapter)
case e1000_82573:
case e1000_82574:
case e1000_82583:
- /* Disable ASPM L0s due to hardware errata */
- e1000e_disable_aspm(adapter->pdev, PCIE_LINK_STATE_L0S);
-
if (pdev->device == E1000_DEV_ID_82573L) {
adapter->flags |= FLAG_HAS_JUMBO_FRAMES;
adapter->max_hw_frame_size = DEFAULT_JUMBO;
@@ -2066,7 +2063,8 @@ struct e1000_info e1000_82573_info = {
| FLAG_HAS_SMART_POWER_DOWN
| FLAG_HAS_AMT
| FLAG_HAS_SWSM_ON_LOAD,
- .flags2 = FLAG2_DISABLE_ASPM_L1,
+ .flags2 = FLAG2_DISABLE_ASPM_L1
+ | FLAG2_DISABLE_ASPM_L0S,
.pba = 20,
.max_hw_frame_size = ETH_FRAME_LEN + ETH_FCS_LEN,
.get_variants = e1000_get_variants_82571,
@@ -2086,7 +2084,8 @@ struct e1000_info e1000_82574_info = {
| FLAG_HAS_SMART_POWER_DOWN
| FLAG_HAS_AMT
| FLAG_HAS_CTRLEXT_ON_LOAD,
- .flags2 = FLAG2_CHECK_PHY_HANG,
+ .flags2 = FLAG2_CHECK_PHY_HANG
+ | FLAG2_DISABLE_ASPM_L0S,
.pba = 32,
.max_hw_frame_size = DEFAULT_JUMBO,
.get_variants = e1000_get_variants_82571,
@@ -2104,6 +2103,7 @@ struct e1000_info e1000_82583_info = {
| FLAG_HAS_SMART_POWER_DOWN
| FLAG_HAS_AMT
| FLAG_HAS_CTRLEXT_ON_LOAD,
+ .flags2 = FLAG2_DISABLE_ASPM_L0S,
.pba = 32,
.max_hw_frame_size = ETH_FRAME_LEN + ETH_FCS_LEN,
.get_variants = e1000_get_variants_82571,
diff --git a/drivers/net/e1000e/e1000.h b/drivers/net/e1000e/e1000.h
index e610e1369053..606aa5d44226 100644
--- a/drivers/net/e1000e/e1000.h
+++ b/drivers/net/e1000e/e1000.h
@@ -455,6 +455,7 @@ struct e1000_info {
#define FLAG2_HAS_PHY_STATS (1 << 4)
#define FLAG2_HAS_EEE (1 << 5)
#define FLAG2_DMA_BURST (1 << 6)
+#define FLAG2_DISABLE_ASPM_L0S (1 << 7)
#define FLAG2_DISABLE_AIM (1 << 8)
#define FLAG2_CHECK_PHY_HANG (1 << 9)

@@ -499,7 +500,6 @@ extern void e1000e_set_interrupt_capability(struct e1000_adapter *adapter);
extern void e1000e_reset_interrupt_capability(struct e1000_adapter *adapter);
extern void e1000e_get_hw_control(struct e1000_adapter *adapter);
extern void e1000e_release_hw_control(struct e1000_adapter *adapter);
-extern void e1000e_disable_aspm(struct pci_dev *pdev, u16 state);

extern unsigned int copybreak;

diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
index c7df32b97a49..545237bb0ff4 100644
--- a/drivers/net/e1000e/netdev.c
+++ b/drivers/net/e1000e/netdev.c
@@ -58,6 +58,8 @@
char e1000e_driver_name[] = "e1000e";
const char e1000e_driver_version[] = DRV_VERSION;

+static void e1000e_disable_aspm(struct pci_dev *pdev, u16 state);
+
static const struct e1000_info *e1000_info_tbl[] = {
[board_82571] = &e1000_82571_info,
[board_82572] = &e1000_82572_info,
@@ -5334,7 +5336,7 @@ static void __e1000e_disable_aspm(struct pci_dev *pdev, u16 state)
pci_write_config_word(pdev->bus->self, pos + PCI_EXP_LNKCTL, reg16);
}
#endif
-void e1000e_disable_aspm(struct pci_dev *pdev, u16 state)
+static void e1000e_disable_aspm(struct pci_dev *pdev, u16 state)
{
dev_info(&pdev->dev, "Disabling ASPM %s %s
",
(state & PCIE_LINK_STATE_L0S) ? "L0s" : "",
@@ -5354,13 +5356,19 @@ static int __e1000_resume(struct pci_dev *pdev)
struct net_device *netdev = pci_get_drvdata(pdev);
struct e1000_adapter *adapter = netdev_priv(netdev);
struct e1000_hw *hw = &adapter->hw;
+ u16 aspm_disable_flag = 0;
u32 err;

+ if (adapter->flags2 & FLAG2_DISABLE_ASPM_L0S)
+ aspm_disable_flag = PCIE_LINK_STATE_L0S;
+ if (adapter->flags2 & FLAG2_DISABLE_ASPM_L1)
+ aspm_disable_flag |= PCIE_LINK_STATE_L1;
+ if (aspm_disable_flag)
+ e1000e_disable_aspm(pdev, aspm_disable_flag);
+
pci_set_power_state(pdev, PCI_D0);
pci_restore_state(pdev);
pci_save_state(pdev);
- if (adapter->flags2 & FLAG2_DISABLE_ASPM_L1)
- e1000e_disable_aspm(pdev, PCIE_LINK_STATE_L1);

e1000e_set_interrupt_capability(adapter);
if (netif_running(netdev)) {
@@ -5603,11 +5611,17 @@ static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev)
struct net_device *netdev = pci_get_drvdata(pdev);
struct e1000_adapter *adapter = netdev_priv(netdev);
struct e1000_hw *hw = &adapter->hw;
+ u16 aspm_disable_flag = 0;
int err;
pci_ers_result_t result;

+ if (adapter->flags2 & FLAG2_DISABLE_ASPM_L0S)
+ aspm_disable_flag = PCIE_LINK_STATE_L0S;
if (adapter->flags2 & FLAG2_DISABLE_ASPM_L1)
- e1000e_disable_aspm(pdev, PCIE_LINK_STATE_L1);
+ aspm_disable_flag |= PCIE_LINK_STATE_L1;
+ if (aspm_disable_flag)
+ e1000e_disable_aspm(pdev, aspm_disable_flag);
+
err = pci_enable_device_mem(pdev);
if (err) {
dev_err(&pdev->dev,
@@ -5749,12 +5763,17 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
resource_size_t flash_start, flash_len;

static int cards_found;
+ u16 aspm_disable_flag = 0;
int i, err, pci_using_dac;
u16 eeprom_data = 0;
u16 eeprom_apme_mask = E1000_EEPROM_APME;

+ if (ei->flags2 & FLAG2_DISABLE_ASPM_L0S)
+ aspm_disable_flag = PCIE_LINK_STATE_L0S;
if (ei->flags2 & FLAG2_DISABLE_ASPM_L1)
- e1000e_disable_aspm(pdev, PCIE_LINK_STATE_L1);
+ aspm_disable_flag |= PCIE_LINK_STATE_L1;
+ if (aspm_disable_flag)
+ e1000e_disable_aspm(pdev, aspm_disable_flag);

err = pci_enable_device_mem(pdev);
if (err)
--
1.7.9.2

From: David Decotigny <decot@google.com>
Date: Wed, 27 Apr 2011 18:32:39 +0000
Subject: ethtool: Use full 32 bit speed range in ethtool's set_settings

commit 25db0338813a8915457636b1f6abe6a28fa73f8d upstream.

This makes sure the ethtool's set_settings() callback of network
drivers don't ignore the 16 most significant bits when ethtool calls
their set_settings().

All drivers compiled with make allyesconfig on x86_64 have been
updated.

[jn: restricted to drivers/net/e1000e/]

Signed-off-by: David Decotigny <decot@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
drivers/net/e1000e/ethtool.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/e1000e/ethtool.c b/drivers/net/e1000e/ethtool.c
index 8c3bce6d5503..c4af5beec228 100644
--- a/drivers/net/e1000e/ethtool.c
+++ b/drivers/net/e1000e/ethtool.c
@@ -283,7 +283,8 @@ static int e1000_set_settings(struct net_device *netdev,
if (adapter->fc_autoneg)
hw->fc.requested_mode = e1000_fc_default;
} else {
- if (e1000_set_spd_dplx(adapter, ecmd->speed + ecmd->duplex)) {
+ u32 speed = ethtool_cmd_speed(ecmd);
+ if (e1000_set_spd_dplx(adapter, speed + ecmd->duplex)) {
clear_bit(__E1000_RESETTING, &adapter->state);
return -EINVAL;
}
--
1.7.9.2

From: David Decotigny <decot@google.com>
Date: Wed, 27 Apr 2011 18:32:43 +0000
Subject: net/igb/e1000/e1000e: more robust ethtool duplex/speed configuration

commit 14ad2513ed5b709e566a853f4b515d91c5d83311 upstream.

This makes sure that one cannot request a 99Mbps full-duplex and get a
100Mbps half-duplex configuration in return due to the way the
speed/duplex parameters are handled internally.

[jn: restricted to drivers/net/e1000e/]

Signed-off-by: David Decotigny <decot@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
drivers/net/e1000e/ethtool.c | 24 ++++++++++++++++--------
1 file changed, 16 insertions(+), 8 deletions(-)

diff --git a/drivers/net/e1000e/ethtool.c b/drivers/net/e1000e/ethtool.c
index c4af5beec228..4b8690024a56 100644
--- a/drivers/net/e1000e/ethtool.c
+++ b/drivers/net/e1000e/ethtool.c
@@ -212,20 +212,25 @@ static u32 e1000_get_link(struct net_device *netdev)
!!(er32(STATUS) & E1000_STATUS_LU);
}

-static int e1000_set_spd_dplx(struct e1000_adapter *adapter, u16 spddplx)
+static int e1000_set_spd_dplx(struct e1000_adapter *adapter, u32 spd, u8 dplx)
{
struct e1000_mac_info *mac = &adapter->hw.mac;

mac->autoneg = 0;

+ /* Make sure dplx is at most 1 bit and lsb of speed is not set
+ * for the switch() below to work */
+ if ((spd & 1) || (dplx & ~1))
+ goto err_inval;
+
/* Fiber NICs only allow 1000 gbps Full duplex */
if ((adapter->hw.phy.media_type == e1000_media_type_fiber) &&
- spddplx != (SPEED_1000 + DUPLEX_FULL)) {
- e_err("Unsupported Speed/Duplex configuration
");
- return -EINVAL;
+ spd != SPEED_1000 &&
+ dplx != DUPLEX_FULL) {
+ goto err_inval;
}

- switch (spddplx) {
+ switch (spd + dplx) {
case SPEED_10 + DUPLEX_HALF:
mac->forced_speed_duplex = ADVERTISE_10_HALF;
break;
@@ -244,10 +249,13 @@ static int e1000_set_spd_dplx(struct e1000_adapter *adapter, u16 spddplx)
break;
case SPEED_1000 + DUPLEX_HALF: /* not supported */
default:
- e_err("Unsupported Speed/Duplex configuration
");
- return -EINVAL;
+ goto err_inval;
}
return 0;
+
+err_inval:
+ e_err("Unsupported Speed/Duplex configuration
");
+ return -EINVAL;
}

static int e1000_set_settings(struct net_device *netdev,
@@ -284,7 +292,7 @@ static int e1000_set_settings(struct net_device *netdev,
hw->fc.requested_mode = e1000_fc_default;
} else {
u32 speed = ethtool_cmd_speed(ecmd);
- if (e1000_set_spd_dplx(adapter, speed + ecmd->duplex)) {
+ if (e1000_set_spd_dplx(adapter, speed, ecmd->duplex)) {
clear_bit(__E1000_RESETTING, &adapter->state);
return -EINVAL;
}
--
1.7.9.2

From: Yinghai Lu <yinghai@kernel.org>
Date: Thu, 12 May 2011 17:11:47 -0700
Subject: PCI/e1000e: Add and use pci_disable_link_state_locked()

commit 9f728f53dd70396f3183d2f0861022259471824b upstream.

Need to use it in _e1000e_disable_aspm. This routine is used for error
recovery, where the pci_bus_sem is already held, and we don't want
pci_disable_link_state to try to take it again. So add a locked variant
for use in cases like this.

Found lock up:

[ 2374.654557] kworker/32:1 D ffff881027f6b0f0 0 6075 2 0x00000000
[ 2374.654816] ffff88503f099a68 0000000000000046 ffff88503f098000 0000000000004000
[ 2374.654837] 00000000001d1ec0 ffff88503f099fd8 00000000001d1ec0 ffff88503f099fd8
[ 2374.654860] 0000000000004000 00000000001d1ec0 ffff88503dcc8000 ffff88503f090000
[ 2374.654880] Call Trace:
[ 2374.654898] [<ffffffff810b1302>] ? __lock_acquired+0x3a/0x224
[ 2374.654914] [<ffffffff81c2b59c>] ? _raw_spin_unlock_irq+0x30/0x36
[ 2374.654925] [<ffffffff810b069d>] ? trace_hardirqs_on_caller+0x1f/0x178
[ 2374.654936] [<ffffffff81c2ab24>] rwsem_down_failed_common+0xd3/0x103
[ 2374.654945] [<ffffffff810b158f>] ? __lock_contended+0x3a/0x2a2
[ 2374.654955] [<ffffffff81c2ab7b>] rwsem_down_read_failed+0x12/0x14
[ 2374.654967] [<ffffffff813371e4>] call_rwsem_down_read_failed+0x14/0x30
[ 2374.654981] [<ffffffff8135df20>] ? pci_disable_link_state+0x5f/0xf5
[ 2374.654990] [<ffffffff81c2a0e6>] ? down_read+0x7e/0x91
[ 2374.654999] [<ffffffff8135df20>] ? pci_disable_link_state+0x5f/0xf5
[ 2374.655008] [<ffffffff8135df20>] pci_disable_link_state+0x5f/0xf5
[ 2374.655024] [<ffffffff81661796>] e1000e_disable_aspm+0x55/0x5a
[ 2374.655037] [<ffffffff816677eb>] e1000_io_slot_reset+0x59/0xea
[ 2374.655048] [<ffffffff8135fe0d>] ? report_mmio_enabled+0x5d/0x5d
[ 2374.655057] [<ffffffff8135fe3b>] report_slot_reset+0x2e/0x5d
[ 2374.655072] [<ffffffff8135369e>] pci_walk_bus+0x8a/0xb7
[ 2374.655081] [<ffffffff8135fe0d>] ? report_mmio_enabled+0x5d/0x5d
[ 2374.655091] [<ffffffff813603be>] broadcast_error_message+0xa4/0xb2
[ 2374.655101] [<ffffffff81352c71>] ? pci_bus_read_config_dword+0x72/0x80
[ 2374.655110] [<ffffffff813606df>] do_recovery+0x9e/0xf9
[ 2374.655120] [<ffffffff81360786>] handle_error_source+0x4c/0x51
[ 2374.655129] [<ffffffff81360974>] aer_isr_one_error+0x1e9/0x21a
[ 2374.655138] [<ffffffff81360a6c>] aer_isr+0xc7/0xcc
[ 2374.655147] [<ffffffff813609a5>] ? aer_isr_one_error+0x21a/0x21a
[ 2374.655159] [<ffffffff81096d9f>] process_one_work+0x237/0x3ec
[ 2374.655168] [<ffffffff81096d10>] ? process_one_work+0x1a8/0x3ec
[ 2374.655178] [<ffffffff8109728d>] worker_thread+0x17c/0x240
[ 2374.655186] [<ffffffff810b0803>] ? trace_hardirqs_on+0xd/0xf
[ 2374.655196] [<ffffffff81097111>] ? manage_workers+0xab/0xab
[ 2374.655209] [<ffffffff8109c8ed>] kthread+0xa0/0xa8
[ 2374.655223] [<ffffffff81c332d4>] kernel_thread_helper+0x4/0x10
[ 2374.655232] [<ffffffff81c2b880>] ? retint_restore_args+0xe/0xe
[ 2374.655243] [<ffffffff8109c84d>] ? __init_kthread_worker+0x5b/0x5b
[ 2374.655252] [<ffffffff81c332d0>] ? gs_change+0xb/0xb

when aer happens,
pci_walk_bus already have down_read(&pci_bus_sem)...
then report_slot_reset
==> e1000_io_slot_reset
==> e1000e_disable_aspm
==> pci_disable_link_state...

We can not use pci_disable_link_state, and it will try to hold pci_bus_sem again.

Try to have __pci_disable_link_state that will not need to hold pci_bus_sem.

-v2: change name to pci_disable_link_state_locked() according to Jesse.

[jbarnes: make sure new function is exported for modules]

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
drivers/net/e1000e/netdev.c | 2 +-
drivers/pci/pcie/aspm.c | 19 ++++++++++++++++---
include/linux/pci-aspm.h | 1 +
3 files changed, 18 insertions(+), 4 deletions(-)

diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
index 545237bb0ff4..0fd1664f0581 100644
--- a/drivers/net/e1000e/netdev.c
+++ b/drivers/net/e1000e/netdev.c
@@ -5310,7 +5310,7 @@ static void e1000_complete_shutdown(struct pci_dev *pdev, bool sleep,
#ifdef CONFIG_PCIEASPM
static void __e1000e_disable_aspm(struct pci_dev *pdev, u16 state)
{
- pci_disable_link_state(pdev, state);
+ pci_disable_link_state_locked(pdev, state);
}
#else
static void __e1000e_disable_aspm(struct pci_dev *pdev, u16 state)
diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c
index 5b7056cec00c..1b008449ed35 100644
--- a/drivers/pci/pcie/aspm.c
+++ b/drivers/pci/pcie/aspm.c
@@ -691,7 +691,7 @@ void pcie_aspm_pm_state_change(struct pci_dev *pdev)
* pci_disable_link_state - disable pci device's link state, so the link will
* never enter specific states
*/
-void pci_disable_link_state(struct pci_dev *pdev, int state)
+static void __pci_disable_link_state(struct pci_dev *pdev, int state, bool sem)
{
struct pci_dev *parent = pdev->bus->self;
struct pcie_link_state *link;
@@ -704,7 +704,8 @@ void pci_disable_link_state(struct pci_dev *pdev, int state)
if (!parent || !parent->link_state)
return;

- down_read(&pci_bus_sem);
+ if (sem)
+ down_read(&pci_bus_sem);
mutex_lock(&aspm_lock);
link = parent->link_state;
if (state & PCIE_LINK_STATE_L0S)
@@ -718,7 +719,19 @@ void pci_disable_link_state(struct pci_dev *pdev, int state)
pcie_set_clkpm(link, 0);
}
mutex_unlock(&aspm_lock);
- up_read(&pci_bus_sem);
+ if (sem)
+ up_read(&pci_bus_sem);
+}
+
+void pci_disable_link_state_locked(struct pci_dev *pdev, int state)
+{
+ __pci_disable_link_state(pdev, state, false);
+}
+EXPORT_SYMBOL(pci_disable_link_state_locked);
+
+void pci_disable_link_state(struct pci_dev *pdev, int state)
+{
+ __pci_disable_link_state(pdev, state, true);
}
EXPORT_SYMBOL(pci_disable_link_state);

diff --git a/include/linux/pci-aspm.h b/include/linux/pci-aspm.h
index 91ba0b338b47..158c7ec65fe5 100644
--- a/include/linux/pci-aspm.h
+++ b/include/linux/pci-aspm.h
@@ -27,6 +27,7 @@ extern void pcie_aspm_init_link_state(struct pci_dev *pdev);
extern void pcie_aspm_exit_link_state(struct pci_dev *pdev);
extern void pcie_aspm_pm_state_change(struct pci_dev *pdev);
extern void pci_disable_link_state(struct pci_dev *pdev, int state);
+extern void pci_disable_link_state_locked(struct pci_dev *pdev, int state);
extern void pcie_no_aspm(void);
#else
static inline void pcie_aspm_init_link_state(struct pci_dev *pdev)
--
1.7.9.2


All times are GMT. The time now is 09:49 PM.

VBulletin, Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.
Content Relevant URLs by vBSEO ©2007, Crawlability, Inc.