Ethernet device is not detecting on ubuntu 20.04 LTS on BBG

That smells like PHY reset… I’ll need to correct my prior comment, don’t upgrade to 5.4.x-ti or mainline 5.10.x/5.10.x-ti your 5.4.x-ti is running the updated ti cpsw driver that TI eventually submitted mainline…

The randomness is part of the problem with this bug… The MDIO bus is hard-wired on the board, the PHY’s configuration is hard-coded with pull-up/down’s, yet some boards will have an SMSC phy come up in a broken state.

The kernel hack, basically asks the phy, what address are you at, i’ll just use that. (instead of how it was physically wired and setup…)

The RevC3 has two fixes, removing C24, which seemed to help some users on older board designs, and wiring a gpio directly to the reset on the SMSC phy… So far i haven’t found a RevC3 that shows the old issue, so i haven’t personally been able to verify the gpio-reset would fix it…

If you have a board that is showing random mdio address, first remove C24 and re-test…

Regards,

Robert,

Thanks.

That actually explains what happens (in a way that I understand). Interesting… I can’t imagine how one would start troubleshooting this after customer complaints…

These current boards are REV B (they procured about 20 of them at one point), I’ll try to get the users to not use these boards anymore but replace them with REV C. The cost of additional service trips to the measurement platforms greatly exceeds the cost of a BBB…

RCN,

Upgrading my host computer to Ubuntu 20.04 fixed the build problem. I also found that I could build the BB-DT on my BBB revC3 because it has DTC 1.4.7 installed.
Thank you. Now on to the next step.
The BBB revC3 came with kernel 4.19.94-ti-r42 so I choose the BB-DT v4.19.94.x-ti-overlays to build. I built the files and copied am335x-boneblack-uboot-univ.dtb to the BBBrC3. Connected an o-scope to U1 pin-1 (ETH_RST_GPIO1_8). Powered on the BBB and noticed pin-1 stayed high (3.3v) during boot.
Changes to am335x-bone-common.dtsi

&am33xx_pinmux {
	davinci_mdio_default: davinci_mdio_default {
		pinctrl-single,pins = <
			/* MDIO */
			AM33XX_PADCONF(AM335X_PIN_MDIO, PIN_INPUT_PULLUP | SLEWCTRL_FAST, MUX_MODE0)
			AM33XX_PADCONF(AM335X_PIN_MDC, PIN_OUTPUT_PULLUP, MUX_MODE0)
			// added to support gpio controlled PHY reset
			AM33XX_PADCONF(AM335X_PIN_UART0_CTSN, PIN_OUTPUT_PULLUP, MUX_MODE7)
		>;
	};

	davinci_mdio_sleep: davinci_mdio_sleep {
		pinctrl-single,pins = <
			/* MDIO reset value */
			AM33XX_PADCONF(AM335X_PIN_MDIO, PIN_INPUT_PULLDOWN, MUX_MODE7)
			AM33XX_PADCONF(AM335X_PIN_MDC, PIN_INPUT_PULLDOWN, MUX_MODE7)
			// added to support gpio controlled PHY reset
			AM33XX_PADCONF(AM335X_PIN_UART0_CTSN, PIN_INPUT_PULLDOWN, MUX_MODE7)
		>;
	};
};

&davinci_mdio {
	pinctrl-names = "default", "sleep";
	pinctrl-0 = <&davinci_mdio_default>;
	pinctrl-1 = <&davinci_mdio_sleep>;
	status = "okay";
	// added to support gpio controlled PHY reset
	reset-gpios = <&gpio1 8 GPIO_ACTIVE_LOW>;
	reset-delay-us = <2>;
};

Again, I built the files and copied am335x-boneblack-uboot-univ.dtb to the BBBrC3. Pressed reset button on the BBB. I noticed during kernel loading that pin-1 toggled low for approx 4us.
20230221_122110
There is not an entry in dmesg showing that gpio1_8 reset-gpios was toggled. It would be nice for the kernel to report a message.

I have more questions but I am not sure if I should create a new ‘BBB revC3 reset-gpio phy hardware fix’ topic or continue to hijack this topic. I don’t know if there is another forum where this topic is already being discussed.
Should I create another topic, continue to post in this topic or move to another forum?

Thank you,

I have been successful in editing the am335x-bone-common.dtsi file to cause the kernel to trigger the reset. Now I am trying to create a ‘BB-phy-gpio-reset’ device-tree overlay. Here is my overlay.dts file.

/dts-v1/;
/plugin/;

#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/pinctrl/am33xx.h>

/*
 * Helper to show loaded overlays under: /proc/device-tree/chosen/overlays/
 */
&{/chosen} {
	overlays {
		BB-phy-gpio-reset.kernel = __TIMESTAMP__;
	};
};

&am33xx_pinmux {
	davinci_mdio_default: davinci_mdio_default {
		pinctrl-single,pins = <
			// added to support gpio controlled PHY reset
			AM33XX_PADCONF(AM335X_PIN_UART0_CTSN, PIN_OUTPUT_PULLUP, MUX_MODE7)
		>;
	};

	davinci_mdio_sleep: davinci_mdio_sleep {
		pinctrl-single,pins = <
			// added to support gpio controlled PHY reset
			AM33XX_PADCONF(AM335X_PIN_UART0_CTSN, PIN_INPUT_PULLDOWN, MUX_MODE7)
		>;
	};
};

&davinci_mdio {
	// added to support gpio controlled PHY reset
	reset-gpios = <&gpio1 8 GPIO_ACTIVE_LOW>;
	reset-delay-us = <2>;
};

I created the file in the BB-DT overlays folder and the file builds a BB-phy-gpio-rest.dtbo. The .dtbo file is copied to BBB revC3 /lib/firmware folder. I pause u-boot and type

Press SPACE to abort autoboot in 0 seconds
=>    
=> 
=> setenv uboot_overlay_addr4 /lib/firmware/BB-phy-gpio-reset.dtbo
=> boot
board_name=[A335BNLT] ...
board_rev=[00C0] ...
Card did not respond to voltage select!
Card did not respond to voltage select!
Card did not respond to voltage select!
gpio: pin 56 (gpio 56) value is 0
gpio: pin 55 (gpio 55) value is 0
gpio: pin 54 (gpio 54) value is 0
gpio: pin 53 (gpio 53) value is 1
Card did not respond to voltage select!
Card did not respond to voltage select!
switch to partitions #0, OK
mmc1(part 0) is current device
Scanning mmc 1:1...
gpio: pin 56 (gpio 56) value is 0
gpio: pin 55 (gpio 55) value is 0
gpio: pin 54 (gpio 54) value is 0
gpio: pin 53 (gpio 53) value is 1
switch to partitions #0, OK
mmc1(part 0) is current device
gpio: pin 54 (gpio 54) value is 1
Checking for: /uEnv.txt ...
Checking for: /boot.scr ...
Checking for: /boot/boot.scr ...
Checking for: /boot/uEnv.txt ...
gpio: pin 55 (gpio 55) value is 1
2062 bytes read in 13 ms (154.3 KiB/s)
Loaded environment from /boot/uEnv.txt
Checking if uname_r is set in /boot/uEnv.txt...
gpio: pin 56 (gpio 56) value is 1
Running uname_boot ...
loading /boot/vmlinuz-4.19.94-ti-r42 ...
10095592 bytes read in 653 ms (14.7 MiB/s)
debug: [enable_uboot_overlays=1] ...
debug: [enable_uboot_cape_universal=1] ...
debug: [uboot_base_dtb_univ=am335x-boneblack-uboot-univ.dtb] ...
uboot_overlays: [uboot_base_dtb=am335x-boneblack-uboot-univ.dtb] ...
uboot_overlays: Switching too: dtb=am335x-boneblack-uboot-univ.dtb ...
loading /boot/dtbs/4.19.94-ti-r42/am335x-boneblack-uboot-univ.dtb ...
167492 bytes read in 42 ms (3.8 MiB/s)
uboot_overlays: [fdt_buffer=0x60000] ...
uboot_overlays: loading /lib/firmware/BB-ADC-00A0.dtbo ...
867 bytes read in 31 ms (26.4 KiB/s)
uboot_overlays: loading /lib/firmware/BB-phy-gpio-reset.dtbo ...
960 bytes read in 106 ms (8.8 KiB/s)
uboot_overlays: loading /lib/firmware/BB-BONE-eMMC1-01-00A0.dtbo ...
1584 bytes read in 110 ms (13.7 KiB/s)
uboot_overlays: loading /lib/firmware/BB-HDMI-TDA998x-00A0.dtbo ...
4915 bytes read in 47 ms (101.6 KiB/s)
uboot_overlays: loading /lib/firmware/AM335X-PRU-RPROC-4-19-TI-00A0.dtbo ...
3801 bytes read in 249 ms (14.6 KiB/s)
loading /boot/initrd.img-4.19.94-ti-r42 ...
7418142 bytes read in 482 ms (14.7 MiB/s)
debug: [console=ttyO0,115200n8 bone_capemgr.uboot_capemgr_enabled=1 root=/dev/mmcblk1p1 ro rootfstype=ext4 rootwait coherent_pool=1
M net.ifnames=0 lpj=1990656 rng_core.default_quality=100 quiet] ...
debug: [bootz 0x82000000 0x88080000:71311e 88000000] ...
## Flattened Device Tree blob at 88000000
   Booting using the fdt blob at 0x88000000
   Loading Ramdisk to 8f8ec000, end 8ffff11e ... OK
   Loading Device Tree to 8f85f000, end 8f8ebfff ... OK

Starting kernel ...

[    0.002308] timer_probe: no matching timers found
[    0.195524] l4_wkup_cm:clk:0010:0: failed to disable
[    1.275954] davinci_mdio 4a101000.mdio: prop pinctrl-0 index 0 invalid phandle
[    1.423908] omap_voltage_late_init: Voltage driver support not added
rootfs: clean, 86673/231536 files, 527319/924672 blocks
[   24.729586] libphy: PHY 4a101000.mdio:00 not found
[   24.771726] net eth0: phy "4a101000.mdio:00" not found on slave 0, err -19

U-boot appears to load the overlay but the kernel complains about invalid phandle. Also the o-scope shows that gpio1_8 is held high and not toggling.

Is there something wrong with the syntax of my overlay file?

Thank you

i’ve never had much luck with an overlay ‘appending’ inside a node, just copy the default pins and add yours…

&davinci_mdio {
	pinctrl-names = "default", "sleep";
	pinctrl-0 = <&davinci_mdio_default>;
	pinctrl-1 = <&davinci_mdio_sleep>;
	reset-gpios = <&gpio1 8 GPIO_ACTIVE_LOW>;
	reset-delay-us = <2>;
	status = "okay";
};

RCN,
Copying the node worked! Here is my working overlay file. Maybe you can add it to your BB-DT repo for safe keeping.
Thank you,

dts-v1/;
/plugin/;

#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/pinctrl/am33xx.h>

/*
 * Helper to show loaded overlays under: /proc/device-tree/chosen/overlays/
 */
&{/chosen} {
	overlays {
		BB-PHY-GPIO-RESET.kernel = __TIMESTAMP__;
	};
};

&am33xx_pinmux {
	davinci_mdio_default: davinci_mdio_default {
		pinctrl-single,pins = <
			/* MDIO */
			AM33XX_PADCONF(AM335X_PIN_MDIO, PIN_INPUT_PULLUP | SLEWCTRL_FAST, MUX_MODE0)
			AM33XX_PADCONF(AM335X_PIN_MDC, PIN_OUTPUT_PULLUP, MUX_MODE0)
			// added to support gpio controlled PHY reset
			AM33XX_PADCONF(AM335X_PIN_UART0_CTSN, PIN_OUTPUT_PULLUP, MUX_MODE7)
		>;
	};

	davinci_mdio_sleep: davinci_mdio_sleep {
		pinctrl-single,pins = <
			/* MDIO reset value */
			AM33XX_PADCONF(AM335X_PIN_MDIO, PIN_INPUT_PULLDOWN, MUX_MODE7)
			AM33XX_PADCONF(AM335X_PIN_MDC, PIN_INPUT_PULLDOWN, MUX_MODE7)
			// added to support gpio controlled PHY reset
			AM33XX_PADCONF(AM335X_PIN_UART0_CTSN, PIN_INPUT_PULLDOWN, MUX_MODE7)
		>;
	};

};

&davinci_mdio {
	pinctrl-names = "default", "sleep";
	pinctrl-0 = <&davinci_mdio_default>;
	pinctrl-1 = <&davinci_mdio_sleep>;
	status = "okay";
	// added to support gpio controlled PHY reset
	reset-gpios = <&gpio1 8 GPIO_ACTIVE_LOW>;
	reset-delay-us = <2>;
};

Out of curiosity…

Is there a know reason why some boards would show this behaviour and some don’t? Or are all boards susceptible and do users just reboot every once in a while when there board comes up without Ethernet, not realizing they are seeing a known issue?

thanks @jakthree and pushed… GPIO PHY reset on RevC3 boards:... (74d3055c) · Commits · BeagleBoard.org / BeagleBoard-DeviceTrees · GitLab it’s safe to enable by default.

Regards,

I believe it’s a tolerance issue, with how much capacitance was on the reset line, which is why removing C24 seems to fix it for some users. Where previously it was borderline for the external PHY, but after removing C24, it’s now far low enough to work…

Regards,

HI @dieterv found another ‘buggy’ BeagleBone Green in my hardware collection… Removed C24, and it’s now working again on bootup, correctly…

Regards,

That is reassuring… I’m wondering if I should look into this software based solution.

Creating my own device tree is something that will take a while to get there…

@RobertCNelson

What is the correct way to update the bootloader?

I found

  • Your digikey page
  • eLinux using the bb-u-boot-am335x-evm package (Nice and easy way, but likely too easy)
  • On the same page, it mentions another way (seemingly loosely based on another page I found made by you) crosscompiling it on another system.

If I follow the first option (your page), do I still need to use the v2022.04 branch and pull the https://git.beagleboard.org/beagleboard/u-boot.git v2022.04-bbb.io-am335x-am57xx patch?

I know these might be very obvious questions, but this is my first time doing these kind of things and there’s an incredible amount of outdated information available.

I already tried following your guide which worked up until the end, but I couldn’t get the sd card image copied to the onboard eMMC.

Hi @dieterv ,

So bb-u-boot-am335x-evm is a production pre-packaged version of the top of branch (v2022.04-bbb.io-am335x-am57xx) of: BeagleBoard.org / u-boot · GitLab

The directions are really set for 2 audiences, those that like to learn how each piece comes together (this forum) and those that just want it to work (bb-uboot-am335x-evm)…

During development/testing we use the git repo, for production updates the native pacakge.

Regards,

Trying to understand what happens here.

If I look at the schematics, it seems like the ball on E18 (UART0_CTSN/UART4_RXD/DCAN1_TX/I2C1_SDA/SPI1_D0/TIMER7/PR1_EDC_SYNC0_OUT/GPIO1_8) is not connected to anything:

What does your overlay do then? Something internally?

Gpio1_8 was never used in designs prior to rev c3, which made this pin perfect for the fix…

Right, sorry. I still had the v2 schematics on my hard drive, where that ball isn’t connected to anything.
My apologies.

Hi Robert,

I just bought a BBB RevC3 (made by seeedstudio) and I have an older RevC that does not have the U1 AND gate.

I probably won the lottery because RevC3’s PHY NEVER comes up with 6.7.0-rc6.
the old RevC’s PHY comes up properly most of the time with the same SD card as above.

I isolated the issue on the RevC3 and I think it’s purely software-bound:

  • if I boot with a 4.19.94 kernel (from a debian image) pins 1 and 4 of U1 are 3.4V after boot and eth0 works.
  • if I boot with 6.7.0-rc6 generated by bb-kernel, pins 1 and 4 of U1 are always 0V, keeping the PHY in an infinite reset.
SMSC LAN8710/LAN8720: probe of 4a101000.mdio:00 failed with error -5
[..]
6.014114] cpsw-switch 4a100000.switch: phy "/ocp/interconnect@4a000000/segment@0/target-module@100000/switch@0/mdio@1000/ethernet-phy@0" not found on slave 0

the kernel (6.7.0-rc6) and the u-boot (2022.04) were generated based on your guide.
I checked and it’s using am335x-boneblack.dts that has the gpio1_8 reset information in it.

an interesting artefact is that my gpio numbering starts at 512, which makes
the PHY reset gpio == 520, and look, it’s set low by some driver:

# cat /sys/kernel/debug/gpio
gpiochip0: GPIOs 512-543, parent: platform/4804c000.gpio, gpio-0-31:
 gpio-512 (P8_25 [mmc1_dat0]   )
 gpio-513 ([mmc1_dat1]         )
 gpio-514 (P8_5 [mmc1_dat2]    )
 gpio-515 (P8_6 [mmc1_dat3]    )
 gpio-516 (P8_23 [mmc1_dat4]   )
 gpio-517 (P8_22 [mmc1_dat5]   )
 gpio-518 (P8_3 [mmc1_dat6]    )
 gpio-519 (P8_4 [mmc1_dat7]    )
 gpio-520 (NC                  |PHY reset           ) out lo ACTIVE LOW   <------
 gpio-521 (NC                  )
 gpio-522 (NC                  )
[..]

writing to that pin is not allowed:

beagle /sys/class/gpio # echo 520 > export
-bash: echo: write error: Device or resource busy

trying a PHY reset the elegant way, and failing probably due to wrong gpio (0x40 instead of 520) being hardcoded?

beagle ~ # ethtool --reset eth0 phy
ETHTOOL_RESET 0x40
Cannot issue ETHTOOL_RESET: Operation not supported

so to summarize,

  1. any idea why the gpio numbering is different on 6.7.0 vs old kernel (numbering starts at 512 instead of 0)?
  2. any idea why the PHY reset signal is stuck in a low state on 6.7.0? we established that the mosfets inside AM335 are just fine.
  3. how can I take control over that gpio (without cutting that trace and transforming the board into a RevC2)?

the RevC3 devboard has these markings
pcb front:
94V-0
E225430 KB-04
2210
pcb back:
PCB RevC
connector sticker (QR code):
BBBVC
202204
018967
box (barcode):
1252411
1 MPN: 102110420
box back:
Manufactured by seeedstudio

U1 (marking AJJ), R34, R33, C174 all exist on the board, so it’s definitely a RevC3
C24 is not populated

yeah gpio numbers are all over the place… looking at:

debian@40-am335x-bbb:~$ uname -r ; cat /sys/kernel/debug/gpio
6.1.46-ti-r18
gpiochip0: GPIOs 0-31, parent: platform/4804c000.gpio, gpio-0-31:
 gpio-0   (P8_25 [mmc1_dat0]   )
 gpio-1   ([mmc1_dat1]         )
 gpio-2   (P8_5 [mmc1_dat2]    )
 gpio-3   (P8_6 [mmc1_dat3]    )
 gpio-4   (P8_23 [mmc1_dat4]   )
 gpio-5   (P8_22 [mmc1_dat5]   )
 gpio-6   (P8_3 [mmc1_dat6]    )
 gpio-7   (P8_4 [mmc1_dat7]    )
 gpio-8   (NC                  |PHY reset           ) out hi ACTIVE LOW
debian@40-am335x-bbb:~$ dmesg | grep gpio
[    3.410918] gpio gpiochip0: (gpio-0-31): not an immutable chip, please consider fixing it!
[    3.526430] gpio gpiochip1: (gpio-32-63): not an immutable chip, please consider fixing it!
[    3.529201] gpio gpiochip2: (gpio-64-95): not an immutable chip, please consider fixing it!
[    3.736478] gpio gpiochip3: (gpio-96-127): not an immutable chip, please consider fixing it!
[    5.497706] omap_gpio 44e07000.gpio: Could not set line 6 debounce to 200000 microseconds (-22)

So using that, you can grab the io via gpio…

debian@40-am335x-bbb:~$ gpioget gpiochip0 8
0
debian@40-am335x-bbb:~$ gpioget gpiochip0 8
0
debian@40-am335x-bbb:~$ sudo gpioset gpiochip0 8=0
debian@40-am335x-bbb:~$ gpioget gpiochip0 8
0
debian@40-am335x-bbb:~$ sudo gpioset gpiochip0 8=1
debian@40-am335x-bbb:~$ gpioget gpiochip0 8
0
debian@40-am335x-bbb:~$ uname -r ; gpioinfo
6.7.0-rc6-bone6
gpiochip0 - 32 lines:
	line   0: "P8_25 [mmc1_dat0]" unused input active-high 
	line   1: "[mmc1_dat1]" unused input active-high 
	line   2: "P8_5 [mmc1_dat2]" unused input active-high 
	line   3: "P8_6 [mmc1_dat3]" unused input active-high 
	line   4: "P8_23 [mmc1_dat4]" unused input active-high 
	line   5: "P8_22 [mmc1_dat5]" unused input active-high 
	line   6: "P8_3 [mmc1_dat6]" unused input active-high 
	line   7: "P8_4 [mmc1_dat7]" unused input active-high 
	line   8:         "NC"  "PHY reset"  output   active-low [used]

i questioned this before…

On mainline: am335x-bone-common.dtsi « omap « ti « dts « boot « arm « arch - kernel/git/torvalds/linux.git - Linux kernel source tree

&davinci_mdio_sw {
	pinctrl-names = "default", "sleep";
	pinctrl-0 = <&davinci_mdio_default>;
	pinctrl-1 = <&davinci_mdio_sleep>;

	ethphy0: ethernet-phy@0 {
		reg = <0>;
		/* Support GPIO reset on revision C3 boards */
		reset-gpios = <&gpio1 8 GPIO_ACTIVE_LOW>;
		reset-assert-us = <300>;
		reset-deassert-us = <6500>;
	};
};

Whereas…mdio.yaml « net « bindings « devicetree « Documentation - kernel/git/torvalds/linux.git - Linux kernel source tree

    davinci_mdio: mdio@5c030000 {
        reg = <0x5c030000 0x1000>;
        #address-cells = <1>;
        #size-cells = <0>;

        reset-gpios = <&gpio2 5 1>;
        reset-delay-us = <2>;

        ethphy0: ethernet-phy@1 {
            reg = <1>;
        };

        ethphy1: ethernet-phy@3 {
            reg = <3>;
        };
    };

Did we screw up?

trying: am335x-bone-common: move reset-gpios under node (7bf56e95) · Commits · BeagleBoard.org / BeagleBoard-DeviceTrees · GitLab

Please try:

git clone -b v6.7.x https://git.beagleboard.org/beagleboard/BeagleBoard-DeviceTrees.git
cd ./BeagleBoard-DeviceTrees/
make
sudo make install_arm
sudo reboot

Regards,

Robert, first of all thank you for your extremely quick answer, it is much appreciated.

the bad news is that I … lost the lottery ticket.

so this RevC3 board never had a working PHY in 6.7.0, during a few dozen cold-boots.
until this morning - and it started working under that kernel without me changing absolutely anything on that particular SD card.

the only thing I did before booting up in 6.7.0 was to toggle gpio1_8 in that old debian OS, where control of that pin does not end in ‘Device or resource busy’. and using your recommended

gpioset --mode=wait gpiochip0 8=0
gpioset --mode=wait gpiochip0 8=1

I was able to actually assert/deassert RST on PHY (as seen on the voltmeter).

currently I’m running 6.7.0 with a modified dts that has all references to pin 0x968/gpio1_8 removed, thus allowing me to manually control the pin instead of being marked as ‘in use’ and thus unreachable.

AFAICT the driver asserts PHY RST and leaves it asserted under some corner case. maybe this is the idle state after the driver gives up?
sorry I can’t acknowledge your fix since I can’t replicate the problem. but I will keep an eye out, maybe it reappears.

thanks and Happy Holidays!
peter

could be a red herring, but I’m gona leave this here.

cd /usr/src/linux/arch/arm/boot/dts/ti/omap
cpp -nostdinc -I include -I /usr/src/linux/include/  -I ./ -I /usr/src/linux/arch -undef -x assembler-with-cpp am335x-boneblack.dts am335x-boneblack.dts.preprocessed
dtc -@ -I dts -O dtb -o "./am335x-boneblack.dtb" am335x-boneblack.dts.preprocessed
[..]
am33xx-l4.dtsi:720.20-769.6: Warning (unique_unit_address): /ocp/interconnect@4a000000/segment@0/target-module@100000/ethernet@0: duplicate unit-address (also used in node /ocp/interconnect@4a000000/segment@0/target-module@100000/switch@0)