From f56a3f95b800bd8d435fd9af8bb29541dfb7fc61 Mon Sep 17 00:00:00 2001 From: nuttxs Date: Fri, 20 Sep 2024 13:40:09 +0800 Subject: [PATCH] xtensa/esp32s3: Configure the number of universal management (IEEE) MAC addresses when there are multiple interfaces. Optimize Lan9250 to adapt to ESP32S3 universal MAC address. --- arch/xtensa/src/esp32s3/Kconfig | 38 +++++++++++++++++++ .../esp32s3/common/src/esp32s3_lan9250.c | 34 +++++++++++++++-- drivers/net/lan9250.c | 6 ++- include/nuttx/net/lan9250.h | 2 +- 4 files changed, 74 insertions(+), 6 deletions(-) diff --git a/arch/xtensa/src/esp32s3/Kconfig b/arch/xtensa/src/esp32s3/Kconfig index bac73895b850b..64968c3d81344 100644 --- a/arch/xtensa/src/esp32s3/Kconfig +++ b/arch/xtensa/src/esp32s3/Kconfig @@ -1682,6 +1682,44 @@ config ESP32S3_BLE_INTERRUPT_SAVE_STATUS endmenu # BLE Configuration +choice ESP32S3_UNIVERSAL_MAC_ADDRESSES + bool "Number of universally administered (by IEEE) MAC address" + default ESP32S3_UNIVERSAL_MAC_ADDRESSES_FOUR + depends on ESP32S3_WIFI || ESP32S3_BLE + help + Configure the number of universally administered (by IEEE) MAC addresses. + During initialization, MAC addresses for each network interface are generated or derived from a + single base MAC address. + If the number of universal MAC addresses is four, all four interfaces (WiFi station, WiFi softap, + Bluetooth and Ethernet) receive a universally administered MAC address. These are generated + sequentially by adding 0, 1, 2 and 3 (respectively) to the final octet of the base MAC address. + If the number of universal MAC addresses is two, only two interfaces (WiFi station and Bluetooth) + receive a universally administered MAC address. These are generated sequentially by adding 0 + and 1 (respectively) to the base MAC address. The remaining two interfaces (WiFi softap and Ethernet) + receive local MAC addresses. These are derived from the universal WiFi station and Bluetooth MAC + addresses, respectively. + When using the default (Espressif-assigned) base MAC address, either setting can be used. When using + a custom universal MAC address range, the correct setting will depend on the allocation of MAC + addresses in this range (either 2 or 4 per device.) + + config ESP32S3_UNIVERSAL_MAC_ADDRESSES_TWO + bool "Two" + select ESP_MAC_ADDR_UNIVERSE_WIFI_STA + select ESP_MAC_ADDR_UNIVERSE_BT + + config ESP32S3_UNIVERSAL_MAC_ADDRESSES_FOUR + bool "Four" + select ESP_MAC_ADDR_UNIVERSE_WIFI_STA + select ESP_MAC_ADDR_UNIVERSE_WIFI_AP + select ESP_MAC_ADDR_UNIVERSE_BT + select ESP_MAC_ADDR_UNIVERSE_ETH +endchoice + +config ESP32S3_UNIVERSAL_MAC_ADDRESSES + int + default 2 if ESP32S3_UNIVERSAL_MAC_ADDRESSES_TWO + default 4 if ESP32S3_UNIVERSAL_MAC_ADDRESSES_FOUR + menu "PHY" depends on ESP32S3_PARTITION_TABLE diff --git a/boards/xtensa/esp32s3/common/src/esp32s3_lan9250.c b/boards/xtensa/esp32s3/common/src/esp32s3_lan9250.c index 6e1ca110498f7..f838f13240d7a 100644 --- a/boards/xtensa/esp32s3/common/src/esp32s3_lan9250.c +++ b/boards/xtensa/esp32s3/common/src/esp32s3_lan9250.c @@ -55,7 +55,7 @@ static int lan9250_attach(const struct lan9250_lower_s *lower, xcpt_t handler, void *arg); static void lan9250_enable(const struct lan9250_lower_s *lower); static void lan9250_disable(const struct lan9250_lower_s *lower); -static void lan9250_getmac(const struct lan9250_lower_s *lower, +static int lan9250_getmac(const struct lan9250_lower_s *lower, uint8_t *mac); /**************************************************************************** @@ -175,18 +175,44 @@ static void lan9250_disable(const struct lan9250_lower_s *lower) * ****************************************************************************/ -static void lan9250_getmac(const struct lan9250_lower_s *lower, uint8_t *mac) +static int lan9250_getmac(const struct lan9250_lower_s *lower, uint8_t *mac) { uint32_t regval[2]; uint8_t *data = (uint8_t *)regval; + int i; regval[0] = esp32s3_efuse_read_reg(EFUSE_BLK1, 0); regval[1] = esp32s3_efuse_read_reg(EFUSE_BLK1, 1); - for (int i = 0; i < 6; i++) + for (i = 0; i < 6; i++) { - mac[i] = data[i]; + mac[i] = data[5 - i]; } + +#ifdef CONFIG_ESP32S3_UNIVERSAL_MAC_ADDRESSES_FOUR + mac[5] += 3; +#else + mac[5] += 1; + uint8_t tmp = mac[0]; + for (i = 0; i < 64; i++) + { + mac[0] = tmp | 0x02; + mac[0] ^= i << 2; + + if (mac[0] != tmp) + { + break; + } + } + + if (i >= 64) + { + wlerr("Failed to generate ethernet MAC\n"); + return -1; + } +#endif + + return 0; } /**************************************************************************** diff --git a/drivers/net/lan9250.c b/drivers/net/lan9250.c index 43f7dfb304b2b..fa617ce4a02f4 100644 --- a/drivers/net/lan9250.c +++ b/drivers/net/lan9250.c @@ -2472,7 +2472,11 @@ int lan9250_initialize( if (lower->getmac) { - lower->getmac(lower, priv->dev.d_mac.ether.ether_addr_octet); + if (lower->getmac(lower, priv->dev.d_mac.ether.ether_addr_octet) < 0) + { + nerr("ERROR: Failed read MAC address\n"); + return -EAGAIN; + } } /* Register the device with the OS so that socket IOCTLs can be performed */ diff --git a/include/nuttx/net/lan9250.h b/include/nuttx/net/lan9250.h index fe5dc0cab8ce2..dc0d719b6db92 100644 --- a/include/nuttx/net/lan9250.h +++ b/include/nuttx/net/lan9250.h @@ -66,7 +66,7 @@ struct lan9250_lower_s * driver will not read the MAC from the CPU. */ - CODE void (*getmac)(FAR const struct lan9250_lower_s *lower, + CODE int (*getmac)(FAR const struct lan9250_lower_s *lower, FAR uint8_t *mac); };