apm821xx: switch to 4.14.x kernel
[openwrt/openwrt.git] / target / linux / apm821xx / patches-4.9 / 703-net-emac-fix-reset-timeout-with-AR8035-phy.patch
1 From b2e79053e7456a961249c8865214a1e95b49c863 Mon Sep 17 00:00:00 2001
2 From: Christian Lamparter <chunkeey@googlemail.com>
3 Date: Sat, 3 Jun 2017 18:16:19 +0200
4 Subject: [PATCH] net: emac: fix reset timeout with AR8035 phy
5
6 This patch fixes a problem where the AR8035 PHY can't be
7 detected on an Cisco Meraki MR24, if the ethernet cable is
8 not connected on boot.
9
10 Russell Senior provided steps to reproduce the issue:
11 |Disconnect ethernet cable, apply power, wait until device has booted,
12 |plug in ethernet, check for interfaces, no eth0 is listed.
13 |
14 |This appears to be a problem during probing of the AR8035 Phy chip.
15 |When ethernet has no link, the phy detection fails, and eth0 is not
16 |created. Plugging ethernet later has no effect, because there is no
17 |interface as far as the kernel is concerned. The relevant part of
18 |the boot log looks like this:
19 |this is the failing case:
20 |
21 |[ 0.876611] /plb/opb/emac-rgmii@ef601500: input 0 in RGMII mode
22 |[ 0.882532] /plb/opb/ethernet@ef600c00: reset timeout
23 |[ 0.888546] /plb/opb/ethernet@ef600c00: can't find PHY!
24 |and the succeeding case:
25 |
26 |[ 0.876672] /plb/opb/emac-rgmii@ef601500: input 0 in RGMII mode
27 |[ 0.883952] eth0: EMAC-0 /plb/opb/ethernet@ef600c00, MAC 00:01:..
28 |[ 0.890822] eth0: found Atheros 8035 Gigabit Ethernet PHY (0x01)
29
30 Based on the comment and the commit message of
31 commit 23fbb5a87c56 ("emac: Fix EMAC soft reset on 460EX/GT").
32 This is because the AR8035 PHY doesn't provide the TX Clock,
33 if the ethernet cable is not attached. This causes the reset
34 to timeout and the PHY detection code in emac_init_phy() is
35 unable to detect the AR8035 PHY. As a result, the emac driver
36 bails out early and the user left with no ethernet.
37
38 In order to stay compatible with existing configurations, the driver
39 tries the current reset approach at first. Only if the first attempt
40 timed out, it does perform one more retry with the clock input
41 temporarily switched to the internal clock source for just the
42 duration of the reset.
43
44 LEDE-Bug: #687 <https://bugs.lede-project.org/index.php?do=details&task_id=687>
45
46 Cc: Chris Blake <chrisrblake93@gmail.com>
47 Reported-by: Russell Senior <russell@personaltelco.net>
48 Fixes: 23fbb5a87c56e98 ("emac: Fix EMAC soft reset on 460EX/GT")
49 Reviewed-by: Andrew Lunn <andrew@lunn.ch>
50 Signed-off-by: Christian Lamparter <chunkeey@googlemail.com>
51 ---
52 drivers/net/ethernet/ibm/emac/core.c | 26 ++++++++++++++++++++++----
53 1 file changed, 22 insertions(+), 4 deletions(-)
54
55 --- a/drivers/net/ethernet/ibm/emac/core.c
56 +++ b/drivers/net/ethernet/ibm/emac/core.c
57 @@ -352,6 +352,7 @@ static int emac_reset(struct emac_instan
58 {
59 struct emac_regs __iomem *p = dev->emacp;
60 int n = 20;
61 + bool __maybe_unused try_internal_clock = false;
62
63 DBG(dev, "reset" NL);
64
65 @@ -364,6 +365,7 @@ static int emac_reset(struct emac_instan
66 }
67
68 #ifdef CONFIG_PPC_DCR_NATIVE
69 +do_retry:
70 /*
71 * PPC460EX/GT Embedded Processor Advanced User's Manual
72 * section 28.10.1 Mode Register 0 (EMACx_MR0) states:
73 @@ -371,10 +373,19 @@ static int emac_reset(struct emac_instan
74 * of the EMAC. If none is present, select the internal clock
75 * (SDR0_ETH_CFG[EMACx_PHY_CLK] = 1).
76 * After a soft reset, select the external clock.
77 + *
78 + * The AR8035-A PHY Meraki MR24 does not provide a TX Clk if the
79 + * ethernet cable is not attached. This causes the reset to timeout
80 + * and the PHY detection code in emac_init_phy() is unable to
81 + * communicate and detect the AR8035-A PHY. As a result, the emac
82 + * driver bails out early and the user has no ethernet.
83 + * In order to stay compatible with existing configurations, the
84 + * driver will temporarily switch to the internal clock, after
85 + * the first reset fails.
86 */
87 if (emac_has_feature(dev, EMAC_FTR_460EX_PHY_CLK_FIX)) {
88 - if (dev->phy_address == 0xffffffff &&
89 - dev->phy_map == 0xffffffff) {
90 + if (try_internal_clock || (dev->phy_address == 0xffffffff &&
91 + dev->phy_map == 0xffffffff)) {
92 /* No PHY: select internal loop clock before reset */
93 dcri_clrset(SDR0, SDR0_ETH_CFG,
94 0, SDR0_ETH_CFG_ECS << dev->cell_index);
95 @@ -392,8 +403,15 @@ static int emac_reset(struct emac_instan
96
97 #ifdef CONFIG_PPC_DCR_NATIVE
98 if (emac_has_feature(dev, EMAC_FTR_460EX_PHY_CLK_FIX)) {
99 - if (dev->phy_address == 0xffffffff &&
100 - dev->phy_map == 0xffffffff) {
101 + if (!n && !try_internal_clock) {
102 + /* first attempt has timed out. */
103 + n = 20;
104 + try_internal_clock = true;
105 + goto do_retry;
106 + }
107 +
108 + if (try_internal_clock || (dev->phy_address == 0xffffffff &&
109 + dev->phy_map == 0xffffffff)) {
110 /* No PHY: restore external clock source after reset */
111 dcri_clrset(SDR0, SDR0_ETH_CFG,
112 SDR0_ETH_CFG_ECS << dev->cell_index, 0);