diff --git a/components/bt/Kconfig b/components/bt/Kconfig index 1dd04bb0b1..63dce8d1f9 100644 --- a/components/bt/Kconfig +++ b/components/bt/Kconfig @@ -3,15 +3,6 @@ menuconfig BT_ENABLED help Select this option to enable Bluetooth stack and show the submenu with Bluetooth configuration choices. -config ESP_MAC_OFFSET_BT - int "MAC address offset value of WiFi station" - depends on BT_ENABLED - range 0 255 - default 2 - help - The offset value of bluetooth MAC address from the MAC address which is read from efuse. - This offset value must be different from that of WiFi softap, WiFi station and ethernet. - config BTC_TASK_STACK_SIZE int "Bluetooth event (callback to application) task stack size" depends on BT_ENABLED diff --git a/components/bt/bt.c b/components/bt/bt.c index 9af9dd0edd..e8f4204ef4 100644 --- a/components/bt/bt.c +++ b/components/bt/bt.c @@ -45,7 +45,6 @@ extern void btdm_controller_deinit(void); extern int btdm_controller_enable(esp_bt_mode_t mode); extern int btdm_controller_disable(esp_bt_mode_t mode); extern void btdm_rf_bb_init(void); -extern int esp_read_mac(uint8_t *mac, int type); /* VHCI function interface */ typedef struct vhci_host_callback { diff --git a/components/esp32/Kconfig b/components/esp32/Kconfig index 361ddccd52..eea04a3327 100644 --- a/components/esp32/Kconfig +++ b/components/esp32/Kconfig @@ -105,6 +105,28 @@ config MEMMAP_SPISRAM main memory map. Enable this if you have this hardware and want to use it in the same way as on-chip RAM. +choice NUMBER_OF_MAC_ADDRESS_GENERATED_FROM_EFUSE + bool "Number of MAC address generated from the hardware MAC address in efuse" + default FOUR_MAC_ADDRESS_FROM_EFUSE + help + Config the number of MAC address which is generated from the hardware MAC address in efuse. + If the number is two, the MAC addresses of WiFi station and bluetooth are generated from + the hardware MAC address in efuse. The MAC addresses of WiFi softap and ethernet are derived + from that of WiFi station and bluetooth respectively. + If the number is four, the MAC addresses of WiFi station, WiFi softap, bluetooth and ethernet + are all generated from the hardware MAC address in efuse. + +config TWO_MAC_ADDRESS_FROM_EFUSE + bool "Two" +config FOUR_MAC_ADDRESS_FROM_EFUSE + bool "Four" +endchoice + +config NUMBER_OF_MAC_ADDRESS_GENERATED_FROM_EFUSE + int + default 2 if TWO_MAC_ADDRESS_FROM_EFUSE + default 4 if FOUR_MAC_ADDRESS_FROM_EFUSE + config SYSTEM_EVENT_QUEUE_SIZE int "System event queue size" default 32 @@ -481,24 +503,6 @@ menuconfig WIFI_ENABLED help Select this option to enable WiFi stack and show the submenu with WiFi configuration choices. -config ESP_MAC_OFFSET_WIFI_STA - int "MAC address offset value of WiFi station" - depends on WIFI_ENABLED - range 0 255 - default 0 - help - The offset value of WiFi station MAC address from the MAC address which is read from efuse. - This offset value must be different from that of WiFi softap, bluetooth and ethernet. - -config ESP_MAC_OFFSET_WIFI_SOFTAP - int "MAC address offset value of WiFi softap" - depends on WIFI_ENABLED - range 0 255 - default 1 - help - The offset value of WiFi softap MAC address from the MAC address which is read from efuse. - This offset value must be different from that of WiFi station, bluetooth and ethernet. - config SW_COEXIST_ENABLE bool "Software controls WiFi/Bluetooth coexistence" depends on WIFI_ENABLED && BT_ENABLED diff --git a/components/esp32/include/esp_system.h b/components/esp32/include/esp_system.h index b127d56fea..9a88743b80 100644 --- a/components/esp32/include/esp_system.h +++ b/components/esp32/include/esp_system.h @@ -24,12 +24,16 @@ extern "C" { #endif -enum { +typedef enum { ESP_MAC_WIFI_STA, ESP_MAC_WIFI_SOFTAP, ESP_MAC_BT, ESP_MAC_ETH, -}; +} esp_mac_type_t; + +#define TWO_MAC_ADDRESS_FROM_EFUSE 2 +#define FOUR_MAC_ADDRESS_FROM_EFUSE 4 +#define NUM_MAC_ADDRESS_FROM_EFUSE CONFIG_NUMBER_OF_MAC_ADDRESS_GENERATED_FROM_EFUSE /** * @attention application don't need to call this function anymore. It do nothing and will @@ -126,14 +130,42 @@ esp_err_t system_efuse_read_mac(uint8_t mac[6]) __attribute__ ((deprecated)); * @brief Read hardware MAC address and set MAC address of the interface. * * This function first reads hardware MAC address from efuse. Then set the MAC address of the interface - * including wifi station, wifi softap, bluetooth and ethernet according to the offset value in menuconfig. + * including wifi station, wifi softap, bluetooth and ethernet. * * @param mac MAC address of the interface, length: 6 bytes. - * @param interface interface, 0:wifi station, 1:wifi softap, 2:bluetooth, 3:ethernet. + * @param type type of MAC address, 0:wifi station, 1:wifi softap, 2:bluetooth, 3:ethernet. * * @return ESP_OK on success */ -esp_err_t esp_read_mac(uint8_t* mac, int interface); +esp_err_t esp_read_mac(uint8_t* mac, esp_mac_type_t type); + +/** + * @brief Derive MAC address. + * + * This function derives a local MAC address from an universal MAC address. + * Addresses can either be universally administered addresses or locally administered addresses. + * A universally administered address is uniquely assigned to a device by its manufacturer. + * The first three octets (in transmission order) identify the organization that issued the identifier + * and are known as the Organizationally Unique Identifier (OUI).[4] The remainder of the address + * (three octets for MAC-48 and EUI-48 or five for EUI-64) are assigned by that organization in nearly + * any manner they please, subject to the constraint of uniqueness. A locally administered address is + * assigned to a device by a network administrator, overriding the burned-in address. + * Universally administered and locally administered addresses are distinguished by setting + * the second-least-significant bit of the first octet of the address. This bit is also referred to + * as the U/L bit, short for Universal/Local, which identifies how the address is administered. + * If the bit is 0, the address is universally administered. If it is 1, the address is locally administered. + * In the example address 06-00-00-00-00-00 the first octet is 06 (hex), the binary form of which is 00000110, + * where the second-least-significant bit is 1. Therefore, it is a locally administered address.[7] Consequently, + * this bit is 0 in all OUIs. + * In ESP32, universal MAC address is generated from the hardware MAC address in efuse. + * Local MAC address is derived from the universal MAC address. + * + * @param dst_mac Derived local MAC address, length: 6 bytes. + * @param src_mac Source universal MAC address, length: 6 bytes. + * + * @return ESP_OK on success + */ +esp_err_t esp_derive_mac(uint8_t* dst_mac, const uint8_t* src_mac); /** * Get SDK version diff --git a/components/esp32/system_api.c b/components/esp32/system_api.c index 7f1243f5db..429ef867e1 100644 --- a/components/esp32/system_api.c +++ b/components/esp32/system_api.c @@ -74,42 +74,82 @@ esp_err_t esp_efuse_read_mac(uint8_t* mac) esp_err_t system_efuse_read_mac(uint8_t mac[6]) __attribute__((alias("esp_efuse_read_mac"))); -esp_err_t esp_read_mac(uint8_t* mac, int interface) +esp_err_t esp_derive_mac(uint8_t* dst_mac, const uint8_t* src_mac) +{ + uint8_t idx; + + if (dst_mac == NULL || src_mac == NULL) { + ESP_LOGE(TAG, "mac address param is NULL"); + return ESP_ERR_INVALID_ARG; + } + + memcpy(dst_mac, src_mac, 6); + for (idx = 0; idx < 64; idx++) { + dst_mac[0] = src_mac[0] | 0x02; + dst_mac[0] ^= idx << 2; + + if (memcmp(dst_mac, src_mac, 6)) { + break; + } + } + + return ESP_OK; +} + +esp_err_t esp_read_mac(uint8_t* mac, esp_mac_type_t type) { uint8_t efuse_mac[6]; if (mac == NULL) { ESP_LOGE(TAG, "mac address param is NULL"); - abort(); + return ESP_ERR_INVALID_ARG; } + if (type < ESP_MAC_WIFI_STA || type > ESP_MAC_ETH) { + ESP_LOGE(TAG, "mac type is incorrect"); + return ESP_ERR_INVALID_ARG; + } + + _Static_assert(NUM_MAC_ADDRESS_FROM_EFUSE == FOUR_MAC_ADDRESS_FROM_EFUSE \ + || NUM_MAC_ADDRESS_FROM_EFUSE == TWO_MAC_ADDRESS_FROM_EFUSE, \ + "incorrect NUM_MAC_ADDRESS_FROM_EFUSE value"); + esp_efuse_read_mac(efuse_mac); - switch (interface) { -#if CONFIG_WIFI_ENABLED + switch (type) { case ESP_MAC_WIFI_STA: memcpy(mac, efuse_mac, 6); - mac[5] += CONFIG_ESP_MAC_OFFSET_WIFI_STA; break; case ESP_MAC_WIFI_SOFTAP: - memcpy(mac, efuse_mac, 6); - mac[5] += CONFIG_ESP_MAC_OFFSET_WIFI_SOFTAP; + if (NUM_MAC_ADDRESS_FROM_EFUSE == FOUR_MAC_ADDRESS_FROM_EFUSE) { + memcpy(mac, efuse_mac, 6); + mac[5] += 1; + } + else if (NUM_MAC_ADDRESS_FROM_EFUSE == TWO_MAC_ADDRESS_FROM_EFUSE) { + esp_derive_mac(mac, efuse_mac); + } break; -#endif -#if CONFIG_BT_ENABLED case ESP_MAC_BT: memcpy(mac, efuse_mac, 6); - mac[5] += CONFIG_ESP_MAC_OFFSET_BT; + if (NUM_MAC_ADDRESS_FROM_EFUSE == FOUR_MAC_ADDRESS_FROM_EFUSE) { + mac[5] += 2; + } + else if (NUM_MAC_ADDRESS_FROM_EFUSE == TWO_MAC_ADDRESS_FROM_EFUSE) { + mac[5] += 1; + } break; -#endif -#if CONFIG_ETHERNET case ESP_MAC_ETH: - memcpy(mac, efuse_mac, 6); - mac[5] += CONFIG_ESP_MAC_OFFSET_ETH; + if (NUM_MAC_ADDRESS_FROM_EFUSE == FOUR_MAC_ADDRESS_FROM_EFUSE) { + memcpy(mac, efuse_mac, 6); + mac[5] += 3; + } + else if (NUM_MAC_ADDRESS_FROM_EFUSE == TWO_MAC_ADDRESS_FROM_EFUSE) { + efuse_mac[5] += 1; + esp_derive_mac(mac, efuse_mac); + } break; -#endif default: - ESP_LOGW(TAG, "wrong mac type"); + ESP_LOGW(TAG, "incorrect mac type"); break; } diff --git a/components/ethernet/Kconfig b/components/ethernet/Kconfig index 230e53cdc7..46e86cc60e 100644 --- a/components/ethernet/Kconfig +++ b/components/ethernet/Kconfig @@ -4,15 +4,6 @@ menuconfig ETHERNET help Select this option to enable ethernet driver and show the submenu with ethernet features. -config ESP_MAC_OFFSET_ETH - int "MAC address offset value of ethernet" - depends on ETHERNET - range 0 255 - default 3 - help - The offset value of ethernet MAC address from the MAC address which is read from efuse. - This offset value must be different from that of WiFi softap, bluetooth and WiFi station. - config DMA_RX_BUF_NUM int "Number of DMA RX buffers" range 3 20