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 = <ðphy>;
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?
Solved! Go to Solution.
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!
-----------------------------------------------------------------------------------------------------------------------
Matthew can I get your board.c file? from U-boot source code
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;
}
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?
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!
-----------------------------------------------------------------------------------------------------------------------
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.
Any ideas what could be the root cause of not receiving Ethernet packets?
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.
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.
Just wanted to add here: we have encountered probably exactly the same problem with the combination i.MX6Q and TK106 PHY, and the above fix also works for us (thanks!).