i.MX6UL ENET1 (with LAN8720A PHY) working in Uboot but not in Linux

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

i.MX6UL ENET1 (with LAN8720A PHY) working in Uboot but not in Linux

Jump to solution
14,291 Views
compmas2
Contributor V


I have a custom board where I am using a single Ethernet connection on ENET1 (fec1 in Linux).  I am able to ping and transfer a file using TFTP in Uboot, but I am unable to ping or see any activity once in Linux.  I have checked that my IOMUX configuration is identical between Uboot and Linux. I can setup a MAC address in Uboot or through the .dts file, but neither seem to help in Linux.  I have verified using an oscilloscope that I am getting a 50MHz clock coming out of ENET1_TX_CLK on the i.MX6UL.  I am able to use mii-diag and ethtool to probe settings of the interface and PHY successfully. I see no change in the received or transmitted packets count when I run ifconfig after attempting to send the board messages from a PC or from trying to send from the board to the PC.

As a side note I have Wi-Fi working on this same board in Linux so networking in general is working.

Additionally the schematic layout is almost identical to an i.MX53 using the same LAN8720A PHY, except that the i.MX53 used an external source for the 50MHz clock and in the this board the clock is generated by the i.MX6UL.

I have tested using the following versions of software with the same results:

U-boot: 2015.04 tags:  rel_imx_3.14.38_6ul_ga, rel_imx_3.14.52_1.1.0_ga, and rel_imx_4.1.15_1.1.0_ga

Linux tags:  rel_imx_3.14.38_6ul_ga, rel_imx_3.14.52_1.1.0_ga, and rel_imx_4.1.15_1.1.0_ga

Here is the output at Linux boot related to Ethernet:

[    3.197605] libphy: fec_enet_mii_bus: probed

[    3.214882] fec 2188000.ethernet eth0: registered PHC device 0

[    4.813571] fec 2188000.ethernet eth0: Freescale FEC PHY driver [SMSC LAN8710/LAN8720] (mii_bus:phy_addr=2188000.ethernet:00, irq=-1)

[    4.850884] IPv6: ADDRCONF(NETDEV_UP): eth0: link is not ready

[    7.891111] fec 2188000.ethernet eth0: Link is Up - 100Mbps/Full - flow control rx/tx

[    7.899009] IPv6: ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready

After attempting to use the eth0 interface with no success and then bringing down the interface, I get the following message:

[   70.000719] fec 2188000.ethernet eth0: Graceful transmit stop did not complete!

Here is my Linux .dts file related contents:

&fec1 {

        pinctrl-names = "default";

        pinctrl-0 = <&pinctrl_enet1>;

        phy-mode = "rmii";

        phy-handle = <&ethphy>;

        local-mac-address = [00 04 9F 01 1B B9];

        phy-reset-gpios = <&gpio1 18 GPIO_ACTIVE_LOW>;

        phy-reset-duration = <1>;

        phy-supply = <&sw2_reg>;

        status = "okay";

        mdio {

                #address-cells = <1>;

                #size-cells = <0>;

                ethphy: ethernet-phy@0 {

                        compatible = "ethernet-phy-ieee802.3-c22";

                        reg = <0>;

                        interrupt-parent = <&gpio1>;

                        interrupts = <19 8>;

                        max-speed = <100>;

                };

        };

};

pinctrl_enet1: enet1grp {

        fsl,pins = <

                MX6UL_PAD_UART1_CTS_B__GPIO1_IO18       0x0b0b0 /* MPU_ETH_RESET */

                MX6UL_PAD_UART1_RTS_B__GPIO1_IO19       0x0b0b0 /* MPU_ETH_INT */

                MX6UL_PAD_GPIO1_IO07__ENET1_MDC         0x1b0a9 /* ENET_MDC */

                MX6UL_PAD_GPIO1_IO06__ENET1_MDIO        0x1b8a9 /* ENET_MDIO */

                MX6UL_PAD_ENET1_RX_EN__ENET1_RX_EN      0x1b0a9 /* FEC_CRS_DV */

                MX6UL_PAD_ENET1_RX_ER__ENET1_RX_ER      0x1b0a9 /* FEC_RX_ER */

                MX6UL_PAD_ENET1_RX_DATA0__ENET1_RDATA00 0x1b0a9 /* FEC_RXD0 */

                MX6UL_PAD_ENET1_RX_DATA1__ENET1_RDATA01 0x1b0a9 /* FEC_RXD1 */

                MX6UL_PAD_ENET1_TX_EN__ENET1_TX_EN      0x1b0a9 /* FEC_TX_EN */

                MX6UL_PAD_ENET1_TX_DATA0__ENET1_TDATA00 0x000a9 /* FEC_TXD0 */

                MX6UL_PAD_ENET1_TX_DATA1__ENET1_TDATA01 0x000a9 /* FEC_TXD1 */

                MX6UL_PAD_ENET1_TX_CLK__ENET1_REF_CLK1  0x010a9 /* FEC_TXCLK */

        >;

};

Here is the output from mii-diag:

Using the default interface 'eth0'.

Basic registers of MII PHY #0:  3100 782d 0007 c0f1 05e1 cde1 000b ffff.

The autonegotiated capability is 01e0.

The autonegotiated media type is 100baseTx-FD.

Basic mode control register 0x3100: Auto-negotiation enabled.

You have link beat, and everything is working OK.

Your link partner advertised cde1: Flow-control 100baseTx-FD 100baseTx 10baseT-FD 10baseT, w/ 802.3X flow control.

   End of basic transceiver information.

Here is the output from ethtool:

Settings for eth0:

Supported ports: [ TP MII ]

Supported link modes:   10baseT/Half 10baseT/Full

                        100baseT/Half 100baseT/Full

Supported pause frame use: Symmetric

Supports auto-negotiation: Yes

Advertised link modes:  10baseT/Half 10baseT/Full

                        100baseT/Half 100baseT/Full

Advertised pause frame use: Symmetric

Advertised auto-negotiation: Yes

Link partner advertised link modes:  10baseT/Half 10baseT/Full

                                     100baseT/Half 100baseT/Full

Link partner advertised pause frame use: Symmetric Receive-only

Link partner advertised auto-negotiation: Yes

Speed: 100Mb/s

Duplex: Full

Port: MII

PHYAD: 0

Transceiver: external

Auto-negotiation: on

Supports Wake-on: g

Wake-on: d

Link detected: yes

Here is the output of ifconfig after trying to send packets to and send package from the board:

eth0      Link encap:Ethernet  HWaddr DE:AD:BE:EF:DE:AD 

          inet addr:10.1.1.11  Bcast:10.1.1.255  Mask:255.255.255.0

          inet6 addr: fe80::dcad:beff:feef:dead/64 Scope:Link

          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1

          RX packets:0 errors:0 dropped:0 overruns:0 frame:0

          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0

          collisions:0 txqueuelen:1000

          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

Anyone have any suggestions on what might be wrong or what next to check to get Ethernet working in Linux on the i.MX6UL?

Labels (2)
1 Solution
7,123 Views
igorpadykov
NXP Employee
NXP Employee

Hi Matthew

could you try to set MX6UL_PAD_ENET1_TX_CLK__ENET1_REF_CLK1
as 0x4001b031, this sets SION bit, as in example

linux-2.6-imx.git - Freescale i.MX Linux Tree

Linux/drivers/pinctrl/freescale/pinctrl-imx.c - Linux Cross Reference - Free Electrons

Best regards

igor

-----------------------------------------------------------------------------------------------------------------------

Note: If this post answers your question, please click the Correct Answer button. Thank you!

-----------------------------------------------------------------------------------------------------------------------

View solution in original post

7 Replies
7,121 Views
shree97
Contributor II

Matthew can I get your board.c file? from U-boot source code

0 Kudos
7,121 Views
compmas2
Contributor V

Here are the relevant sections for Ethernet:

#define ENET_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \
    PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \
    PAD_CTL_DSE_48ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS)

#define MDIO_PAD_CTRL (PAD_CTL_PUE | PAD_CTL_PKE | \
    PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \
    PAD_CTL_DSE_48ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS | \
    PAD_CTL_ODE)

#define ENET_TDATA_PAD_CTRL (PAD_CTL_SPEED_MED | \
    PAD_CTL_DSE_48ohm | PAD_CTL_SRE_FAST)

#define ENET_CLK_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_SPEED_MED | \
    PAD_CTL_DSE_48ohm | PAD_CTL_SRE_FAST)

#ifdef CONFIG_FEC_MXC
static iomux_v3_cfg_t const fec1_pads[] = {
    MX6_PAD_GPIO1_IO06__ENET1_MDIO | MUX_PAD_CTRL(MDIO_PAD_CTRL),
    MX6_PAD_GPIO1_IO07__ENET1_MDC | MUX_PAD_CTRL(ENET_PAD_CTRL),
    MX6_PAD_ENET1_TX_DATA0__ENET1_TDATA00 | MUX_PAD_CTRL(ENET_TDATA_PAD_CTRL),
    MX6_PAD_ENET1_TX_DATA1__ENET1_TDATA01 | MUX_PAD_CTRL(ENET_TDATA_PAD_CTRL),
    MX6_PAD_ENET1_TX_EN__ENET1_TX_EN | MUX_PAD_CTRL(ENET_PAD_CTRL),
    MX6_PAD_ENET1_TX_CLK__ENET1_REF_CLK1 | MUX_PAD_CTRL(ENET_CLK_PAD_CTRL),
    MX6_PAD_ENET1_RX_DATA0__ENET1_RDATA00 | MUX_PAD_CTRL(ENET_PAD_CTRL),
    MX6_PAD_ENET1_RX_DATA1__ENET1_RDATA01 | MUX_PAD_CTRL(ENET_PAD_CTRL),
    MX6_PAD_ENET1_RX_ER__ENET1_RX_ER | MUX_PAD_CTRL(ENET_PAD_CTRL),
    MX6_PAD_ENET1_RX_EN__ENET1_RX_EN | MUX_PAD_CTRL(ENET_PAD_CTRL),
};

static void setup_iomux_fec(int fec_id)
{
    if (fec_id == 0) {
          imx_iomux_v3_setup_multiple_pads(fec1_pads, ARRAY_SIZE(fec1_pads));
    }
}
#endif

#ifdef CONFIG_FEC_MXC
int board_eth_init(bd_t *bis)
{
    int ret;

    setup_iomux_fec(CONFIG_FEC_ENET_DEV);

    ret = fecmxc_initialize_multi(bis, CONFIG_FEC_ENET_DEV,
    CONFIG_FEC_MXC_PHYADDR, IMX_FEC_BASE);
    if (ret)
          printf("FEC%d MXC: %s:failed\n", CONFIG_FEC_ENET_DEV, __func__);

    return 0;
}

static int setup_fec(int fec_id)
{
    struct iomuxc_gpr_base_regs *const iomuxc_gpr_regs
          = (struct iomuxc_gpr_base_regs *) IOMUXC_GPR_BASE_ADDR;
    int ret;

    if (0 == fec_id) {
    /* Use 50M anatop loopback REF_CLK1 for ENET1, clear gpr1[13], set gpr1[17]*/
    clrsetbits_le32(&iomuxc_gpr_regs->gpr[1], IOMUX_GPR1_FEC1_MASK,
          IOMUX_GPR1_FEC1_CLOCK_MUX1_SEL_MASK);
    }

    ret = enable_fec_anatop_clock(fec_id, ENET_50MHZ);
    if (ret)
          return ret;

    enable_enet_clk(1);

    return 0;
}
#endif

int board_init(void)
{

#ifdef CONFIG_FEC_MXC
    setup_fec(CONFIG_FEC_ENET_DEV);
#endif

    return 0;

}

0 Kudos
7,121 Views
lvmh
Contributor I

Matthew can I get your board.h file? from U-boot source code.

In addition, does the reset time sequence of lan8720 do not need operation?

0 Kudos
7,124 Views
igorpadykov
NXP Employee
NXP Employee

Hi Matthew

could you try to set MX6UL_PAD_ENET1_TX_CLK__ENET1_REF_CLK1
as 0x4001b031, this sets SION bit, as in example

linux-2.6-imx.git - Freescale i.MX Linux Tree

Linux/drivers/pinctrl/freescale/pinctrl-imx.c - Linux Cross Reference - Free Electrons

Best regards

igor

-----------------------------------------------------------------------------------------------------------------------

Note: If this post answers your question, please click the Correct Answer button. Thank you!

-----------------------------------------------------------------------------------------------------------------------

7,124 Views
compmas2
Contributor V

Igor,

Thank you for the response.  It looks like this solved one issue but it is still not fully working.

I can now transmit Ethernet packets and they can be seen on a test PC, but I cannot receive any Ethernet packets on my i.MX6UL board even though they are successfully being sent from the test PC.  Please see the attached Wireshark output captured on the test PC where 1e:ca:f2:23:00:c0 is the MAC address of the i.MX6UL board.

Ethernet_Receive_Issue.png

Any ideas what could be the root cause of not receiving Ethernet packets?

0 Kudos
7,124 Views
compmas2
Contributor V

I got it working. It looks like the exact IOMUXing setting you gave me did not work on my board, but adding the SION bit to my existing settings fixed the issue. Thanks.

0 Kudos
7,124 Views
compmas2
Contributor V

Just in case others encounter the same issue, the Ethernet connection would not always reliably come up in Linux still after fixing the IOMUX settings.  When I started getting larger volumes of the product using the i.MX6UL, some units Ethernet connection would never work in Linux.

It turns on the Linux fec driver is disabling the Ethernet reference clock and then re-enabling it.  Sometimes this occurred when the PHY was initializing and would put the PHY in a bad state.  Sometimes bringing down the eth interface in Linux and then bringing it back up would fix the issue.  Sometimes nothing would fix the issue.  The only thing that always fixed the issue was to comment out the code that disabled the Ethernet clock in the fec_probe function of the fec driver in the Linux kernel.  Here is the line in the fec_probe function in the drivers/net/ethernet/freescale/fec_main.c file of the 4.1.15 kernel I commented out:

fec_enet_clk_enable(ndev, false);

After making that change to the driver, the clock still disables the Ethernet clock in suspend and if the eth interface is brought down so it shouldn't affect power savings.  Also turning the clock on and off after being out of the fec_probe function of the fec driver seems to work without causing a weird broken state.