Update patches for 8139cp issues from David Woodhouse (rhbz 851278)
This commit is contained in:
parent
0263651479
commit
826eb77610
29
8139cp-re-enable-interrupts-after-tx-timeout.patch
Normal file
29
8139cp-re-enable-interrupts-after-tx-timeout.patch
Normal file
@ -0,0 +1,29 @@
|
||||
From 01ffc0a7f1c1801a2354719dedbc32aff45b987d Mon Sep 17 00:00:00 2001
|
||||
From: David Woodhouse <dwmw2@infradead.org>
|
||||
Date: Sat, 24 Nov 2012 12:11:21 +0000
|
||||
Subject: [PATCH] 8139cp: re-enable interrupts after tx timeout
|
||||
|
||||
Recovery doesn't work too well if we leave interrupts disabled...
|
||||
|
||||
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
|
||||
Acked-by: Francois Romieu <romieu@fr.zoreil.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/ethernet/realtek/8139cp.c | 1 +
|
||||
1 files changed, 1 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/realtek/8139cp.c b/drivers/net/ethernet/realtek/8139cp.c
|
||||
index 3de318d..6cb96b4 100644
|
||||
--- a/drivers/net/ethernet/realtek/8139cp.c
|
||||
+++ b/drivers/net/ethernet/realtek/8139cp.c
|
||||
@@ -1219,6 +1219,7 @@ static void cp_tx_timeout(struct net_device *dev)
|
||||
cp_clean_rings(cp);
|
||||
rc = cp_init_rings(cp);
|
||||
cp_start_hw(cp);
|
||||
+ cp_enable_irq(cp);
|
||||
|
||||
netif_wake_queue(dev);
|
||||
|
||||
--
|
||||
1.7.6.5
|
||||
|
@ -1,62 +0,0 @@
|
||||
From b26623dab7eeb1e9f5898c7a49458789dd492f20 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?fran=C3=A7ois=20romieu?= <romieu@fr.zoreil.com>
|
||||
Date: Wed, 21 Nov 2012 10:07:29 +0000
|
||||
Subject: [PATCH] 8139cp: revert "set ring address before enabling receiver"
|
||||
|
||||
This patch reverts b01af4579ec41f48e9b9c774e70bd6474ad210db.
|
||||
|
||||
The original patch was tested with emulated hardware. Real
|
||||
hardware chokes.
|
||||
|
||||
Fixes https://bugzilla.kernel.org/show_bug.cgi?id=47041
|
||||
|
||||
Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
|
||||
Acked-by: Jeff Garzik <jgarzik@redhat.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/ethernet/realtek/8139cp.c | 22 +++++++++++-----------
|
||||
1 file changed, 11 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/realtek/8139cp.c b/drivers/net/ethernet/realtek/8139cp.c
|
||||
index 1c81825..b01f83a 100644
|
||||
--- a/drivers/net/ethernet/realtek/8139cp.c
|
||||
+++ b/drivers/net/ethernet/realtek/8139cp.c
|
||||
@@ -979,17 +979,6 @@ static void cp_init_hw (struct cp_private *cp)
|
||||
cpw32_f (MAC0 + 0, le32_to_cpu (*(__le32 *) (dev->dev_addr + 0)));
|
||||
cpw32_f (MAC0 + 4, le32_to_cpu (*(__le32 *) (dev->dev_addr + 4)));
|
||||
|
||||
- cpw32_f(HiTxRingAddr, 0);
|
||||
- cpw32_f(HiTxRingAddr + 4, 0);
|
||||
-
|
||||
- ring_dma = cp->ring_dma;
|
||||
- cpw32_f(RxRingAddr, ring_dma & 0xffffffff);
|
||||
- cpw32_f(RxRingAddr + 4, (ring_dma >> 16) >> 16);
|
||||
-
|
||||
- ring_dma += sizeof(struct cp_desc) * CP_RX_RING_SIZE;
|
||||
- cpw32_f(TxRingAddr, ring_dma & 0xffffffff);
|
||||
- cpw32_f(TxRingAddr + 4, (ring_dma >> 16) >> 16);
|
||||
-
|
||||
cp_start_hw(cp);
|
||||
cpw8(TxThresh, 0x06); /* XXX convert magic num to a constant */
|
||||
|
||||
@@ -1003,6 +992,17 @@ static void cp_init_hw (struct cp_private *cp)
|
||||
|
||||
cpw8(Config5, cpr8(Config5) & PMEStatus);
|
||||
|
||||
+ cpw32_f(HiTxRingAddr, 0);
|
||||
+ cpw32_f(HiTxRingAddr + 4, 0);
|
||||
+
|
||||
+ ring_dma = cp->ring_dma;
|
||||
+ cpw32_f(RxRingAddr, ring_dma & 0xffffffff);
|
||||
+ cpw32_f(RxRingAddr + 4, (ring_dma >> 16) >> 16);
|
||||
+
|
||||
+ ring_dma += sizeof(struct cp_desc) * CP_RX_RING_SIZE;
|
||||
+ cpw32_f(TxRingAddr, ring_dma & 0xffffffff);
|
||||
+ cpw32_f(TxRingAddr + 4, (ring_dma >> 16) >> 16);
|
||||
+
|
||||
cpw16(MultiIntr, 0);
|
||||
|
||||
cpw8_f(Cfg9346, Cfg9346_Lock);
|
||||
--
|
||||
1.8.0
|
||||
|
100
8139cp-set-ring-address-after-enabling-C-mode.patch
Normal file
100
8139cp-set-ring-address-after-enabling-C-mode.patch
Normal file
@ -0,0 +1,100 @@
|
||||
From a9dbe40fc10cea2efe6e1ff9e03c62dd7579c5ba Mon Sep 17 00:00:00 2001
|
||||
From: David Woodhouse <dwmw2@infradead.org>
|
||||
Date: Wed, 21 Nov 2012 10:27:19 +0000
|
||||
Subject: [PATCH] 8139cp: set ring address after enabling C+ mode
|
||||
|
||||
This fixes (for me) a regression introduced by commit b01af457 ("8139cp:
|
||||
set ring address before enabling receiver"). That commit configured the
|
||||
descriptor ring addresses earlier in the initialisation sequence, in
|
||||
order to avoid the possibility of triggering stray DMA before the
|
||||
correct address had been set up.
|
||||
|
||||
Unfortunately, it seems that the hardware will scribble garbage into the
|
||||
TxRingAddr registers when we enable "plus mode" Tx in the CpCmd
|
||||
register. Observed on a Traverse Geos router board.
|
||||
|
||||
To deal with this, while not reintroducing the problem which led to the
|
||||
original commit, we augment cp_start_hw() to write to the CpCmd register
|
||||
*first*, then set the descriptor ring addresses, and then finally to
|
||||
enable Rx and Tx in the original 8139 Cmd register. The datasheet
|
||||
actually indicates that we should enable Tx/Rx in the Cmd register
|
||||
*before* configuring the descriptor addresses, but that would appear to
|
||||
re-introduce the problem that the offending commit b01af457 was trying
|
||||
to solve. And this variant appears to work fine on real hardware.
|
||||
|
||||
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
|
||||
Cc: stable@kernel.org [3.5+]
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/ethernet/realtek/8139cp.c | 40 +++++++++++++++++++++++----------
|
||||
1 files changed, 28 insertions(+), 12 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/realtek/8139cp.c b/drivers/net/ethernet/realtek/8139cp.c
|
||||
index 1c81825..5166d94 100644
|
||||
--- a/drivers/net/ethernet/realtek/8139cp.c
|
||||
+++ b/drivers/net/ethernet/realtek/8139cp.c
|
||||
@@ -957,7 +957,35 @@ static void cp_reset_hw (struct cp_private *cp)
|
||||
|
||||
static inline void cp_start_hw (struct cp_private *cp)
|
||||
{
|
||||
+ dma_addr_t ring_dma;
|
||||
+
|
||||
cpw16(CpCmd, cp->cpcmd);
|
||||
+
|
||||
+ /*
|
||||
+ * These (at least TxRingAddr) need to be configured after the
|
||||
+ * corresponding bits in CpCmd are enabled. Datasheet v1.6 §6.33
|
||||
+ * (C+ Command Register) recommends that these and more be configured
|
||||
+ * *after* the [RT]xEnable bits in CpCmd are set. And on some hardware
|
||||
+ * it's been observed that the TxRingAddr is actually reset to garbage
|
||||
+ * when C+ mode Tx is enabled in CpCmd.
|
||||
+ */
|
||||
+ cpw32_f(HiTxRingAddr, 0);
|
||||
+ cpw32_f(HiTxRingAddr + 4, 0);
|
||||
+
|
||||
+ ring_dma = cp->ring_dma;
|
||||
+ cpw32_f(RxRingAddr, ring_dma & 0xffffffff);
|
||||
+ cpw32_f(RxRingAddr + 4, (ring_dma >> 16) >> 16);
|
||||
+
|
||||
+ ring_dma += sizeof(struct cp_desc) * CP_RX_RING_SIZE;
|
||||
+ cpw32_f(TxRingAddr, ring_dma & 0xffffffff);
|
||||
+ cpw32_f(TxRingAddr + 4, (ring_dma >> 16) >> 16);
|
||||
+
|
||||
+ /*
|
||||
+ * Strictly speaking, the datasheet says this should be enabled
|
||||
+ * *before* setting the descriptor addresses. But what, then, would
|
||||
+ * prevent it from doing DMA to random unconfigured addresses?
|
||||
+ * This variant appears to work fine.
|
||||
+ */
|
||||
cpw8(Cmd, RxOn | TxOn);
|
||||
}
|
||||
|
||||
@@ -969,7 +997,6 @@ static void cp_enable_irq(struct cp_private *cp)
|
||||
static void cp_init_hw (struct cp_private *cp)
|
||||
{
|
||||
struct net_device *dev = cp->dev;
|
||||
- dma_addr_t ring_dma;
|
||||
|
||||
cp_reset_hw(cp);
|
||||
|
||||
@@ -979,17 +1006,6 @@ static void cp_init_hw (struct cp_private *cp)
|
||||
cpw32_f (MAC0 + 0, le32_to_cpu (*(__le32 *) (dev->dev_addr + 0)));
|
||||
cpw32_f (MAC0 + 4, le32_to_cpu (*(__le32 *) (dev->dev_addr + 4)));
|
||||
|
||||
- cpw32_f(HiTxRingAddr, 0);
|
||||
- cpw32_f(HiTxRingAddr + 4, 0);
|
||||
-
|
||||
- ring_dma = cp->ring_dma;
|
||||
- cpw32_f(RxRingAddr, ring_dma & 0xffffffff);
|
||||
- cpw32_f(RxRingAddr + 4, (ring_dma >> 16) >> 16);
|
||||
-
|
||||
- ring_dma += sizeof(struct cp_desc) * CP_RX_RING_SIZE;
|
||||
- cpw32_f(TxRingAddr, ring_dma & 0xffffffff);
|
||||
- cpw32_f(TxRingAddr + 4, (ring_dma >> 16) >> 16);
|
||||
-
|
||||
cp_start_hw(cp);
|
||||
cpw8(TxThresh, 0x06); /* XXX convert magic num to a constant */
|
||||
|
||||
--
|
||||
1.7.6.5
|
||||
|
11
kernel.spec
11
kernel.spec
@ -54,7 +54,7 @@ Summary: The Linux kernel
|
||||
# For non-released -rc kernels, this will be appended after the rcX and
|
||||
# gitX tags, so a 3 here would become part of release "0.rcX.gitX.3"
|
||||
#
|
||||
%global baserelease 1
|
||||
%global baserelease 2
|
||||
%global fedora_build %{baserelease}
|
||||
|
||||
# base_sublevel is the kernel version we're starting with and patching
|
||||
@ -728,7 +728,8 @@ Patch21229: exec-use-eloop-for-max-recursion-depth.patch
|
||||
Patch21230: SCSI-mvsas-Fix-oops-when-ata-commond-timeout.patch
|
||||
|
||||
#rhbz 851278
|
||||
Patch21232: 8139cp-revert-set-ring-address-before-enabling-recei.patch
|
||||
Patch21232: 8139cp-set-ring-address-after-enabling-C-mode.patch
|
||||
Patch21233: 8139cp-re-enable-interrupts-after-tx-timeout.patch
|
||||
|
||||
# END OF PATCH DEFINITIONS
|
||||
|
||||
@ -1375,7 +1376,8 @@ ApplyPatch exec-use-eloop-for-max-recursion-depth.patch
|
||||
ApplyPatch SCSI-mvsas-Fix-oops-when-ata-commond-timeout.patch
|
||||
|
||||
#rhbz 851278
|
||||
ApplyPatch 8139cp-revert-set-ring-address-before-enabling-recei.patch
|
||||
ApplyPatch 8139cp-set-ring-address-after-enabling-C-mode.patch
|
||||
ApplyPatch 8139cp-re-enable-interrupts-after-tx-timeout.patch
|
||||
|
||||
# END OF PATCH APPLICATIONS
|
||||
|
||||
@ -2077,6 +2079,9 @@ fi
|
||||
# and build.
|
||||
|
||||
%changelog
|
||||
* Tue Nov 27 2012 Josh Boyer <jwboyer@redhat.com>
|
||||
- Update patches for 8139cp issues from David Woodhouse (rhbz 851278)
|
||||
|
||||
* Mon Nov 26 2012 Josh Boyer <jwboyer@redhat.com> - 3.6.8-1
|
||||
- Linux v3.6.8
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user