I designed a RMII ethernet PHY cape for PocketBeagle 2 using LAN8720A.
The clock is provided to both PHY and MAC using an external 50MHz oscillator.
MDIO works fine as well as link is detected by both the PHY and the eth switch it’s
connected to (watching the LEDs). I can also read PHY registers using phytool.
No packets however go in or out of the interface.
Here are some diagnostics:
Correctly detected PHY chip:
debian@BeagleBone:~$ dmesg | grep -i mdio
[ 2.852261] davinci_mdio 8000f00.mdio: Configuring MDIO in manual mode
[ 2.896562] davinci_mdio 8000f00.mdio: davinci mdio revision 9.7, bus freq 1000000
[ 2.898524] davinci_mdio 8000f00.mdio: phy[0]: device 8000f00.mdio:00, driver SMSC LAN8710/LAN8720
[ 13.041332] am65-cpsw-nuss 8000000.ethernet eth0: PHY [8000f00.mdio:00] driver [SMSC LAN8710/LAN8720] (irq=POLL)
Correctly detected link state (which also updates if I plug/unplug ETH cable):
debian@BeagleBone:~$ ip addr
2: eth0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether dc:be:04:b1:12:fe brd ff:ff:ff:ff:ff:ff
altname enxdcbe04b112fe
inet6 fe80::debe:4ff:feb1:12fe/64 scope link proto kernel_ll
valid_lft forever preferred_lft forever
I’m watching the TX_EN pin with an oscilloscope and it’s not changing,
even though I’m trying to ping something. These start appearing in dmesg:
debian@BeagleBone:~$ dmesg | grep cpsw
[ 15.104975] am65-cpsw-nuss 8000000.ethernet eth0: Link is Up - 100Mbps/Full - flow control rx/tx
[ 301.036541] am65-cpsw-nuss 8000000.ethernet eth0: NETDEV WATCHDOG: CPU: 2: transmit queue 2 timed out 5004 ms
[ 301.036581] am65-cpsw-nuss 8000000.ethernet eth0: txq:2 DRV_XOFF:0 tmo:5004 dql_avail:-22 free_desc:514
[ 305.888543] am65-cpsw-nuss 8000000.ethernet eth0: NETDEV WATCHDOG: CPU: 0: transmit queue 2 timed out 9856 ms
[ 305.888582] am65-cpsw-nuss 8000000.ethernet eth0: txq:2 DRV_XOFF:0 tmo:9856 dql_avail:-22 free_desc:514
[ 311.008567] am65-cpsw-nuss 8000000.ethernet eth0: NETDEV WATCHDOG: CPU: 3: transmit queue 2 timed out 14976 ms
[ 311.008608] am65-cpsw-nuss 8000000.ethernet eth0: txq:2 DRV_XOFF:0 tmo:14976 dql_avail:-22 free_desc:514
Which, according to AI, is MAC not transmitting to the PHY, suggesting something
might be wrong/misconfigured and my external 50MHz clock is not really being routed to MAC,
causing the MAC state machine to be stuck.
I’m 90% sure my PCB is good. I checked the signals I could, including the 50MHz clock which is
clean, both on the PHY and PB2 CLKIN pins.
A lot of time went into the dtso, but I fear it’s still not correct and I seem not to be able to
progress futher with chatgpt/gemini.
Here’s what I have so far (k3-am62-pocketbeagle2-lan8720.dtso):
/dts-v1/;
/plugin/;
#include “../ti/k3-pinctrl.h”
#include <dt-bindings/gpio/gpio.h>
/ {
compatible = “ti,am625”;
};
&{/chosen} {
overlays {
k3-am62-pocketbeagle2-lan8720.kernel = TIMESTAMP;
};
};
&main_pmx0 {
pb2_lan8720_pins: pb2-lan8720-pins {
pinctrl-single,pins = <
AM62X_IOPAD(0x15c, PIN_INPUT, 0) /* MDIO, P2.03, PADCONFIG87 /
AM62X_IOPAD(0x160, PIN_OUTPUT, 0) / MDC, P2.01A, PADCONFIG88 /
AM62X_IOPAD(0x164, PIN_OUTPUT, 1) / TX_EN, P1.02A, PADCONFIG89 /
AM62X_IOPAD(0x168, PIN_INPUT, 1) / CRS_DV, P1.35, PADCONFIG90 /
AM62X_IOPAD(0x16c, PIN_OUTPUT, 1) / TXD0, P1.04A, PADCONFIG91 /
AM62X_IOPAD(0x170, PIN_OUTPUT, 1) / TXD1, P2.31A, PADCONFIG92 /
AM62X_IOPAD(0x17c, PIN_INPUT, 1) / RX_ER, P1.19, PADCONFIG95 /
AM62X_IOPAD(0x180, PIN_INPUT, 1) / REF_CLK, P1.34, PADCONFIG96 /
AM62X_IOPAD(0x184, PIN_INPUT, 1) / RXD0, P1.27, PADCONFIG97 /
AM62X_IOPAD(0x188, PIN_INPUT, 1) / RXD1, P1.25, PADCONFIG98 /
//AM62X_IOPAD(0x1c4, PIN_OUTPUT, 7) / PHY_RST, P2.25, PADCONFIG113, GPIO1_19 /
AM62X_IOPAD(0x0d4, PIN_OUTPUT, 7) / PHY_RST, P2.33, PADCONFIG53, GPIO0_52, paired with reset-gpios below!!! */
;
};
};
&cpsw3g {
pinctrl-names = “default”;
pinctrl-0 = <&pb2_lan8720_pins>;
status = "okay";
};
&cpsw3g_mdio {
#address-cells = <1>;
#size-cells = <0>;
status = “okay”;
//reset-gpios = <&main_gpio1 19 GPIO_ACTIVE_LOW>;
reset-gpios = <&main_gpio0 52 GPIO_ACTIVE_LOW>;
reset-delay-us = <5000>;
lan8720: ethernet-phy@0 {
compatible = "ethernet-phy-ieee802.3-c22";
reg = <0>;
};
};
&cpsw_port1 {
phy-handle = <&lan8720>;
phy-mode = “rmii”;
phys = <&phy_gmii_sel 1>;
ti,rmii-clock-in;
status = “okay”;
};
&ecap2 {
// claims PIN88 which is MDIO0_MDC. Base DT error?
status = “disabled”;
};
&main_spi0 {
// SPI0_CS0 (P2.31, PIN109) is shared with RMII2_TXD1 (P2.31A, PIN92)
status = “disabled”;
};
This is the status of the pins:
debian@BeagleBone:~$ cat /sys/kernel/debug/pinctrl/f4000.pinctrl-pinctrl-single/pinmux-pins | grep eth
pin 53 (PIN53): 8000000.ethernet 600000.gpio:591 function pb2-lan8720-pins group pb2-lan8720-pins
pin 87 (PIN87): 8000000.ethernet (GPIO UNCLAIMED) function pb2-lan8720-pins group pb2-lan8720-pins
pin 88 (PIN88): 8000000.ethernet (GPIO UNCLAIMED) function pb2-lan8720-pins group pb2-lan8720-pins
pin 89 (PIN89): 8000000.ethernet (GPIO UNCLAIMED) function pb2-lan8720-pins group pb2-lan8720-pins
pin 90 (PIN90): 8000000.ethernet (GPIO UNCLAIMED) function pb2-lan8720-pins group pb2-lan8720-pins
pin 91 (PIN91): 8000000.ethernet (GPIO UNCLAIMED) function pb2-lan8720-pins group pb2-lan8720-pins
pin 92 (PIN92): 8000000.ethernet (GPIO UNCLAIMED) function pb2-lan8720-pins group pb2-lan8720-pins
pin 95 (PIN95): 8000000.ethernet (GPIO UNCLAIMED) function pb2-lan8720-pins group pb2-lan8720-pins
pin 96 (PIN96): 8000000.ethernet (GPIO UNCLAIMED) function pb2-lan8720-pins group pb2-lan8720-pins
pin 97 (PIN97): 8000000.ethernet (GPIO UNCLAIMED) function pb2-lan8720-pins group pb2-lan8720-pins
pin 98 (PIN98): 8000000.ethernet (GPIO UNCLAIMED) function pb2-lan8720-pins group pb2-lan8720-pins
Base device tree is:
debian@BeagleBone:~$ cat /sys/firmware/devicetree/base/chosen/base_dtb
k3-am62-pocketbeagle2.dts
which is here:
Kernel:
Linux BeagleBone 6.18.32-arm64-k3-r39 #1 SMP PREEMPT_RT Mon May 18 23:37:32 UTC 2026 aarch64 GNU/Linux
BB image:
BeagleBoard.org Debian Trixie IOT Image 2026-05-19
Can anyone help? Thanks.

