I have a board based on the Freescale iMX6DL SabreSD design that I have working fine with the Korgoth based BSP that runs Linux 4.1.15. I am trying to upgrade the BSP running on the board to the Morty based BSP that runs Linux 4.9.11.
The design uses the Micrel KSZ8081RNACA PHY in a RMII configuration where the PHY is driving the 50 MHz reference clock.
I can run the Ethernet link with no problems using the 4.1.15 kernel. However, I am having issues getting the Ethernet on the 4.9.11 kernel to handle packets. I can never get packets in or out of the Ethernet link.
I can bring the link up using the iproute2 commands (e.g. ip link set dev eth1 up) and see the link come up and report that it is active. I am able to communicate with the PHY via MDIO and it reports that has a valid link and negotiates to a 100 Mb/s stream.
When I use a scope to look at the CRS_DV signal, I see a valid detection of incoming packets. (The signal looks the same for both the 4.1.15 and 4.9.11 kernels.) However, I never see the interrupt activated for the incoming RX Buffer.
IOMuxC for the CRS_DV signal which is connected to the ENET_CRS_DV pin.
=======================================================================
IOMUXC_SW_MUX_CTL_PAD_ENET_CRS_DV
0x020E01E4 = 0x00000001
ALT1 — Select signal ENET_RX_EN.
IOMUXC_ENET_MAC0_RX_EN_SELECT_INPUT
0x020E0828 = 0x00000000
(ENET_CRS_DV_ALT1 — Selecting ALT1 mode of pad ENET_CRS_DV for ENET_RX_EN.)
IOMUXC_SW_PAD_CTL_PAD_ENET_CRS_DV
0x020E05B4 = 0x000130B0
IOMuxC for the RMII Reference Clock input on GPIO16.
====================================================
IOMUXC_SW_MUX_CTL_PAD_GPIO16
0x020E0214 = 0x00000002
ALT2 — Select signal ENET_REF_CLK.
IOMUXC_ENET_REF_CLK_SELECT_INPUT
0x020E080C = 0x00000000
GPIO16_ALT2 — Selecting ALT2 mode of pad GPIO_16 for ENET_REF_CLK.
IOMUXC_SW_PAD_CTL_PAD_GPIO16
0x020E05E4 = 0x0001B0B0
FEC Ethernet Registers:
======================
Interrupt Mask Register (ENET_EIMR)
0x02188008 = 0x0A8080AA
Enabled Interrupts: TXF, RXF, MII, TS_TIMER
(Note: I only see the MII interrupt handled. )
Ethernet Control Register (ENET_ECR)
0x02188024 = 0xF0000112
10/100 mode, MAC is enabled, and reception and transmission are possible.
Receive Control Register (ENET_RCR)
0x02188084 = 0x45F20124
RMII Mode, Frame len 1522 bytes
(Note I tried both promiscuous and non-promiscuous mode with the same result)
Rx Packet Count Statistic Register (ENET_RMON_R_PACKETS)
0x2188284 = 0
The devicetree set up I am using is as follows:
&fec {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_enet>;
phy-mode = "rmii";
phy-reset-gpios = <&gpio1 2 0>;
phy-reset-duration = <10>;
fsl,magic-packet;
status = "okay";
};
soc {
aips-bus@02100000 {
fec: ethernet@02188000 {
compatible = "fsl,imx6q-fec";
reg = <0x02188000 0x4000>;
interrupts-extended =
<&gpc 0 118 IRQ_TYPE_LEVEL_HIGH>,
<&gpc 0 119 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks IMX6QDL_CLK_ENET>,
<&clks IMX6QDL_CLK_ENET>,
<&clks IMX6QDL_CLK_ENET_REF>;
clock-names = "ipg", "ahb", "ptp";
stop-mode = <&gpr 0x34 27>;
fsl,wakeup_irq = <0>;
status = "disabled";
};
};
};
&iomuxc {
pinctrl_enet: enetgrp {
fsl,pins = <
MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0
MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0
MX6QDL_PAD_ENET_TXD0__ENET_TX_DATA0 0x1b0b0
MX6QDL_PAD_ENET_TXD1__ENET_TX_DATA1 0x1b0b0
MX6QDL_PAD_ENET_TX_EN__ENET_TX_EN 0x1b0b0
MX6QDL_PAD_GPIO_16__ENET_REF_CLK 0x1b0b0
MX6QDL_PAD_ENET_RXD0__ENET_RX_DATA0 0x1b0b0
MX6QDL_PAD_ENET_RXD1__ENET_RX_DATA1 0x1b0b0
MX6QDL_PAD_ENET_CRS_DV__ENET_RX_EN 0x130b0
MX6QDL_PAD_ENET_RX_ER__ENET_RX_ER 0x1b0b0
MX6QDL_PAD_GPIO_2__GPIO1_IO02 0x1b0b0
>;
};
};
Since the Ethernet works with the 4.1.15 kernel, I am assuming that I am just not setting something up correctly in the 4.9 kernel.
Does anyone have any suggestions as to where I can look that can give me an indication as to why I am not seeing any incoming packets? Are there any decent app notes describing what is required for the Fast Ethernet Controller's initialization?
Regards,
Doug Bailey
It turns out that my problem is the ENET_CLK_SEL bit in the IOMUXC_GPR1 register. This was causing contention on the reference clock line.
I have not seen a way to clear this bit via the device tree. Anybobdy know the magic formula?
Hi Doug
one can add IOMUXC_GPR1 configuration in uboot board file (./mx6sabresd/mx6sabresd.c), as
for dts one can look in fec source file described in attached Linux Manual sect.4.5 Fast Ethernet
Controller (FEC), seems there is no such setting.
Best regards
igor
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
Unfortunately, the bit is set actively in the kernel initialization.
The following fragment sets the bit ./arch/arm/mach-imx/mach-imx6q.c
/*
* If enet_ref from ANATOP/CCM is the PTP clock source, we need to
* set bit IOMUXC_GPR1[21]. Or the PTP clock must be from pad
* (external OSC), and we need to clear the bit.
*/
gpr = syscon_regmap_lookup_by_compatible("fsl,imx6q-iomuxc-gpr");
if (!IS_ERR(gpr))
regmap_update_bits(gpr, IOMUXC_GPR1,
IMX6Q_GPR1_ENET_CLK_SEL_MASK,
IMX6Q_GPR1_ENET_CLK_SEL_ANATOP);
else
pr_err("failed to find fsl,imx6q-iomuxc-gpr regmap\n");
Regards,
Doug
My solution was to change:
regmap_update_bits(gpr, IOMUXC_GPR1,
IMX6Q_GPR1_ENET_CLK_SEL_MASK,
IMX6Q_GPR1_ENET_CLK_SEL_ANATOP);
to
regmap_update_bits(gpr, IOMUXC_GPR1,
IMX6Q_GPR1_ENET_CLK_SEL_MASK,
IMX6Q_GPR1_ENET_CLK_SEL_PAD);