Skip to content

Commit

Permalink
generate mac address for eth/wlan based on soc serial
Browse files Browse the repository at this point in the history
  • Loading branch information
gtxaspec committed Mar 30, 2024
1 parent 4044cd5 commit 3ce5ecb
Showing 1 changed file with 66 additions and 24 deletions.
90 changes: 66 additions & 24 deletions arch/mips/lib/board.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@
#define BOOT_SCRIPT "fatload mmc 0 ${baseaddr} boot.scr"
#define ENV_FILE "fatload mmc 0 ${baseaddr} uEnv.txt"

#define SERIAL_NUM_ADDR1 0x13540200
#define SERIAL_NUM_ADDR2 0x13540204
#define SERIAL_NUM_ADDR3 0x13540208
#define SERIAL_NUM_ADDR4 0x13540238 // T10/T20/T30

extern int debug_socinfo;
extern int do_socinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);

Expand Down Expand Up @@ -112,24 +117,64 @@ static int init_baudrate(void)
}

// Lets move this into another file, along with most of the other env setup gear...
static void set_random_mac_address(const char *iface_name, const char *iface_type, uint8_t *addr) {
// Check if a valid address is already set for the given interface
if (!eth_getenv_enetaddr(iface_name, addr)) {
// No valid address set, generate and set a new one
eth_random_enetaddr(addr);
if (eth_setenv_enetaddr(iface_name, addr)) {
printf("Net: Failed to set %s address for %s\n", iface_type, iface_name);
} else {
printf("Net: Random MAC address for %s (%s) set successfully\n", iface_type, iface_name);
saveenv();
}
} else {
// A valid address is already set, so no need to set it again
printf("Net: HW %s Ethernet address for %s: %02X:%02X:%02X:%02X:%02X:%02X\n",
iface_type, iface_name,
addr[0], addr[1], addr[2],
addr[3], addr[4], addr[5]);
}

static void increment_mac_address(uint8_t *mac) {
int i; // Declare loop variable outside of the for loop
// Increment the last byte of the MAC address
// If it rolls over, increment the next byte, and so on
for (i = 5; i >= 0; i--) {
mac[i]++;
if (mac[i] != 0) {
break; // No rollover, so stop
}
}
}

static void generate_mac_from_serial(uint8_t *mac, uint32_t base1, uint32_t base2, uint32_t base3, uint32_t base4) {
// Generate MAC address using parts of the serial number
mac[0] = 0x02; // Locally administered and unicast
mac[1] = (base4 >> 24) & 0xFF;
mac[2] = (base4 >> 16) & 0xFF;
mac[3] = (base4 >> 8) & 0xFF;
mac[4] = base4 & 0xFF;
// Use a combination of serial parts for the last byte
mac[5] = ((base1 ^ base2 ^ base3 ^ base4) & 0xFF) | 0x01; // Ensure the last bit is 1 for unicast
}

static void generate_or_set_mac_address(const char *iface_name, const char *iface_type, bool increment) {
uint8_t addr[6];
uint32_t serial_part1 = readl(SERIAL_NUM_ADDR1);
uint32_t serial_part2 = readl(SERIAL_NUM_ADDR2);
uint32_t serial_part3 = readl(SERIAL_NUM_ADDR3);
uint32_t serial_part4 = readl(SERIAL_NUM_ADDR4 + 4);

if (!eth_getenv_enetaddr((char*)iface_name, addr)) {
// Check if all serial parts are zero
if (serial_part1 == 0 && serial_part2 == 0 && serial_part3 == 0 && serial_part4 == 0) {
// Generate a random MAC address
eth_random_enetaddr(addr);
printf("Net: Random MAC address for %s generated\n", iface_type);
} else {
// Generate MAC from serial
generate_mac_from_serial(addr, serial_part1, serial_part2, serial_part3, serial_part4);
if (increment) {
increment_mac_address(addr); // For WLAN, make MAC +1 compared to ETH
}
printf("Net: MAC address for %s based on device serial set\n", iface_type);
}

if (eth_setenv_enetaddr((char*)iface_name, addr)) {
printf("Net: Failed to set address for %s\n", iface_type);
} else {
saveenv();
}
} else {
// A valid MAC address is already set
printf("Net: HW address for %s: %02X:%02X:%02X:%02X:%02X:%02X\n",
iface_type,
addr[0], addr[1], addr[2],
addr[3], addr[4], addr[5]);
}
}

/*
Expand Down Expand Up @@ -368,13 +413,10 @@ void board_init_r(gd_t *id, ulong dest_addr)

/* At this point, Environment has been setup, now we can use it */

/* Generate a random mac address, and save it as soon as the environment is up*/
#ifdef CONFIG_RANDOM_MACADDR
uint8_t enetaddr[6];
uint8_t wlanaddr[6];

set_random_mac_address("ethaddr", "ETH", enetaddr);
set_random_mac_address("wlanmac", "WLAN", wlanaddr);
// Generate/set MAC Address
generate_or_set_mac_address("ethaddr", "ETH", false);
generate_or_set_mac_address("wlanmac", "WLAN", true);
#endif

#if defined(CONFIG_PCI)
Expand Down

0 comments on commit 3ce5ecb

Please sign in to comment.