Open mzakharocsc opened 2 days ago
@mzakharocsc That's right, IDF's esp_read_mac
doesn't query the MAC address from the network device, instead it derives the address from the base MAC address stored in eFuse. Therefore setting the MAC address on the network device side doesn't affect the result returned by esp_read_mac
.
To extract the MAC address from the network device you can use esp_eth_ioctl with ETH_CMD_G_MAC_ADDR argument:
esp_err_t get_addr(esp_eth_handle_t eth_handle, uint8_t eth_mac[6]) {
return esp_eth_ioctl(eth_handle, ETH_CMD_G_MAC_ADDR, eth_mac)
}
Or, directly from the esp_eth_mac_t MAC instance, if you have that instead of esp_eth_handle_t:
esp_err_t get_addr(esp_eth_mac_t *mac_handle, uint8_t eth_mac[6]) {
return mac_handle->read_addr(mac_handle, eth_mac);
}
Once you have read the address from the device, you either use it to configure your base MAC address (which is absent from eFuses) or just set the custom MAC address for the interface.
Edit: I'll also see if we can provide reasonable behavior (to use the MAC address configured via QEMU arguments) at least in IDF examples (which rely on examples/common_components/protocol_examples_common/eth_connect.c) or if we can add a --mac-addr
argument to idf.py qemu
which will pre-set the MAC address in eFuse.
Running examples/ethernet/basic, which does esp_eth_ioctl(eth_handle, ETH_CMD_G_MAC_ADDR, mac_addr);
returns '00:00:00:00:00:03' also, thats because I suspect in static esp_err_t emac_opencores_init(esp_eth_mac_t *mac
in esp_eth_mac_openeth.c it also uses esp_read_mac()
to set mac address of the interface.
Please confirm
Ah yes, you are totally right, I have missed that part.
I see two things we could do here:
esp_read_mac
to obtain the address derived for the Ethernet interface. This would handle the case when the emulated eFuses do contain a valid MAC address.-nic user,model=open_eth,mac=....
argument.--mac-addr
option in idf.py qemu
wrapper to allow setting the base address in eFuses.Does that sound reasonable to you?
(If we do the above, we also need to fix the ifdef in protocols_examples_common so that the address doesn't get overridden in the example projects which use this component. Currently we check for !CONFIG_EXAMPLE_USE_INTERNAL_ETHERNET
which includes the openeth case.)
I tried to read the MAC address like so:
// Initialize the MAC
openeth_reset();
openeth_set_tx_desc_cnt(TX_BUF_COUNT);
uint32_t mac0 = REG_READ(OPENETH_MAC_ADDR0_REG);
uint32_t mac1 = REG_READ(OPENETH_MAC_ADDR1_REG);
printf("MAC0=%#lx MAC1=%#lx\n", mac0, mac1);
inside esp_eth_mac_openeth.c, however I am getting all 0's even when -nic user,model=open_eth,mac=00:00:00:00:00:05
is set on QEMU parameters
Please advise.
Edit. it looks like MAC_ADDR0
and MAC_ADDR1
are never set on init inside QEMU emulator: opencores_eth.c . How else would one retreive the mac address set by QEMU parameters?
Looks like openeth emulation doesn't call qemu_macaddr_default_if_unset
to initialize the MAC address, like other ethernet adapter emulations in QEMU do, for example
Will fix that as well.
(And we have to copy the MAC address from NICInfo into the registers.)
Checklist
How often does this bug occurs?
always
Expected behavior
when specifying custom mac on qemu command line like this:
-nic user,model=open_eth,mac=00:00:00:00:00:05
, the value does not reflect expected bytes when read using the following api:esp_read_mac(mac_addr, ESP_MAC_ETH)
Actual behavior (suspected bug)
mac_addr always shows up as "00:00:00:00:00:03", regardless of what qemu's parameter 'mac=XX:XX;XX:XX:XX:XX' is set to.
Error logs or terminal output
No response
Steps to reproduce the behavior
idf.py qemu monitor
Project release version
latest
System architecture
Intel/AMD 64-bit (modern PC, older Mac)
Operating system
Linux
Operating system version
Ubuntu 20.04
Shell
Bash
Additional context
No response