Making wlan0 MAC address static/fixed

There are some situations where a stable MAC address is wanted on wlan0/p2p0. Like using the ROCK Pi S in a private wifi network and want to use DHCP-assigned static IP addresses.

After many hours building and debugging the kernel, I came up with the following workaround.

First, read up on NetworkManager configuration https://developer.gnome.org/NetworkManager/stable/NetworkManager.conf.html to choose whether you want a stable or permanent MAC address for wlan0/p2p0. permanent means to use the hardware MAC address.

In my environment, I opted to use permanent, so I created /etc/NetworkManager/conf.d/20-rock.conf (use the same exact file path to override /usr/lib/NetworkManager/conf.d/20-rock.conf) with the following content:

[device-mac-addr-change-wifi]
match-device=driver:rtl8723ds
wifi.scan-rand-mac-address=no
wifi.cloned-mac-address=permanent

However, either stable or permanent option requires that there be a fixed hardware MAC address to use as a key in the MAC address maps. From looking at the board datasheet, the Realtek 8723DS driver source code, and the kernel logs, it seems that the Realtek 8723DS doesn’t provide a hardware MAC address. It seems to rely on the MAC address being stored in some Flash memory or some Rockchip NANDC memory, which I’m guessing is not present on the ROCK Pi S. Many have reported seeing the following errors in the boot logs:

vendor storage:20160801 ret = -1
…
get_wifi_addr_vendor: rk_vendor_read wifi mac address failed (-1)
…

When the hardware MAC address cannot be read, the rtl8723ds driver assigns a MAC address like 00:E0:4C:XX:YY:ZZ. Realtek’s OUI is 00:E0:4C and the last three octets are random values. The random values are different on every boot.

Luckily, the rtl8723ds kernel module allows specifying the MAC address through configuration. So I added something like the following into /boot/uEnv.txt to feed a specific MAC address of my choice:
extraargs=rtl8723ds.rtw_initmac="00:E0:4C:01:02:03"

Using the permanent option in NetworkManager, that assigned MAC address is seen on the wifi network. A DHCP server can issue static IP addresses corresponding to those “static” MAC addresses.

3 Likes

Greetings !

Dear Pitz , thanks for your wonderful explanation . This works perfectly fine on Rockpi-S with Ubuntu image .
Is the procedure is same for Yocto build also ?

Thanks

I think yes. You can add the parameters to this file. https://github.com/radxa/meta-radxa/blob/zeus/recipes-bsp/u-boot/files/rockpi-s-rk3308/uEnv.txt

Greetings !

Thanks for your reply . As per your suggestion :

  1. I have added "extraargs=rtl8723ds.rtw_initmac=“00:e0:4c:eb:09:13” in “uEnv.txt” file.
  2. Also I have added “networkmanager” in our yocto build , and created “/etc/NetworkManager/conf.d/20-rock.conf” file with the mentioned content.

But after this also wlan0 mac address is keeps on changing on every reboot. Since I have stucked in the middle of the project , it will be really helpful if Radxa team can suggest us the procedure to make wlan0 mac address static in the yocto build. Please let me know if any modification in kernel is required.

Thanks in Advance,

Greetings !

Any updates on this issue !

You need this patch. https://github.com/radxa/meta-radxa/commit/96eb58cf46106ad4e4fd011b757fe840f2b31cc7

Hey Stephen ,

Thanks much for the patch . It worked !

Hi Stephen ,

Since we are going with production we cannot make change every time in "extraargs=rtl8723ds.rtw_initmac=“00:E0:4C:xx:xx:xx” and compile the yocto source .
Kindly suggest us any possibilities on this !

What’s the latest on this?

Same situation in Radxa CM3, it seems that the LAN_MAC is completely random… with all the implications that entails…

The latest Armbian images derive the wlan0 MAC address from the CPU’s unique serial number. Here’s how it works:

#!/bin/sh
#Assign specified interface a fixed, unique Ethernet MAC address constructed
#from given prefix byte followed by five byte RK3308 CPU serial number
#Ethernet prefix byte value less 2 should be exactly divisible by 4
#e.g. (prefix - 2) % 4 == 0

[ “$2” ] || {
echo “Specify network interface and first Ethernet address byte in hex” >&2
exit 1
}

cpuSerialNum() {
#output first 5 bytes of CPU Serial number in hex with a space between each
#nvmem on RK3308 does not handle multiple simultaneous readers :frowning:
nvmem=/sys/bus/nvmem/devices/rockchip-otp0/nvmem
serNumOffset=20
/bin/flock -w2 $nvmem /bin/od -An -vtx1 -j $serNumOffset -N 5 $nvmem
}

Id=cpuSerialNum || exit #fail if Rockchip nvmem not available
/sbin/ifconfig $1 hw ether $2:echo $Id | tr ' ' :

1 Like