diff options
3 files changed, 116 insertions, 5 deletions
diff --git a/target/linux/apm821xx/patches-4.9/701-powerpc_ibm_apm82181_phyclk_fix.patch b/target/linux/apm821xx/patches-4.9/701-powerpc_ibm_apm82181_phyclk_fix.patch index 93a0858b26..457c5e3780 100644 --- a/target/linux/apm821xx/patches-4.9/701-powerpc_ibm_apm82181_phyclk_fix.patch +++ b/target/linux/apm821xx/patches-4.9/701-powerpc_ibm_apm82181_phyclk_fix.patch @@ -30,15 +30,14 @@ #endif } -@@ -2617,7 +2626,7 @@ static int emac_init_config(struct emac_ +@@ -2617,6 +2626,7 @@ static int emac_init_config(struct emac_ if (of_device_is_compatible(np, "ibm,emac-apm821xx")) { dev->features |= (EMAC_APM821XX_REQ_JUMBO_FRAME_SIZE | EMAC_FTR_APM821XX_NO_HALF_DUPLEX | -- EMAC_FTR_460EX_PHY_CLK_FIX); -+ EMAC_FTR_APM821XX_PHY_CLK_FIX); ++ EMAC_FTR_APM821XX_PHY_CLK_FIX | + EMAC_FTR_460EX_PHY_CLK_FIX); } } else if (of_device_is_compatible(np, "ibm,emac4")) { - dev->features |= EMAC_FTR_EMAC4; --- a/drivers/net/ethernet/ibm/emac/core.h +++ b/drivers/net/ethernet/ibm/emac/core.h @@ -333,6 +333,8 @@ struct emac_instance { diff --git a/target/linux/apm821xx/patches-4.9/702-powerpc_ibm_phy_add_dt_parser.patch b/target/linux/apm821xx/patches-4.9/702-powerpc_ibm_phy_add_dt_parser.patch index f1edb9cc7a..4e53fdfa21 100644 --- a/target/linux/apm821xx/patches-4.9/702-powerpc_ibm_phy_add_dt_parser.patch +++ b/target/linux/apm821xx/patches-4.9/702-powerpc_ibm_phy_add_dt_parser.patch @@ -300,7 +300,7 @@ Signed-off-by: Christian Lamparter <chunkeey@googlemail.com> /* Init PHY */ if (dev->phy.def->ops->init) dev->phy.def->ops->init(&dev->phy); -@@ -2987,6 +3228,12 @@ static int emac_remove(struct platform_d +@@ -2988,6 +3229,12 @@ static int emac_remove(struct platform_d if (emac_has_feature(dev, EMAC_FTR_HAS_ZMII)) zmii_detach(dev->zmii_dev, dev->zmii_port); diff --git a/target/linux/apm821xx/patches-4.9/703-net-emac-fix-reset-timeout-with-AR8035-phy.patch b/target/linux/apm821xx/patches-4.9/703-net-emac-fix-reset-timeout-with-AR8035-phy.patch new file mode 100644 index 0000000000..8acde84ec0 --- /dev/null +++ b/target/linux/apm821xx/patches-4.9/703-net-emac-fix-reset-timeout-with-AR8035-phy.patch @@ -0,0 +1,112 @@ +From b2e79053e7456a961249c8865214a1e95b49c863 Mon Sep 17 00:00:00 2001 +From: Christian Lamparter <chunkeey@googlemail.com> +Date: Sat, 3 Jun 2017 18:16:19 +0200 +Subject: [PATCH] net: emac: fix reset timeout with AR8035 phy + +This patch fixes a problem where the AR8035 PHY can't be +detected on an Cisco Meraki MR24, if the ethernet cable is +not connected on boot. + +Russell Senior provided steps to reproduce the issue: +|Disconnect ethernet cable, apply power, wait until device has booted, +|plug in ethernet, check for interfaces, no eth0 is listed. +| +|This appears to be a problem during probing of the AR8035 Phy chip. +|When ethernet has no link, the phy detection fails, and eth0 is not +|created. Plugging ethernet later has no effect, because there is no +|interface as far as the kernel is concerned. The relevant part of +|the boot log looks like this: +|this is the failing case: +| +|[ 0.876611] /plb/opb/emac-rgmii@ef601500: input 0 in RGMII mode +|[ 0.882532] /plb/opb/ethernet@ef600c00: reset timeout +|[ 0.888546] /plb/opb/ethernet@ef600c00: can't find PHY! +|and the succeeding case: +| +|[ 0.876672] /plb/opb/emac-rgmii@ef601500: input 0 in RGMII mode +|[ 0.883952] eth0: EMAC-0 /plb/opb/ethernet@ef600c00, MAC 00:01:.. +|[ 0.890822] eth0: found Atheros 8035 Gigabit Ethernet PHY (0x01) + +Based on the comment and the commit message of +commit 23fbb5a87c56 ("emac: Fix EMAC soft reset on 460EX/GT"). +This is because the AR8035 PHY doesn't provide the TX Clock, +if the ethernet cable is not attached. This causes the reset +to timeout and the PHY detection code in emac_init_phy() is +unable to detect the AR8035 PHY. As a result, the emac driver +bails out early and the user left with no ethernet. + +In order to stay compatible with existing configurations, the driver +tries the current reset approach at first. Only if the first attempt +timed out, it does perform one more retry with the clock input +temporarily switched to the internal clock source for just the +duration of the reset. + +LEDE-Bug: #687 <https://bugs.lede-project.org/index.php?do=details&task_id=687> + +Cc: Chris Blake <chrisrblake93@gmail.com> +Reported-by: Russell Senior <russell@personaltelco.net> +Fixes: 23fbb5a87c56e98 ("emac: Fix EMAC soft reset on 460EX/GT") +Reviewed-by: Andrew Lunn <andrew@lunn.ch> +Signed-off-by: Christian Lamparter <chunkeey@googlemail.com> +--- + drivers/net/ethernet/ibm/emac/core.c | 26 ++++++++++++++++++++++---- + 1 file changed, 22 insertions(+), 4 deletions(-) + +--- a/drivers/net/ethernet/ibm/emac/core.c ++++ b/drivers/net/ethernet/ibm/emac/core.c +@@ -352,6 +352,7 @@ static int emac_reset(struct emac_instan + { + struct emac_regs __iomem *p = dev->emacp; + int n = 20; ++ bool __maybe_unused try_internal_clock = false; + + DBG(dev, "reset" NL); + +@@ -364,6 +365,7 @@ static int emac_reset(struct emac_instan + } + + #ifdef CONFIG_PPC_DCR_NATIVE ++do_retry: + /* + * PPC460EX/GT Embedded Processor Advanced User's Manual + * section 28.10.1 Mode Register 0 (EMACx_MR0) states: +@@ -371,10 +373,19 @@ static int emac_reset(struct emac_instan + * of the EMAC. If none is present, select the internal clock + * (SDR0_ETH_CFG[EMACx_PHY_CLK] = 1). + * After a soft reset, select the external clock. ++ * ++ * The AR8035-A PHY Meraki MR24 does not provide a TX Clk if the ++ * ethernet cable is not attached. This causes the reset to timeout ++ * and the PHY detection code in emac_init_phy() is unable to ++ * communicate and detect the AR8035-A PHY. As a result, the emac ++ * driver bails out early and the user has no ethernet. ++ * In order to stay compatible with existing configurations, the ++ * driver will temporarily switch to the internal clock, after ++ * the first reset fails. + */ + if (emac_has_feature(dev, EMAC_FTR_460EX_PHY_CLK_FIX)) { +- if (dev->phy_address == 0xffffffff && +- dev->phy_map == 0xffffffff) { ++ if (try_internal_clock || (dev->phy_address == 0xffffffff && ++ dev->phy_map == 0xffffffff)) { + /* No PHY: select internal loop clock before reset */ + dcri_clrset(SDR0, SDR0_ETH_CFG, + 0, SDR0_ETH_CFG_ECS << dev->cell_index); +@@ -392,8 +403,15 @@ static int emac_reset(struct emac_instan + + #ifdef CONFIG_PPC_DCR_NATIVE + if (emac_has_feature(dev, EMAC_FTR_460EX_PHY_CLK_FIX)) { +- if (dev->phy_address == 0xffffffff && +- dev->phy_map == 0xffffffff) { ++ if (!n && !try_internal_clock) { ++ /* first attempt has timed out. */ ++ n = 20; ++ try_internal_clock = true; ++ goto do_retry; ++ } ++ ++ if (try_internal_clock || (dev->phy_address == 0xffffffff && ++ dev->phy_map == 0xffffffff)) { + /* No PHY: restore external clock source after reset */ + dcri_clrset(SDR0, SDR0_ETH_CFG, + SDR0_ETH_CFG_ECS << dev->cell_index, 0); |