This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

AM3352: Setting MAC address in u-boot does not reflect in Linux

Part Number: AM3352

Tool/software:

I have set a MAC address in u-boot and saved the environment, but this is not reflected in Linux once it has booted. When I set the serial# in u-boot as well it is reflected in linux. I'm not sure exactly why the kernel does not use the set MAC address. Is there a setting or config option that I need to configure the kernel with to allow this?

u-boot version: ti-uboot-2023.04

kernel version: ti-linux-6.1

Setting the environment in u-boot (this is persistent over power cycles and is saved on the boot partition in eMMC):

U-Boot 2023.04-gc30478b7-dirty (Apr 24 2025 - 13:20:35 +0200)

CPU  : AM335X-GP rev 2.1
Model: TI AM335x BeagleBone Black
DRAM:  512 MiB
Core:  161 devices, 18 uclasses, devicetree: separate
WDT:   Started wdt@44e35000 with servicing every 1000ms (60s timeout)
NAND:  0 MiB
MMC:   OMAP SD/MMC: 0, OMAP SD/MMC: 1
Loading Environment from FAT... Unable to read "uboot.env" from mmc1:1...
<ethaddr> not set. Validating first E-fuse MAC
Net:   eth2: ethernet@4a100000, eth3: usb_ether
Hit any key to stop autoboot:  0
=> print ethaddr
ethaddr=88:0c:e0:3f:d3:0e
=> print serial#
serial#=88:0c:e0:3f:d3:0e
=> setenv ethaddr D4:84:31:9C:68:2C
=> setenv serial# 1234-1234
=> saveenv
Saving Environment to FAT... OK
=>

Confirming variables after power cycle:

U-Boot SPL 2023.04-gc30478b7-dirty (Oct 08 2024 - 12:05:34 +0200)
Trying to boot from MMC2


U-Boot 2023.04-gc30478b7-dirty (Apr 24 2025 - 13:20:35 +0200)

CPU  : AM335X-GP rev 2.1
Model: TI AM335x BeagleBone Black
DRAM:  512 MiB
Core:  161 devices, 18 uclasses, devicetree: separate
WDT:   Started wdt@44e35000 with servicing every 1000ms (60s timeout)
NAND:  0 MiB
MMC:   OMAP SD/MMC: 0, OMAP SD/MMC: 1
Loading Environment from FAT... OK
Net:   eth2: ethernet@4a100000, eth3: usb_ether
Hit any key to stop autoboot:  0
=> print ethaddr
ethaddr=D4:84:31:9C:68:2C
=> print serial#
serial#=1234-1234
=>

Relevant boot log:

...
[    1.803560] omap_rng 48310000.rng: Random Number Generator ver. 20
[    1.810404] random: crng init done
[    1.870255] davinci_mdio 4a101000.mdio: davinci mdio revision 1.6, bus freq 1000000
[    1.878163] davinci_mdio 4a101000.mdio: detected phy mask fffffffe
[    1.911397] davinci_mdio 4a101000.mdio: phy[0]: device 4a101000.mdio:00, driver SMSC LAN8710/LAN8720
[    1.930809] cpsw 4a100000.ethernet: No slave[1] phy_id, phy-handle, or fixed-link property
[    1.939388] cpsw 4a100000.ethernet: initialized cpsw ale version 1.4
[    1.960273] cpsw 4a100000.ethernet: ALE Table size 1024
[    1.965760] cpsw 4a100000.ethernet: cpts: overflow check period 500 (jiffies)
[    1.990289] cpsw 4a100000.ethernet: Detected MACID = 88:0c:e0:3f:d3:0e
[    2.017371] debugfs: Directory '49000000.dma' with parent 'dmaengine' already present!
[    2.040265] edma 49000000.dma: TI EDMA DMA engine driver
...

Any help would be greatly appreciated,

TJ

  • Hi, I now tried to set a bunch of mac addresses to check if it might pull it from somewhere else but it does not seem to be the case

    => print eth1addr
    eth1addr=88:0c:e0:3f:d3:10
    => print eth2addr
    eth2addr=88:0c:e0:3f:d3:0e
    => print eth3addr
    eth3addr=de:ad:be:ef:00:01
    => setenv eth1addr D4:84:31:9C:68:01
    => setenv eth2addr D4:84:31:9C:68:02
    => setenv eth3addr D4:84:31:9C:68:03
    => saveenv
    Saving Environment to FAT... OK
    =>
    

    After power cycle confirming that it was set:

    Hit any key to stop autoboot:  0
    => print eth1addr
    eth1addr=D4:84:31:9C:68:01
    => print eth2addr
    eth2addr=D4:84:31:9C:68:02
    => print eth3addr
    eth3addr=D4:84:31:9C:68:03
    

    Boot log:

    [    1.808978] random: crng init done
    [    1.880259] davinci_mdio 4a101000.mdio: davinci mdio revision 1.6, bus freq 1000000
    [    1.888169] davinci_mdio 4a101000.mdio: detected phy mask fffffffe
    [    1.921409] davinci_mdio 4a101000.mdio: phy[0]: device 4a101000.mdio:00, driver SMSC LAN8710/LAN87          20
    [    1.940819] cpsw 4a100000.ethernet: No slave[1] phy_id, phy-handle, or fixed-link property
    [    1.949402] cpsw 4a100000.ethernet: initialized cpsw ale version 1.4
    [    1.970274] cpsw 4a100000.ethernet: ALE Table size 1024
    [    1.975761] cpsw 4a100000.ethernet: cpts: overflow check period 500 (jiffies)
    [    2.000284] cpsw 4a100000.ethernet: Detected MACID = 88:0c:e0:3f:d3:0e
    [    2.027377] debugfs: Directory '49000000.dma' with parent 'dmaengine' already present!
    [    2.050266] edma 49000000.dma: TI EDMA DMA engine driver
    

    How do I determine if u-boot is passing the mac address to the kernel correctly? Or check where the kernel gets that Detected MACID?

  • Hi, Is there anything I'm missing? From my understanding this should just work, Is there specific kernel config options I should be looking at?

  • Hi, 

    The MAC address that is passed to the kernel is not using the u-boot MAC address stored in the environment. U-boot passes an address that is stored in the device e-fuse. The MAC address in the Linux boot sequence is a TI address. You will have to change code in u-boot and have a device such as a i2c eeprom to store a unique address. I will look at the code and point to area where u-boot is reading the code.

    Best Regards,

    Schuyler

  • Hi Schuyler,

    Thank you for the response.

    In the file "ti-uboot/board/ti/am335x/board.c" I see that in the function "int board_late_init(void)" is where the MAC address is read from the efuse then the following code checks for a ethaddr environment variable:

    	if (!env_get("ethaddr")) {
    		printf("<ethaddr> not set. Validating first E-fuse MAC\n");
    
    		if (is_valid_ethaddr(mac_addr))
    			eth_env_set_enetaddr("ethaddr", mac_addr);
    	}

    This looks to me like if it does not find ethaddr variable as set, it will set the MAC address to what was read from the efuse. If it does see that ethaddr is already set, it will not run this code. The difference I see here is that it calls eth_env_set_enetaddr to set the environment variable, while when settings serial# it uses env_set("serial#", board_serial);. Does this mean that I must run eth_env_set_enetaddr to set the variable with my own MAC address

    Regards,

    TJ

  • Hi,

    I managed to solve this issue, it was a problem with the device tree. The original network part of the device tree was left unmodified during my upgrade to newer yocto version, as the network was working. I modified the device tree using "am335x-bone-commot.dtsi" as a base. Below is what I changed.

    Old dts:

    &cpsw_emac0 {
    	phy_id = <&davinci_mdio>, <0>;
    	phy-mode = "mii";
    };
    
    &mac {
    	pinctrl-names = "default";
    	pinctrl-0 = <&mii1_pins_default>;
    	status = "okay";
    };
    
    &davinci_mdio {
    	pinctrl-names = "default";
    	pinctrl-0 = <&mdio_pins_default>;
    	status = "okay";
    };

    New dts:

    &cpsw_port1 {
    	phy-handle = <&ethphy0>;
    	phy-mode = "mii";
    	ti,dual-emac-pvid = <1>;
    };
    
    &cpsw_port2 {
    	status = "disabled";
    };
    
    &mac_sw {
    	pinctrl-names = "default";
    	pinctrl-0 = <&mii1_pins_default>;
    	status = "okay";
    };
    
    &davinci_mdio_sw {
    	pinctrl-names = "default";
    	pinctrl-0 = <&mdio_pins_default>;
    
    	ethphy0: ethernet-phy@0 {
    		reg = <0>;
    	};
    };

    uboot log:

    U-Boot 2023.04-gc30478b7-dirty (Apr 24 2025 - 13:20:35 +0200)
    
    CPU  : AM335X-GP rev 2.1
    Model: TI AM335x BeagleBone Black
    DRAM:  512 MiB
    Core:  161 devices, 18 uclasses, devicetree: separate
    WDT:   Started wdt@44e35000 with servicing every 1000ms (60s timeout)
    NAND:  0 MiB
    MMC:   OMAP SD/MMC: 0, OMAP SD/MMC: 1
    Loading Environment from FAT... OK
    Net:
    Warning: ethernet@4a100000 MAC addresses don't match:
    Address in ROM is               88:0c:e0:3f:d3:0e
    Address in environment is       d4:84:31:9c:68:02
    eth2: ethernet@4a100000
    Warning: usb_ether MAC addresses don't match:
    Address in ROM is               de:ad:be:ef:00:01
    Address in environment is       d4:84:31:9c:68:03
    , eth3: usb_ether
    Hit any key to stop autoboot:  0
    => print ethaddr
    ethaddr=00:11:22:33:44:55
    

    I do get a couple of warnings about MAC addresses being different from environment and ROM, so will have to see where that is from (might just me breaking things as I was testing)

    Confirming that it was set in Linux:

    root@ipb5:~# dmesg | grep cpsw
    [    1.930560] cpsw-switch 4a100000.switch: initialized cpsw ale version 1.4
    [    1.937552] cpsw-switch 4a100000.switch: ALE Table size 1024
    [    1.960359] cpsw-switch 4a100000.switch: cpts: overflow check period 500 (jiffies)
    [    1.968160] cpsw-switch 4a100000.switch: CPTS: ref_clk_freq:250000000 calc_mult:2147483648 calc_shift:29 error:0 nsec/sec
    [    2.000270] cpsw-switch 4a100000.switch: Detected MACID = 00:11:22:33:44:55
    [    2.008591] cpsw-switch 4a100000.switch: initialized (regs 0x4a100000, pool size 256) hw_ver:0019010C 1.12 (0)
    [   11.855716] cpsw-switch 4a100000.switch: starting ndev. mode: dual_mac
    [   14.191158] cpsw-switch 4a100000.switch eth0: Link is Up - 100Mbps/Full - flow control off
    
    
    root@ipb5:~# ip addr
    1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
        link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
        inet 127.0.0.1/8 scope host lo
           valid_lft forever preferred_lft forever
        inet6 ::1/128 scope host noprefixroute
           valid_lft forever preferred_lft forever
    2: sit0@NONE: <NOARP> mtu 1480 qdisc noop qlen 1000
        link/sit 0.0.0.0 brd 0.0.0.0
    3: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq qlen 1000
        link/ether 00:11:22:33:44:55 brd ff:ff:ff:ff:ff:ff
        inet 192.168.0.131/24 brd 192.168.0.255 scope global dynamic eth0
           valid_lft 86290sec preferred_lft 86290sec
        inet6 fe80::211:22ff:fe33:4455/64 scope link
           valid_lft forever preferred_lft forever