diff --git a/arch/mips/lib/board.c b/arch/mips/lib/board.c index 9d940018..6e8bc743 100644 --- a/arch/mips/lib/board.c +++ b/arch/mips/lib/board.c @@ -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[]); @@ -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]); + } } /* @@ -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)