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 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 a1cfcf31c41..dfefebcb8bd 100644 --- a/connectivity/lwipstack/source/LWIPInterface.cpp +++ b/connectivity/lwipstack/source/LWIPInterface.cpp @@ -169,8 +169,12 @@ 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) { connected = NSAPI_STATUS_DISCONNECTED; if (client_callback) { diff --git a/connectivity/lwipstack/source/LWIPInterfaceEMAC.cpp b/connectivity/lwipstack/source/LWIPInterfaceEMAC.cpp index 56fbcc0d904..ed4397879ef 100644 --- a/connectivity/lwipstack/source/LWIPInterfaceEMAC.cpp +++ b/connectivity/lwipstack/source/LWIPInterfaceEMAC.cpp @@ -27,15 +27,26 @@ #if LWIP_ETHERNET + 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 { + 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..29b9cdd1871 100644 --- a/connectivity/netsocket/include/netsocket/EMAC.h +++ b/connectivity/netsocket/include/netsocket/EMAC.h @@ -176,6 +176,17 @@ 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);