From 0970aa2a8138400a2603f1bbfff27ced8168a984 Mon Sep 17 00:00:00 2001 From: Josh Boyer Date: Tue, 27 Nov 2012 14:01:21 -0500 Subject: [PATCH] Update patches for 8139cp issues from David Woodhouse (rhbz 851278) --- ...e-enable-interrupts-after-tx-timeout.patch | 29 +++++ ...t-ring-address-after-enabling-C-mode.patch | 100 ++++++++++++++++++ ...ert-set-ring-address-before-enabling.patch | 59 +++++++++++ kernel.spec | 15 ++- 4 files changed, 202 insertions(+), 1 deletion(-) create mode 100644 8139cp-re-enable-interrupts-after-tx-timeout.patch create mode 100644 8139cp-set-ring-address-after-enabling-C-mode.patch create mode 100644 Revert-8139cp-revert-set-ring-address-before-enabling.patch 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 +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 +Acked-by: Francois Romieu +Signed-off-by: David S. Miller +--- + 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 +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 +Cc: stable@kernel.org [3.5+] +Signed-off-by: David S. Miller +--- + 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" +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 +--- + 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 +- Update patches for 8139cp issues from David Woodhouse (rhbz 851278) + * Tue Nov 27 2012 Josh Boyer - 3.7.0-0.rc7.git1.1 - Linux v3.7-rc7-25-g2844a48 - Reenable debugging options.