@@ -116,6 +116,120 @@ static inline uint16_t allocate_tx_buffer(void)
116116 }
117117}
118118
119+ #if defined(CONFIG_ETH_STM32_HAL_TX_ASYNC )
120+ /* allocate a tx context and mark it as used, the first tx buffer is also allocated */
121+ static struct eth_stm32_tx_context * allocate_tx_context_async (struct net_pkt * pkt )
122+ {
123+ int tx_index ;
124+
125+ for (uint16_t index = 0 ; index < ETH_TX_DESC_CNT ; index ++ ) {
126+ if (!dma_tx_context [index ].used ) {
127+ dma_tx_context [index ].used = true;
128+ dma_tx_context [index ].pkt = pkt ;
129+ tx_index = allocate_tx_buffer ();
130+ if (tx_index < 0 ) {
131+ return NULL ;
132+ }
133+ dma_tx_context [index ].first_tx_buffer_index = tx_index ;
134+ return & dma_tx_context [index ];
135+ }
136+ }
137+ return NULL ;
138+ }
139+
140+ int eth_stm32_tx (const struct device * dev , struct net_pkt * pkt )
141+ {
142+ struct eth_stm32_hal_dev_data * dev_data = dev -> data ;
143+ ETH_HandleTypeDef * heth = & dev_data -> heth ;
144+ int res = 0 ;
145+ size_t total_len ;
146+ size_t remaining_read ;
147+ struct eth_stm32_tx_context * ctx = NULL ;
148+ struct eth_stm32_tx_buffer_header * buf_header = NULL ;
149+ HAL_StatusTypeDef hal_ret = HAL_OK ;
150+
151+ #if defined(CONFIG_PTP_CLOCK_STM32_HAL )
152+ bool timestamped_frame ;
153+ #endif /* CONFIG_PTP_CLOCK_STM32_HAL */
154+
155+ __ASSERT_NO_MSG (pkt != NULL );
156+ __ASSERT_NO_MSG (pkt -> frags != NULL );
157+
158+ total_len = net_pkt_get_len (pkt );
159+ if (total_len > (ETH_STM32_TX_BUF_SIZE * ETH_TXBUFNB )) {
160+ LOG_ERR ("PKT too big" );
161+ return - EIO ;
162+ }
163+
164+ k_mutex_lock (& dev_data -> tx_mutex , K_FOREVER );
165+
166+ while (ctx == NULL ) {
167+ ctx = allocate_tx_context_async (pkt );
168+ if (ctx == NULL ) {
169+ k_sem_take (& dev_data -> tx_int_sem , K_MSEC (ETH_DMA_TX_TIMEOUT_MS ));
170+ hal_ret = HAL_ETH_ReleaseTxPacket (heth );
171+ __ASSERT_NO_MSG (hal_ret == HAL_OK );
172+ }
173+ }
174+ buf_header = & dma_tx_buffer_header [ctx -> first_tx_buffer_index ];
175+
176+ #if defined(CONFIG_PTP_CLOCK_STM32_HAL )
177+ timestamped_frame = eth_stm32_is_ptp_pkt (net_pkt_iface (pkt ), pkt ) ||
178+ net_pkt_is_tx_timestamping (pkt );
179+ if (timestamped_frame ) {
180+ /* Enable transmit timestamp */
181+ if (HAL_ETH_PTP_InsertTxTimestamp (heth ) != HAL_OK ) {
182+ res = - EIO ;
183+ goto error ;
184+ }
185+ }
186+ #endif /* CONFIG_PTP_CLOCK_STM32_HAL */
187+
188+ remaining_read = total_len ;
189+ /* fill and allocate buffer until remaining data fits in one buffer */
190+ while (remaining_read > ETH_STM32_TX_BUF_SIZE ) {
191+ res = net_pkt_read (pkt , buf_header -> tx_buff .buffer , ETH_STM32_TX_BUF_SIZE );
192+ if (res < 0 ) {
193+ goto error ;
194+ }
195+
196+ const uint16_t next_buffer_id = allocate_tx_buffer ();
197+
198+ buf_header -> tx_buff .len = ETH_STM32_TX_BUF_SIZE ;
199+ /* append new buffer to the linked list */
200+ buf_header -> tx_buff .next = & dma_tx_buffer_header [next_buffer_id ].tx_buff ;
201+ /* and adjust tail pointer */
202+ buf_header = & dma_tx_buffer_header [next_buffer_id ];
203+ remaining_read -= ETH_STM32_TX_BUF_SIZE ;
204+ }
205+ res = net_pkt_read (pkt , buf_header -> tx_buff .buffer , remaining_read );
206+ if (res < 0 ) {
207+ goto error ;
208+ }
209+ buf_header -> tx_buff .len = remaining_read ;
210+ buf_header -> tx_buff .next = NULL ;
211+
212+ tx_config .Length = total_len ;
213+ tx_config .pData = ctx ;
214+ tx_config .TxBuffer = & dma_tx_buffer_header [ctx -> first_tx_buffer_index ].tx_buff ;
215+
216+ if (HAL_ETH_Transmit_IT (heth , & tx_config ) != HAL_OK ) {
217+ LOG_ERR ("HAL_ETH_Transmit: failed!" );
218+ res = - EIO ;
219+ }
220+
221+ error :
222+ if (res < 0 && ctx ) {
223+ /* We need to release the tx context and its buffers */
224+ HAL_ETH_TxFreeCallback ((uint32_t * )ctx );
225+ }
226+
227+ k_mutex_unlock (& dev_data -> tx_mutex );
228+
229+ return res ;
230+ }
231+ #else
232+
119233/* allocate a tx context and mark it as used, the first tx buffer is also allocated */
120234static inline struct eth_stm32_tx_context * allocate_tx_context (struct net_pkt * pkt )
121235{
@@ -132,28 +246,6 @@ static inline struct eth_stm32_tx_context *allocate_tx_context(struct net_pkt *p
132246 }
133247}
134248
135- void eth_stm32_setup_mac_filter (ETH_HandleTypeDef * heth )
136- {
137- ETH_MACFilterConfigTypeDef MACFilterConf ;
138- HAL_StatusTypeDef __maybe_unused hal_ret ;
139-
140- __ASSERT_NO_MSG (heth != NULL );
141-
142- hal_ret = HAL_ETH_GetMACFilterConfig (heth , & MACFilterConf );
143- __ASSERT_NO_MSG (hal_ret == HAL_OK );
144-
145- MACFilterConf .HashMulticast =
146- IS_ENABLED (CONFIG_ETH_STM32_MULTICAST_FILTER ) ? ENABLE : DISABLE ;
147- MACFilterConf .PassAllMulticast =
148- IS_ENABLED (CONFIG_ETH_STM32_MULTICAST_FILTER ) ? DISABLE : ENABLE ;
149- MACFilterConf .HachOrPerfectFilter = DISABLE ;
150-
151- hal_ret = HAL_ETH_SetMACFilterConfig (heth , & MACFilterConf );
152- __ASSERT_NO_MSG (hal_ret == HAL_OK );
153-
154- k_sleep (K_MSEC (1 ));
155- }
156-
157249int eth_stm32_tx (const struct device * dev , struct net_pkt * pkt )
158250{
159251 struct eth_stm32_hal_dev_data * dev_data = dev -> data ;
@@ -294,6 +386,7 @@ int eth_stm32_tx(const struct device *dev, struct net_pkt *pkt)
294386
295387 return res ;
296388}
389+ #endif /* ETH_STM32_HAL_TX_ASYNC */
297390
298391struct net_pkt * eth_stm32_rx (const struct device * dev )
299392{
@@ -559,6 +652,28 @@ void eth_stm32_set_mac_config(const struct device *dev, struct phy_link_state *s
559652 }
560653}
561654
655+ void eth_stm32_setup_mac_filter (ETH_HandleTypeDef * heth )
656+ {
657+ ETH_MACFilterConfigTypeDef MACFilterConf ;
658+ HAL_StatusTypeDef __maybe_unused hal_ret ;
659+
660+ __ASSERT_NO_MSG (heth != NULL );
661+
662+ hal_ret = HAL_ETH_GetMACFilterConfig (heth , & MACFilterConf );
663+ __ASSERT_NO_MSG (hal_ret == HAL_OK );
664+
665+ MACFilterConf .HashMulticast =
666+ IS_ENABLED (CONFIG_ETH_STM32_MULTICAST_FILTER ) ? ENABLE : DISABLE ;
667+ MACFilterConf .PassAllMulticast =
668+ IS_ENABLED (CONFIG_ETH_STM32_MULTICAST_FILTER ) ? DISABLE : ENABLE ;
669+ MACFilterConf .HachOrPerfectFilter = DISABLE ;
670+
671+ hal_ret = HAL_ETH_SetMACFilterConfig (heth , & MACFilterConf );
672+ __ASSERT_NO_MSG (hal_ret == HAL_OK );
673+
674+ k_sleep (K_MSEC (1 ));
675+ }
676+
562677int eth_stm32_hal_start (const struct device * dev )
563678{
564679 struct eth_stm32_hal_dev_data * dev_data = dev -> data ;
0 commit comments