machine: read a factory MAC from flash via mac_flash_offset

Adds an optional per-board mac_flash_offset. When non-zero, RTLPlayground
reads a 6-byte MAC from that flash address and uses it if it is a valid
globally-administered unicast address; otherwise it falls back to the
generated locally-administered MAC. Offset 0 (default for every board)
preserves current behaviour.

Enable it for the SWTGW218AS, whose stock firmware keeps the factory MAC
in nvcfg at 0x1FC000. RTLPlayground images and web upgrades only touch
flash below that region, so the factory MAC survives flashing.
This commit is contained in:
bloqaudio
2026-08-11 02:32:31 -05:00
parent 52692d05b1
commit 3853a2701d
3 changed files with 24 additions and 14 deletions
+1
View File
@@ -415,6 +415,7 @@ void machine_custom_init(void) { }
__code const struct machine machine = { __code const struct machine machine = {
.machine_name = "SWTGW218AS 8+1 Managed Switch", .machine_name = "SWTGW218AS 8+1 Managed Switch",
.isRTL8373 = 1, .isRTL8373 = 1,
.mac_flash_offset = 0x1FC000,
.min_port = 0, .min_port = 0,
.max_port = 8, .max_port = 8,
.n_sfp = 1, .n_sfp = 1,
+1
View File
@@ -85,6 +85,7 @@ typedef struct machine {
uint32_t led_sets[4][4]; uint32_t led_sets[4][4];
uint8_t led_mux_custom; uint8_t led_mux_custom;
uint8_t led_mux[28]; uint8_t led_mux[28];
uint32_t mac_flash_offset;
}; };
typedef struct machine_runtime typedef struct machine_runtime
+22 -14
View File
@@ -2112,20 +2112,28 @@ void main(void)
uip_ipaddr(&uip_hostaddr, ownIP[0], ownIP[1], ownIP[2], ownIP[3]); uip_ipaddr(&uip_hostaddr, ownIP[0], ownIP[1], ownIP[2], ownIP[3]);
uip_ipaddr(&uip_draddr, gatewayIP[0], gatewayIP[1], gatewayIP[2], gatewayIP[3]); uip_ipaddr(&uip_draddr, gatewayIP[0], gatewayIP[1], gatewayIP[2], gatewayIP[3]);
uip_ipaddr(&uip_netmask, netmask[0], netmask[1], netmask[2], netmask[3]); uip_ipaddr(&uip_netmask, netmask[0], netmask[1], netmask[2], netmask[3]);
reg_read_m(RTL837X_REG_CHIP_UUID); uip_ethaddr.addr[0] = 0xff;
#ifdef DEBUG if (machine.mac_flash_offset) {
print_string("SoC UUID: "); print_sfr_data(); flash_region.addr = machine.mac_flash_offset;
#endif flash_region.len = FLASH_BUF_SIZE;
uip_ethaddr.addr[0] = 0x06; // LAA prefix flash_read_bulk(flash_buf);
uip_ethaddr.addr[3] = sfr_data[0] ^ sfr_data[3]; // accept only a real unicast, globally-administered address (reject blank/LAA/multicast/all-zero OUI)
uip_ethaddr.addr[4] = sfr_data[1] ^ sfr_data[3]; if (flash_buf[0] != 0xff && !(flash_buf[0] & 0x03) && (flash_buf[0] | flash_buf[1] | flash_buf[2])) {
uip_ethaddr.addr[5] = sfr_data[2] ^ sfr_data[3]; uip_ethaddr.addr[0] = flash_buf[0]; uip_ethaddr.addr[1] = flash_buf[1];
reg_read_m(RTL837X_REG_CHIP_LOT_NO); uip_ethaddr.addr[2] = flash_buf[2]; uip_ethaddr.addr[3] = flash_buf[3];
#ifdef DEBUG uip_ethaddr.addr[4] = flash_buf[4]; uip_ethaddr.addr[5] = flash_buf[5];
print_string(", LOT: "); print_sfr_data(); write_char(' '); }
#endif }
uip_ethaddr.addr[1] = sfr_data[0] ^ sfr_data[2]; if (uip_ethaddr.addr[0] == 0xff) { // no valid flash MAC -> generate locally-administered
uip_ethaddr.addr[2] = sfr_data[1] ^ sfr_data[3]; reg_read_m(RTL837X_REG_CHIP_UUID);
uip_ethaddr.addr[0] = 0x06; // LAA prefix
uip_ethaddr.addr[3] = sfr_data[0] ^ sfr_data[3];
uip_ethaddr.addr[4] = sfr_data[1] ^ sfr_data[3];
uip_ethaddr.addr[5] = sfr_data[2] ^ sfr_data[3];
reg_read_m(RTL837X_REG_CHIP_LOT_NO);
uip_ethaddr.addr[1] = sfr_data[0] ^ sfr_data[2];
uip_ethaddr.addr[2] = sfr_data[1] ^ sfr_data[3];
}
print_string("Setting MAC to: "); print_string("Setting MAC to: ");
print_byte(uip_ethaddr.addr[0]); write_char(':'); print_byte(uip_ethaddr.addr[1]); write_char(':'); print_byte(uip_ethaddr.addr[0]); write_char(':'); print_byte(uip_ethaddr.addr[1]); write_char(':');
print_byte(uip_ethaddr.addr[2]); write_char(':'); print_byte(uip_ethaddr.addr[3]); write_char(':'); print_byte(uip_ethaddr.addr[2]); write_char(':'); print_byte(uip_ethaddr.addr[3]); write_char(':');