|
| 1 | +From e0cad5c4277b3c5ee9cb01a9529df9333612bbeb Mon Sep 17 00:00:00 2001 |
| 2 | + |
| 3 | +Date: Mon, 8 Jul 2024 12:08:48 +0200 |
| 4 | +Subject: [PATCH 234/234] emac: stm32: check inteface status before link_out() |
| 5 | + |
| 6 | +This allows handling of HAL_ETH_STATE_ERROR, usually on interface teardown/up with strict timings |
| 7 | +--- |
| 8 | + .../drivers/emac/TARGET_STM/stm32xx_emac.cpp | 27 +++++++++++++++++++ |
| 9 | + .../drivers/emac/TARGET_STM/stm32xx_emac.h | 7 +++++ |
| 10 | + .../lwipstack/source/LWIPInterfaceEMAC.cpp | 15 +++++++++-- |
| 11 | + .../netsocket/include/netsocket/EMAC.h | 11 ++++++++ |
| 12 | + .../STM32H7xx_HAL_Driver/stm32h7xx_hal_eth.c | 8 +----- |
| 13 | + 5 files changed, 59 insertions(+), 9 deletions(-) |
| 14 | + |
| 15 | +diff --git a/connectivity/drivers/emac/TARGET_STM/stm32xx_emac.cpp b/connectivity/drivers/emac/TARGET_STM/stm32xx_emac.cpp |
| 16 | +index 0230a90665..0e7d64ad34 100644 |
| 17 | +--- a/connectivity/drivers/emac/TARGET_STM/stm32xx_emac.cpp |
| 18 | ++++ b/connectivity/drivers/emac/TARGET_STM/stm32xx_emac.cpp |
| 19 | +@@ -402,6 +402,33 @@ bool STM32_EMAC::low_level_init_successful() |
| 20 | + } |
| 21 | + #endif // ETH_IP_VERSION_V2 |
| 22 | + |
| 23 | ++/** |
| 24 | ++ * This function get the state of emac interface |
| 25 | ++ */ |
| 26 | ++int STM32_EMAC::get_interface_status() { |
| 27 | ++ return HAL_ETH_GetState(&EthHandle); |
| 28 | ++} |
| 29 | ++ |
| 30 | ++/** |
| 31 | ++ * This function returns true if the status of the interface is in the |
| 32 | ++ * correct state for the trasmission |
| 33 | ++ */ |
| 34 | ++bool STM32_EMAC::is_ready_to_tx() { |
| 35 | ++ return (HAL_ETH_GetState(&EthHandle) == HAL_ETH_STATE_READY); |
| 36 | ++} |
| 37 | ++ |
| 38 | ++/** |
| 39 | ++ * This function reset the emac interface in case the status is in error |
| 40 | ++ * Apparently there was not anything to recover from an error state |
| 41 | ++ */ |
| 42 | ++void STM32_EMAC::restart() { |
| 43 | ++ if(HAL_ETH_STATE_ERROR == HAL_ETH_GetState(&EthHandle)){ |
| 44 | ++ HAL_ETH_Stop(&EthHandle); |
| 45 | ++ HAL_ETH_Start(&EthHandle); |
| 46 | ++ } |
| 47 | ++} |
| 48 | ++ |
| 49 | ++ |
| 50 | + /** |
| 51 | + * This function should do the actual transmission of the packet. The packet is |
| 52 | + * contained in the memory buffer chain that is passed to the function. |
| 53 | +diff --git a/connectivity/drivers/emac/TARGET_STM/stm32xx_emac.h b/connectivity/drivers/emac/TARGET_STM/stm32xx_emac.h |
| 54 | +index cfa6752177..ecc280b2f8 100644 |
| 55 | +--- a/connectivity/drivers/emac/TARGET_STM/stm32xx_emac.h |
| 56 | ++++ b/connectivity/drivers/emac/TARGET_STM/stm32xx_emac.h |
| 57 | +@@ -148,6 +148,13 @@ public: |
| 58 | + */ |
| 59 | + virtual void set_memory_manager(EMACMemoryManager &mem_mngr); |
| 60 | + |
| 61 | ++ /* return the status of the interface as integer */ |
| 62 | ++ int get_interface_status() override; |
| 63 | ++ /* return true if the interface is in the correct state to transmit */ |
| 64 | ++ bool is_ready_to_tx() override; |
| 65 | ++ /* restart only if the interface is in error state */ |
| 66 | ++ void restart() override; |
| 67 | ++ |
| 68 | + // Called from driver functions |
| 69 | + ETH_HandleTypeDef EthHandle; |
| 70 | + osThreadId_t thread; /**< Processing thread */ |
| 71 | +diff --git a/connectivity/lwipstack/source/LWIPInterfaceEMAC.cpp b/connectivity/lwipstack/source/LWIPInterfaceEMAC.cpp |
| 72 | +index 56fbcc0d90..ed4397879e 100644 |
| 73 | +--- a/connectivity/lwipstack/source/LWIPInterfaceEMAC.cpp |
| 74 | ++++ b/connectivity/lwipstack/source/LWIPInterfaceEMAC.cpp |
| 75 | +@@ -27,15 +27,26 @@ |
| 76 | + |
| 77 | + #if LWIP_ETHERNET |
| 78 | + |
| 79 | ++ |
| 80 | + err_t LWIP::Interface::emac_low_level_output(struct netif *netif, struct pbuf *p) |
| 81 | + { |
| 82 | ++ bool ret = false; |
| 83 | + /* Increase reference counter since lwip stores handle to pbuf and frees |
| 84 | + it after output */ |
| 85 | + pbuf_ref(p); |
| 86 | + |
| 87 | + LWIP::Interface *mbed_if = static_cast<LWIP::Interface *>(netif->state); |
| 88 | +- bool ret = mbed_if->emac->link_out(p); |
| 89 | +- return ret ? ERR_OK : ERR_IF; |
| 90 | ++ |
| 91 | ++ if(mbed_if->emac->is_ready_to_tx()) { |
| 92 | ++ ret = mbed_if->emac->link_out(p); |
| 93 | ++ } |
| 94 | ++ else { |
| 95 | ++ mbed_if->emac->restart(); |
| 96 | ++ ret = mbed_if->emac->link_out(p); |
| 97 | ++ } |
| 98 | ++ |
| 99 | ++ err_t rv = ret ? ERR_OK : ERR_IF; |
| 100 | ++ return rv; |
| 101 | + } |
| 102 | + |
| 103 | + void LWIP::Interface::emac_input(emac_mem_buf_t *buf) |
| 104 | +diff --git a/connectivity/netsocket/include/netsocket/EMAC.h b/connectivity/netsocket/include/netsocket/EMAC.h |
| 105 | +index 515629b5a6..885bc92c01 100644 |
| 106 | +--- a/connectivity/netsocket/include/netsocket/EMAC.h |
| 107 | ++++ b/connectivity/netsocket/include/netsocket/EMAC.h |
| 108 | +@@ -176,6 +176,17 @@ public: |
| 109 | + * @param mem_mngr Pointer to memory manager |
| 110 | + */ |
| 111 | + virtual void set_memory_manager(EMACMemoryManager &mem_mngr) = 0; |
| 112 | ++ |
| 113 | ++ virtual bool is_ready_to_tx() { |
| 114 | ++ return true; |
| 115 | ++ } |
| 116 | ++ |
| 117 | ++ virtual void restart() { |
| 118 | ++ } |
| 119 | ++ |
| 120 | ++ virtual int get_interface_status() { |
| 121 | ++ return -1; |
| 122 | ++ } |
| 123 | + }; |
| 124 | + |
| 125 | + |
| 126 | +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 |
| 127 | +index decff79455..df797092fc 100644 |
| 128 | +--- a/targets/TARGET_STM/TARGET_STM32H7/STM32Cube_FW/STM32H7xx_HAL_Driver/stm32h7xx_hal_eth.c |
| 129 | ++++ b/targets/TARGET_STM/TARGET_STM32H7/STM32Cube_FW/STM32H7xx_HAL_Driver/stm32h7xx_hal_eth.c |
| 130 | +@@ -2341,13 +2341,7 @@ HAL_StatusTypeDef HAL_ETH_SetWakeUpFilter(ETH_HandleTypeDef *heth, uint32_t *pFi |
| 131 | + */ |
| 132 | + HAL_ETH_StateTypeDef HAL_ETH_GetState(ETH_HandleTypeDef *heth) |
| 133 | + { |
| 134 | +- HAL_ETH_StateTypeDef ret; |
| 135 | +- HAL_ETH_StateTypeDef gstate = heth->gState; |
| 136 | +- HAL_ETH_StateTypeDef rxstate =heth->RxState; |
| 137 | +- |
| 138 | +- ret = gstate; |
| 139 | +- ret |= rxstate; |
| 140 | +- return ret; |
| 141 | ++ return heth->gState; |
| 142 | + } |
| 143 | + |
| 144 | + /** |
| 145 | +-- |
| 146 | +2.45.2 |
| 147 | + |
0 commit comments