zephyr-cp: fall back to the WiFi MAC for cpu.uid on siwx91x - #11246
Conversation
|
Now verified on two boards rather than one, each a different die with a different MAC:
Both match byte for byte, and the two boards give different values, so this is reading real per-die data rather than a constant. Read from the REPL with: import microcontroller, binascii
print(binascii.hexlify(microcontroller.cpu.uid).decode())Test images were main + #11230 + this patch. #11230 is needed only because main currently panics at boot on this board without it (see my comment there); it does not touch this code path. Unrelated observation while I was in there, filed here only so it is written down somewhere: |
tannewt
left a comment
There was a problem hiding this comment.
This is too SoC specific for here.
| ssize_t len = hwinfo_get_device_id(raw_id, COMMON_HAL_MCU_PROCESSOR_UID_LENGTH); | ||
| #if defined(CONFIG_SOC_FAMILY_SILABS_SIWX91X) | ||
| if (len < 0) { | ||
| ssize_t mac_len = siwx91x_uid_from_wifi_mac(raw_id); |
There was a problem hiding this comment.
Isn't there a generic way to do this? Seems like a reasonable fallback to do in a generic way.
Board and SoC specific stuff shouldn't be done here.
You could also modify the zephyr side of this.
hwinfo_get_device_id() returns -ENOSYS on any SoC without an hwinfo driver,
so cpu.uid, and the web workflow's version.json UID field, read as all zeros.
When that happens and the board has WiFi, derive the UID from the WiFi
interface link address instead. A link address is per-device, so it is a
better answer than nothing. It is also what at least one vendor already means
by the part's unique ID: Simplicity Commander reports the siwx91x unique ID as
the WiFi MAC zero-extended to eight bytes, and this produces the same value.
Unlike a burned-in serial this can generally be reprogrammed by vendor
tooling, so cpu.uid must not be relied on as tamper proof where it comes from
this path. Boards whose SoC has a real hwinfo driver never reach it.
Gated on CONFIG_WIFI, and purely additive: the existing diagnostics still fire
on any board where nothing supplies a UID.
Verified on two SiWx917-DK2605A boards, each a different die:
board A commander 0000c09b9ec2eec8 cpu.uid 0000c09b9ec2eec8
board B commander 0000c09b9ec39910 cpu.uid 0000c09b9ec39910
f1bb58c to
3dbb714
Compare
|
Made it generic, no SoC references left. Gated on CONFIG_WIFI, so any board whose SoC has no hwinfo driver but does have WiFi gets the link address instead of zeros. Still matches commander on both boards after the rewrite. An hwinfo driver upstream would be the cleaner home, but it would have nothing to read: the efuse identity region is unprogrammed on this silicon, verified on both dies, so the MAC in flash config space is the only per-device value there is. |
What
cpu.uidreads as all zeros on siwx91x. Falls back to the WiFi MAC whenhwinfohas nothing, matching how Silicon Labs' own tooling defines this part's unique ID.Why
Zephyr has no hwinfo driver for siwx91x, so
hwinfo_get_device_id()returns-ENOSYS,common_hal_mcu_processor_get_uid()zero-fills, and bothmicrocontroller.cpu.uidand the web workflow'sversion.jsonUID field come back as zeros.Writing an hwinfo driver against the efuse controller would not fix it. The efuse identity region (
0x020..0x02Fof the array behindTA_EFUSE_IO_BASE_ADDR) is unprogrammed on this silicon. I read it on two independent dies, on two separate benches, and both carry only four nonzero calibration bytes at0x3A..0x3Dand zeros where the MACs would live. The MACs are only in the flash-resident config space, and Simplicity Commander's own "Unique ID" for this part is the WiFi MAC zero-extended to eight bytes.So this matches that definition rather than inventing a second one: when hwinfo yields nothing, build the UID as
00 00 | mac[6]from the wifinet_iflink address. That address is populated at driver init, before the radio is enabled, so it is available whenever this function can be called.Caveat, stated in the code comment as well: unlike a burned-in serial, this is whatever the WiFi MAC currently is, and Silicon Labs'
mfg917tool can reprogram it. Nothing on this silicon offers an immutable per-device ID, socpu.uidshould not be treated as tamper-proof on this port.The change is additive and guarded on
CONFIG_SOC_FAMILY_SILABS_SIWX91X. The two existing diagnosticprintklines are untouched and still fire on any board where nothing supplies a UID; on siwx91x they now stay quiet because the fallback succeeds.Hardware tested
Silicon Labs SiWx917-DK2605A (Zephyr board
siwx917_dk2605a, SoC SiWG917M111MGTBA), zephyr-cp, built on currentmain.version.jsonUID field all zeros.0000C09B9EC39910, matchingcommander device infofor the same board byte for byte.Flash cost 64 bytes: 799136 B (76.21%) on
main, 799200 B (76.22%) with this change.Not tested on other zephyr-cp boards; the new code is inside
#if CONFIG_SOC_FAMILY_SILABS_SIWX91Xand compiles out everywhere else.AI assistance
Written with Claude Code. I read the efuse arrays on the two boards, ran the before/after comparison against Simplicity Commander, and reviewed the diff myself.