9ce01aac5edaeb29a6213f45523048386cd113df
[openwrt/openwrt.git] / target / linux / generic / pending-4.14 / 191-1-6-e1000e-Remove-Other-from-EIAC.diff
1 From patchwork Mon Mar 5 21:40:25 2018
2 Content-Type: text/plain; charset="utf-8"
3 MIME-Version: 1.0
4 Content-Transfer-Encoding: 7bit
5 Subject: [net,v2,1/6] e1000e: Remove Other from EIAC
6 X-Patchwork-Submitter: "Kirsher, Jeffrey T" <jeffrey.t.kirsher@intel.com>
7 X-Patchwork-Id: 881773
8 X-Patchwork-Delegate: davem@davemloft.net
9 Message-Id: <20180305214030.25141-2-jeffrey.t.kirsher@intel.com>
10 To: davem@davemloft.net
11 Cc: Benjamin Poirier <bpoirier@suse.com>, netdev@vger.kernel.org,
12 nhorman@redhat.com, sassmann@redhat.com, jogreene@redhat.com,
13 Jeff Kirsher <jeffrey.t.kirsher@intel.com>
14 Date: Mon, 5 Mar 2018 13:40:25 -0800
15 From: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
16 List-Id: <netdev.vger.kernel.org>
17
18 From: Benjamin Poirier <bpoirier@suse.com>
19
20 It was reported that emulated e1000e devices in vmware esxi 6.5 Build
21 7526125 do not link up after commit 4aea7a5c5e94 ("e1000e: Avoid receiver
22 overrun interrupt bursts", v4.15-rc1). Some tracing shows that after
23 e1000e_trigger_lsc() is called, ICR reads out as 0x0 in e1000_msix_other()
24 on emulated e1000e devices. In comparison, on real e1000e 82574 hardware,
25 icr=0x80000004 (_INT_ASSERTED | _LSC) in the same situation.
26
27 Some experimentation showed that this flaw in vmware e1000e emulation can
28 be worked around by not setting Other in EIAC. This is how it was before
29 16ecba59bc33 ("e1000e: Do not read ICR in Other interrupt", v4.5-rc1).
30
31 Fixes: 4aea7a5c5e94 ("e1000e: Avoid receiver overrun interrupt bursts")
32 Signed-off-by: Benjamin Poirier <bpoirier@suse.com>
33 Tested-by: Aaron Brown <aaron.f.brown@intel.com>
34 Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
35 ---
36 drivers/net/ethernet/intel/e1000e/netdev.c | 5 +++--
37 1 file changed, 3 insertions(+), 2 deletions(-)
38
39 --- a/drivers/net/ethernet/intel/e1000e/netdev.c
40 +++ b/drivers/net/ethernet/intel/e1000e/netdev.c
41 @@ -1914,6 +1914,8 @@ static irqreturn_t e1000_msix_other(int
42 bool enable = true;
43
44 icr = er32(ICR);
45 + ew32(ICR, E1000_ICR_OTHER);
46 +
47 if (icr & E1000_ICR_RXO) {
48 ew32(ICR, E1000_ICR_RXO);
49 enable = false;
50 @@ -2036,7 +2038,6 @@ static void e1000_configure_msix(struct
51 hw->hw_addr + E1000_EITR_82574(vector));
52 else
53 writel(1, hw->hw_addr + E1000_EITR_82574(vector));
54 - adapter->eiac_mask |= E1000_IMS_OTHER;
55
56 /* Cause Tx interrupts on every write back */
57 ivar |= BIT(31);
58 @@ -2261,7 +2262,7 @@ static void e1000_irq_enable(struct e100
59
60 if (adapter->msix_entries) {
61 ew32(EIAC_82574, adapter->eiac_mask & E1000_EIAC_MASK_82574);
62 - ew32(IMS, adapter->eiac_mask | E1000_IMS_LSC);
63 + ew32(IMS, adapter->eiac_mask | E1000_IMS_OTHER | E1000_IMS_LSC);
64 } else if (hw->mac.type >= e1000_pch_lpt) {
65 ew32(IMS, IMS_ENABLE_MASK | E1000_IMS_ECCER);
66 } else {