From 58f2dd5a6621b280cb9be07028e82f1010408dd9 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Mon, 9 Dec 2024 10:51:19 +0100 Subject: [PATCH 1/2] fix(protocol_examples_common): don't override MAC address for openeth The intention of the code block was to set MAC address for SPI Ethernet modules, however !CONFIG_EXAMPLE_USE_INTERNAL_ETHERNET also affected the case of CONFIG_EXAMPLE_USE_OPENETH. This commit corrects the code to match the original intention. Related to https://github.com/espressif/qemu/issues/107 --- .../protocol_examples_common/eth_connect.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/examples/common_components/protocol_examples_common/eth_connect.c b/examples/common_components/protocol_examples_common/eth_connect.c index 86e856527c..0cd105621d 100644 --- a/examples/common_components/protocol_examples_common/eth_connect.c +++ b/examples/common_components/protocol_examples_common/eth_connect.c @@ -154,7 +154,8 @@ static esp_netif_t *eth_start(void) // Install Ethernet driver esp_eth_config_t config = ETH_DEFAULT_CONFIG(s_mac, s_phy); ESP_ERROR_CHECK(esp_eth_driver_install(&config, &s_eth_handle)); -#if !CONFIG_EXAMPLE_USE_INTERNAL_ETHERNET + +#if CONFIG_EXAMPLE_USE_SPI_ETHERNET /* The SPI Ethernet module might doesn't have a burned factory MAC address, we cat to set it manually. We set the ESP_MAC_ETH mac address as the default, if you want to use ESP_MAC_EFUSE_CUSTOM mac address, please enable the configuration: `ESP_MAC_USE_CUSTOM_MAC_AS_BASE_MAC` @@ -162,7 +163,8 @@ static esp_netif_t *eth_start(void) uint8_t eth_mac[6] = {0}; ESP_ERROR_CHECK(esp_read_mac(eth_mac, ESP_MAC_ETH)); ESP_ERROR_CHECK(esp_eth_ioctl(s_eth_handle, ETH_CMD_S_MAC_ADDR, eth_mac)); -#endif +#endif // CONFIG_EXAMPLE_USE_SPI_ETHERNET + // combine driver with netif s_eth_glue = esp_eth_new_netif_glue(s_eth_handle); esp_netif_attach(netif, s_eth_glue); From 6d06f5fe441182a20d9d251d49353812e6d8a3f0 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Mon, 9 Dec 2024 11:00:48 +0100 Subject: [PATCH 2/2] fix(esp_eth): fix openeth driver to consider MAC address set in QEMU Openeth driver did not consider the possibility that the MAC address was specified when launching QEMU, and would always overwrite that address with the address obtained from esp_read_mac. When running QEMU, setting the MAC address via QEMU arguments is more convenient than crafting an eFuse file with the correct MAC address. This change modifies openeth driver to first check if an address has been set in QEMU and uses it if so. Otherwise it falls back to the address obtained from esp_read_mac. As part of this change, also removed the unnecessary variable emac_opencores_t::addr, the address is only kept in the registers of the emulated peripheral now. For full effect this also requires changes in QEMU, see https://github.com/espressif/qemu/issues/107 for background. Without changes in QEMU, this commit keeps the same behavior. --- .../esp_eth/src/openeth/esp_eth_mac_openeth.c | 31 ++++++++++++++----- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/components/esp_eth/src/openeth/esp_eth_mac_openeth.c b/components/esp_eth/src/openeth/esp_eth_mac_openeth.c index 0cf8d91442..2883a64680 100644 --- a/components/esp_eth/src/openeth/esp_eth_mac_openeth.c +++ b/components/esp_eth/src/openeth/esp_eth_mac_openeth.c @@ -38,7 +38,6 @@ typedef struct { TaskHandle_t rx_task_hdl; int cur_rx_desc; int cur_tx_desc; - uint8_t addr[6]; uint8_t *rx_buf[RX_BUF_COUNT]; uint8_t *tx_buf[TX_BUF_COUNT]; } emac_opencores_t; @@ -143,8 +142,6 @@ static esp_err_t emac_opencores_set_addr(esp_eth_mac_t *mac, uint8_t *addr) ESP_LOGV(TAG, "%s: " MACSTR, __func__, MAC2STR(addr)); esp_err_t ret = ESP_OK; ESP_GOTO_ON_FALSE(addr, ESP_ERR_INVALID_ARG, err, TAG, "can't set mac addr to null"); - emac_opencores_t *emac = __containerof(mac, emac_opencores_t, parent); - memcpy(emac->addr, addr, 6); const uint8_t mac0[4] = {addr[5], addr[4], addr[3], addr[2]}; const uint8_t mac1[4] = {addr[1], addr[0]}; uint32_t mac0_u32, mac1_u32; @@ -162,8 +159,17 @@ static esp_err_t emac_opencores_get_addr(esp_eth_mac_t *mac, uint8_t *addr) ESP_LOGV(TAG, "%s: " MACSTR, __func__, MAC2STR(addr)); esp_err_t ret = ESP_OK; ESP_GOTO_ON_FALSE(addr, ESP_ERR_INVALID_ARG, err, TAG, "can't set mac addr to null"); - emac_opencores_t *emac = __containerof(mac, emac_opencores_t, parent); - memcpy(addr, emac->addr, 6); + uint32_t mac0_u32 = REG_READ(OPENETH_MAC_ADDR0_REG); + uint32_t mac1_u32 = REG_READ(OPENETH_MAC_ADDR1_REG); + const uint8_t mac_addr[ETH_ADDR_LEN] = { + (mac1_u32 >> 8) & 0xFF, + mac1_u32 & 0xFF, + (mac0_u32 >> 24) & 0xFF, + (mac0_u32 >> 16) & 0xFF, + (mac0_u32 >> 8) & 0xFF, + mac0_u32 & 0xFF, + }; + memcpy(addr, mac_addr, ETH_ADDR_LEN); return ESP_OK; err: return ret; @@ -288,7 +294,6 @@ static esp_err_t emac_opencores_init(esp_eth_mac_t *mac) emac_opencores_t *emac = __containerof(mac, emac_opencores_t, parent); esp_eth_mediator_t *eth = emac->eth; ESP_GOTO_ON_ERROR(eth->on_state_changed(eth, ETH_STATE_LLINIT, NULL), err, TAG, "lowlevel init failed"); - ESP_GOTO_ON_ERROR(esp_read_mac(emac->addr, ESP_MAC_ETH), err, TAG, "fetch ethernet mac address failed"); // Sanity check if (REG_READ(OPENETH_MODER_REG) != OPENETH_MODER_DEFAULT) { @@ -299,7 +304,19 @@ static esp_err_t emac_opencores_init(esp_eth_mac_t *mac) // Initialize the MAC openeth_reset(); openeth_set_tx_desc_cnt(TX_BUF_COUNT); - emac_opencores_set_addr(mac, emac->addr); + + // Check if MAC address has been set in QEMU + uint8_t mac_addr[ETH_ADDR_LEN]; + emac_opencores_get_addr(mac, mac_addr); + const uint8_t zero_mac[ETH_ADDR_LEN] = {0}; + if (memcmp(mac_addr, zero_mac, ETH_ADDR_LEN) != 0) { + ESP_LOGD(TAG, "Using MAC address " MACSTR " set in QEMU", MAC2STR(mac_addr)); + } else { + // Fall back to the default MAC address + ESP_GOTO_ON_ERROR(esp_read_mac(mac_addr, ESP_MAC_ETH), err, TAG, "fetch ethernet mac address failed"); + ESP_LOGD(TAG, "Using MAC address " MACSTR " from esp_read_mac", MAC2STR(mac_addr)); + emac_opencores_set_addr(mac, mac_addr); + } return ESP_OK; err: