From: Christian Lamparter <chunkeey@googlemail.com> Date: 2017-06-07 13:51:19
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 temporarily
switched to the internal 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 <redacted>
Reported-by: Russell Senior <redacted>
Fixes: 23fbb5a87c56e98 ("emac: Fix EMAC soft reset on 460EX/GT")
Signed-off-by: Christian Lamparter <chunkeey@googlemail.com>
---
v1 -> v2:
- made it clear, that the clock source is only switched
temporarily.
- fixed missing goto label, if !CONFIG_PPC_DCR_NATIVE
---
drivers/net/ethernet/ibm/emac/core.c | 26 ++++++++++++++++++++++----
1 file changed, 22 insertions(+), 4 deletions(-)
@@ -343,6 +343,7 @@ static int emac_reset(struct emac_instance *dev){structemac_regs__iomem*p=dev->emacp;intn=20;+bool__maybe_unusedtry_internal_clock=false;DBG(dev,"reset"NL);
@@ -355,6 +356,7 @@ static int emac_reset(struct emac_instance *dev)}#ifdef CONFIG_PPC_DCR_NATIVE+do_retry:/**PPC460EX/GTEmbeddedProcessorAdvancedUser'sManual*section28.10.1ModeRegister0(EMACx_MR0)states:
@@ -362,10 +364,19 @@ static int emac_reset(struct emac_instance *dev)*oftheEMAC.Ifnoneispresent,selecttheinternalclock*(SDR0_ETH_CFG[EMACx_PHY_CLK]=1).*Afterasoftreset,selecttheexternalclock.+*+*TheAR8035-APHYMerakiMR24doesnotprovideaTXClkifthe+*ethernetcableisnotattached.Thiscausestheresettotimeout+*andthePHYdetectioncodeinemac_init_phy()isunableto+*communicateanddetecttheAR8035-APHY.Asaresult,theemac+*driverbailsoutearlyandtheuserhasnoethernet.+*Inordertostaycompatiblewithexistingconfigurations,the+*driverwilltemporarilyswitchtotheinternalclock,after+*thefirstresetfails.*/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);
@@ -383,8 +394,15 @@ static int emac_reset(struct emac_instance *dev)#ifdef CONFIG_PPC_DCR_NATIVEif(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;+gotodo_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);
From: Christian Lamparter <chunkeey@googlemail.com> Date: 2017-06-07 13:51:19
emac_mdio_read_link() was not copying the requested phy settings
back into the emac driver's own phy api. This has caused a link
speed mismatch issue for the AR8035 as the emac driver kept
trying to connect with 10/100MBps on a 1GBit/s link.
This patch also unifies shared code between emac_setup_aneg()
and emac_mdio_setup_forced(). And furthermore it removes
a chunk of emac_mdio_init_phy(), that was copying the same
data into itself.
Signed-off-by: Christian Lamparter <chunkeey@googlemail.com>
---
drivers/net/ethernet/ibm/emac/core.c | 41 ++++++++++++++++--------------------
1 file changed, 18 insertions(+), 23 deletions(-)
@@ -2478,20 +2478,24 @@ static int emac_mii_bus_reset(struct mii_bus *bus)returnemac_reset(dev);}+staticintemac_mdio_phy_start_aneg(structmii_phy*phy,+structphy_device*phy_dev)+{+phy_dev->autoneg=phy->autoneg;+phy_dev->speed=phy->speed;+phy_dev->duplex=phy->duplex;+phy_dev->advertising=phy->advertising;+returnphy_start_aneg(phy_dev);+}+staticintemac_mdio_setup_aneg(structmii_phy*phy,u32advertise){structnet_device*ndev=phy->dev;structemac_instance*dev=netdev_priv(ndev);-dev->phy.autoneg=AUTONEG_ENABLE;-dev->phy.speed=SPEED_1000;-dev->phy.duplex=DUPLEX_FULL;-dev->phy.advertising=advertise;phy->autoneg=AUTONEG_ENABLE;-phy->speed=dev->phy.speed;-phy->duplex=dev->phy.duplex;phy->advertising=advertise;-returnphy_start_aneg(dev->phy_dev);+returnemac_mdio_phy_start_aneg(phy,dev->phy_dev);}staticintemac_mdio_setup_forced(structmii_phy*phy,intspeed,intfd)
@@ -2499,13 +2503,10 @@ static int emac_mdio_setup_forced(struct mii_phy *phy, int speed, int fd)structnet_device*ndev=phy->dev;structemac_instance*dev=netdev_priv(ndev);-dev->phy.autoneg=AUTONEG_DISABLE;-dev->phy.speed=speed;-dev->phy.duplex=fd;phy->autoneg=AUTONEG_DISABLE;phy->speed=speed;phy->duplex=fd;-returnphy_start_aneg(dev->phy_dev);+returnemac_mdio_phy_start_aneg(phy,dev->phy_dev);}staticintemac_mdio_poll_link(structmii_phy*phy)
@@ -2527,16 +2528,17 @@ static int emac_mdio_read_link(struct mii_phy *phy){structnet_device*ndev=phy->dev;structemac_instance*dev=netdev_priv(ndev);+structphy_device*phy_dev=dev->phy_dev;intres;-res=phy_read_status(dev->phy_dev);+res=phy_read_status(phy_dev);if(res)returnres;-dev->phy.speed=phy->speed;-dev->phy.duplex=phy->duplex;-dev->phy.pause=phy->pause;-dev->phy.asym_pause=phy->asym_pause;+phy->speed=phy_dev->speed;+phy->duplex=phy_dev->duplex;+phy->pause=phy_dev->pause;+phy->asym_pause=phy_dev->asym_pause;return0;}
@@ -2546,13 +2548,6 @@ static int emac_mdio_init_phy(struct mii_phy *phy)structemac_instance*dev=netdev_priv(ndev);phy_start(dev->phy_dev);-dev->phy.autoneg=phy->autoneg;-dev->phy.speed=phy->speed;-dev->phy.duplex=phy->duplex;-dev->phy.advertising=phy->advertising;-dev->phy.pause=phy->pause;-dev->phy.asym_pause=phy->asym_pause;-returnphy_init_hw(dev->phy_dev);}
From: Andrew Lunn <andrew@lunn.ch> Date: 2017-06-07 14:13:30
On Wed, Jun 07, 2017 at 03:51:15PM +0200, Christian Lamparter wrote:
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 temporarily
switched to the internal 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 <redacted>
Reported-by: Russell Senior <redacted>
Fixes: 23fbb5a87c56e98 ("emac: Fix EMAC soft reset on 460EX/GT")
Signed-off-by: Christian Lamparter <chunkeey@googlemail.com>
From: Andrew Lunn <andrew@lunn.ch> Date: 2017-06-07 14:14:28
On Wed, Jun 07, 2017 at 03:51:16PM +0200, Christian Lamparter wrote:
emac_mdio_read_link() was not copying the requested phy settings
back into the emac driver's own phy api. This has caused a link
speed mismatch issue for the AR8035 as the emac driver kept
trying to connect with 10/100MBps on a 1GBit/s link.
This patch also unifies shared code between emac_setup_aneg()
and emac_mdio_setup_forced(). And furthermore it removes
a chunk of emac_mdio_init_phy(), that was copying the same
data into itself.
Signed-off-by: Christian Lamparter <chunkeey@googlemail.com>
From: David Miller <davem@davemloft.net> Date: 2017-06-08 14:48:03
From: Christian Lamparter <chunkeey@googlemail.com>
Date: Wed, 7 Jun 2017 15:51:16 +0200
emac_mdio_read_link() was not copying the requested phy settings
back into the emac driver's own phy api. This has caused a link
speed mismatch issue for the AR8035 as the emac driver kept
trying to connect with 10/100MBps on a 1GBit/s link.
This patch also unifies shared code between emac_setup_aneg()
and emac_mdio_setup_forced(). And furthermore it removes
a chunk of emac_mdio_init_phy(), that was copying the same
data into itself.
Signed-off-by: Christian Lamparter <chunkeey@googlemail.com>