From ef10b7085d61c6743e97d6bba153e4956d59ed30 Mon Sep 17 00:00:00 2001 From: maidnl Date: Thu, 20 Jun 2024 12:02:04 +0200 Subject: [PATCH 1/5] fix for dhcp not asking for address when host if goes down and up again --- connectivity/lwipstack/source/LWIPInterface.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/connectivity/lwipstack/source/LWIPInterface.cpp b/connectivity/lwipstack/source/LWIPInterface.cpp index a1cfcf31c41..c5c851406fe 100644 --- a/connectivity/lwipstack/source/LWIPInterface.cpp +++ b/connectivity/lwipstack/source/LWIPInterface.cpp @@ -199,6 +199,11 @@ void LWIP::Interface::netif_link_irq(struct netif *netif) netif_set_down(&interface->netif); } } else { + if(interface->dhcp_started) { + interface->dhcp_started = false; + interface->dhcp_has_to_be_set = true; + dhcp_stop(netif); + } osSemaphoreRelease(interface->unlinked); if (netif_is_up(&interface->netif)) { interface->connected = NSAPI_STATUS_CONNECTING; From f8c2920334bf2d99440ebdee9b10f0591e9b0e6a Mon Sep 17 00:00:00 2001 From: maidnl Date: Thu, 20 Jun 2024 17:21:32 +0200 Subject: [PATCH 2/5] reformat previous patch to not use dhcp_stop in isr --- connectivity/lwipstack/source/LWIPInterface.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/connectivity/lwipstack/source/LWIPInterface.cpp b/connectivity/lwipstack/source/LWIPInterface.cpp index c5c851406fe..4cc6d303e07 100644 --- a/connectivity/lwipstack/source/LWIPInterface.cpp +++ b/connectivity/lwipstack/source/LWIPInterface.cpp @@ -169,6 +169,11 @@ nsapi_error_t LWIP::Interface::set_dhcp() #if LWIP_DHCP if (dhcp_has_to_be_set) { + if(dhcp_started) { + dhcp_stop(&netif); + dhcp_started = false; + } + err_t err = dhcp_start(&netif); dhcp_has_to_be_set = false; if (err) { @@ -200,9 +205,7 @@ void LWIP::Interface::netif_link_irq(struct netif *netif) } } else { if(interface->dhcp_started) { - interface->dhcp_started = false; interface->dhcp_has_to_be_set = true; - dhcp_stop(netif); } osSemaphoreRelease(interface->unlinked); if (netif_is_up(&interface->netif)) { From f1c8d7a8130177010944cbf2ae3e1f33dd29ed89 Mon Sep 17 00:00:00 2001 From: Martino Facchin Date: Tue, 2 Jul 2024 16:30:07 +0200 Subject: [PATCH 3/5] emac_stm32: properly invalidate DCache before disabling it --- .../TARGET_STM/TARGET_STM32H7/TARGET_OPTA/stm32h7_eth_init.c | 3 +++ .../TARGET_STM32H7/TARGET_PORTENTA_H7/stm32h7_eth_init.c | 1 + 2 files changed, 4 insertions(+) diff --git a/connectivity/drivers/emac/TARGET_STM/TARGET_STM32H7/TARGET_OPTA/stm32h7_eth_init.c b/connectivity/drivers/emac/TARGET_STM/TARGET_STM32H7/TARGET_OPTA/stm32h7_eth_init.c index 0572fae7a2a..8b9cc8bcd03 100644 --- a/connectivity/drivers/emac/TARGET_STM/TARGET_STM32H7/TARGET_OPTA/stm32h7_eth_init.c +++ b/connectivity/drivers/emac/TARGET_STM/TARGET_STM32H7/TARGET_OPTA/stm32h7_eth_init.c @@ -66,7 +66,10 @@ void HAL_ETH_MspInit(ETH_HandleTypeDef *heth) #if !(defined(DUAL_CORE) && defined(CORE_CM4)) /* Disable DCache for STM32H7 family */ + core_util_critical_section_enter(); + SCB_CleanInvalidateDCache(); SCB_DisableDCache(); + core_util_critical_section_exit(); #endif /* GPIO Ports Clock Enable */ diff --git a/connectivity/drivers/emac/TARGET_STM/TARGET_STM32H7/TARGET_PORTENTA_H7/stm32h7_eth_init.c b/connectivity/drivers/emac/TARGET_STM/TARGET_STM32H7/TARGET_PORTENTA_H7/stm32h7_eth_init.c index 643fc5acd36..7f5b4206cb5 100644 --- a/connectivity/drivers/emac/TARGET_STM/TARGET_STM32H7/TARGET_PORTENTA_H7/stm32h7_eth_init.c +++ b/connectivity/drivers/emac/TARGET_STM/TARGET_STM32H7/TARGET_PORTENTA_H7/stm32h7_eth_init.c @@ -68,6 +68,7 @@ void HAL_ETH_MspInit(ETH_HandleTypeDef *heth) #if !(defined(DUAL_CORE) && defined(CORE_CM4)) /* Disable DCache for STM32H7 family */ core_util_critical_section_enter(); + SCB_CleanInvalidateDCache(); SCB_DisableDCache(); core_util_critical_section_exit(); #endif From 7204508fa1740247a49654ed96c9f4b531a5f2c6 Mon Sep 17 00:00:00 2001 From: maidnl Date: Fri, 5 Jul 2024 15:28:29 +0200 Subject: [PATCH 4/5] fix that restart interface in case of error (DEBUG LOG TO BE REMOVED) --- .../drivers/emac/TARGET_STM/stm32xx_emac.cpp | 27 +++++++++++++++++++ .../drivers/emac/TARGET_STM/stm32xx_emac.h | 7 +++++ .../lwipstack/source/LWIPInterface.cpp | 4 --- .../lwipstack/source/LWIPInterfaceEMAC.cpp | 17 ++++++++++-- .../netsocket/include/netsocket/EMAC.h | 4 +++ .../STM32H7xx_HAL_Driver/stm32h7xx_hal_eth.c | 4 +++ .../STM32H7xx_HAL_Driver/stm32h7xx_hal_eth.h | 1 + 7 files changed, 58 insertions(+), 6 deletions(-) diff --git a/connectivity/drivers/emac/TARGET_STM/stm32xx_emac.cpp b/connectivity/drivers/emac/TARGET_STM/stm32xx_emac.cpp index 0230a90665c..ce62b91294f 100644 --- a/connectivity/drivers/emac/TARGET_STM/stm32xx_emac.cpp +++ b/connectivity/drivers/emac/TARGET_STM/stm32xx_emac.cpp @@ -402,6 +402,33 @@ bool STM32_EMAC::low_level_init_successful() } #endif // ETH_IP_VERSION_V2 +/** + * This function get the state of emac interface + */ +int STM32_EMAC::get_interface_status() { + return HAL_ETH_GetStateOnly(&EthHandle); +} + +/** + * This function returns true if the status of the interface is in the + * correct state for the trasmission + */ +bool STM32_EMAC::is_ready_to_tx() { + return (HAL_ETH_GetStateOnly(&EthHandle) == HAL_ETH_STATE_READY); +} + +/** + * This function reset the emac interface in case the status is in error + * Apparently there was not anything to recover from an error state + */ +void STM32_EMAC::restart() { + if(HAL_ETH_STATE_ERROR == HAL_ETH_GetStateOnly(&EthHandle)){ + HAL_ETH_Stop(&EthHandle); + HAL_ETH_Start(&EthHandle); + } +} + + /** * This function should do the actual transmission of the packet. The packet is * contained in the memory buffer chain that is passed to the function. diff --git a/connectivity/drivers/emac/TARGET_STM/stm32xx_emac.h b/connectivity/drivers/emac/TARGET_STM/stm32xx_emac.h index cfa67521774..ecc280b2f84 100644 --- a/connectivity/drivers/emac/TARGET_STM/stm32xx_emac.h +++ b/connectivity/drivers/emac/TARGET_STM/stm32xx_emac.h @@ -148,6 +148,13 @@ class STM32_EMAC : public EMAC { */ virtual void set_memory_manager(EMACMemoryManager &mem_mngr); + /* return the status of the interface as integer */ + int get_interface_status() override; + /* return true if the interface is in the correct state to transmit */ + bool is_ready_to_tx() override; + /* restart only if the interface is in error state */ + void restart() override; + // Called from driver functions ETH_HandleTypeDef EthHandle; osThreadId_t thread; /**< Processing thread */ diff --git a/connectivity/lwipstack/source/LWIPInterface.cpp b/connectivity/lwipstack/source/LWIPInterface.cpp index 4cc6d303e07..dfefebcb8bd 100644 --- a/connectivity/lwipstack/source/LWIPInterface.cpp +++ b/connectivity/lwipstack/source/LWIPInterface.cpp @@ -175,7 +175,6 @@ nsapi_error_t LWIP::Interface::set_dhcp() } err_t err = dhcp_start(&netif); - dhcp_has_to_be_set = false; if (err) { connected = NSAPI_STATUS_DISCONNECTED; if (client_callback) { @@ -204,9 +203,6 @@ void LWIP::Interface::netif_link_irq(struct netif *netif) netif_set_down(&interface->netif); } } else { - if(interface->dhcp_started) { - interface->dhcp_has_to_be_set = true; - } osSemaphoreRelease(interface->unlinked); if (netif_is_up(&interface->netif)) { interface->connected = NSAPI_STATUS_CONNECTING; diff --git a/connectivity/lwipstack/source/LWIPInterfaceEMAC.cpp b/connectivity/lwipstack/source/LWIPInterfaceEMAC.cpp index 56fbcc0d904..e372fe2b379 100644 --- a/connectivity/lwipstack/source/LWIPInterfaceEMAC.cpp +++ b/connectivity/lwipstack/source/LWIPInterfaceEMAC.cpp @@ -27,15 +27,28 @@ #if LWIP_ETHERNET +extern "C" void log_add(const char *fmt, ...); + err_t LWIP::Interface::emac_low_level_output(struct netif *netif, struct pbuf *p) { + bool ret = false; /* Increase reference counter since lwip stores handle to pbuf and frees it after output */ pbuf_ref(p); LWIP::Interface *mbed_if = static_cast(netif->state); - bool ret = mbed_if->emac->link_out(p); - return ret ? ERR_OK : ERR_IF; + + if(mbed_if->emac->is_ready_to_tx()) { + ret = mbed_if->emac->link_out(p); + } + else { + log_add("!!!! emac is NOT OK ---> RESTART!!!"); + mbed_if->emac->restart(); + ret = mbed_if->emac->link_out(p); + } + + err_t rv = ret ? ERR_OK : ERR_IF; + return rv; } void LWIP::Interface::emac_input(emac_mem_buf_t *buf) diff --git a/connectivity/netsocket/include/netsocket/EMAC.h b/connectivity/netsocket/include/netsocket/EMAC.h index 515629b5a61..bbbc42f4a73 100644 --- a/connectivity/netsocket/include/netsocket/EMAC.h +++ b/connectivity/netsocket/include/netsocket/EMAC.h @@ -176,6 +176,10 @@ class EMAC { * @param mem_mngr Pointer to memory manager */ virtual void set_memory_manager(EMACMemoryManager &mem_mngr) = 0; + + virtual bool is_ready_to_tx() { return false;} + virtual void restart() {} + virtual int get_interface_status() { return -1; } }; diff --git a/targets/TARGET_STM/TARGET_STM32H7/STM32Cube_FW/STM32H7xx_HAL_Driver/stm32h7xx_hal_eth.c b/targets/TARGET_STM/TARGET_STM32H7/STM32Cube_FW/STM32H7xx_HAL_Driver/stm32h7xx_hal_eth.c index decff79455a..ec45d0e6af9 100644 --- a/targets/TARGET_STM/TARGET_STM32H7/STM32Cube_FW/STM32H7xx_HAL_Driver/stm32h7xx_hal_eth.c +++ b/targets/TARGET_STM/TARGET_STM32H7/STM32Cube_FW/STM32H7xx_HAL_Driver/stm32h7xx_hal_eth.c @@ -2333,6 +2333,10 @@ HAL_StatusTypeDef HAL_ETH_SetWakeUpFilter(ETH_HandleTypeDef *heth, uint32_t *pFi * @{ */ +HAL_ETH_StateTypeDef HAL_ETH_GetStateOnly(ETH_HandleTypeDef *heth) { + return heth->gState; +} + /** * @brief Returns the ETH state. * @param heth: pointer to a ETH_HandleTypeDef structure that contains diff --git a/targets/TARGET_STM/TARGET_STM32H7/STM32Cube_FW/STM32H7xx_HAL_Driver/stm32h7xx_hal_eth.h b/targets/TARGET_STM/TARGET_STM32H7/STM32Cube_FW/STM32H7xx_HAL_Driver/stm32h7xx_hal_eth.h index 354ce3f5f8b..33310f6b5b9 100644 --- a/targets/TARGET_STM/TARGET_STM32H7/STM32Cube_FW/STM32H7xx_HAL_Driver/stm32h7xx_hal_eth.h +++ b/targets/TARGET_STM/TARGET_STM32H7/STM32Cube_FW/STM32H7xx_HAL_Driver/stm32h7xx_hal_eth.h @@ -1654,6 +1654,7 @@ HAL_StatusTypeDef HAL_ETH_SetWakeUpFilter(ETH_HandleTypeDef *heth, uint32_t *pFi */ /* Peripheral State functions **************************************************/ HAL_ETH_StateTypeDef HAL_ETH_GetState(ETH_HandleTypeDef *heth); +HAL_ETH_StateTypeDef HAL_ETH_GetStateOnly(ETH_HandleTypeDef *heth); uint32_t HAL_ETH_GetError(ETH_HandleTypeDef *heth); uint32_t HAL_ETH_GetDMAError(ETH_HandleTypeDef *heth); uint32_t HAL_ETH_GetMACError(ETH_HandleTypeDef *heth); From 2610b54aeb83863863082937f2c22e0cb741ff08 Mon Sep 17 00:00:00 2001 From: maidnl Date: Mon, 8 Jul 2024 10:44:06 +0200 Subject: [PATCH 5/5] removed test logs --- connectivity/lwipstack/source/LWIPInterfaceEMAC.cpp | 2 -- connectivity/netsocket/include/netsocket/EMAC.h | 13 ++++++++++--- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/connectivity/lwipstack/source/LWIPInterfaceEMAC.cpp b/connectivity/lwipstack/source/LWIPInterfaceEMAC.cpp index e372fe2b379..ed4397879ef 100644 --- a/connectivity/lwipstack/source/LWIPInterfaceEMAC.cpp +++ b/connectivity/lwipstack/source/LWIPInterfaceEMAC.cpp @@ -27,7 +27,6 @@ #if LWIP_ETHERNET -extern "C" void log_add(const char *fmt, ...); err_t LWIP::Interface::emac_low_level_output(struct netif *netif, struct pbuf *p) { @@ -42,7 +41,6 @@ err_t LWIP::Interface::emac_low_level_output(struct netif *netif, struct pbuf *p ret = mbed_if->emac->link_out(p); } else { - log_add("!!!! emac is NOT OK ---> RESTART!!!"); mbed_if->emac->restart(); ret = mbed_if->emac->link_out(p); } diff --git a/connectivity/netsocket/include/netsocket/EMAC.h b/connectivity/netsocket/include/netsocket/EMAC.h index bbbc42f4a73..29b9cdd1871 100644 --- a/connectivity/netsocket/include/netsocket/EMAC.h +++ b/connectivity/netsocket/include/netsocket/EMAC.h @@ -177,9 +177,16 @@ class EMAC { */ virtual void set_memory_manager(EMACMemoryManager &mem_mngr) = 0; - virtual bool is_ready_to_tx() { return false;} - virtual void restart() {} - virtual int get_interface_status() { return -1; } + virtual bool is_ready_to_tx() { + return false; + } + + virtual void restart() { + } + + virtual int get_interface_status() { + return -1; + } };