summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosh Boyer <jwboyer@redhat.com>2012-11-27 14:01:21 -0500
committerJosh Boyer <jwboyer@redhat.com>2012-11-27 14:06:45 -0500
commit0970aa2a8138400a2603f1bbfff27ced8168a984 (patch)
tree00038ddf8c4a1b2c1e81549ce79b336f34f89247
parent739840a50514d76fcb3c19732ff899b9270284a6 (diff)
downloadkernel-0970aa2a8138400a2603f1bbfff27ced8168a984.tar.gz
kernel-0970aa2a8138400a2603f1bbfff27ced8168a984.tar.xz
kernel-0970aa2a8138400a2603f1bbfff27ced8168a984.zip
Update patches for 8139cp issues from David Woodhouse (rhbz 851278)
-rw-r--r--8139cp-re-enable-interrupts-after-tx-timeout.patch29
-rw-r--r--8139cp-set-ring-address-after-enabling-C-mode.patch100
-rw-r--r--Revert-8139cp-revert-set-ring-address-before-enabling.patch59
-rw-r--r--kernel.spec15
4 files changed, 202 insertions, 1 deletions
diff --git a/8139cp-re-enable-interrupts-after-tx-timeout.patch b/8139cp-re-enable-interrupts-after-tx-timeout.patch
new file mode 100644
index 000000000..c0196188e
--- /dev/null
+++ b/8139cp-re-enable-interrupts-after-tx-timeout.patch
@@ -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
+
diff --git a/8139cp-set-ring-address-after-enabling-C-mode.patch b/8139cp-set-ring-address-after-enabling-C-mode.patch
new file mode 100644
index 000000000..33bd340e9
--- /dev/null
+++ b/8139cp-set-ring-address-after-enabling-C-mode.patch
@@ -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
+
diff --git a/Revert-8139cp-revert-set-ring-address-before-enabling.patch b/Revert-8139cp-revert-set-ring-address-before-enabling.patch
new file mode 100644
index 000000000..6ed20c43c
--- /dev/null
+++ b/Revert-8139cp-revert-set-ring-address-before-enabling.patch
@@ -0,0 +1,59 @@
+From 071e3ef4a94a021b16a2912f3885c86f4ff36b49 Mon Sep 17 00:00:00 2001
+From: "David S. Miller" <davem@davemloft.net>
+Date: Sun, 25 Nov 2012 15:52:09 -0500
+Subject: [PATCH] Revert "8139cp: revert "set ring address before enabling
+ receiver""
+
+This reverts commit b26623dab7eeb1e9f5898c7a49458789dd492f20.
+
+This reverts the revert, in net-next we'll try another scheme
+to fix this bug using patches from David Woodhouse.
+
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/ethernet/realtek/8139cp.c | 22 +++++++++++-----------
+ 1 files changed, 11 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/net/ethernet/realtek/8139cp.c b/drivers/net/ethernet/realtek/8139cp.c
+index b01f83a..1c81825 100644
+--- a/drivers/net/ethernet/realtek/8139cp.c
++++ b/drivers/net/ethernet/realtek/8139cp.c
+@@ -979,6 +979,17 @@ 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 */
+
+@@ -992,17 +1003,6 @@ 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.7.6.5
+
diff --git a/kernel.spec b/kernel.spec
index dfe86ab58..0155a4680 100644
--- a/kernel.spec
+++ b/kernel.spec
@@ -62,7 +62,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
@@ -773,6 +773,11 @@ Patch21226: vt-Drop-K_OFF-for-VC_MUTE.patch
Patch21228: exec-do-not-leave-bprm-interp-on-stack.patch
Patch21229: exec-use-eloop-for-max-recursion-depth.patch
+#rhbz 851278
+Patch21234: Revert-8139cp-revert-set-ring-address-before-enabling.patch
+Patch21232: 8139cp-set-ring-address-after-enabling-C-mode.patch
+Patch21233: 8139cp-re-enable-interrupts-after-tx-timeout.patch
+
# END OF PATCH DEFINITIONS
%endif
@@ -1489,6 +1494,11 @@ ApplyPatch vt-Drop-K_OFF-for-VC_MUTE.patch
ApplyPatch exec-do-not-leave-bprm-interp-on-stack.patch
ApplyPatch exec-use-eloop-for-max-recursion-depth.patch
+#rhbz 851278
+ApplyPatch Revert-8139cp-revert-set-ring-address-before-enabling.patch
+ApplyPatch 8139cp-set-ring-address-after-enabling-C-mode.patch
+ApplyPatch 8139cp-re-enable-interrupts-after-tx-timeout.patch
+
# END OF PATCH APPLICATIONS
%endif
@@ -2356,6 +2366,9 @@ fi
# ||----w |
# || ||
%changelog
+* Tue Nov 27 2012 Josh Boyer <jwboyer@redhat.com>
+- Update patches for 8139cp issues from David Woodhouse (rhbz 851278)
+
* Tue Nov 27 2012 Josh Boyer <jwboyer@redhat.com> - 3.7.0-0.rc7.git1.1
- Linux v3.7-rc7-25-g2844a48
- Reenable debugging options.