This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

AM335x and LAN8720A Ethernet Connection after kernel boot not detected.



Basically i have a custom AM335x board with and LAN8720A running in RMII mode.  I have modified the board files in the Kernel as necessary to support the board.  Here is what i am finding with the ethernet:

1.  Plugged in before power up:  works great, can ping the controller and even start httpd and browse to the controllers served webpage.

2.  Plugged in while in U-Boot before booting to Kernel:  Same as above, i see lights on the Connector blink and once i boot to the Kernel everything is still great.

3. Plugged in after the Kernel is started:  Nothing, no light no connection.  I have an ifplugd action specified to ifup the connection but nothing happens when the cable is plugged in.  If i manually type ifup eth0 it says the connection is already up.  If i ifdown it then ifup it there are no lights on the connector and it fails to connect and get lease from DHCP.

4. Plugged in before kernel boot then removed after kernel is booted:  The ifplugd action executes and ifdowns eth0 when unplugged; however, I then almost immediately see:  "[ 64.116729] net eth0: CPSW phy found : id is : 0x7c0f1".  And if i then plug the cable back in it does not connect again and manually typing ifup just fails to get lease from DHCP and there are no lights on the connector or hub.

So it would seem to me that if i do not have a cable plugged in before the kernel starts up networking or i unplug it after it starts then it registers 0x7c0F1 and sets it to eth0 and i can no longer make a new connection when i plug a cable in : /.

Any ideas of the issue here?  (0x7c0F1 seems to correspond to the BBB_PHY_ID in the original EVM Board file).

  • Hi Jarrod,
     
    What Linux version are you using?
  • I am using 3.2 from the latest release of the SDK (06.00.00.00)  : )

  • Can you post the fragment of the schematics that contains the connections between the PHY and AM355X? I looked through the PHY datasheet today and I suspect that there may be a hardware issue.
  • Thanks for the assistance!  Here is the the setup:

    It is just weird that it would work great in U-boot, but not in the kernel that is what made me assume software issue.

  • Hi Jarrod,
     
    I found another thread that discusses an issue that may be similar to yours: http://e2e.ti.com/support/arm/sitara_arm/f/791/p/262854/922128.aspx#922128. Please check if your 50MHz clocks collide when the kernel boots.
  • Looks like clock collision may be the issue:

    50MHz clock in U-Boot:

    50MHz clock once booted to kernel:

    I setup the U-boot network stuff to not source the clocks, but i didn't even think about it when setting up the kernel config, I simply set the muxes and called init for the correct mode.  I will get it changed in the kernel and post back and let you know if it fixes it : ).  Thanks again!!!

  • Alright, well that did fix the clock so that it is now correct; however, it did not fix the issue.  It seems that when the kernel see that there is no connection the REFCLK goes away completely and doesn't come back.  So maybe the kernel is putting the chip in some sleep or powersave mode if there is no connection? 

    I can tell when the clock goes away, basically the kernel completely boots and my rcS script runs this command:

    ifplugd -i eth0 -f -r /etc/network/ifplugd.action

    I see the following output:

    [ 18.902465] net eth0: CPSW phy found : id is : 0x7c0f1

    Then the clock goes away never to return.

    CONTENTS OF /etc/network/ifplugd.action:

    #!/bin/sh

    if [ $2 == "up" ]; then
    ifup -f $1
    elif [ $2 == "down" ]; then
    ifdown $1
    fi

    return 0

    CONTENTS OF /network/interfaces:

    auto lo

    iface lo inet loopback

    iface eth0 inet dhcp
    hostname MYBOARD

    #auto usb1
    #iface usb1 inet static
    # address 169.254.10.1
    # netmask 255.255.255.0
    # hostname MYBOARD

    So do you know of any mode that the kernel would put the chip in that would cause it to stop producing the refclk?

    Also here is the diff of what i changed to correct the clocks:

    diff -r f480743a8012 arch/arm/mach-omap2/control.h
    --- a/arch/arm/mach-omap2/control.h Tue Nov 26 10:03:20 2013 -0500
    +++ b/arch/arm/mach-omap2/control.h Wed Nov 27 12:04:30 2013 -0500
    @@ -372,7 +372,7 @@
    #define AM33XX_CONTROL_GMII_SEL_OFFSET 0x650
    #define AM33XX_RGMII_DISABLE_INT_DLY (BIT(4) | BIT(5))
    #define AM33XX_MII_MODE_EN 0x0
    -#define AM33XX_RMII_MODE_EN ((1 << 0) | (1 << 2))
    +#define AM33XX_RMII_MODE_EN ((1 << 0) | (1 << 2) | (1 << 6) | (1 << 7))
    #define AM33XX_RGMII_MODE_EN ((0x2 << 0) | (0x2 << 2) | \
    (AM33XX_RGMII_DISABLE_INT_DLY))

  • Alright i stepped through the Kernel code and i found it was a powersave feature.  The clock stops as soon as the driver puts the LAN8720A into "Energy Detect Power-Down".  This is done in drivers/net/phy/smsc.c:

    static int smsc_phy_config_init(struct phy_device *phydev)
    {
    	int rc = phy_read(phydev, MII_LAN83C185_CTRL_STATUS);
    	if (rc < 0)
    		return rc;
    
    	/* Enable energy detect mode for this SMSC Transceivers */
    	rc = phy_write(phydev, MII_LAN83C185_CTRL_STATUS,
    		       rc | MII_LAN83C185_EDPWRDOWN);
    	if (rc < 0)
    		return rc;
    
    	return smsc_phy_ack_interrupt (phydev);
    }

    According to the LAN8720A datasheet the logic should detect the presence of the signals when plugged in and power back up.  Once i discovered this i started to play around with my actual connection.  I have my unit connected to a 5 port SWITCH.  If i unplug a cable that is currently seeing traffic and immediately plug my unit into that port it detects energy and the phy comes up.  If i power off the switch and power it back on the phy also comes up.  It is only when there is no activity on the port for a few seconds and i then plug the unit in that the phy does NOT come up.

    So my assumption here is that since the LAN8720A is in energy detect power-down it will not be sending anything out and i am guessing after a few seconds of no activity on a port the switch (Netgear FS605v2) stops sending anything down that port since it "learns" there is nothing there.  Since noone is sending any traffic power up never occurs.  

    Does this theory sound correct?

    If so then i think i may either disable energy detect power-down or routinely come out of it to check for connection, because there is not telling what type of switch, hub, router, etc. someone will use in the field.

  • Hi Jarrod,
     
    Great progress! Yes, what you say sounds logical. I would just mention that if you decide to poll for connection periodically you will probably need to send a ping or something to activate the interface in case the opposite device is asleep.
  • Awesome, thanks for the reassurance!  I disabled the Energy Detect Power-Down mode and everything is working great now.  Currently the system the board will go in will always be sourced from a wall supply, so going into power down isn't a huge necessity at the moment.

    In the future if we progress to battery powered systems i will make modifications to do the polling.  When that occurs i will keep your suggestion of sending ping or some other message in mind!  Thank you for all the help and suggestions!!! : )

    -Jarrod