diff --git a/cpu/stm32/Makefile.dep b/cpu/stm32/Makefile.dep index 519ed17c9c2ab..f1a7e1b7bacad 100644 --- a/cpu/stm32/Makefile.dep +++ b/cpu/stm32/Makefile.dep @@ -24,7 +24,7 @@ ifneq (,$(filter stm32_eth,$(USEMODULE))) FEATURES_REQUIRED += periph_eth USEMODULE += iolist USEMODULE += netdev_eth - USEMODULE += netdev_legacy_api + USEMODULE += netdev_new_api USEMODULE += ztimer USEMODULE += ztimer_msec diff --git a/cpu/stm32/periph/eth.c b/cpu/stm32/periph/eth.c index 15c6d96b81085..ea72325f115f2 100644 --- a/cpu/stm32/periph/eth.c +++ b/cpu/stm32/periph/eth.c @@ -91,9 +91,6 @@ static ztimer_t _link_status_timer; #define MIN(a, b) (((a) <= (b)) ? (a) : (b)) -/* Synchronization between IRQ and thread context */ -mutex_t stm32_eth_tx_completed = MUTEX_INIT_LOCKED; - /* Descriptors */ static edma_desc_t rx_desc[ETH_RX_DESCRIPTOR_COUNT]; static edma_desc_t tx_desc[ETH_TX_DESCRIPTOR_COUNT]; @@ -300,6 +297,14 @@ static int stm32_eth_get(netdev_t *dev, netopt_t opt, } res = sizeof(netopt_enable_t); break; + case NETOPT_TX_END_IRQ: + assert(max_len == sizeof(netopt_enable_t)); + { + const netopt_enable_t yes = NETOPT_ENABLE; + memcpy(value, &yes, sizeof(yes)); + } + res = sizeof(netopt_enable_t); + break; default: res = netdev_eth_get(dev, opt, value, max_len); break; @@ -495,17 +500,23 @@ static int stm32_eth_send(netdev_t *netdev, const struct iolist *iolist) /* start TX */ ETH->DMATPDR = 0; - /* await completion */ if (IS_ACTIVE(ENABLE_DEBUG_VERBOSE)) { DEBUG("[stm32_eth] Started to send %u B via DMA\n", bytes_to_send); } - mutex_lock(&stm32_eth_tx_completed); - if (IS_ACTIVE(ENABLE_DEBUG_VERBOSE)) { - DEBUG("[stm32_eth] TX completed\n"); - } + + return 0; +} + + +static int stm32_eth_confirm_send(netdev_t *netdev, void *info) +{ + (void)info; + (void)netdev; + DEBUG("[stm32_eth] TX completed\n"); /* Error check */ _debug_tx_descriptor_info(__LINE__); + int tx_bytes = 0; int error = 0; while (1) { uint32_t status = tx_curr->status; @@ -530,16 +541,16 @@ static int stm32_eth_send(netdev_t *netdev, const struct iolist *iolist) _reset_eth_dma(); } tx_curr = tx_curr->desc_next; + tx_bytes += tx_curr->control; if (status & TX_DESC_STAT_LS) { break; } } - netdev->event_callback(netdev, NETDEV_EVENT_TX_COMPLETE); if (error) { return error; } - return (int)bytes_to_send; + return tx_bytes; } static int get_rx_frame_size(void) @@ -706,6 +717,7 @@ static void stm32_eth_isr(netdev_t *netdev) static const netdev_driver_t netdev_driver_stm32f4eth = { .send = stm32_eth_send, + .confirm_send = stm32_eth_confirm_send, .recv = stm32_eth_recv, .init = stm32_eth_init, .isr = stm32_eth_isr, diff --git a/cpu/stm32/periph/eth_common.c b/cpu/stm32/periph/eth_common.c index a3bec50311fe3..1a3b04751ca7b 100644 --- a/cpu/stm32/periph/eth_common.c +++ b/cpu/stm32/periph/eth_common.c @@ -79,13 +79,13 @@ void isr_eth(void) if (IS_USED(MODULE_STM32_ETH)) { extern netdev_t *stm32_eth_netdev; - extern mutex_t stm32_eth_tx_completed; unsigned tmp = ETH->DMASR; if ((tmp & ETH_DMASR_TS)) { ETH->DMASR = ETH_DMASR_NIS | ETH_DMASR_TS; DEBUG("isr_eth: TX completed\n"); - mutex_unlock(&stm32_eth_tx_completed); + stm32_eth_netdev->event_callback(stm32_eth_netdev, + NETDEV_EVENT_TX_COMPLETE); } if ((tmp & ETH_DMASR_RS)) {