1 /**
2   ******************************************************************************
3   * @file    stm32n6xx_hal_eth.c
4   * @author  MCD Application Team
5   * @brief   ETH HAL module driver.
6   *          This file provides firmware functions to manage the following
7   *          functionalities of the Ethernet (ETH) peripheral:
8   *           + Initialization and deinitialization functions
9   *           + IO operation functions
10   *           + Peripheral Control functions
11   *           + Peripheral State and Errors functions
12   *
13   ******************************************************************************
14   * @attention
15   *
16   * Copyright (c) 2023 STMicroelectronics.
17   * All rights reserved.
18   *
19   * This software is licensed under terms that can be found in the LICENSE file
20   * in the root directory of this software component.
21   * If no LICENSE file comes with this software, it is provided AS-IS.
22   *
23   ******************************************************************************
24   @verbatim
25   ==============================================================================
26                     ##### How to use this driver #####
27   ==============================================================================
28      [..]
29      The ETH HAL driver can be used as follows:
30 
31       (#)Declare a ETH_HandleTypeDef handle structure, for example:
32          ETH_HandleTypeDef  heth;
33 
34       (#)Fill parameters of Init structure in heth handle
35 
36       (#)Call HAL_ETH_Init() API to initialize the Ethernet peripheral (MAC, DMA, ...)
37 
38       (#)Initialize the ETH low level resources through the HAL_ETH_MspInit() API:
39           (##) Enable the Ethernet interface clock using
40                 (+++)  __HAL_RCC_ETH1MAC_CLK_ENABLE()
41                 (+++)  __HAL_RCC_ETH1TX_CLK_ENABLE()
42                 (+++)  __HAL_RCC_ETH1RX_CLK_ENABLE()
43 
44           (##) Initialize the related GPIO clocks
45           (##) Configure Ethernet pinout
46           (##) Configure Ethernet NVIC interrupt (in Interrupt mode)
47 
48       (#) Ethernet data reception is asynchronous, so call the following API
49           to start the listening mode:
50           (##) HAL_ETH_Start():
51                This API starts the MAC and DMA transmission and reception process,
52                without enabling end of transfer interrupts, in this mode user
53                has to poll for data reception by calling HAL_ETH_ReadData()
54           (##) HAL_ETH_Start_IT():
55                This API starts the MAC and DMA transmission and reception process,
56                end of transfer interrupts are enabled in this mode,
57                HAL_ETH_RxCpltCallback() will be executed when an Ethernet packet is received
58 
59       (#) When data is received user can call the following API to get received data:
60           (##) HAL_ETH_ReadData(): Read a received packet
61 
62       (#) For transmission path, two APIs are available:
63          (##) HAL_ETH_Transmit(): Transmit an ETH frame in blocking mode
64          (##) HAL_ETH_Transmit_IT(): Transmit an ETH frame in interrupt mode,
65               HAL_ETH_TxCpltCallback() will be executed when end of transfer occur
66 
67       (#) Communication with an external PHY device:
68          (##) HAL_ETH_ReadPHYRegister(): Read a register from an external PHY
69          (##) HAL_ETH_WritePHYRegister(): Write data to an external RHY register
70 
71       (#) Configure the Ethernet MAC after ETH peripheral initialization
72           (##) HAL_ETH_GetMACConfig(): Get MAC actual configuration into ETH_MACConfigTypeDef
73           (##) HAL_ETH_SetMACConfig(): Set MAC configuration based on ETH_MACConfigTypeDef
74 
75       (#) Configure the Ethernet DMA after ETH peripheral initialization
76           (##) HAL_ETH_GetDMAConfig(): Get DMA actual configuration into ETH_DMAConfigTypeDef
77           (##) HAL_ETH_SetDMAConfig(): Set DMA configuration based on ETH_DMAConfigTypeDef
78 
79       (#) Configure the Ethernet PTP after ETH peripheral initialization
80           (##) Define HAL_ETH_USE_PTP to use PTP APIs.
81           (##) HAL_ETH_PTP_GetConfig(): Get PTP actual configuration into ETH_PTP_ConfigTypeDef
82           (##) HAL_ETH_PTP_SetConfig(): Set PTP configuration based on ETH_PTP_ConfigTypeDef
83           (##) HAL_ETH_PTP_GetTime(): Get Seconds and Nanoseconds for the Ethernet PTP registers
84           (##) HAL_ETH_PTP_SetTime(): Set Seconds and Nanoseconds for the Ethernet PTP registers
85           (##) HAL_ETH_PTP_AddTimeOffset(): Add Seconds and Nanoseconds offset for the Ethernet PTP registers
86           (##) HAL_ETH_PTP_InsertTxTimestamp(): Insert Timestamp in transmission
87           (##) HAL_ETH_PTP_GetTxTimestamp(): Get transmission timestamp
88           (##) HAL_ETH_PTP_GetRxTimestamp(): Get reception timestamp
89 
90       -@- The ARP offload feature is not supported in this driver.
91 
92       -@- The PTP offload feature is not supported in this driver.
93 
94   *** Callback registration ***
95   =============================================
96 
97   The compilation define  USE_HAL_ETH_REGISTER_CALLBACKS when set to 1
98   allows the user to configure dynamically the driver callbacks.
99   Use Function HAL_ETH_RegisterCallback() to register an interrupt callback.
100 
101   Function HAL_ETH_RegisterCallback() allows to register following callbacks:
102     (+) TxCpltCallback   : Tx Complete Callback.
103     (+) RxCpltCallback   : Rx Complete Callback.
104     (+) ErrorCallback    : Error Callback.
105     (+) PMTCallback      : Power Management Callback
106     (+) EEECallback      : EEE Callback.
107     (+) WakeUpCallback   : Wake UP Callback
108     (+) MspInitCallback  : MspInit Callback.
109     (+) MspDeInitCallback: MspDeInit Callback.
110 
111   This function takes as parameters the HAL peripheral handle, the Callback ID
112   and a pointer to the user callback function.
113 
114   For specific callbacks RxAllocateCallback use dedicated register callbacks:
115   respectively HAL_ETH_RegisterRxAllocateCallback().
116 
117   For specific callbacks RxLinkCallback use dedicated register callbacks:
118   respectively HAL_ETH_RegisterRxLinkCallback().
119 
120   For specific callbacks TxFreeCallback use dedicated register callbacks:
121   respectively HAL_ETH_RegisterTxFreeCallback().
122 
123   For specific callbacks TxPtpCallback use dedicated register callbacks:
124   respectively HAL_ETH_RegisterTxPtpCallback().
125 
126   Use function HAL_ETH_UnRegisterCallback() to reset a callback to the default
127   weak function.
128   HAL_ETH_UnRegisterCallback takes as parameters the HAL peripheral handle,
129   and the Callback ID.
130   This function allows to reset following callbacks:
131     (+) TxCpltCallback   : Tx Complete Callback.
132     (+) RxCpltCallback   : Rx Complete Callback.
133     (+) ErrorCallback    : Error Callback.
134     (+) PMTCallback      : Power Management Callback
135     (+) EEECallback      : EEE Callback.
136     (+) WakeUpCallback   : Wake UP Callback
137     (+) MspInitCallback  : MspInit Callback.
138     (+) MspDeInitCallback: MspDeInit Callback.
139 
140   For specific callbacks RxAllocateCallback use dedicated unregister callbacks:
141   respectively HAL_ETH_UnRegisterRxAllocateCallback().
142 
143   For specific callbacks RxLinkCallback use dedicated unregister callbacks:
144   respectively HAL_ETH_UnRegisterRxLinkCallback().
145 
146   For specific callbacks TxFreeCallback use dedicated unregister callbacks:
147   respectively HAL_ETH_UnRegisterTxFreeCallback().
148 
149   For specific callbacks TxPtpCallback use dedicated unregister callbacks:
150   respectively HAL_ETH_UnRegisterTxPtpCallback().
151 
152   By default, after the HAL_ETH_Init and when the state is HAL_ETH_STATE_RESET
153   all callbacks are set to the corresponding weak functions:
154   examples HAL_ETH_TxCpltCallback(), HAL_ETH_RxCpltCallback().
155   Exception done for MspInit and MspDeInit functions that are
156   reset to the legacy weak function in the HAL_ETH_Init/ HAL_ETH_DeInit only when
157   these callbacks are null (not registered beforehand).
158   if not, MspInit or MspDeInit are not null, the HAL_ETH_Init/ HAL_ETH_DeInit
159   keep and use the user MspInit/MspDeInit callbacks (registered beforehand)
160 
161   Callbacks can be registered/unregistered in HAL_ETH_STATE_READY state only.
162   Exception done MspInit/MspDeInit that can be registered/unregistered
163   in HAL_ETH_STATE_READY or HAL_ETH_STATE_RESET state,
164   thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit.
165   In that case first register the MspInit/MspDeInit user callbacks
166   using HAL_ETH_RegisterCallback() before calling HAL_ETH_DeInit
167   or HAL_ETH_Init function.
168 
169   When The compilation define USE_HAL_ETH_REGISTER_CALLBACKS is set to 0 or
170   not defined, the callback registration feature is not available and all callbacks
171   are set to the corresponding weak functions.
172 
173   @endverbatim
174   ******************************************************************************
175   */
176 
177 /* Includes ------------------------------------------------------------------*/
178 #include "stm32n6xx_hal.h"
179 
180 /** @addtogroup STM32N6xx_HAL_Driver
181   * @{
182   */
183 #ifdef HAL_ETH_MODULE_ENABLED
184 
185 #if defined(ETH1)
186 
187 /** @defgroup ETH ETH
188   * @brief ETH HAL module driver
189   * @{
190   */
191 
192 /* Private typedef -----------------------------------------------------------*/
193 /* Private define ------------------------------------------------------------*/
194 /** @addtogroup ETH_Private_Constants ETH Private Constants
195   * @{
196   */
197 #define ETH_MACCR_MASK                0xFFFBFF7CU
198 #define ETH_MACECR_MASK               0x7F073FFFU
199 #define ETH_MACPFR_MASK               0x803107FFU
200 #define ETH_MACWTR_MASK               0x0000010FU
201 #define ETH_MACQ0TXFCR_MASK           0xFFFF00F3U
202 #define ETH_MACRXFCR_MASK             0x00000003U
203 
204 #define ETH_MTLRXQDMAMR_MASK          0x00001111U
205 
206 #define ETH_MACVTDR_MASK              0x031FFFFFU
207 #define ETH_MACVTCR_MASK              0xBF7F000FU
208 
209 #define ETH_MACRXQCR_MASK             0x00030303U
210 #define ETH_MACRXQC0R_MASK            0x0000000FU
211 #define ETH_MACRXQC1R_MASK            0x37F77077U
212 
213 #define ETH_DMAMR_MASK                0x0003091DU
214 #define ETH_DMASBMR_MASK              0xC30334FFU
215 #define ETH_DMACxCR_MASK              0x001D3FFFU
216 #define ETH_MACPCSR_MASK              (ETH_MACPCSR_PWRDWN | ETH_MACPCSR_RWKPKTEN | \
217                                        ETH_MACPCSR_MGKPKTEN | ETH_MACPCSR_GLBLUCAST | \
218                                        ETH_MACPCSR_RWKPFE)
219 
220 /* Timeout values */
221 #define ETH_DMARXNDESCWBF_ERRORS_MASK ((uint32_t)(ETH_DMARXNDESCWBF_DE | ETH_DMARXNDESCWBF_RE | \
222                                                   ETH_DMARXNDESCWBF_OE | ETH_DMARXNDESCWBF_RWT |\
223                                                   ETH_DMARXNDESCWBF_GP | ETH_DMARXNDESCWBF_CE))
224 
225 #define ETH_MACTSCR_MASK              0x1107FF2FU
226 
227 #define ETH_MACSTSUR_VALUE            0xFFFFFFFFU
228 #define ETH_MACSTNUR_VALUE            0xBB9ACA00U
229 #define ETH_SEGMENT_SIZE_DEFAULT      0x218U
230 
231 /**
232   * @}
233   */
234 
235 /* Private macros ------------------------------------------------------------*/
236 /** @defgroup ETH_Private_Macros ETH Private Macros
237   * @{
238   */
239 /* Helper macros for TX descriptor handling */
240 #define INCR_TX_DESC_INDEX(inx, offset) do {\
241                                              (inx) += (offset);\
242                                              if ((inx) >= (uint32_t)ETH_TX_DESC_CNT){\
243                                              (inx) = ((inx) - (uint32_t)ETH_TX_DESC_CNT);}\
244                                            } while (0)
245 
246 /* Helper macros for RX descriptor handling */
247 #define INCR_RX_DESC_INDEX(inx, offset) do {\
248                                              (inx) += (offset);\
249                                              if ((inx) >= (uint32_t)ETH_RX_DESC_CNT){\
250                                              (inx) = ((inx) - (uint32_t)ETH_RX_DESC_CNT);}\
251                                            } while (0)
252 /**
253   * @}
254   */
255 /* Private function prototypes -----------------------------------------------*/
256 /** @defgroup ETH_Private_Functions   ETH Private Functions
257   * @{
258   */
259 static void ETH_SetMACConfig(ETH_HandleTypeDef *heth, const ETH_MACConfigTypeDef *macconf);
260 static void ETH_SetDMAConfig(ETH_HandleTypeDef *heth, const ETH_DMAConfigTypeDef *dmaconf);
261 static void ETH_MACDMAConfig(ETH_HandleTypeDef *heth);
262 static void ETH_DMATxDescListInit(ETH_HandleTypeDef *heth);
263 static void ETH_DMARxDescListInit(ETH_HandleTypeDef *heth);
264 static uint32_t ETH_Prepare_Tx_Descriptors(ETH_HandleTypeDef *heth, const ETH_TxPacketConfigTypeDef *pTxConfig,
265                                            uint32_t ItMode);
266 static void ETH_UpdateDescriptor(ETH_HandleTypeDef *heth);
267 
268 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
269 static void ETH_InitCallbacksToDefault(ETH_HandleTypeDef *heth);
270 #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */
271 /**
272   * @}
273   */
274 
275 /* Exported functions ---------------------------------------------------------*/
276 /** @defgroup ETH_Exported_Functions ETH Exported Functions
277   * @{
278   */
279 
280 /** @defgroup ETH_Exported_Functions_Group1 Initialization and deinitialization functions
281   *  @brief    Initialization and Configuration functions
282   *
283 @verbatim
284 ===============================================================================
285             ##### Initialization and Configuration functions #####
286  ===============================================================================
287     [..]  This subsection provides a set of functions allowing to initialize and
288           deinitialize the ETH peripheral:
289 
290       (+) User must Implement HAL_ETH_MspInit() function in which he configures
291           all related peripherals resources (CLOCK, GPIO and NVIC ).
292 
293       (+) Call the function HAL_ETH_Init() to configure the selected device with
294           the selected configuration:
295         (++) MAC address
296         (++) Media interface (MII or RMII)
297         (++) Rx DMA Descriptors Tab
298         (++) Tx DMA Descriptors Tab
299         (++) Length of Rx Buffers
300 
301       (+) Call the function HAL_ETH_DeInit() to restore the default configuration
302           of the selected ETH peripheral.
303 
304 @endverbatim
305   * @{
306   */
307 
308 /**
309   * @brief  Initialize the Ethernet peripheral registers.
310   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
311   *         the configuration information for ETHERNET module
312   * @retval HAL status
313   */
HAL_ETH_Init(ETH_HandleTypeDef * heth)314 HAL_StatusTypeDef HAL_ETH_Init(ETH_HandleTypeDef *heth)
315 {
316   uint32_t tickstart;
317   uint32_t ch;
318 
319   if (heth == NULL)
320   {
321     return HAL_ERROR;
322   }
323   if (heth->gState == HAL_ETH_STATE_RESET)
324   {
325     heth->gState = HAL_ETH_STATE_BUSY;
326 
327 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
328 
329     ETH_InitCallbacksToDefault(heth);
330 
331     if (heth->MspInitCallback == NULL)
332     {
333       heth->MspInitCallback = HAL_ETH_MspInit;
334     }
335 
336     /* Init the low level hardware */
337     heth->MspInitCallback(heth);
338 #else
339     /* Init the low level hardware : GPIO, CLOCK, NVIC. */
340     HAL_ETH_MspInit(heth);
341 
342 #endif /* (USE_HAL_ETH_REGISTER_CALLBACKS) */
343   }
344 
345   if (heth->Init.MediaInterface == HAL_ETH_MII_MODE)
346   {
347     SET_BIT(RCC->CCIPR2, RCC_ETH1PHYIF_MII);
348   }
349   else if (heth->Init.MediaInterface == HAL_ETH_RGMII_MODE)
350   {
351     SET_BIT(RCC->CCIPR2, RCC_ETH1PHYIF_RGMII);
352   }
353   else
354   {
355     SET_BIT(RCC->CCIPR2, RCC_ETH1PHYIF_RMII);
356   }
357 
358   /* Ethernet Software reset */
359   /* Set the SWR bit: resets all MAC subsystem internal registers and logic */
360   /* After reset all the registers holds their respective reset values */
361   SET_BIT(heth->Instance->DMAMR, ETH_DMAMR_SWR);
362 
363   /* Get tick */
364   tickstart = HAL_GetTick();
365 
366   /* Wait for software reset */
367   while (READ_BIT(heth->Instance->DMAMR, ETH_DMAMR_SWR) > 0U)
368   {
369     if (((HAL_GetTick() - tickstart) > ETH_SWRESET_TIMEOUT))
370     {
371       /* Set Error Code */
372       heth->ErrorCode = HAL_ETH_ERROR_TIMEOUT;
373       /* Set State as Error */
374       heth->gState = HAL_ETH_STATE_ERROR;
375       /* Return Error */
376       return HAL_ERROR;
377     }
378   }
379 
380   /*------------------ MDIO CSR Clock Range Configuration --------------------*/
381   HAL_ETH_SetMDIOClockRange(heth);
382 
383   /*------------------ MAC LPI 1US Tic Counter Configuration --------------------*/
384   WRITE_REG(heth->Instance->MAC1USTCR, (((uint32_t)HAL_RCC_GetHCLKFreq() / ETH_MAC_US_TICK) - 1U));
385 
386   /*------------------ MAC, MTL and DMA default Configuration ----------------*/
387   ETH_MACDMAConfig(heth);
388 
389   /*------------------ DMA Tx Descriptors Configuration ----------------------*/
390   ETH_DMATxDescListInit(heth);
391 
392   /*------------------ DMA Rx Descriptors Configuration ----------------------*/
393   ETH_DMARxDescListInit(heth);
394 
395   /* Set Receive Buffers Length (must be a multiple of 4) */
396   if ((heth->Init.RxBuffLen % 0x4U) != 0x0U)
397   {
398     /* Set Error Code */
399     heth->ErrorCode = HAL_ETH_ERROR_PARAM;
400     /* Set State as Error */
401     heth->gState = HAL_ETH_STATE_ERROR;
402     /* Return Error */
403     return HAL_ERROR;
404   }
405   else
406   {
407     for (ch = 0; ch < ETH_DMA_RX_CH_CNT; ch++)
408     {
409       MODIFY_REG(heth->Instance->DMA_CH[ch].DMACRXCR, ETH_DMACxRXCR_RBSZ, ((heth->Init.RxBuffLen) << 1));
410     }
411   }
412   /*--------------------- ETHERNET MAC Address Configuration ------------------*/
413   /* Set MAC addr bits 32 to 47 */
414   heth->Instance->MACA0HR = (((uint32_t)(heth->Init.MACAddr[5]) << 8) | (uint32_t)heth->Init.MACAddr[4]);
415   /* Set MAC addr bits 0 to 31 */
416   heth->Instance->MACA0LR = (((uint32_t)(heth->Init.MACAddr[3]) << 24) | ((uint32_t)(heth->Init.MACAddr[2]) << 16) |
417                              ((uint32_t)(heth->Init.MACAddr[1]) << 8) | (uint32_t)heth->Init.MACAddr[0]);
418 
419 
420   /* Disable Rx MMC Interrupts */
421   SET_BIT(heth->Instance->MMCRIMR, ETH_MMCRIMR_RXLPITRCIM | ETH_MMCRIMR_RXLPIUSCIM | \
422           ETH_MMCRIMR_RXUCGPIM | ETH_MMCRIMR_RXALGNERPIM | ETH_MMCRIMR_RXCRCERPIM);
423 
424   /* Disable Tx MMC Interrupts */
425   SET_BIT(heth->Instance->MMCTIMR, ETH_MMCTIMR_TXLPITRCIM | ETH_MMCTIMR_TXLPIUSCIM | \
426           ETH_MMCTIMR_TXGPKTIM | ETH_MMCTIMR_TXMCOLGPIM | ETH_MMCTIMR_TXSCOLGPIM);
427 
428   heth->ErrorCode = HAL_ETH_ERROR_NONE;
429   heth->gState = HAL_ETH_STATE_READY;
430 
431   return HAL_OK;
432 }
433 /**
434   * @brief  DeInitializes the ETH peripheral.
435   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
436   *         the configuration information for ETHERNET module
437   * @retval HAL status
438   */
HAL_ETH_DeInit(ETH_HandleTypeDef * heth)439 HAL_StatusTypeDef HAL_ETH_DeInit(ETH_HandleTypeDef *heth)
440 {
441   /* Set the ETH peripheral state to BUSY */
442   heth->gState = HAL_ETH_STATE_BUSY;
443 
444 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
445 
446   if (heth->MspDeInitCallback == NULL)
447   {
448     heth->MspDeInitCallback = HAL_ETH_MspDeInit;
449   }
450   /* DeInit the low level hardware */
451   heth->MspDeInitCallback(heth);
452 #else
453 
454   /* De-Init the low level hardware : GPIO, CLOCK, NVIC. */
455   HAL_ETH_MspDeInit(heth);
456 
457 #endif /* (USE_HAL_ETH_REGISTER_CALLBACKS) */
458 
459   /* Set ETH HAL state to Disabled */
460   heth->gState = HAL_ETH_STATE_RESET;
461 
462   /* Return function status */
463   return HAL_OK;
464 }
465 
466 /**
467   * @brief  Initializes the ETH MSP.
468   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
469   *         the configuration information for ETHERNET module
470   * @retval None
471   */
HAL_ETH_MspInit(ETH_HandleTypeDef * heth)472 __weak void HAL_ETH_MspInit(ETH_HandleTypeDef *heth)
473 {
474   /* Prevent unused argument(s) compilation warning */
475   UNUSED(heth);
476   /* NOTE : This function Should not be modified, when the callback is needed,
477   the HAL_ETH_MspInit could be implemented in the user file
478   */
479 }
480 
481 /**
482   * @brief  DeInitializes ETH MSP.
483   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
484   *         the configuration information for ETHERNET module
485   * @retval None
486   */
HAL_ETH_MspDeInit(ETH_HandleTypeDef * heth)487 __weak void HAL_ETH_MspDeInit(ETH_HandleTypeDef *heth)
488 {
489   /* Prevent unused argument(s) compilation warning */
490   UNUSED(heth);
491   /* NOTE : This function Should not be modified, when the callback is needed,
492   the HAL_ETH_MspDeInit could be implemented in the user file
493   */
494 }
495 
496 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
497 /**
498   * @brief  Register a User ETH Callback
499   *         To be used instead of the weak predefined callback
500   * @param heth eth handle
501   * @param CallbackID ID of the callback to be registered
502   *        This parameter can be one of the following values:
503   *          @arg @ref HAL_ETH_TX_COMPLETE_CB_ID Tx Complete Callback ID
504   *          @arg @ref HAL_ETH_RX_COMPLETE_CB_ID Rx Complete Callback ID
505   *          @arg @ref HAL_ETH_ERROR_CB_ID       Error Callback ID
506   *          @arg @ref HAL_ETH_PMT_CB_ID         Power Management Callback ID
507   *          @arg @ref HAL_ETH_EEE_CB_ID         EEE Callback ID
508   *          @arg @ref HAL_ETH_WAKEUP_CB_ID      Wake UP Callback ID
509   *          @arg @ref HAL_ETH_MSPINIT_CB_ID     MspInit callback ID
510   *          @arg @ref HAL_ETH_MSPDEINIT_CB_ID   MspDeInit callback ID
511   * @param pCallback pointer to the Callback function
512   * @retval status
513   */
HAL_ETH_RegisterCallback(ETH_HandleTypeDef * heth,HAL_ETH_CallbackIDTypeDef CallbackID,pETH_CallbackTypeDef pCallback)514 HAL_StatusTypeDef HAL_ETH_RegisterCallback(ETH_HandleTypeDef *heth, HAL_ETH_CallbackIDTypeDef CallbackID,
515                                            pETH_CallbackTypeDef pCallback)
516 {
517   HAL_StatusTypeDef status = HAL_OK;
518 
519   if (pCallback == NULL)
520   {
521     /* Update the error code */
522     heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK;
523     return HAL_ERROR;
524   }
525 
526   if (heth->gState == HAL_ETH_STATE_READY)
527   {
528     switch (CallbackID)
529     {
530       case HAL_ETH_TX_COMPLETE_CB_ID :
531         heth->TxCpltCallback = pCallback;
532         break;
533 
534       case HAL_ETH_RX_COMPLETE_CB_ID :
535         heth->RxCpltCallback = pCallback;
536         break;
537 
538       case HAL_ETH_ERROR_CB_ID :
539         heth->ErrorCallback = pCallback;
540         break;
541 
542       case HAL_ETH_PMT_CB_ID :
543         heth->PMTCallback = pCallback;
544         break;
545 
546       case HAL_ETH_EEE_CB_ID :
547         heth->EEECallback = pCallback;
548         break;
549 
550       case HAL_ETH_WAKEUP_CB_ID :
551         heth->WakeUpCallback = pCallback;
552         break;
553 
554       case HAL_ETH_MSPINIT_CB_ID :
555         heth->MspInitCallback = pCallback;
556         break;
557 
558       case HAL_ETH_MSPDEINIT_CB_ID :
559         heth->MspDeInitCallback = pCallback;
560         break;
561 
562       default :
563         /* Update the error code */
564         heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK;
565         /* Return error status */
566         status =  HAL_ERROR;
567         break;
568     }
569   }
570   else if (heth->gState == HAL_ETH_STATE_RESET)
571   {
572     switch (CallbackID)
573     {
574       case HAL_ETH_MSPINIT_CB_ID :
575         heth->MspInitCallback = pCallback;
576         break;
577 
578       case HAL_ETH_MSPDEINIT_CB_ID :
579         heth->MspDeInitCallback = pCallback;
580         break;
581 
582       default :
583         /* Update the error code */
584         heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK;
585         /* Return error status */
586         status =  HAL_ERROR;
587         break;
588     }
589   }
590   else
591   {
592     /* Update the error code */
593     heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK;
594     /* Return error status */
595     status =  HAL_ERROR;
596   }
597 
598   return status;
599 }
600 
601 /**
602   * @brief  Unregister an ETH Callback
603   *         ETH callback is redirected to the weak predefined callback
604   * @param heth eth handle
605   * @param CallbackID ID of the callback to be unregistered
606   *        This parameter can be one of the following values:
607   *          @arg @ref HAL_ETH_TX_COMPLETE_CB_ID Tx Complete Callback ID
608   *          @arg @ref HAL_ETH_RX_COMPLETE_CB_ID Rx Complete Callback ID
609   *          @arg @ref HAL_ETH_ERROR_CB_ID       Error Callback ID
610   *          @arg @ref HAL_ETH_PMT_CB_ID         Power Management Callback ID
611   *          @arg @ref HAL_ETH_EEE_CB_ID         EEE Callback ID
612   *          @arg @ref HAL_ETH_WAKEUP_CB_ID      Wake UP Callback ID
613   *          @arg @ref HAL_ETH_MSPINIT_CB_ID     MspInit callback ID
614   *          @arg @ref HAL_ETH_MSPDEINIT_CB_ID   MspDeInit callback ID
615   * @retval status
616   */
HAL_ETH_UnRegisterCallback(ETH_HandleTypeDef * heth,HAL_ETH_CallbackIDTypeDef CallbackID)617 HAL_StatusTypeDef HAL_ETH_UnRegisterCallback(ETH_HandleTypeDef *heth, HAL_ETH_CallbackIDTypeDef CallbackID)
618 {
619   HAL_StatusTypeDef status = HAL_OK;
620 
621   if (heth->gState == HAL_ETH_STATE_READY)
622   {
623     switch (CallbackID)
624     {
625       case HAL_ETH_TX_COMPLETE_CB_ID :
626         heth->TxCpltCallback = HAL_ETH_TxCpltCallback;
627         break;
628 
629       case HAL_ETH_RX_COMPLETE_CB_ID :
630         heth->RxCpltCallback = HAL_ETH_RxCpltCallback;
631         break;
632 
633       case HAL_ETH_ERROR_CB_ID :
634         heth->ErrorCallback = HAL_ETH_ErrorCallback;
635         break;
636 
637       case HAL_ETH_PMT_CB_ID :
638         heth->PMTCallback = HAL_ETH_PMTCallback;
639         break;
640 
641       case HAL_ETH_EEE_CB_ID :
642         heth->EEECallback = HAL_ETH_EEECallback;
643         break;
644 
645       case HAL_ETH_WAKEUP_CB_ID :
646         heth->WakeUpCallback = HAL_ETH_WakeUpCallback;
647         break;
648 
649       case HAL_ETH_MSPINIT_CB_ID :
650         heth->MspInitCallback = HAL_ETH_MspInit;
651         break;
652 
653       case HAL_ETH_MSPDEINIT_CB_ID :
654         heth->MspDeInitCallback = HAL_ETH_MspDeInit;
655         break;
656 
657       default :
658         /* Update the error code */
659         heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK;
660         /* Return error status */
661         status =  HAL_ERROR;
662         break;
663     }
664   }
665   else if (heth->gState == HAL_ETH_STATE_RESET)
666   {
667     switch (CallbackID)
668     {
669       case HAL_ETH_MSPINIT_CB_ID :
670         heth->MspInitCallback = HAL_ETH_MspInit;
671         break;
672 
673       case HAL_ETH_MSPDEINIT_CB_ID :
674         heth->MspDeInitCallback = HAL_ETH_MspDeInit;
675         break;
676 
677       default :
678         /* Update the error code */
679         heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK;
680         /* Return error status */
681         status =  HAL_ERROR;
682         break;
683     }
684   }
685   else
686   {
687     /* Update the error code */
688     heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK;
689     /* Return error status */
690     status =  HAL_ERROR;
691   }
692 
693   return status;
694 }
695 #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */
696 
697 /**
698   * @}
699   */
700 
701 /** @defgroup ETH_Exported_Functions_Group2 IO operation functions
702   *  @brief ETH Transmit and Receive functions
703   *
704 @verbatim
705   ==============================================================================
706                       ##### IO operation functions #####
707   ==============================================================================
708   [..]
709     This subsection provides a set of functions allowing to manage the ETH
710     data transfer.
711 
712 @endverbatim
713   * @{
714   */
715 
716 /**
717   * @brief  Enables Ethernet MAC and DMA reception and transmission
718   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
719   *         the configuration information for ETHERNET module
720   * @retval HAL status
721   */
HAL_ETH_Start(ETH_HandleTypeDef * heth)722 HAL_StatusTypeDef HAL_ETH_Start(ETH_HandleTypeDef *heth)
723 {
724   uint32_t ch;
725 
726   if (heth->gState == HAL_ETH_STATE_READY)
727   {
728     heth->gState = HAL_ETH_STATE_BUSY;
729 
730     /* Set number of descriptors to build */
731     for (ch = 0; ch < ETH_DMA_CH_CNT; ch++)
732     {
733       heth->RxOpCH = ch;
734       heth->RxDescList[ch].RxBuildDescCnt = ETH_RX_DESC_CNT;
735       /* Build all descriptors */
736       ETH_UpdateDescriptor(heth);
737     }
738 
739     /* Reset Rx Operation Channel to 0 */
740     heth->RxOpCH = 0;
741 
742     for (ch = 0; ch < ETH_MTL_TX_Q_CNT; ch++)
743     {
744       /* Set the Flush Transmit FIFO bit */
745       SET_BIT(heth->Instance->MTL_QUEUE[ch].MTLTXQOMR, ETH_MTLTXQxOMR_FTQ);
746       /* Enable the DMA transmission */
747       SET_BIT(heth->Instance->DMA_CH[ch].DMACTXCR, ETH_DMACxTXCR_ST);
748       /* Enable the DMA reception */
749       SET_BIT(heth->Instance->DMA_CH[ch].DMACRXCR, ETH_DMACxRXCR_SR);
750       /* Clear Tx and Rx process stopped flags */
751       heth->Instance->DMA_CH[ch].DMACSR |= (ETH_DMACxSR_TPS | ETH_DMACxSR_RPS);
752     }
753 
754     /* Enable the MAC transmission */
755     SET_BIT(heth->Instance->MACCR, ETH_MACCR_TE);
756 
757     /* Enable the MAC reception */
758     SET_BIT(heth->Instance->MACCR, ETH_MACCR_RE);
759 
760     heth->gState = HAL_ETH_STATE_STARTED;
761 
762     return HAL_OK;
763   }
764   else
765   {
766     return HAL_ERROR;
767   }
768 }
769 
770 /**
771   * @brief  Enables Ethernet MAC and DMA reception/transmission in Interrupt mode
772   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
773   *         the configuration information for ETHERNET module
774   * @retval HAL status
775   */
HAL_ETH_Start_IT(ETH_HandleTypeDef * heth)776 HAL_StatusTypeDef HAL_ETH_Start_IT(ETH_HandleTypeDef *heth)
777 {
778   uint32_t ch;
779 
780   if (heth->gState == HAL_ETH_STATE_READY)
781   {
782     heth->gState = HAL_ETH_STATE_BUSY;
783 
784     /* save IT mode to ETH Handle */
785     for (ch = 0; ch < ETH_DMA_CH_CNT; ch++)
786     {
787       /* Set the DMA channel to configure */
788       heth->RxOpCH = ch;
789       heth->RxDescList[ch].ItMode = 1U;
790       /* Set number of descriptors to build */
791       heth->RxDescList[ch].RxBuildDescCnt = ETH_RX_DESC_CNT;
792       /* Build all descriptors */
793       ETH_UpdateDescriptor(heth);
794 
795       /* Enable ETH DMA interrupts:
796       - Tx complete interrupt
797       - Rx complete interrupt
798       - Fatal bus interrupt
799       */
800       __HAL_ETH_DMA_CH_ENABLE_IT(heth, (ETH_DMACxIER_NIE | ETH_DMACxIER_RIE | ETH_DMACxIER_TIE  |
801                                         ETH_DMACxIER_FBEE | ETH_DMACxIER_AIE | ETH_DMACxIER_RBUE), ch);
802       /* Enable the DMA reception */
803       SET_BIT(heth->Instance->DMA_CH[ch].DMACRXCR, ETH_DMACxRXCR_SR);
804       /* Clear Tx and Rx process stopped flags */
805       heth->Instance->DMA_CH[ch].DMACSR |= (ETH_DMACxSR_TPS | ETH_DMACxSR_RPS);
806       /* Set the Flush Transmit FIFO bit */
807       SET_BIT(heth->Instance->MTL_QUEUE[ch].MTLTXQOMR, ETH_MTLTXQxOMR_FTQ);
808       /* Enable the DMA transmission */
809       SET_BIT(heth->Instance->DMA_CH[ch].DMACTXCR, ETH_DMACxTXCR_ST);
810     }
811 
812     /* Reset Rx Operation Channel to 0 */
813     heth->RxOpCH = 0;
814 
815     /* Enable the MAC transmission */
816     SET_BIT(heth->Instance->MACCR, ETH_MACCR_TE);
817 
818     /* Enable the MAC reception */
819     SET_BIT(heth->Instance->MACCR, ETH_MACCR_RE);
820 
821     heth->gState = HAL_ETH_STATE_STARTED;
822     return HAL_OK;
823   }
824   else
825   {
826     return HAL_ERROR;
827   }
828 }
829 
830 /**
831   * @brief  Stop Ethernet MAC and DMA reception/transmission
832   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
833   *         the configuration information for ETHERNET module
834   * @retval HAL status
835   */
HAL_ETH_Stop(ETH_HandleTypeDef * heth)836 HAL_StatusTypeDef HAL_ETH_Stop(ETH_HandleTypeDef *heth)
837 {
838   uint32_t ch;
839 
840   if (heth->gState == HAL_ETH_STATE_STARTED)
841   {
842     /* Set the ETH peripheral state to BUSY */
843     heth->gState = HAL_ETH_STATE_BUSY;
844 
845     for (ch = 0; ch < ETH_MTL_TX_Q_CNT; ch++)
846     {
847       /* Disable the DMA transmission */
848       CLEAR_BIT(heth->Instance->DMA_CH[ch].DMACTXCR, ETH_DMACxTXCR_ST);
849       /* Disable the DMA reception */
850       CLEAR_BIT(heth->Instance->DMA_CH[ch].DMACRXCR, ETH_DMACxRXCR_SR);
851       /* Set the Flush Transmit FIFO bit */
852       SET_BIT(heth->Instance->MTL_QUEUE[ch].MTLTXQOMR, ETH_MTLTXQxOMR_FTQ);
853     }
854 
855     /* Disable the MAC reception */
856     CLEAR_BIT(heth->Instance->MACCR, ETH_MACCR_RE);
857 
858     /* Disable the MAC transmission */
859     CLEAR_BIT(heth->Instance->MACCR, ETH_MACCR_TE);
860 
861     heth->gState = HAL_ETH_STATE_READY;
862 
863     /* Return function status */
864     return HAL_OK;
865   }
866   else
867   {
868     return HAL_ERROR;
869   }
870 }
871 
872 /**
873   * @brief  Stop Ethernet MAC and DMA reception/transmission in Interrupt mode
874   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
875   *         the configuration information for ETHERNET module
876   * @retval HAL status
877   */
HAL_ETH_Stop_IT(ETH_HandleTypeDef * heth)878 HAL_StatusTypeDef HAL_ETH_Stop_IT(ETH_HandleTypeDef *heth)
879 {
880   ETH_DMADescTypeDef *dmarxdesc;
881   uint32_t descindex;
882   uint32_t ch;
883 
884   if (heth->gState == HAL_ETH_STATE_STARTED)
885   {
886     /* Set the ETH peripheral state to BUSY */
887     heth->gState = HAL_ETH_STATE_BUSY;
888 
889     /* Disable interrupts:
890     - Tx complete interrupt
891     - Rx complete interrupt
892     - Fatal bus interrupt
893     */
894 
895     for (ch = 0; ch < ETH_MTL_TX_Q_CNT; ch++)
896     {
897       __HAL_ETH_DMA_CH_DISABLE_IT(heth, (ETH_DMACxIER_NIE | ETH_DMACxIER_RIE | ETH_DMACxIER_TIE  |
898                                          ETH_DMACxIER_FBEE | ETH_DMACxIER_AIE | ETH_DMACxIER_RBUE), ch);
899 
900       /* Disable the DMA transmission */
901       CLEAR_BIT(heth->Instance->DMA_CH[ch].DMACTXCR, ETH_DMACxTXCR_ST);
902 
903       /* Disable the DMA reception */
904       CLEAR_BIT(heth->Instance->DMA_CH[ch].DMACRXCR, ETH_DMACxRXCR_SR);
905 
906       /* Set the Flush Transmit FIFO bit */
907       SET_BIT(heth->Instance->MTL_QUEUE[ch].MTLTXQOMR, ETH_MTLTXQxOMR_FTQ);
908 
909     }
910 
911     /* Disable the MAC reception */
912     CLEAR_BIT(heth->Instance->MACCR, ETH_MACCR_RE);
913 
914     /* Disable the MAC transmission */
915     CLEAR_BIT(heth->Instance->MACCR, ETH_MACCR_TE);
916 
917     for (ch = 0; ch < ETH_DMA_CH_CNT; ch++)
918     {
919       /* Clear IOC bit to all Ch0 Rx descriptors */
920       for (descindex = 0; descindex < (uint32_t)ETH_RX_DESC_CNT; descindex++)
921       {
922         dmarxdesc = (ETH_DMADescTypeDef *)heth->RxDescList[ch].RxDesc[descindex];
923         CLEAR_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCRF_IOC);
924         heth->RxDescList[ch].ItMode = 0U;
925       }
926     }
927 
928     heth->gState = HAL_ETH_STATE_READY;
929 
930     /* Return function status */
931     return HAL_OK;
932   }
933   else
934   {
935     return HAL_ERROR;
936   }
937 }
938 
939 /**
940   * @brief  Sends an Ethernet Packet in polling mode.
941   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
942   *         the configuration information for ETHERNET module
943   * @param  pTxConfig: Hold the configuration of packet to be transmitted
944   * @param  Timeout: timeout value
945   * @retval HAL status
946   */
HAL_ETH_Transmit(ETH_HandleTypeDef * heth,ETH_TxPacketConfigTypeDef * pTxConfig,uint32_t Timeout)947 HAL_StatusTypeDef HAL_ETH_Transmit(ETH_HandleTypeDef *heth, ETH_TxPacketConfigTypeDef *pTxConfig, uint32_t Timeout)
948 {
949   uint32_t ch;
950   uint32_t tickstart;
951   ETH_DMADescTypeDef *dmatxdesc;
952 
953   if (pTxConfig == NULL)
954   {
955     heth->ErrorCode |= HAL_ETH_ERROR_PARAM;
956     return HAL_ERROR;
957   }
958 
959   if (heth->gState == HAL_ETH_STATE_STARTED)
960   {
961     ch = pTxConfig->TxDMACh;
962 
963     /* Config DMA Tx descriptor by Tx Packet info */
964     if (ETH_Prepare_Tx_Descriptors(heth, pTxConfig, 0) != HAL_ETH_ERROR_NONE)
965     {
966       /* Set the ETH error code */
967       heth->ErrorCode |= HAL_ETH_ERROR_BUSY;
968       return HAL_ERROR;
969     }
970 
971     /* Ensure completion of descriptor preparation before transmission start */
972     __DSB();
973 
974     dmatxdesc = (ETH_DMADescTypeDef *)(&heth->TxDescList[ch])->
975                 TxDesc[heth->TxDescList[ch].CurTxDesc];
976 
977     /* Incr current tx desc index */
978     INCR_TX_DESC_INDEX(heth->TxDescList[ch].CurTxDesc, 1U);
979 
980     /* Start transmission */
981     /* issue a poll command to Tx DMA by writing address of next immediate free descriptor */
982     WRITE_REG(heth->Instance->DMA_CH[ch].DMACTXDTPR,
983               (uint32_t)(heth->TxDescList[ch].TxDesc[heth->TxDescList[ch].CurTxDesc]));
984 
985     tickstart = HAL_GetTick();
986 
987     /* Wait for data to be transmitted or timeout occurred */
988     while ((dmatxdesc->DESC3 & ETH_DMATXNDESCWBF_OWN) != (uint32_t)RESET)
989     {
990       if ((heth->Instance->DMA_CH[ch].DMACSR & ETH_DMACxSR_FBE) != (uint32_t)RESET)
991       {
992         heth->ErrorCode |= (uint32_t)HAL_ETH_ERROR_DMA;
993         heth->DMAErrorCode = heth->Instance->DMA_CH[ch].DMACSR;
994         /* Return function status */
995         return HAL_ERROR;
996       }
997 
998       /* Check for the Timeout */
999       if (Timeout != HAL_MAX_DELAY)
1000       {
1001         if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
1002         {
1003           heth->ErrorCode |= HAL_ETH_ERROR_TIMEOUT;
1004           /* Clear TX descriptor so that we can proceed */
1005           dmatxdesc->DESC3 = (ETH_DMATXNDESCWBF_FD | ETH_DMATXNDESCWBF_LD);
1006           return HAL_ERROR;
1007         }
1008       }
1009     }
1010 
1011     /* Return function status */
1012     return HAL_OK;
1013   }
1014   else
1015   {
1016     return HAL_ERROR;
1017   }
1018 }
1019 
1020 /**
1021   * @brief  Sends an Ethernet Packet in interrupt mode.
1022   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1023   *         the configuration information for ETHERNET module
1024   * @param  pTxConfig: Hold the configuration of packet to be transmitted
1025   * @retval HAL status
1026   */
HAL_ETH_Transmit_IT(ETH_HandleTypeDef * heth,ETH_TxPacketConfigTypeDef * pTxConfig)1027 HAL_StatusTypeDef HAL_ETH_Transmit_IT(ETH_HandleTypeDef *heth, ETH_TxPacketConfigTypeDef *pTxConfig)
1028 {
1029   uint32_t ch;
1030 
1031   if (pTxConfig == NULL)
1032   {
1033     heth->ErrorCode |= HAL_ETH_ERROR_PARAM;
1034     return HAL_ERROR;
1035   }
1036 
1037   if (heth->gState == HAL_ETH_STATE_STARTED)
1038   {
1039     ch = pTxConfig->TxDMACh;
1040 
1041     /* Save the packet pointer to release.  */
1042     heth->TxDescList[ch].CurrentPacketAddress = (uint32_t *)pTxConfig->pData;
1043 
1044     /* Config DMA Tx descriptor by Tx Packet info */
1045     if (ETH_Prepare_Tx_Descriptors(heth, pTxConfig, 1) != HAL_ETH_ERROR_NONE)
1046     {
1047       heth->ErrorCode |= HAL_ETH_ERROR_BUSY;
1048       return HAL_ERROR;
1049     }
1050 
1051     /* Incr current tx desc for Ch index */
1052     INCR_TX_DESC_INDEX(heth->TxDescList[ch].CurTxDesc, 1U);
1053 
1054     /* Ensure completion of descriptor preparation before transmission start */
1055     __DSB();
1056 
1057     /* Start transmission */
1058     /* issue a poll command to Tx DMA by writing address of next immediate free descriptor */
1059     WRITE_REG(heth->Instance->DMA_CH[ch].DMACTXDTPR,
1060               (uint32_t)(heth->TxDescList[ch].TxDesc[heth->TxDescList[ch].CurTxDesc]));
1061     return HAL_OK;
1062   }
1063   else
1064   {
1065     return HAL_ERROR;
1066   }
1067 }
1068 
1069 /**
1070   * @brief  Read a received packet.
1071   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1072   *         the configuration information for ETHERNET module
1073   * @param  pAppBuff: Pointer to an application buffer to receive the packet.
1074   * @retval HAL status
1075   */
HAL_ETH_ReadData(ETH_HandleTypeDef * heth,void ** pAppBuff)1076 HAL_StatusTypeDef HAL_ETH_ReadData(ETH_HandleTypeDef *heth, void **pAppBuff)
1077 {
1078   uint32_t ch = heth->RxOpCH;
1079   uint32_t descidx;
1080   uint32_t descidx_next;
1081   ETH_DMADescTypeDef *dmarxdesc;
1082   ETH_DMADescTypeDef *dmarxdesc_next;
1083   uint32_t desccnt = 0U;
1084   uint32_t desccntmax;
1085   uint32_t bufflength;
1086   uint8_t rxdataready = 0U;
1087 
1088   if (pAppBuff == NULL)
1089   {
1090     heth->ErrorCode |= HAL_ETH_ERROR_PARAM;
1091     return HAL_ERROR;
1092   }
1093 
1094   if (heth->gState != HAL_ETH_STATE_STARTED)
1095   {
1096     return HAL_ERROR;
1097   }
1098 
1099   descidx = heth->RxDescList[ch].RxDescIdx;
1100   dmarxdesc = (ETH_DMADescTypeDef *)heth->RxDescList[ch].RxDesc[descidx];
1101   desccntmax = ETH_RX_DESC_CNT - heth->RxDescList[ch].RxBuildDescCnt;
1102 
1103   /* Check if descriptor is not owned by DMA */
1104   while ((READ_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCWBF_OWN) == (uint32_t)RESET) && (desccnt < desccntmax)
1105          && (rxdataready == 0U))
1106   {
1107     if ((READ_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCWBF_FD) != (uint32_t)RESET) ||
1108         (heth->RxDescList[ch].pRxStart != NULL))
1109     {
1110       /* Check if first descriptor */
1111       if (READ_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCWBF_FD) != (uint32_t)RESET)
1112       {
1113         heth->RxDescList[ch].RxDescCnt = 0;
1114         heth->RxDescList[ch].RxDataLength = 0;
1115       }
1116 
1117       /* Get the Frame Length of the received packet */
1118       bufflength = READ_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCWBF_PL) - heth->RxDescList[ch].RxDataLength;
1119 
1120       /* Check if last descriptor */
1121       if (READ_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCWBF_LD) != (uint32_t)RESET)
1122       {
1123         /* Save Last descriptor index */
1124         heth->RxDescList[ch].pRxLastRxDesc = dmarxdesc->DESC3;
1125 
1126         /* Packet ready */
1127         rxdataready = 1;
1128 
1129         if (READ_BIT(dmarxdesc->DESC1, ETH_DMARXNDESCWBF_TSA) != (uint32_t)RESET)
1130         {
1131           descidx_next = descidx;
1132           INCR_RX_DESC_INDEX(descidx_next, 1U);
1133 
1134           dmarxdesc_next = (ETH_DMADescTypeDef *)heth->RxDescList[ch].RxDesc[descidx_next];
1135 
1136           if (READ_BIT(dmarxdesc_next->DESC3, ETH_DMARXNDESCWBF_CTXT) != (uint32_t)RESET)
1137           {
1138             /* Get timestamp high */
1139             heth->RxDescList[ch].TimeStamp.TimeStampHigh = dmarxdesc_next->DESC1;
1140             /* Get timestamp low */
1141             heth->RxDescList[ch].TimeStamp.TimeStampLow  = dmarxdesc_next->DESC0;
1142           }
1143         }
1144       }
1145 
1146       /* Link data */
1147 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
1148       /*Call registered Link callback*/
1149       heth->rxLinkCallback(&heth->RxDescList[ch].pRxStart, &heth->RxDescList[ch].pRxEnd,
1150                            (uint8_t *)dmarxdesc->BackupAddr0, bufflength);
1151 #else
1152       /* Link callback */
1153       HAL_ETH_RxLinkCallback(&heth->RxDescList[ch].pRxStart, &heth->RxDescList[ch].pRxEnd,
1154                              (uint8_t *)dmarxdesc->BackupAddr0, (uint16_t) bufflength);
1155 #endif  /* USE_HAL_ETH_REGISTER_CALLBACKS */
1156       heth->RxDescList[ch].RxDescCnt++;
1157       heth->RxDescList[ch].RxDataLength += bufflength;
1158 
1159       /* Clear buffer pointer */
1160       dmarxdesc->BackupAddr0 = 0;
1161     }
1162 
1163     /* Increment current rx descriptor index */
1164     INCR_RX_DESC_INDEX(descidx, 1U);
1165     /* Get current descriptor address */
1166     dmarxdesc = (ETH_DMADescTypeDef *)heth->RxDescList[ch].RxDesc[descidx];
1167     desccnt++;
1168   }
1169 
1170   heth->RxDescList[ch].RxBuildDescCnt += desccnt;
1171   if ((heth->RxDescList[ch].RxBuildDescCnt) != 0U)
1172   {
1173     /* Update Descriptors */
1174     ETH_UpdateDescriptor(heth);
1175   }
1176 
1177   heth->RxDescList[ch].RxDescIdx = descidx;
1178 
1179   if (rxdataready == 1U)
1180   {
1181     /* Return received packet */
1182     *pAppBuff = heth->RxDescList[ch].pRxStart;
1183     /* Reset first element */
1184     heth->RxDescList[ch].pRxStart = NULL;
1185 
1186     return HAL_OK;
1187   }
1188 
1189   /* Packet not ready */
1190   return HAL_ERROR;
1191 }
1192 
1193 /**
1194   * @brief  This function gives back Rx Desc of the last received Packet
1195   *         to the DMA, so ETH DMA will be able to use these descriptors
1196   *         to receive next Packets.
1197   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1198   *         the configuration information for ETHERNET module
1199   * @retval HAL status
1200   */
ETH_UpdateDescriptor(ETH_HandleTypeDef * heth)1201 static void ETH_UpdateDescriptor(ETH_HandleTypeDef *heth)
1202 {
1203   uint32_t ch = heth -> RxOpCH;
1204   uint32_t descidx;
1205   uint32_t tailidx;
1206   uint32_t desccount;
1207   ETH_DMADescTypeDef *dmarxdesc;
1208   uint8_t *buff = NULL;
1209   uint8_t allocStatus = 1U;
1210 
1211   descidx = heth->RxDescList[ch].RxBuildDescIdx;
1212   dmarxdesc = (ETH_DMADescTypeDef *)heth->RxDescList[ch].RxDesc[descidx];
1213   desccount = heth->RxDescList[ch].RxBuildDescCnt;
1214 
1215   while ((desccount > 0U) && (allocStatus != 0U))
1216   {
1217     /* Check if a buffer's attached the descriptor */
1218     if (READ_REG(dmarxdesc->BackupAddr0) == 0U)
1219     {
1220       /* Get a new buffer. */
1221 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
1222       /*Call registered Allocate callback*/
1223       heth->rxAllocateCallback(&buff);
1224 #else
1225       /* Allocate callback */
1226       HAL_ETH_RxAllocateCallback(&buff);
1227 #endif  /* USE_HAL_ETH_REGISTER_CALLBACKS */
1228       if (buff == NULL)
1229       {
1230         allocStatus = 0U;
1231       }
1232       else
1233       {
1234         WRITE_REG(dmarxdesc->BackupAddr0, (uint32_t)buff);
1235         WRITE_REG(dmarxdesc->DESC0, (uint32_t)buff);
1236       }
1237     }
1238     else
1239     {
1240       /* Descriptor was used as a context descriptor, buffer still unused */
1241       WRITE_REG(dmarxdesc->DESC0, (uint32_t)dmarxdesc->BackupAddr0);
1242     }
1243 
1244     if (allocStatus != 0U)
1245     {
1246 
1247       if (heth->RxDescList[ch].ItMode != 0U)
1248       {
1249         WRITE_REG(dmarxdesc->DESC3, ETH_DMARXNDESCRF_OWN | ETH_DMARXNDESCRF_BUF1V | ETH_DMARXNDESCRF_IOC);
1250       }
1251       else
1252       {
1253         WRITE_REG(dmarxdesc->DESC3, ETH_DMARXNDESCRF_OWN | ETH_DMARXNDESCRF_BUF1V);
1254       }
1255 
1256       /* Increment current rx descriptor index */
1257       INCR_RX_DESC_INDEX(descidx, 1U);
1258       /* Get current descriptor address */
1259       dmarxdesc = (ETH_DMADescTypeDef *)heth->RxDescList[ch].RxDesc[descidx];
1260       desccount--;
1261     }
1262   }
1263 
1264   if (heth->RxDescList[ch].RxBuildDescCnt != desccount)
1265   {
1266     /* Set the tail pointer index */
1267     tailidx = (ETH_RX_DESC_CNT + descidx - 1U) % ETH_RX_DESC_CNT;
1268 
1269     /* DMB instruction to avoid race condition */
1270     __DMB();
1271 
1272     /* Set the Tail pointer address */
1273     WRITE_REG(heth->Instance->DMA_CH[ch].DMACRXDTPR, ((uint32_t)(heth->Init.RxDesc[ch] + (tailidx))));
1274 
1275     heth->RxDescList[ch].RxBuildDescIdx = descidx;
1276     heth->RxDescList[ch].RxBuildDescCnt = desccount;
1277   }
1278 }
1279 
1280 /**
1281   * @brief  Register the Rx alloc callback.
1282   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1283   *         the configuration information for ETHERNET module
1284   * @param  rxAllocateCallback: pointer to function to alloc buffer
1285   * @retval HAL status
1286   */
HAL_ETH_RegisterRxAllocateCallback(ETH_HandleTypeDef * heth,pETH_rxAllocateCallbackTypeDef rxAllocateCallback)1287 HAL_StatusTypeDef HAL_ETH_RegisterRxAllocateCallback(ETH_HandleTypeDef *heth,
1288                                                      pETH_rxAllocateCallbackTypeDef rxAllocateCallback)
1289 {
1290   if (rxAllocateCallback == NULL)
1291   {
1292     /* No buffer to save */
1293     return HAL_ERROR;
1294   }
1295 
1296   /* Set function to allocate buffer */
1297   heth->rxAllocateCallback = rxAllocateCallback;
1298 
1299   return HAL_OK;
1300 }
1301 
1302 /**
1303   * @brief  Unregister the Rx alloc callback.
1304   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1305   *         the configuration information for ETHERNET module
1306   * @retval HAL status
1307   */
HAL_ETH_UnRegisterRxAllocateCallback(ETH_HandleTypeDef * heth)1308 HAL_StatusTypeDef HAL_ETH_UnRegisterRxAllocateCallback(ETH_HandleTypeDef *heth)
1309 {
1310   /* Set function to allocate buffer */
1311   heth->rxAllocateCallback = HAL_ETH_RxAllocateCallback;
1312 
1313   return HAL_OK;
1314 }
1315 
1316 /**
1317   * @brief  Rx Allocate callback.
1318   * @param  buff: pointer to allocated buffer
1319   * @retval None
1320   */
HAL_ETH_RxAllocateCallback(uint8_t ** buff)1321 __weak void HAL_ETH_RxAllocateCallback(uint8_t **buff)
1322 {
1323   /* Prevent unused argument(s) compilation warning */
1324   UNUSED(buff);
1325   /* NOTE : This function Should not be modified, when the callback is needed,
1326   the HAL_ETH_RxAllocateCallback could be implemented in the user file
1327   */
1328 }
1329 
1330 /**
1331   * @brief  Rx Link callback.
1332   * @param  pStart: pointer to packet start
1333   * @param  pEnd: pointer to packet end
1334   * @param  buff: pointer to received data
1335   * @param  Length: received data length
1336   * @retval None
1337   */
HAL_ETH_RxLinkCallback(void ** pStart,void ** pEnd,uint8_t * buff,uint16_t Length)1338 __weak void HAL_ETH_RxLinkCallback(void **pStart, void **pEnd, uint8_t *buff, uint16_t Length)
1339 {
1340   /* Prevent unused argument(s) compilation warning */
1341   UNUSED(pStart);
1342   UNUSED(pEnd);
1343   UNUSED(buff);
1344   UNUSED(Length);
1345   /* NOTE : This function Should not be modified, when the callback is needed,
1346   the HAL_ETH_RxLinkCallback could be implemented in the user file
1347   */
1348 }
1349 
1350 /**
1351   * @brief  Set the Rx link data function.
1352   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1353   *         the configuration information for ETHERNET module
1354   * @param  rxLinkCallback: pointer to function to link data
1355   * @retval HAL status
1356   */
HAL_ETH_RegisterRxLinkCallback(ETH_HandleTypeDef * heth,pETH_rxLinkCallbackTypeDef rxLinkCallback)1357 HAL_StatusTypeDef HAL_ETH_RegisterRxLinkCallback(ETH_HandleTypeDef *heth, pETH_rxLinkCallbackTypeDef rxLinkCallback)
1358 {
1359   if (rxLinkCallback == NULL)
1360   {
1361     /* No buffer to save */
1362     return HAL_ERROR;
1363   }
1364 
1365   /* Set function to link data */
1366   heth->rxLinkCallback = rxLinkCallback;
1367 
1368   return HAL_OK;
1369 }
1370 
1371 /**
1372   * @brief  Unregister the Rx link callback.
1373   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1374   *         the configuration information for ETHERNET module
1375   * @retval HAL status
1376   */
HAL_ETH_UnRegisterRxLinkCallback(ETH_HandleTypeDef * heth)1377 HAL_StatusTypeDef HAL_ETH_UnRegisterRxLinkCallback(ETH_HandleTypeDef *heth)
1378 {
1379   /* Set function to allocate buffer */
1380   heth->rxLinkCallback = HAL_ETH_RxLinkCallback;
1381 
1382   return HAL_OK;
1383 }
1384 
1385 /**
1386   * @brief  Get the error state of the last received packet.
1387   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1388   *         the configuration information for ETHERNET module
1389   * @param  pErrorCode: pointer to uint32_t to hold the error code
1390   * @retval HAL status
1391   */
HAL_ETH_GetRxDataErrorCode(const ETH_HandleTypeDef * heth,uint32_t * pErrorCode)1392 HAL_StatusTypeDef HAL_ETH_GetRxDataErrorCode(const ETH_HandleTypeDef *heth, uint32_t *pErrorCode)
1393 {
1394   uint32_t ch = heth->RxOpCH;
1395   /* Get error bits. */
1396   *pErrorCode = READ_BIT(heth->RxDescList[ch].pRxLastRxDesc, ETH_DMARXNDESCWBF_ERRORS_MASK);
1397 
1398   return HAL_OK;
1399 }
1400 
1401 /**
1402   * @brief  Set the Tx free function.
1403   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1404   *         the configuration information for ETHERNET module
1405   * @param  txFreeCallback: pointer to function to release the packet
1406   * @retval HAL status
1407   */
HAL_ETH_RegisterTxFreeCallback(ETH_HandleTypeDef * heth,pETH_txFreeCallbackTypeDef txFreeCallback)1408 HAL_StatusTypeDef HAL_ETH_RegisterTxFreeCallback(ETH_HandleTypeDef *heth, pETH_txFreeCallbackTypeDef txFreeCallback)
1409 {
1410   if (txFreeCallback == NULL)
1411   {
1412     /* No buffer to save */
1413     return HAL_ERROR;
1414   }
1415 
1416   /* Set function to free transmmitted packet */
1417   heth->txFreeCallback = txFreeCallback;
1418 
1419   return HAL_OK;
1420 }
1421 
1422 /**
1423   * @brief  Unregister the Tx free callback.
1424   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1425   *         the configuration information for ETHERNET module
1426   * @retval HAL status
1427   */
HAL_ETH_UnRegisterTxFreeCallback(ETH_HandleTypeDef * heth)1428 HAL_StatusTypeDef HAL_ETH_UnRegisterTxFreeCallback(ETH_HandleTypeDef *heth)
1429 {
1430   /* Set function to allocate buffer */
1431   heth->txFreeCallback = HAL_ETH_TxFreeCallback;
1432 
1433   return HAL_OK;
1434 }
1435 
1436 /**
1437   * @brief  Tx Free callback.
1438   * @param  buff: pointer to buffer to free
1439   * @retval None
1440   */
HAL_ETH_TxFreeCallback(uint32_t * buff)1441 __weak void HAL_ETH_TxFreeCallback(uint32_t *buff)
1442 {
1443   /* Prevent unused argument(s) compilation warning */
1444   UNUSED(buff);
1445   /* NOTE : This function Should not be modified, when the callback is needed,
1446   the HAL_ETH_TxFreeCallback could be implemented in the user file
1447   */
1448 }
1449 
1450 /**
1451   * @brief  Release transmitted Tx packets.
1452   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1453   *         the configuration information for ETHERNET module
1454   * @retval HAL status
1455   */
HAL_ETH_ReleaseTxPacket(ETH_HandleTypeDef * heth)1456 HAL_StatusTypeDef HAL_ETH_ReleaseTxPacket(ETH_HandleTypeDef *heth)
1457 {
1458   uint32_t ch = heth->TxOpCH;
1459   ETH_TxDescListTypeDef *dmatxdesclist = &heth->TxDescList[ch];
1460   uint32_t numOfBuf =  dmatxdesclist->BuffersInUse;
1461   uint32_t idx =       dmatxdesclist->releaseIndex;
1462   uint8_t pktTxStatus = 1U;
1463   uint8_t pktInUse;
1464 #ifdef HAL_ETH_USE_PTP
1465   ETH_TimeStampTypeDef *timestamp = &heth->TxTimestamp;
1466 #endif /* HAL_ETH_USE_PTP */
1467 
1468   /* Loop through buffers in use.  */
1469   while ((numOfBuf != 0U) && (pktTxStatus != 0U))
1470   {
1471     pktInUse = 1U;
1472     numOfBuf--;
1473     /* If no packet, just examine the next packet.  */
1474     if (dmatxdesclist->PacketAddress[idx] == NULL)
1475     {
1476       /* No packet in use, skip to next.  */
1477       INCR_TX_DESC_INDEX(idx, 1U);
1478       pktInUse = 0U;
1479     }
1480 
1481     if (pktInUse != 0U)
1482     {
1483       /* Determine if the packet has been transmitted.  */
1484       if ((heth->Init.TxDesc[ch][idx].DESC3 & ETH_DMATXNDESCRF_OWN) == 0U)
1485       {
1486 #ifdef HAL_ETH_USE_PTP
1487         /* Disable Ptp transmission */
1488         CLEAR_BIT(heth->Init.TxDesc[ch][idx].DESC2, ETH_DMATXNDESCRF_TTSE);
1489 
1490         if ((heth->Init.TxDesc[ch][idx].DESC3 & ETH_DMATXNDESCWBF_LD)
1491             && (heth->Init.TxDesc[ch][idx].DESC3 & ETH_DMATXNDESCWBF_TTSS))
1492         {
1493           /* Get timestamp low */
1494           timestamp->TimeStampLow = heth->Init.TxDesc[ch][idx].DESC0;
1495           /* Get timestamp high */
1496           timestamp->TimeStampHigh = heth->Init.TxDesc[ch][idx].DESC1;
1497         }
1498         else
1499         {
1500           timestamp->TimeStampHigh = timestamp->TimeStampLow = UINT32_MAX;
1501         }
1502 
1503 #endif /* HAL_ETH_USE_PTP */
1504 
1505 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
1506         /*Call registered callbacks*/
1507 #ifdef HAL_ETH_USE_PTP
1508         /* Handle Ptp  */
1509         if (timestamp->TimeStampHigh != UINT32_MAX && timestamp->TimeStampLow != UINT32_MAX)
1510         {
1511           heth->txPtpCallback(dmatxdesclist->PacketAddress[idx], timestamp);
1512         }
1513 #endif  /* HAL_ETH_USE_PTP */
1514         /* Release the packet.  */
1515         heth->txFreeCallback(dmatxdesclist->PacketAddress[idx]);
1516 #else
1517         /* Call callbacks */
1518 #ifdef HAL_ETH_USE_PTP
1519         /* Handle Ptp  */
1520         if (timestamp->TimeStampHigh != UINT32_MAX && timestamp->TimeStampLow != UINT32_MAX)
1521         {
1522           HAL_ETH_TxPtpCallback(dmatxdesclist->PacketAddress[idx], timestamp);
1523         }
1524 #endif  /* HAL_ETH_USE_PTP */
1525         /* Release the packet.  */
1526         HAL_ETH_TxFreeCallback(dmatxdesclist->PacketAddress[idx]);
1527 #endif  /* USE_HAL_ETH_REGISTER_CALLBACKS */
1528 
1529         /* Clear the entry in the in-use array.  */
1530         dmatxdesclist->PacketAddress[idx] = NULL;
1531 
1532         /* Update the transmit relesae index and number of buffers in use.  */
1533         INCR_TX_DESC_INDEX(idx, 1U);
1534         dmatxdesclist->BuffersInUse = numOfBuf;
1535         dmatxdesclist->releaseIndex = idx;
1536       }
1537       else
1538       {
1539         /* Get out of the loop!  */
1540         pktTxStatus = 0U;
1541       }
1542     }
1543   }
1544   return HAL_OK;
1545 }
1546 
1547 #ifdef HAL_ETH_USE_PTP
1548 /**
1549   * @brief  Set the Ethernet PTP configuration.
1550   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1551   *         the configuration information for ETHERNET module
1552   * @param  ptpconfig: pointer to a ETH_PTP_ConfigTypeDef structure that contains
1553   *         the configuration information for PTP
1554   * @retval HAL status
1555   */
HAL_ETH_PTP_SetConfig(ETH_HandleTypeDef * heth,ETH_PTP_ConfigTypeDef * ptpconfig)1556 HAL_StatusTypeDef HAL_ETH_PTP_SetConfig(ETH_HandleTypeDef *heth, ETH_PTP_ConfigTypeDef *ptpconfig)
1557 {
1558   uint32_t tmpTSCR;
1559   ETH_TimeTypeDef time;
1560 
1561   if (ptpconfig == NULL)
1562   {
1563     return HAL_ERROR;
1564   }
1565 
1566   /* Mask the Timestamp Trigger interrupt */
1567   CLEAR_BIT(heth->Instance->MACIER, ETH_MACIER_TSIE);
1568 
1569   tmpTSCR = ((uint32_t)ptpconfig->AV8021ASMEN << ETH_MACTSCR_AV8021ASMEN_Pos) |
1570             ((uint32_t)ptpconfig->Timestamp << ETH_MACTSCR_TSENA_Pos) |
1571             ((uint32_t)ptpconfig->TimestampUpdate << ETH_MACTSCR_TSUPDT_Pos) |
1572             ((uint32_t)ptpconfig->TimestampAll << ETH_MACTSCR_TSENALL_Pos) |
1573             ((uint32_t)ptpconfig->TimestampRolloverMode << ETH_MACTSCR_TSCTRLSSR_Pos) |
1574             ((uint32_t)ptpconfig->TimestampV2 << ETH_MACTSCR_TSVER2ENA_Pos) |
1575             ((uint32_t)ptpconfig->TimestampEthernet << ETH_MACTSCR_TSIPENA_Pos) |
1576             ((uint32_t)ptpconfig->TimestampIPv6 << ETH_MACTSCR_TSIPV6ENA_Pos) |
1577             ((uint32_t)ptpconfig->TimestampIPv4 << ETH_MACTSCR_TSIPV4ENA_Pos) |
1578             ((uint32_t)ptpconfig->TimestampEvent << ETH_MACTSCR_TSEVNTENA_Pos) |
1579             ((uint32_t)ptpconfig->TimestampMaster << ETH_MACTSCR_TSMSTRENA_Pos) |
1580             (uint32_t)ptpconfig->TimestampSnapshots |
1581             ((uint32_t)ptpconfig->TimestampFilter << ETH_MACTSCR_TSENMACADDR_Pos) |
1582             ((uint32_t)ptpconfig->TimestampStatusMode << ETH_MACTSCR_TXTSSTSM_Pos) |
1583             ((uint32_t)ptpconfig->TimestampUpdateMode);
1584 
1585   /* Write to MACTSCR */
1586   MODIFY_REG(heth->Instance->MACTSCR, ETH_MACTSCR_MASK, tmpTSCR);
1587 
1588   /* Enable Timestamp */
1589   SET_BIT(heth->Instance->MACTSCR, ETH_MACTSCR_TSENA);
1590   WRITE_REG(heth->Instance->MACSSIR, ptpconfig->TimestampSubsecondInc);
1591   WRITE_REG(heth->Instance->MACTSAR, ptpconfig->TimestampAddend);
1592 
1593   /* Enable Timestamp */
1594   if (ptpconfig->TimestampAddendUpdate == ENABLE)
1595   {
1596     SET_BIT(heth->Instance->MACTSCR, ETH_MACTSCR_TSADDREG);
1597     while ((heth->Instance->MACTSCR & ETH_MACTSCR_TSADDREG) != 0)
1598     {
1599 
1600     }
1601   }
1602 
1603   /* Set PTP Configuration done */
1604   heth->IsPtpConfigured = HAL_ETH_PTP_CONFIGURED;
1605 
1606   /* Set Seconds */
1607   time.Seconds = heth->Instance->MACSTSR;
1608   /* Set NanoSeconds */
1609   time.NanoSeconds = heth->Instance->MACSTNR;
1610 
1611   HAL_ETH_PTP_SetTime(heth, &time);
1612 
1613   /* Ptp Init */
1614   SET_BIT(heth->Instance->MACTSCR, ETH_MACTSCR_TSINIT);
1615 
1616   /* Return function status */
1617   return HAL_OK;
1618 }
1619 
1620 /**
1621   * @brief  Get the Ethernet PTP configuration.
1622   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1623   *         the configuration information for ETHERNET module
1624   * @param  ptpconfig: pointer to a ETH_PTP_ConfigTypeDef structure that contains
1625   *         the configuration information for PTP
1626   * @retval HAL status
1627   */
HAL_ETH_PTP_GetConfig(ETH_HandleTypeDef * heth,ETH_PTP_ConfigTypeDef * ptpconfig)1628 HAL_StatusTypeDef HAL_ETH_PTP_GetConfig(ETH_HandleTypeDef *heth, ETH_PTP_ConfigTypeDef *ptpconfig)
1629 {
1630   if (ptpconfig == NULL)
1631   {
1632     return HAL_ERROR;
1633   }
1634   ptpconfig->AV8021ASMEN = ((READ_BIT(heth->Instance->MACTSCR, ETH_MACTSCR_AV8021ASMEN) >>
1635                              ETH_MACTSCR_AV8021ASMEN_Pos) > 0U) ? ENABLE : DISABLE;
1636   ptpconfig->Timestamp = ((READ_BIT(heth->Instance->MACTSCR, ETH_MACTSCR_TSENA) >>
1637                            ETH_MACTSCR_TSENA_Pos) > 0U) ? ENABLE : DISABLE;
1638   ptpconfig->TimestampUpdate = ((READ_BIT(heth->Instance->MACTSCR, ETH_MACTSCR_TSCFUPDT) >>
1639                                  ETH_MACTSCR_TSUPDT_Pos) > 0U) ? ENABLE : DISABLE;
1640   ptpconfig->TimestampAll = ((READ_BIT(heth->Instance->MACTSCR, ETH_MACTSCR_TSENALL) >>
1641                               ETH_MACTSCR_TSENALL_Pos) > 0U) ? ENABLE : DISABLE;
1642   ptpconfig->TimestampRolloverMode = ((READ_BIT(heth->Instance->MACTSCR, ETH_MACTSCR_TSCTRLSSR) >>
1643                                        ETH_MACTSCR_TSCTRLSSR_Pos) > 0U) ? ENABLE : DISABLE;
1644   ptpconfig->TimestampV2 = ((READ_BIT(heth->Instance->MACTSCR, ETH_MACTSCR_TSVER2ENA) >>
1645                              ETH_MACTSCR_TSVER2ENA_Pos) > 0U) ? ENABLE : DISABLE;
1646   ptpconfig->TimestampEthernet = ((READ_BIT(heth->Instance->MACTSCR, ETH_MACTSCR_TSIPENA) >>
1647                                    ETH_MACTSCR_TSIPENA_Pos) > 0U) ? ENABLE : DISABLE;
1648   ptpconfig->TimestampIPv6 = ((READ_BIT(heth->Instance->MACTSCR, ETH_MACTSCR_TSIPV6ENA) >>
1649                                ETH_MACTSCR_TSIPV6ENA_Pos) > 0U) ? ENABLE : DISABLE;
1650   ptpconfig->TimestampIPv4 = ((READ_BIT(heth->Instance->MACTSCR, ETH_MACTSCR_TSIPV4ENA) >>
1651                                ETH_MACTSCR_TSIPV4ENA_Pos) > 0U) ? ENABLE : DISABLE;
1652   ptpconfig->TimestampEvent = ((READ_BIT(heth->Instance->MACTSCR, ETH_MACTSCR_TSEVNTENA) >>
1653                                 ETH_MACTSCR_TSEVNTENA_Pos) > 0U) ? ENABLE : DISABLE;
1654   ptpconfig->TimestampMaster = ((READ_BIT(heth->Instance->MACTSCR, ETH_MACTSCR_TSMSTRENA) >>
1655                                  ETH_MACTSCR_TSMSTRENA_Pos) > 0U) ? ENABLE : DISABLE;
1656   ptpconfig->TimestampSnapshots = ((READ_BIT(heth->Instance->MACTSCR, ETH_MACTSCR_SNAPTYPSEL) >>
1657                                     ETH_MACTSCR_SNAPTYPSEL_Pos) > 0U) ? ENABLE : DISABLE;
1658   ptpconfig->TimestampFilter = ((READ_BIT(heth->Instance->MACTSCR, ETH_MACTSCR_TSENMACADDR) >>
1659                                  ETH_MACTSCR_TSENMACADDR_Pos) > 0U) ? ENABLE : DISABLE;
1660   ptpconfig->TimestampStatusMode = ((READ_BIT(heth->Instance->MACTSCR, ETH_MACTSCR_TXTSSTSM) >>
1661                                      ETH_MACTSCR_TXTSSTSM_Pos) > 0U) ? ENABLE : DISABLE;
1662   ptpconfig->TimestampExternalSystemTime = ((READ_BIT(heth->Instance->MACTSCR, ETH_MACTSCR_ESTI) >>
1663                                              ETH_MACTSCR_ESTI_Pos) > 0U) ? ENABLE : DISABLE;
1664   ptpconfig->TimestampAddend = READ_BIT(heth->Instance->MACTSAR, ETH_MACTSAR_TSAR);
1665   ptpconfig->TimestampSubsecondInc = READ_BIT(heth->Instance->MACSSIR, ETH_MACSTSR_TSS);
1666 
1667   /* Return function status */
1668   return HAL_OK;
1669 }
1670 
1671 /**
1672   * @brief  Set Seconds and Nanoseconds for the Ethernet PTP registers.
1673   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1674   *         the configuration information for ETHERNET module
1675   * @param  time: pointer to a ETH_TimeTypeDef structure that contains
1676   *         time to set
1677   * @retval HAL status
1678   */
HAL_ETH_PTP_SetTime(ETH_HandleTypeDef * heth,ETH_TimeTypeDef * time)1679 HAL_StatusTypeDef HAL_ETH_PTP_SetTime(ETH_HandleTypeDef *heth, ETH_TimeTypeDef *time)
1680 {
1681   if (heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURED)
1682   {
1683     /* Set Seconds */
1684     heth->Instance->MACSTSUR = time->Seconds;
1685 
1686     /* Set NanoSeconds */
1687     heth->Instance->MACSTNUR = time->NanoSeconds;
1688 
1689     /* the system time is updated */
1690     SET_BIT(heth->Instance->MACTSCR, ETH_MACTSCR_TSINIT);
1691 
1692     /* Return function status */
1693     return HAL_OK;
1694   }
1695   else
1696   {
1697     /* Return function status */
1698     return HAL_ERROR;
1699   }
1700 }
1701 
1702 /**
1703   * @brief  Get Seconds and Nanoseconds for the Ethernet PTP registers.
1704   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1705   *         the configuration information for ETHERNET module
1706   * @param  time: pointer to a ETH_TimeTypeDef structure that contains
1707   *         time to get
1708   * @retval HAL status
1709   */
HAL_ETH_PTP_GetTime(ETH_HandleTypeDef * heth,ETH_TimeTypeDef * time)1710 HAL_StatusTypeDef HAL_ETH_PTP_GetTime(ETH_HandleTypeDef *heth, ETH_TimeTypeDef *time)
1711 {
1712   if (heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURED)
1713   {
1714     /* Get Seconds */
1715     time->Seconds = heth->Instance->MACSTSR;
1716     /* Get NanoSeconds */
1717     time->NanoSeconds = heth->Instance->MACSTNR;
1718 
1719     /* Return function status */
1720     return HAL_OK;
1721   }
1722   else
1723   {
1724     /* Return function status */
1725     return HAL_ERROR;
1726   }
1727 }
1728 
1729 /**
1730   * @brief  Update time for the Ethernet PTP registers.
1731   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1732   *         the configuration information for ETHERNET module
1733   * @param  timeoffset: pointer to a ETH_PtpUpdateTypeDef structure that contains
1734   *         the time update information
1735   * @retval HAL status
1736   */
HAL_ETH_PTP_AddTimeOffset(ETH_HandleTypeDef * heth,ETH_PtpUpdateTypeDef ptpoffsettype,ETH_TimeTypeDef * timeoffset)1737 HAL_StatusTypeDef HAL_ETH_PTP_AddTimeOffset(ETH_HandleTypeDef *heth, ETH_PtpUpdateTypeDef ptpoffsettype,
1738                                             ETH_TimeTypeDef *timeoffset)
1739 {
1740   if (heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURED)
1741   {
1742     if (ptpoffsettype ==  HAL_ETH_PTP_NEGATIVE_UPDATE)
1743     {
1744       /* Set Seconds update */
1745       heth->Instance->MACSTSUR = ETH_MACSTSUR_VALUE - timeoffset->Seconds + 1U;
1746 
1747       if (READ_BIT(heth->Instance->MACTSCR, ETH_MACTSCR_TSCTRLSSR) == ETH_MACTSCR_TSCTRLSSR)
1748       {
1749         /* Set nanoSeconds update */
1750         heth->Instance->MACSTNUR = ETH_MACSTNUR_VALUE - timeoffset->NanoSeconds;
1751       }
1752       else
1753       {
1754         /* Set nanoSeconds update */
1755         heth->Instance->MACSTNUR = ETH_MACSTSUR_VALUE - timeoffset->NanoSeconds + 1U;
1756       }
1757     }
1758     else
1759     {
1760       /* Set Seconds update */
1761       heth->Instance->MACSTSUR = timeoffset->Seconds;
1762       /* Set nanoSeconds update */
1763       heth->Instance->MACSTNUR = timeoffset->NanoSeconds;
1764     }
1765 
1766     SET_BIT(heth->Instance->MACTSCR, ETH_MACTSCR_TSUPDT);
1767 
1768     /* Return function status */
1769     return HAL_OK;
1770   }
1771   else
1772   {
1773     /* Return function status */
1774     return HAL_ERROR;
1775   }
1776 }
1777 
1778 /**
1779   * @brief  Insert Timestamp in transmission.
1780   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1781   *         the configuration information for ETHERNET module
1782   * @retval HAL status
1783   */
HAL_ETH_PTP_InsertTxTimestamp(ETH_HandleTypeDef * heth)1784 HAL_StatusTypeDef HAL_ETH_PTP_InsertTxTimestamp(ETH_HandleTypeDef *heth)
1785 {
1786   uint32_t ch = heth->TxOpCH;
1787   ETH_TxDescListTypeDef *dmatxdesclist = &heth->TxDescList[ch];
1788   uint32_t descidx = dmatxdesclist->CurTxDesc;
1789   ETH_DMADescTypeDef *dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[descidx];
1790 
1791   if (heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURED)
1792   {
1793     /* Enable Time Stamp transmission */
1794     SET_BIT(dmatxdesc->DESC2, ETH_DMATXNDESCRF_TTSE);
1795 
1796     /* Return function status */
1797     return HAL_OK;
1798   }
1799   else
1800   {
1801     /* Return function status */
1802     return HAL_ERROR;
1803   }
1804 }
1805 
1806 /**
1807   * @brief  Get transmission timestamp.
1808   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1809   *         the configuration information for ETHERNET module
1810   * @param  timestamp: pointer to ETH_TIMESTAMPTypeDef structure that contains
1811   *         transmission timestamp
1812   * @retval HAL status
1813   */
HAL_ETH_PTP_GetTxTimestamp(ETH_HandleTypeDef * heth,ETH_TimeStampTypeDef * timestamp)1814 HAL_StatusTypeDef HAL_ETH_PTP_GetTxTimestamp(ETH_HandleTypeDef *heth, ETH_TimeStampTypeDef *timestamp)
1815 {
1816   uint32_t ch = heth->TxOpCH;
1817   ETH_TxDescListTypeDef *dmatxdesclist = &heth->TxDescList[ch];
1818   uint32_t idx =       dmatxdesclist->releaseIndex;
1819   ETH_DMADescTypeDef *dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[idx];
1820 
1821   if (heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURED)
1822   {
1823     /* Get timestamp low */
1824     timestamp->TimeStampLow = dmatxdesc->DESC0;
1825     /* Get timestamp high */
1826     timestamp->TimeStampHigh = dmatxdesc->DESC1;
1827 
1828     /* Return function status */
1829     return HAL_OK;
1830   }
1831   else
1832   {
1833     /* Return function status */
1834     return HAL_ERROR;
1835   }
1836 }
1837 
1838 /**
1839   * @brief  Get receive timestamp.
1840   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1841   *         the configuration information for ETHERNET module
1842   * @param  timestamp: pointer to ETH_TIMESTAMPTypeDef structure that contains
1843   *         receive timestamp
1844   * @retval HAL status
1845   */
HAL_ETH_PTP_GetRxTimestamp(ETH_HandleTypeDef * heth,ETH_TimeStampTypeDef * timestamp)1846 HAL_StatusTypeDef HAL_ETH_PTP_GetRxTimestamp(ETH_HandleTypeDef *heth, ETH_TimeStampTypeDef *timestamp)
1847 {
1848   uint32_t ch = heth->RxOpCH;
1849 
1850   if (heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURED)
1851   {
1852     /* Get timestamp low */
1853     timestamp->TimeStampLow = heth->RxDescList[ch].TimeStamp.TimeStampLow;
1854     /* Get timestamp high */
1855     timestamp->TimeStampHigh = heth->RxDescList[ch].TimeStamp.TimeStampHigh;
1856 
1857     /* Return function status */
1858     return HAL_OK;
1859   }
1860   else
1861   {
1862     /* Return function status */
1863     return HAL_ERROR;
1864   }
1865 }
1866 
1867 /**
1868   * @brief  Register the Tx Ptp callback.
1869   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1870   *         the configuration information for ETHERNET module
1871   * @param  txPtpCallback: Function to handle Ptp transmission
1872   * @retval HAL status
1873   */
HAL_ETH_RegisterTxPtpCallback(ETH_HandleTypeDef * heth,pETH_txPtpCallbackTypeDef txPtpCallback)1874 HAL_StatusTypeDef HAL_ETH_RegisterTxPtpCallback(ETH_HandleTypeDef *heth, pETH_txPtpCallbackTypeDef txPtpCallback)
1875 {
1876   if (txPtpCallback == NULL)
1877   {
1878     /* No buffer to save */
1879     return HAL_ERROR;
1880   }
1881   /* Set Function to handle Tx Ptp */
1882   heth->txPtpCallback = txPtpCallback;
1883 
1884   return HAL_OK;
1885 }
1886 
1887 /**
1888   * @brief  Unregister the Tx Ptp callback.
1889   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1890   *         the configuration information for ETHERNET module
1891   * @retval HAL status
1892   */
HAL_ETH_UnRegisterTxPtpCallback(ETH_HandleTypeDef * heth)1893 HAL_StatusTypeDef HAL_ETH_UnRegisterTxPtpCallback(ETH_HandleTypeDef *heth)
1894 {
1895   /* Set function to allocate buffer */
1896   heth->txPtpCallback = HAL_ETH_TxPtpCallback;
1897 
1898   return HAL_OK;
1899 }
1900 
1901 /**
1902   * @brief  Tx Ptp callback.
1903   * @param  buff: pointer to application buffer
1904   * @param  timestamp: pointer to ETH_TimeStampTypeDef structure that contains
1905   *         transmission timestamp
1906   * @retval None
1907   */
HAL_ETH_TxPtpCallback(uint32_t * buff,ETH_TimeStampTypeDef * timestamp)1908 __weak void HAL_ETH_TxPtpCallback(uint32_t *buff, ETH_TimeStampTypeDef *timestamp)
1909 {
1910   /* Prevent unused argument(s) compilation warning */
1911   UNUSED(buff);
1912   /* NOTE : This function Should not be modified, when the callback is needed,
1913   the HAL_ETH_TxPtpCallback could be implemented in the user file
1914   */
1915 }
1916 #endif  /* HAL_ETH_USE_PTP */
1917 
1918 /**
1919   * @brief  This function handles ETH interrupt request.
1920   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1921   *         the configuration information for ETHERNET module
1922   * @retval HAL status
1923   */
HAL_ETH_IRQHandler(ETH_HandleTypeDef * heth)1924 void HAL_ETH_IRQHandler(ETH_HandleTypeDef *heth)
1925 {
1926   uint32_t mac_flag = READ_REG(heth->Instance->MACISR);
1927 
1928   uint32_t dma_ch0_flag = READ_REG(heth->Instance->DMA_CH[ETH_DMA_CH0_IDX].DMACSR);
1929   uint32_t dma_ch1_flag = READ_REG(heth->Instance->DMA_CH[ETH_DMA_CH1_IDX].DMACSR);
1930   uint32_t dma_ch0_itsource = READ_REG(heth->Instance->DMA_CH[ETH_DMA_CH0_IDX].DMACIER);
1931   uint32_t dma_ch1_itsource = READ_REG(heth->Instance->DMA_CH[ETH_DMA_CH1_IDX].DMACIER);
1932 
1933   uint32_t exti_flag = READ_REG(EXTI->IMR2);
1934 
1935   /* Packet received in DMA Channel 0 */
1936   if (((dma_ch0_flag & ETH_DMACxSR_RI) != 0U) && ((dma_ch0_itsource & ETH_DMACxIER_RIE) != 0U))
1937   {
1938     /* Clear the Eth DMA Rx IT pending bits */
1939     __HAL_ETH_DMA_CH_CLEAR_IT(heth, ETH_DMACxSR_RI | ETH_DMACxSR_NIS, ETH_DMA_CH0_IDX);
1940 
1941     /* Set RxCH ETH_DMA_CH0 event*/
1942     SET_BIT(heth->RxCH, ETH_DMA_CH0);
1943 
1944 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
1945     /*Call registered Receive complete callback*/
1946     heth->RxCpltCallback(heth);
1947 #else
1948     /* Receive complete callback */
1949     HAL_ETH_RxCpltCallback(heth);
1950 #endif  /* USE_HAL_ETH_REGISTER_CALLBACKS */
1951 
1952     /* Clear RX ETH_DMA_CH0 event */
1953     CLEAR_BIT(heth->RxCH, ETH_DMA_CH0);
1954   }
1955 
1956   /* Packet received in DMA Channel 1 */
1957   if (((dma_ch1_flag & ETH_DMACxSR_RI) != 0U) && ((dma_ch1_itsource & ETH_DMACxIER_RIE) != 0U))
1958   {
1959     /* Clear the Eth DMA Rx IT pending bits */
1960     __HAL_ETH_DMA_CH_CLEAR_IT(heth, ETH_DMACxSR_RI | ETH_DMACxSR_NIS, ETH_DMA_CH1_IDX);
1961 
1962     /* Set RxCH ETH_DMA_CH1 event*/
1963     SET_BIT(heth->RxCH, ETH_DMA_CH1);
1964 
1965 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
1966     /*Call registered Receive complete callback*/
1967     heth->RxCpltCallback(heth);
1968 #else
1969     /* Receive complete callback */
1970     HAL_ETH_RxCpltCallback(heth);
1971 #endif  /* USE_HAL_ETH_REGISTER_CALLBACKS */
1972 
1973     /* Clear RX ETH_DMA_CH1 event */
1974     CLEAR_BIT(heth->RxCH, ETH_DMA_CH1);
1975   }
1976 
1977   /* Packet transmitted by DMA Channel 0 */
1978   if (((dma_ch0_flag & ETH_DMACxSR_TI) != 0U) && ((dma_ch0_itsource & ETH_DMACxIER_TIE) != 0U))
1979   {
1980     /* Clear the Eth DMA Tx IT pending bits */
1981     __HAL_ETH_DMA_CH_CLEAR_IT(heth, ETH_DMACxSR_TI | ETH_DMACxSR_NIS, ETH_DMA_CH0_IDX);
1982 
1983     /* Set TxCH ETH_DMA_CH0 event*/
1984     SET_BIT(heth->TxCH, ETH_DMA_CH0);
1985 
1986 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
1987     /*Call registered Transmit complete callback*/
1988     heth->TxCpltCallback(heth);
1989 #else
1990     /* Transfer complete callback */
1991     HAL_ETH_TxCpltCallback(heth);
1992 #endif  /* USE_HAL_ETH_REGISTER_CALLBACKS */
1993 
1994     /* Clear TX ETH_DMA_CH0 event */
1995     CLEAR_BIT(heth->TxCH, ETH_DMA_CH0);
1996   }
1997 
1998   /* Packet transmitted by DMA Channel 1 */
1999   if (((dma_ch1_flag & ETH_DMACxSR_TI) != 0U) && ((dma_ch1_itsource & ETH_DMACxIER_TIE) != 0U))
2000   {
2001     /* Clear the Eth DMA Tx IT pending bits */
2002     __HAL_ETH_DMA_CH_CLEAR_IT(heth, ETH_DMACxSR_TI | ETH_DMACxSR_NIS, ETH_DMA_CH1_IDX);
2003 
2004     /* Set TxCH ETH_DMA_CH1 event*/
2005     SET_BIT(heth->TxCH, ETH_DMA_CH1);
2006 
2007 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
2008     /*Call registered Transmit complete callback*/
2009     heth->TxCpltCallback(heth);
2010 #else
2011     /* Transfer complete callback */
2012     HAL_ETH_TxCpltCallback(heth);
2013 #endif  /* USE_HAL_ETH_REGISTER_CALLBACKS */
2014 
2015     /* Clear TX ETH_DMA_CH1 event */
2016     CLEAR_BIT(heth->TxCH, ETH_DMA_CH1);
2017   }
2018 
2019   /* ETH DMA Channel 0 Error */
2020   if (((dma_ch0_flag & ETH_DMACxSR_AIS) != 0U) && ((dma_ch0_itsource & ETH_DMACxIER_AIE) != 0U))
2021   {
2022     heth->ErrorCode |= (uint32_t)HAL_ETH_ERROR_DMA_CH0;
2023     /* if fatal bus error occurred */
2024     if ((dma_ch0_flag & ETH_DMACxSR_FBE) != 0U)
2025     {
2026       /* Get DMA error code  */
2027       heth->DMAErrorCode = READ_BIT(heth->Instance->DMA_CH[ETH_DMA_CH0_IDX].DMACSR,
2028                                     (ETH_DMACxSR_FBE | ETH_DMACxSR_TPS | ETH_DMACxSR_RPS));
2029       /* Disable all interrupts */
2030       __HAL_ETH_DMA_CH_DISABLE_IT(heth, ETH_DMACxIER_NIE | ETH_DMACxIER_AIE, ETH_DMA_CH0_IDX);
2031 
2032       /* Set HAL state to ERROR */
2033       heth->gState = HAL_ETH_STATE_ERROR;
2034     }
2035     else
2036     {
2037       /* Get DMA error status  */
2038       heth->DMAErrorCode = READ_BIT(heth->Instance->DMA_CH[ETH_DMA_CH0_IDX].DMACSR,
2039                                     (ETH_DMACxSR_CDE | ETH_DMACxSR_ETI | ETH_DMACxSR_RWT |
2040                                      ETH_DMACxSR_RBU | ETH_DMACxSR_AIS));
2041 
2042       /* Clear the interrupt summary flag */
2043       __HAL_ETH_DMA_CH_CLEAR_IT(heth, (ETH_DMACxSR_CDE | ETH_DMACxSR_ETI | ETH_DMACxSR_RWT |
2044                                        ETH_DMACxSR_RBU | ETH_DMACxSR_AIS), ETH_DMA_CH0_IDX);
2045     }
2046 
2047 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
2048     /* Call registered Error callback*/
2049     heth->ErrorCallback(heth);
2050 #else
2051     /* Ethernet DMA Error callback */
2052     HAL_ETH_ErrorCallback(heth);
2053 #endif  /* USE_HAL_ETH_REGISTER_CALLBACKS */
2054   }
2055 
2056   /* ETH DMA Channel 1 Error */
2057   if (((dma_ch1_flag & ETH_DMACxSR_AIS) != 0U) && ((dma_ch1_itsource & ETH_DMACxIER_AIE) != 0U))
2058   {
2059     heth->ErrorCode |= (uint32_t)HAL_ETH_ERROR_DMA_CH1;
2060     /* if fatal bus error occurred */
2061     if ((dma_ch1_flag & ETH_DMACxSR_FBE) != 0U)
2062     {
2063       /* Get DMA error code  */
2064       heth->DMAErrorCode = READ_BIT(heth->Instance->DMA_CH[ETH_DMA_CH1_IDX].DMACSR,
2065                                     (ETH_DMACxSR_FBE | ETH_DMACxSR_TPS | ETH_DMACxSR_RPS));
2066       /* Disable all interrupts */
2067       __HAL_ETH_DMA_CH_DISABLE_IT(heth, ETH_DMACxIER_NIE | ETH_DMACxIER_AIE, ETH_DMA_CH1_IDX);
2068 
2069       /* Set HAL state to ERROR */
2070       heth->gState = HAL_ETH_STATE_ERROR;
2071     }
2072     else
2073     {
2074       /* Get DMA error status  */
2075       heth->DMAErrorCode = READ_BIT(heth->Instance->DMA_CH[ETH_DMA_CH1_IDX].DMACSR,
2076                                     (ETH_DMACxSR_CDE | ETH_DMACxSR_ETI | ETH_DMACxSR_RWT |
2077                                      ETH_DMACxSR_RBU | ETH_DMACxSR_AIS));
2078 
2079       /* Clear the interrupt summary flag */
2080       __HAL_ETH_DMA_CH_CLEAR_IT(heth, (ETH_DMACxSR_CDE | ETH_DMACxSR_ETI | ETH_DMACxSR_RWT |
2081                                        ETH_DMACxSR_RBU | ETH_DMACxSR_AIS), ETH_DMA_CH1_IDX);
2082     }
2083 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
2084     /* Call registered Error callback*/
2085     heth->ErrorCallback(heth);
2086 #else
2087     /* Ethernet DMA Error callback */
2088     HAL_ETH_ErrorCallback(heth);
2089 #endif  /* USE_HAL_ETH_REGISTER_CALLBACKS */
2090   }
2091 
2092   /* ETH MAC Error IT */
2093   if (((mac_flag & ETH_MACIER_RXSTSIE) == ETH_MACIER_RXSTSIE) || \
2094       ((mac_flag & ETH_MACIER_TXSTSIE) == ETH_MACIER_TXSTSIE))
2095   {
2096     heth->ErrorCode |= HAL_ETH_ERROR_MAC;
2097 
2098     /* Get MAC Rx Tx status and clear Status register pending bit */
2099     heth->MACErrorCode = READ_REG(heth->Instance->MACRXTXSR);
2100 
2101     heth->gState = HAL_ETH_STATE_ERROR;
2102 
2103 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
2104     /* Call registered Error callback*/
2105     heth->ErrorCallback(heth);
2106 #else
2107     /* Ethernet Error callback */
2108     HAL_ETH_ErrorCallback(heth);
2109 #endif  /* USE_HAL_ETH_REGISTER_CALLBACKS */
2110     heth->MACErrorCode = (uint32_t)(0x0U);
2111   }
2112 
2113   /* ETH PMT IT */
2114   if ((mac_flag & ETH_MAC_PMT_IT) != 0U)
2115   {
2116     /* Get MAC Wake-up source and clear the status register pending bit */
2117     heth->MACWakeUpEvent = READ_BIT(heth->Instance->MACPCSR, (ETH_MACPCSR_RWKPRCVD | ETH_MACPCSR_MGKPRCVD));
2118 
2119 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
2120     /* Call registered PMT callback*/
2121     heth->PMTCallback(heth);
2122 #else
2123     /* Ethernet PMT callback */
2124     HAL_ETH_PMTCallback(heth);
2125 #endif  /* USE_HAL_ETH_REGISTER_CALLBACKS */
2126 
2127     heth->MACWakeUpEvent = (uint32_t)(0x0U);
2128   }
2129 
2130   /* ETH EEE IT */
2131   if ((mac_flag & ETH_MAC_LPI_IT) != 0U)
2132   {
2133     /* Get MAC LPI interrupt source and clear the status register pending bit */
2134     heth->MACLPIEvent = READ_BIT(heth->Instance->MACLCSR, 0x0000000FU);
2135 
2136 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
2137     /* Call registered EEE callback*/
2138     heth->EEECallback(heth);
2139 #else
2140     /* Ethernet EEE callback */
2141     HAL_ETH_EEECallback(heth);
2142 #endif  /* USE_HAL_ETH_REGISTER_CALLBACKS */
2143 
2144     heth->MACLPIEvent = (uint32_t)(0x0U);
2145   }
2146 
2147   /* check ETH WAKEUP exti flag */
2148   if ((exti_flag & ETH_WAKEUP_EXTI_LINE) != 0U)
2149   {
2150     /* Clear ETH WAKEUP Exti pending bit */
2151     __HAL_ETH_WAKEUP_EXTI_CLEAR_FLAG(ETH_WAKEUP_EXTI_LINE);
2152 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
2153     /* Call registered WakeUp callback*/
2154     heth->WakeUpCallback(heth);
2155 #else
2156     /* ETH WAKEUP callback */
2157     HAL_ETH_WakeUpCallback(heth);
2158 #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */
2159   }
2160 }
2161 
2162 /**
2163   * @brief  Tx Transfer completed callbacks.
2164   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2165   *         the configuration information for ETHERNET module
2166   * @retval None
2167   */
HAL_ETH_TxCpltCallback(ETH_HandleTypeDef * heth)2168 __weak void HAL_ETH_TxCpltCallback(ETH_HandleTypeDef *heth)
2169 {
2170   /* Prevent unused argument(s) compilation warning */
2171   UNUSED(heth);
2172   /* NOTE : This function Should not be modified, when the callback is needed,
2173   the HAL_ETH_TxCpltCallback could be implemented in the user file
2174   */
2175 }
2176 
2177 /**
2178   * @brief  Rx Transfer completed callbacks.
2179   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2180   *         the configuration information for ETHERNET module
2181   * @retval None
2182   */
HAL_ETH_RxCpltCallback(ETH_HandleTypeDef * heth)2183 __weak void HAL_ETH_RxCpltCallback(ETH_HandleTypeDef *heth)
2184 {
2185   /* Prevent unused argument(s) compilation warning */
2186   UNUSED(heth);
2187   /* NOTE : This function Should not be modified, when the callback is needed,
2188   the HAL_ETH_RxCpltCallback could be implemented in the user file
2189   */
2190 }
2191 
2192 /**
2193   * @brief  Ethernet transfer error callbacks
2194   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2195   *         the configuration information for ETHERNET module
2196   * @retval None
2197   */
HAL_ETH_ErrorCallback(ETH_HandleTypeDef * heth)2198 __weak void HAL_ETH_ErrorCallback(ETH_HandleTypeDef *heth)
2199 {
2200   /* Prevent unused argument(s) compilation warning */
2201   UNUSED(heth);
2202   /* NOTE : This function Should not be modified, when the callback is needed,
2203   the HAL_ETH_ErrorCallback could be implemented in the user file
2204   */
2205 }
2206 
2207 /**
2208   * @brief  Ethernet Power Management module IT callback
2209   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2210   *         the configuration information for ETHERNET module
2211   * @retval None
2212   */
HAL_ETH_PMTCallback(ETH_HandleTypeDef * heth)2213 __weak void HAL_ETH_PMTCallback(ETH_HandleTypeDef *heth)
2214 {
2215   /* Prevent unused argument(s) compilation warning */
2216   UNUSED(heth);
2217   /* NOTE : This function Should not be modified, when the callback is needed,
2218   the HAL_ETH_PMTCallback could be implemented in the user file
2219   */
2220 }
2221 
2222 /**
2223   * @brief  Energy Efficient Etherent IT callback
2224   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2225   *         the configuration information for ETHERNET module
2226   * @retval None
2227   */
HAL_ETH_EEECallback(ETH_HandleTypeDef * heth)2228 __weak void HAL_ETH_EEECallback(ETH_HandleTypeDef *heth)
2229 {
2230   /* Prevent unused argument(s) compilation warning */
2231   UNUSED(heth);
2232   /* NOTE : This function Should not be modified, when the callback is needed,
2233   the HAL_ETH_EEECallback could be implemented in the user file
2234   */
2235 }
2236 
2237 /**
2238   * @brief  ETH WAKEUP interrupt callback
2239   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2240   *         the configuration information for ETHERNET module
2241   * @retval None
2242   */
HAL_ETH_WakeUpCallback(ETH_HandleTypeDef * heth)2243 __weak void HAL_ETH_WakeUpCallback(ETH_HandleTypeDef *heth)
2244 {
2245   /* Prevent unused argument(s) compilation warning */
2246   UNUSED(heth);
2247   /* NOTE : This function Should not be modified, when the callback is needed,
2248             the HAL_ETH_WakeUpCallback could be implemented in the user file
2249    */
2250 }
2251 
2252 /**
2253   * @brief  Read a PHY register
2254   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2255   *         the configuration information for ETHERNET module
2256   * @param  PHYAddr: PHY port address, must be a value from 0 to 31
2257   * @param  PHYReg: PHY register address, must be a value from 0 to 31
2258   * @param pRegValue: parameter to hold read value
2259   * @retval HAL status
2260   */
HAL_ETH_ReadPHYRegister(ETH_HandleTypeDef * heth,uint32_t PHYAddr,uint32_t PHYReg,uint32_t * pRegValue)2261 HAL_StatusTypeDef HAL_ETH_ReadPHYRegister(ETH_HandleTypeDef *heth, uint32_t PHYAddr, uint32_t PHYReg,
2262                                           uint32_t *pRegValue)
2263 {
2264   uint32_t tickstart;
2265   uint32_t tmpreg;
2266 
2267   /* Check for the Busy flag */
2268   if (READ_BIT(heth->Instance->MACMDIOAR, ETH_MACMDIOAR_GB) != (uint32_t)RESET)
2269   {
2270     return HAL_ERROR;
2271   }
2272 
2273   /* Get the  MACMDIOAR value */
2274   WRITE_REG(tmpreg, heth->Instance->MACMDIOAR);
2275 
2276   /* Prepare the MDIO Address Register value
2277      - Set the PHY device address
2278      - Set the PHY register address
2279      - Set the read mode
2280      - Set the MII Busy bit */
2281 
2282   MODIFY_REG(tmpreg, ETH_MACMDIOAR_PA, (PHYAddr << 21));
2283   MODIFY_REG(tmpreg, ETH_MACMDIOAR_RDA, (PHYReg << 16));
2284   MODIFY_REG(tmpreg, ETH_MACMDIOAR_GOC, (ETH_MACMDIOAR_GOC_1 | ETH_MACMDIOAR_GOC_0));
2285   SET_BIT(tmpreg, ETH_MACMDIOAR_GB);
2286 
2287   /* Write the result value into the MDII Address register */
2288   WRITE_REG(heth->Instance->MACMDIOAR, tmpreg);
2289 
2290   tickstart = HAL_GetTick();
2291 
2292   /* Wait for the Busy flag */
2293   while (READ_BIT(heth->Instance->MACMDIOAR, ETH_MACMDIOAR_GB) > 0U)
2294   {
2295     if (((HAL_GetTick() - tickstart) > ETH_MDIO_BUS_TIMEOUT))
2296     {
2297       return HAL_ERROR;
2298     }
2299   }
2300 
2301   /* Get MACMIIDR value */
2302   WRITE_REG(*pRegValue, (uint16_t)heth->Instance->MACMDIODR);
2303 
2304   return HAL_OK;
2305 }
2306 
2307 /**
2308   * @brief  Writes to a PHY register.
2309   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2310   *         the configuration information for ETHERNET module
2311   * @param  PHYAddr: PHY port address, must be a value from 0 to 31
2312   * @param  PHYReg: PHY register address, must be a value from 0 to 31
2313   * @param  RegValue: the value to write
2314   * @retval HAL status
2315   */
HAL_ETH_WritePHYRegister(const ETH_HandleTypeDef * heth,uint32_t PHYAddr,uint32_t PHYReg,uint32_t RegValue)2316 HAL_StatusTypeDef HAL_ETH_WritePHYRegister(const ETH_HandleTypeDef *heth, uint32_t PHYAddr, uint32_t PHYReg,
2317                                            uint32_t RegValue)
2318 {
2319   uint32_t tickstart;
2320   uint32_t tmpreg;
2321 
2322   /* Check for the Busy flag */
2323   if (READ_BIT(heth->Instance->MACMDIOAR, ETH_MACMDIOAR_GB) != (uint32_t)RESET)
2324   {
2325     return HAL_ERROR;
2326   }
2327 
2328   /* Get the  MACMDIOAR value */
2329   WRITE_REG(tmpreg, heth->Instance->MACMDIOAR);
2330 
2331   /* Prepare the MDIO Address Register value
2332      - Set the PHY device address
2333      - Set the PHY register address
2334      - Set the write mode
2335      - Set the MII Busy bit */
2336 
2337   MODIFY_REG(tmpreg, ETH_MACMDIOAR_PA, (PHYAddr << 21));
2338   MODIFY_REG(tmpreg, ETH_MACMDIOAR_RDA, (PHYReg << 16));
2339   MODIFY_REG(tmpreg, ETH_MACMDIOAR_GOC, ETH_MACMDIOAR_GOC_0);
2340   SET_BIT(tmpreg, ETH_MACMDIOAR_GB);
2341 
2342   /* Give the value to the MII data register */
2343   WRITE_REG(heth->Instance->MACMDIODR, (uint16_t)RegValue);
2344 
2345   /* Write the result value into the MII Address register */
2346   WRITE_REG(heth->Instance->MACMDIOAR, tmpreg);
2347 
2348   tickstart = HAL_GetTick();
2349 
2350   /* Wait for the Busy flag */
2351   while (READ_BIT(heth->Instance->MACMDIOAR, ETH_MACMDIOAR_GB) > 0U)
2352   {
2353     if (((HAL_GetTick() - tickstart) > ETH_MDIO_BUS_TIMEOUT))
2354     {
2355       return HAL_ERROR;
2356     }
2357   }
2358 
2359   return HAL_OK;
2360 }
2361 
2362 /**
2363   * @}
2364   */
2365 
2366 /** @defgroup ETH_Exported_Functions_Group3 Peripheral Control functions
2367   *  @brief   ETH control functions
2368   *
2369 @verbatim
2370   ==============================================================================
2371                       ##### Peripheral Control functions #####
2372   ==============================================================================
2373   [..]
2374     This subsection provides a set of functions allowing to control the ETH
2375     peripheral.
2376 
2377 @endverbatim
2378   * @{
2379   */
2380 /**
2381   * @brief  Get the configuration of the MAC and MTL subsystems.
2382   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2383   *         the configuration information for ETHERNET module
2384   * @param  macconf: pointer to a ETH_MACConfigTypeDef structure that will hold
2385   *         the configuration of the MAC.
2386   * @retval HAL Status
2387   */
HAL_ETH_GetMACConfig(const ETH_HandleTypeDef * heth,ETH_MACConfigTypeDef * macconf)2388 HAL_StatusTypeDef HAL_ETH_GetMACConfig(const ETH_HandleTypeDef *heth, ETH_MACConfigTypeDef *macconf)
2389 {
2390   if (macconf == NULL)
2391   {
2392     return HAL_ERROR;
2393   }
2394 
2395   /* Get MAC parameters */
2396   macconf->PreambleLength = READ_BIT(heth->Instance->MACCR, ETH_MACCR_PRELEN);
2397   macconf->DeferralCheck = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_DC) >> 4) > 0U) ? ENABLE : DISABLE;
2398   macconf->BackOffLimit = READ_BIT(heth->Instance->MACCR, ETH_MACCR_BL);
2399   macconf->RetryTransmission = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_DR) >> 8) == 0U) ? ENABLE : DISABLE;
2400   macconf->CarrierSenseDuringTransmit = ((READ_BIT(heth->Instance->MACCR,
2401                                                    ETH_MACCR_DCRS) >> 9) > 0U) ? ENABLE : DISABLE;
2402   macconf->ReceiveOwn = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_DO) >> 10) == 0U) ? ENABLE : DISABLE;
2403   macconf->CarrierSenseBeforeTransmit = ((READ_BIT(heth->Instance->MACCR,
2404                                                    ETH_MACCR_ECRSFD) >> 11) > 0U) ? ENABLE : DISABLE;
2405   macconf->LoopbackMode = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_LM) >> 12) > 0U) ? ENABLE : DISABLE;
2406   macconf->DuplexMode = READ_BIT(heth->Instance->MACCR, ETH_MACCR_DM);
2407   macconf->Speed = READ_BIT(heth->Instance->MACCR, ETH_MACCR_FES);
2408   macconf->PortSelect = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_PS) >> 15) > 0U) ? ENABLE : DISABLE;
2409   macconf->JumboPacket = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_JE) >> 16) > 0U) ? ENABLE : DISABLE;
2410   macconf->Jabber = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_JD) >> 17) == 0U) ? ENABLE : DISABLE;
2411   macconf->PacketBurst = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_PB) >> 18) > 0U) ? ENABLE : DISABLE;
2412   macconf->Watchdog = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_WD) >> 19) == 0U) ? ENABLE : DISABLE;
2413   macconf->AutomaticPadCRCStrip = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_ACS) >> 20) > 0U) ? ENABLE : DISABLE;
2414   macconf->CRCStripTypePacket = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_CST) >> 21) > 0U) ? ENABLE : DISABLE;
2415   macconf->Support2KPacket = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_S2KP) >> 22) > 0U) ? ENABLE : DISABLE;
2416   macconf->GiantPacketSizeLimitControl = ((READ_BIT(heth->Instance->MACCR,
2417                                                     ETH_MACCR_GPSLCE) >> 23) > 0U) ? ENABLE : DISABLE;
2418   macconf->InterPacketGapVal = READ_BIT(heth->Instance->MACCR, ETH_MACCR_IPG);
2419   macconf->ChecksumOffload = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_IPC) >> 27) > 0U) ? ENABLE : DISABLE;
2420   macconf->SourceAddrControl = READ_BIT(heth->Instance->MACCR, ETH_MACCR_SARC);
2421   macconf->GiantPacketSizeLimit = READ_BIT(heth->Instance->MACECR, ETH_MACECR_GPSL);
2422   macconf->CRCCheckingRxPackets = ((READ_BIT(heth->Instance->MACECR,
2423                                              ETH_MACECR_DCRCC) >> 16) == 0U) ? ENABLE : DISABLE;
2424   macconf->SlowProtocolDetect = ((READ_BIT(heth->Instance->MACECR, ETH_MACECR_SPEN) >> 17) > 0U) ? ENABLE : DISABLE;
2425   macconf->UnicastSlowProtocolPacketDetect = ((READ_BIT(heth->Instance->MACECR,
2426                                                         ETH_MACECR_USP) >> 18) > 0U) ? ENABLE : DISABLE;
2427   macconf->ExtendedInterPacketGap = ((READ_BIT(heth->Instance->MACECR,
2428                                                ETH_MACECR_EIPGEN) >> 24) > 0U) ? ENABLE : DISABLE;
2429   macconf->ExtendedInterPacketGapVal = READ_BIT(heth->Instance->MACECR, ETH_MACECR_EIPG) >> 25;
2430   macconf->ProgrammableWatchdog = ((READ_BIT(heth->Instance->MACWTR, ETH_MACWTR_PWE) >> 8) > 0U) ? ENABLE : DISABLE;
2431   macconf->WatchdogTimeout = READ_BIT(heth->Instance->MACWTR, ETH_MACWTR_WTO);
2432   macconf->TransmitFlowControl = ((READ_BIT(heth->Instance->MACQ0TXFCR,
2433                                             ETH_MACQ0TXFCR_TFE) >> 1) > 0U) ? ENABLE : DISABLE;
2434   macconf->ZeroQuantaPause = ((READ_BIT(heth->Instance->MACQ0TXFCR,
2435                                         ETH_MACQ0TXFCR_DZPQ) >> 7) == 0U) ? ENABLE : DISABLE;
2436   macconf->PauseLowThreshold = READ_BIT(heth->Instance->MACQ0TXFCR, ETH_MACQ0TXFCR_PLT);
2437   macconf->PauseTime = (READ_BIT(heth->Instance->MACQ0TXFCR, ETH_MACQ0TXFCR_PT) >> 16);
2438   macconf->ReceiveFlowControl = (READ_BIT(heth->Instance->MACRXFCR, ETH_MACRXFCR_RFE) > 0U) ? ENABLE : DISABLE;
2439   macconf->UnicastPausePacketDetect = ((READ_BIT(heth->Instance->MACRXFCR,
2440                                                  ETH_MACRXFCR_UP) >> 1) > 0U) ? ENABLE : DISABLE;
2441 
2442   return HAL_OK;
2443 }
2444 
2445 /**
2446   * @brief  Get the configuration of the DMA.
2447   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2448   *         the configuration information for ETHERNET module
2449   * @param  dmaconf: pointer to a ETH_DMAConfigTypeDef structure that will hold
2450   *         the configuration of the ETH DMA.
2451   * @retval HAL Status
2452   */
HAL_ETH_GetDMAConfig(const ETH_HandleTypeDef * heth,ETH_DMAConfigTypeDef * dmaconf)2453 HAL_StatusTypeDef HAL_ETH_GetDMAConfig(const ETH_HandleTypeDef *heth, ETH_DMAConfigTypeDef *dmaconf)
2454 {
2455   uint32_t ch;
2456 
2457   if (dmaconf == NULL)
2458   {
2459     return HAL_ERROR;
2460   }
2461 
2462   dmaconf->AddressAlignedBeats = ((READ_BIT(heth->Instance->DMASBMR, ETH_DMASBMR_AAL) >> 12) > 0U) ? ENABLE : DISABLE;
2463   dmaconf->BurstMode = READ_BIT(heth->Instance->DMASBMR, ETH_DMASBMR_FB);
2464   dmaconf->RxOSRLimit = READ_BIT(heth->Instance->DMASBMR, ETH_DMASBMR_RD_OSR_LMT_1 | ETH_DMASBMR_RD_OSR_LMT_0);
2465   dmaconf->TxOSRLimit = READ_BIT(heth->Instance->DMASBMR, ETH_DMASBMR_WR_OSR_LMT_1 | ETH_DMASBMR_WR_OSR_LMT_0);
2466   dmaconf->TransmitArbitrationAlgorithm = READ_BIT(heth->Instance->DMAMR, (ETH_DMAMR_TAA_WRR | ETH_DMAMR_TAA_WSP));
2467   dmaconf->TransmitPriority = ((READ_BIT(heth->Instance->DMAMR, ETH_DMAMR_TXPR) >> 11) > 0U) ? ENABLE : DISABLE;
2468   dmaconf->AXIBLENMaxSize = READ_BIT(heth->Instance->DMASBMR, ETH_DMASBMR_BLEN256 | ETH_DMASBMR_BLEN128 |
2469                                      ETH_DMASBMR_BLEN64 | ETH_DMASBMR_BLEN32 |
2470                                      ETH_DMASBMR_BLEN16 | ETH_DMASBMR_BLEN8 | ETH_DMASBMR_BLEN4);
2471 
2472   for (ch = 0; ch < ETH_DMA_CH_CNT; ch++)
2473   {
2474     dmaconf->DMACh[ch].RxDMABurstLength = READ_BIT(heth->Instance->DMA_CH[ch].DMACRXCR, ETH_DMACxRXCR_RXPBL);
2475     dmaconf->DMACh[ch].SecondPacketOperate = ((READ_BIT(heth->Instance->DMA_CH[ch].DMACTXCR,
2476                                                         ETH_DMACxTXCR_OSF) >> 4) > 0U) ? ENABLE : DISABLE;
2477     dmaconf->DMACh[ch].TCPSegmentation = ((READ_BIT(heth->Instance->DMA_CH[ch].DMACTXCR,
2478                                                     ETH_DMACxTXCR_TSE) >> 12) > 0U) ? ENABLE : DISABLE;
2479     dmaconf->DMACh[ch].TxDMABurstLength = READ_BIT(heth->Instance->DMA_CH[ch].DMACTXCR, ETH_DMACxTXCR_TXPBL);
2480     dmaconf->DMACh[ch].DescriptorSkipLength = READ_BIT(heth->Instance->DMA_CH[ch].DMACCR, ETH_DMACxCR_DSL);
2481     dmaconf->DMACh[ch].PBLx8Mode = ((READ_BIT(heth->Instance->DMA_CH[ch].DMACCR,
2482                                               ETH_DMACxCR_PBLX8) >> 16) > 0U) ? ENABLE : DISABLE;
2483     dmaconf->DMACh[ch].FlushRxPacket = ((READ_BIT(heth->Instance->DMA_CH[ch].DMACRXCR,
2484                                                   ETH_DMACxRXCR_RPF) >> 31) > 0U) ? ENABLE : DISABLE;
2485     dmaconf->DMACh[ch].MaximumSegmentSize = READ_BIT(heth->Instance->DMA_CH[ch].DMACCR, ETH_DMACxCR_MSS);
2486   }
2487 
2488   return HAL_OK;
2489 }
2490 
2491 /**
2492   * @brief  Set the MAC configuration.
2493   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2494   *         the configuration information for ETHERNET module
2495   * @param  macconf: pointer to a ETH_MACConfigTypeDef structure that contains
2496   *         the configuration of the MAC.
2497   * @retval HAL status
2498   */
HAL_ETH_SetMACConfig(ETH_HandleTypeDef * heth,ETH_MACConfigTypeDef * macconf)2499 HAL_StatusTypeDef HAL_ETH_SetMACConfig(ETH_HandleTypeDef *heth,  ETH_MACConfigTypeDef *macconf)
2500 {
2501   if (macconf == NULL)
2502   {
2503     return HAL_ERROR;
2504   }
2505 
2506   if (heth->gState == HAL_ETH_STATE_READY)
2507   {
2508     ETH_SetMACConfig(heth, macconf);
2509 
2510     return HAL_OK;
2511   }
2512   else
2513   {
2514     return HAL_ERROR;
2515   }
2516 }
2517 
2518 /**
2519   * @brief  Set the ETH DMA configuration.
2520   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2521   *         the configuration information for ETHERNET module
2522   * @param  dmaconf: pointer to a ETH_DMAConfigTypeDef structure that will hold
2523   *         the configuration of the ETH DMA.
2524   * @retval HAL status
2525   */
HAL_ETH_SetDMAConfig(ETH_HandleTypeDef * heth,ETH_DMAConfigTypeDef * dmaconf)2526 HAL_StatusTypeDef HAL_ETH_SetDMAConfig(ETH_HandleTypeDef *heth,  ETH_DMAConfigTypeDef *dmaconf)
2527 {
2528   if (dmaconf == NULL)
2529   {
2530     return HAL_ERROR;
2531   }
2532 
2533   if (heth->gState == HAL_ETH_STATE_READY)
2534   {
2535     ETH_SetDMAConfig(heth, dmaconf);
2536 
2537     return HAL_OK;
2538   }
2539   else
2540   {
2541     return HAL_ERROR;
2542   }
2543 }
2544 
2545 /**
2546   * @brief  Configures the Clock range of ETH MDIO interface.
2547   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2548   *         the configuration information for ETHERNET module
2549   * @retval None
2550   */
HAL_ETH_SetMDIOClockRange(ETH_HandleTypeDef * heth)2551 void HAL_ETH_SetMDIOClockRange(ETH_HandleTypeDef *heth)
2552 {
2553   uint32_t hclk;
2554   uint32_t tmpreg;
2555 
2556   /* Get the ETHERNET MACMDIOAR value */
2557   tmpreg = (heth->Instance)->MACMDIOAR;
2558 
2559   /* Clear CSR Clock Range bits */
2560   tmpreg &= ~ETH_MACMDIOAR_CR;
2561 
2562   /* Get hclk frequency value */
2563   hclk = HAL_RCC_GetHCLKFreq();
2564 
2565   /* Set CR bits depending on hclk value */
2566   if (hclk < 35000000U)
2567   {
2568     /* CSR Clock Range between 0-35 MHz */
2569     tmpreg |= (uint32_t)ETH_MACMDIOAR_CR_DIV16;
2570   }
2571   else if (hclk < 60000000U)
2572   {
2573     /* CSR Clock Range between 35-60 MHz */
2574     tmpreg |= (uint32_t)ETH_MACMDIOAR_CR_DIV26;
2575   }
2576   else if (hclk < 100000000U)
2577   {
2578     /* CSR Clock Range between 60-100 MHz */
2579     tmpreg |= (uint32_t)ETH_MACMDIOAR_CR_DIV42;
2580   }
2581   else if (hclk < 150000000U)
2582   {
2583     /* CSR Clock Range between 100-150 MHz */
2584     tmpreg |= (uint32_t)ETH_MACMDIOAR_CR_DIV62;
2585   }
2586   else if (hclk < 250000000U)
2587   {
2588     /* CSR Clock Range between 150-250 MHz */
2589     tmpreg |= (uint32_t)ETH_MACMDIOAR_CR_DIV102;
2590   }
2591   else if (hclk < 300000000U)
2592   {
2593     /* CSR Clock Range between 250-300 MHz */
2594     tmpreg |= (uint32_t)(ETH_MACMDIOAR_CR_DIV124);
2595   }
2596   else if (hclk < 500000000U)
2597   {
2598     /* CSR Clock Range between 300-500 MHz */
2599     tmpreg |= (uint32_t)(ETH_MACMDIOAR_CR_DIV204);
2600   }
2601   else /* (hclk >= 500000000U)  */
2602   {
2603     /* CSR Clock >= 500 MHz */
2604     tmpreg |= (uint32_t)(ETH_MACMDIOAR_CR_DIV324);
2605   }
2606 
2607   /* Configure the CSR Clock Range */
2608   (heth->Instance)->MACMDIOAR = (uint32_t)tmpreg;
2609 }
2610 
2611 /**
2612   * @brief  Set the ETH MAC (L2) Filters configuration.
2613   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2614   *         the configuration information for ETHERNET module
2615   * @param  pFilterConfig: pointer to a ETH_MACFilterConfigTypeDef structure that contains
2616   *         the configuration of the ETH MAC filters.
2617   * @retval HAL status
2618   */
HAL_ETH_SetMACFilterConfig(ETH_HandleTypeDef * heth,const ETH_MACFilterConfigTypeDef * pFilterConfig)2619 HAL_StatusTypeDef HAL_ETH_SetMACFilterConfig(ETH_HandleTypeDef *heth, const ETH_MACFilterConfigTypeDef *pFilterConfig)
2620 {
2621   uint32_t filterconfig;
2622 
2623   if (pFilterConfig == NULL)
2624   {
2625     return HAL_ERROR;
2626   }
2627 
2628   filterconfig = ((uint32_t)pFilterConfig->PromiscuousMode |
2629                   ((uint32_t)pFilterConfig->HashUnicast << 1) |
2630                   ((uint32_t)pFilterConfig->HashMulticast << 2)  |
2631                   ((uint32_t)pFilterConfig->DestAddrInverseFiltering << 3) |
2632                   ((uint32_t)pFilterConfig->PassAllMulticast << 4) |
2633                   ((uint32_t)((pFilterConfig->BroadcastFilter == ENABLE) ? 1U : 0U) << 5) |
2634                   ((uint32_t)pFilterConfig->SrcAddrInverseFiltering << 8) |
2635                   ((uint32_t)pFilterConfig->SrcAddrFiltering << 9) |
2636                   ((uint32_t)pFilterConfig->HachOrPerfectFilter << 10) |
2637                   ((uint32_t)pFilterConfig->ReceiveAllMode << 31) |
2638                   pFilterConfig->ControlPacketsFilter);
2639 
2640   MODIFY_REG(heth->Instance->MACPFR, ETH_MACPFR_MASK, filterconfig);
2641 
2642   return HAL_OK;
2643 }
2644 
2645 /**
2646   * @brief  Get the ETH MAC (L2) Filters configuration.
2647   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2648   *         the configuration information for ETHERNET module
2649   * @param  pFilterConfig: pointer to a ETH_MACFilterConfigTypeDef structure that will hold
2650   *         the configuration of the ETH MAC filters.
2651   * @retval HAL status
2652   */
HAL_ETH_GetMACFilterConfig(const ETH_HandleTypeDef * heth,ETH_MACFilterConfigTypeDef * pFilterConfig)2653 HAL_StatusTypeDef HAL_ETH_GetMACFilterConfig(const ETH_HandleTypeDef *heth, ETH_MACFilterConfigTypeDef *pFilterConfig)
2654 {
2655   if (pFilterConfig == NULL)
2656   {
2657     return HAL_ERROR;
2658   }
2659 
2660   pFilterConfig->PromiscuousMode = ((READ_BIT(heth->Instance->MACPFR, ETH_MACPFR_PR)) > 0U) ? ENABLE : DISABLE;
2661   pFilterConfig->HashUnicast = ((READ_BIT(heth->Instance->MACPFR, ETH_MACPFR_HUC) >> 1) > 0U) ? ENABLE : DISABLE;
2662   pFilterConfig->HashMulticast = ((READ_BIT(heth->Instance->MACPFR, ETH_MACPFR_HMC) >> 2) > 0U) ? ENABLE : DISABLE;
2663   pFilterConfig->DestAddrInverseFiltering = ((READ_BIT(heth->Instance->MACPFR,
2664                                                        ETH_MACPFR_DAIF) >> 3) > 0U) ? ENABLE : DISABLE;
2665   pFilterConfig->PassAllMulticast = ((READ_BIT(heth->Instance->MACPFR, ETH_MACPFR_PM) >> 4) > 0U) ? ENABLE : DISABLE;
2666   pFilterConfig->BroadcastFilter = ((READ_BIT(heth->Instance->MACPFR, ETH_MACPFR_DBF) >> 5) > 0U) ? ENABLE : DISABLE;
2667   pFilterConfig->ControlPacketsFilter = READ_BIT(heth->Instance->MACPFR, ETH_MACPFR_PCF);
2668   pFilterConfig->SrcAddrInverseFiltering = ((READ_BIT(heth->Instance->MACPFR,
2669                                                       ETH_MACPFR_SAIF) >> 8) > 0U) ? ENABLE : DISABLE;
2670   pFilterConfig->SrcAddrFiltering = ((READ_BIT(heth->Instance->MACPFR, ETH_MACPFR_SAF) >> 9) > 0U) ? ENABLE : DISABLE;
2671   pFilterConfig->HachOrPerfectFilter = ((READ_BIT(heth->Instance->MACPFR, ETH_MACPFR_HPF) >> 10) > 0U)
2672                                        ? ENABLE : DISABLE;
2673   pFilterConfig->ReceiveAllMode = ((READ_BIT(heth->Instance->MACPFR, ETH_MACPFR_RA) >> 31) > 0U) ? ENABLE : DISABLE;
2674 
2675   return HAL_OK;
2676 }
2677 
2678 /**
2679   * @brief  Set the source MAC Address to be matched.
2680   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2681   *         the configuration information for ETHERNET module
2682   * @param  AddrNbr: The MAC address to configure
2683   *          This parameter must be a value of the following:
2684   *            ETH_MAC_ADDRESS1
2685   *            ETH_MAC_ADDRESS2
2686   *            ETH_MAC_ADDRESS3
2687   * @param  pMACAddr: Pointer to MAC address buffer data (6 bytes)
2688   * @retval HAL status
2689   */
HAL_ETH_SetSourceMACAddrMatch(const ETH_HandleTypeDef * heth,uint32_t AddrNbr,const uint8_t * pMACAddr)2690 HAL_StatusTypeDef HAL_ETH_SetSourceMACAddrMatch(const ETH_HandleTypeDef *heth, uint32_t AddrNbr,
2691                                                 const uint8_t *pMACAddr)
2692 {
2693   uint32_t macaddrlr;
2694   uint32_t macaddrhr;
2695 
2696   if (pMACAddr == NULL)
2697   {
2698     return HAL_ERROR;
2699   }
2700 
2701   /* Get mac addr high reg offset */
2702   macaddrhr = ((uint32_t) &(heth->Instance->MACA0HR) + AddrNbr);
2703   /* Get mac addr low reg offset */
2704   macaddrlr = ((uint32_t) &(heth->Instance->MACA0LR) + AddrNbr);
2705 
2706   /* Set MAC addr bits 32 to 47 */
2707   (*(__IO uint32_t *)macaddrhr) = (((uint32_t)(pMACAddr[5]) << 8) | (uint32_t)pMACAddr[4]);
2708   /* Set MAC addr bits 0 to 31 */
2709   (*(__IO uint32_t *)macaddrlr) = (((uint32_t)(pMACAddr[3]) << 24) | ((uint32_t)(pMACAddr[2]) << 16) |
2710                                    ((uint32_t)(pMACAddr[1]) << 8) | (uint32_t)pMACAddr[0]);
2711 
2712   /* Enable address and set source address bit */
2713   (*(__IO uint32_t *)macaddrhr) |= (ETH_MACAxHR_SA | ETH_MACAxHR_AE);
2714 
2715   return HAL_OK;
2716 }
2717 
2718 /**
2719   * @brief  Set the ETH Hash Table Value.
2720   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2721   *         the configuration information for ETHERNET module
2722   * @param  pHashTable: pointer to a table of two 32 bit values, that contains
2723   *         the 64 bits of the hash table.
2724   * @retval HAL status
2725   */
HAL_ETH_SetHashTable(ETH_HandleTypeDef * heth,uint32_t * pHashTable)2726 HAL_StatusTypeDef HAL_ETH_SetHashTable(ETH_HandleTypeDef *heth, uint32_t *pHashTable)
2727 {
2728   if (pHashTable == NULL)
2729   {
2730     return HAL_ERROR;
2731   }
2732 
2733   heth->Instance->MACHT0R = pHashTable[0];
2734   heth->Instance->MACHT1R = pHashTable[1];
2735 
2736   return HAL_OK;
2737 }
2738 
2739 /**
2740   * @brief  Set the VLAN Identifier for Rx packets
2741   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2742   *         the configuration information for ETHERNET module
2743   * @param  ComparisonBits: 12 or 16 bit comparison mode
2744             must be a value of @ref ETH_VLAN_Tag_Comparison
2745   * @param  VLANIdentifier: VLAN Identifier value
2746   * @retval None
2747   */
HAL_ETH_SetRxVLANIdentifier(ETH_HandleTypeDef * heth,uint32_t ComparisonBits,uint32_t VLANIdentifier)2748 void HAL_ETH_SetRxVLANIdentifier(ETH_HandleTypeDef *heth, uint32_t ComparisonBits, uint32_t VLANIdentifier)
2749 {
2750   if (ComparisonBits == ETH_VLANTAGCOMPARISON_16BIT)
2751   {
2752     MODIFY_REG(heth->Instance->MACVTDR, ETH_MACVTDR_VID_16BIT, VLANIdentifier);
2753     CLEAR_BIT(heth->Instance->MACVTCR, ETH_MACVTCR_ETV);
2754   }
2755   else
2756   {
2757     MODIFY_REG(heth->Instance->MACVTDR, ETH_MACVTDR_VID_12BIT, VLANIdentifier);
2758     SET_BIT(heth->Instance->MACVTCR, ETH_MACVTCR_ETV);
2759   }
2760 }
2761 
2762 /**
2763   * @brief  Enters the Power down mode.
2764   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2765   *         the configuration information for ETHERNET module
2766   * @param  pPowerDownConfig: a pointer to ETH_PowerDownConfigTypeDef structure
2767   *         that contains the Power Down configuration
2768   * @retval None.
2769   */
HAL_ETH_EnterPowerDownMode(ETH_HandleTypeDef * heth,const ETH_PowerDownConfigTypeDef * pPowerDownConfig)2770 void HAL_ETH_EnterPowerDownMode(ETH_HandleTypeDef *heth, const ETH_PowerDownConfigTypeDef *pPowerDownConfig)
2771 {
2772   uint32_t powerdownconfig;
2773 
2774   powerdownconfig = (((uint32_t)pPowerDownConfig->MagicPacket << 1) |
2775                      ((uint32_t)pPowerDownConfig->WakeUpPacket << 2) |
2776                      ((uint32_t)pPowerDownConfig->GlobalUnicast << 9) |
2777                      ((uint32_t)pPowerDownConfig->WakeUpForward << 10) |
2778                      ETH_MACPCSR_PWRDWN);
2779 
2780   /* Enable PMT interrupt */
2781   __HAL_ETH_MAC_ENABLE_IT(heth, ETH_MACIER_PMTIE);
2782 
2783   MODIFY_REG(heth->Instance->MACPCSR, ETH_MACPCSR_MASK, powerdownconfig);
2784 }
2785 
2786 /**
2787   * @brief  Exits from the Power down mode.
2788   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2789   *         the configuration information for ETHERNET module
2790   * @retval None.
2791   */
HAL_ETH_ExitPowerDownMode(ETH_HandleTypeDef * heth)2792 void HAL_ETH_ExitPowerDownMode(ETH_HandleTypeDef *heth)
2793 {
2794   /* clear wake up sources */
2795   CLEAR_BIT(heth->Instance->MACPCSR, ETH_MACPCSR_RWKPKTEN | ETH_MACPCSR_MGKPKTEN | ETH_MACPCSR_GLBLUCAST |
2796             ETH_MACPCSR_RWKPFE);
2797 
2798   if (READ_BIT(heth->Instance->MACPCSR, ETH_MACPCSR_PWRDWN) != (uint32_t)RESET)
2799   {
2800     /* Exit power down mode */
2801     CLEAR_BIT(heth->Instance->MACPCSR, ETH_MACPCSR_PWRDWN);
2802   }
2803 
2804   /* Disable PMT interrupt */
2805   __HAL_ETH_MAC_DISABLE_IT(heth, ETH_MACIER_PMTIE);
2806 }
2807 
2808 /**
2809   * @brief  Set the WakeUp filter.
2810   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2811   *         the configuration information for ETHERNET module
2812   * @param  pFilter: pointer to filter registers values
2813   * @param  Count: number of filter registers, must be from 1 to 8.
2814   * @retval None.
2815   */
HAL_ETH_SetWakeUpFilter(ETH_HandleTypeDef * heth,uint32_t * pFilter,uint32_t Count)2816 HAL_StatusTypeDef HAL_ETH_SetWakeUpFilter(ETH_HandleTypeDef *heth, uint32_t *pFilter, uint32_t Count)
2817 {
2818   uint32_t regindex;
2819 
2820   if (pFilter == NULL)
2821   {
2822     return HAL_ERROR;
2823   }
2824 
2825   /* Reset Filter Pointer */
2826   SET_BIT(heth->Instance->MACPCSR, ETH_MACPCSR_RWKFILTRST);
2827 
2828   /* Wake up packet filter config */
2829   for (regindex = 0; regindex < Count; regindex++)
2830   {
2831     /* Write filter regs */
2832     WRITE_REG(heth->Instance->MACRWKPFR, pFilter[regindex]);
2833   }
2834 
2835   return HAL_OK;
2836 }
2837 
2838 /**
2839   * @}
2840   */
2841 
2842 /** @defgroup ETH_Exported_Functions_Group4 Peripheral State and Errors functions
2843   *  @brief   ETH State and Errors functions
2844   *
2845 @verbatim
2846   ==============================================================================
2847                  ##### Peripheral State and Errors functions #####
2848   ==============================================================================
2849  [..]
2850    This subsection provides a set of functions allowing to return the State of
2851    ETH communication process, return Peripheral Errors occurred during communication
2852    process
2853 
2854 
2855 @endverbatim
2856   * @{
2857   */
2858 
2859 /**
2860   * @brief  Returns the ETH state.
2861   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2862   *         the configuration information for ETHERNET module
2863   * @retval HAL state
2864   */
HAL_ETH_GetState(const ETH_HandleTypeDef * heth)2865 HAL_ETH_StateTypeDef HAL_ETH_GetState(const ETH_HandleTypeDef *heth)
2866 {
2867   return heth->gState;
2868 }
2869 
2870 /**
2871   * @brief  Returns the ETH error code
2872   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2873   *         the configuration information for ETHERNET module
2874   * @retval ETH Error Code
2875   */
HAL_ETH_GetError(const ETH_HandleTypeDef * heth)2876 uint32_t HAL_ETH_GetError(const ETH_HandleTypeDef *heth)
2877 {
2878   return heth->ErrorCode;
2879 }
2880 
2881 /**
2882   * @brief  Returns the ETH DMA error code
2883   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2884   *         the configuration information for ETHERNET module
2885   * @retval ETH DMA Error Code
2886   */
HAL_ETH_GetDMAError(const ETH_HandleTypeDef * heth)2887 uint32_t HAL_ETH_GetDMAError(const ETH_HandleTypeDef *heth)
2888 {
2889   return heth->DMAErrorCode;
2890 }
2891 
2892 /**
2893   * @brief  Returns the ETH MAC error code
2894   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2895   *         the configuration information for ETHERNET module
2896   * @retval ETH MAC Error Code
2897   */
HAL_ETH_GetMACError(const ETH_HandleTypeDef * heth)2898 uint32_t HAL_ETH_GetMACError(const ETH_HandleTypeDef *heth)
2899 {
2900   return heth->MACErrorCode;
2901 }
2902 
2903 /**
2904   * @brief  Returns the ETH MAC WakeUp event source
2905   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2906   *         the configuration information for ETHERNET module
2907   * @retval ETH MAC WakeUp event source
2908   */
HAL_ETH_GetMACWakeUpSource(const ETH_HandleTypeDef * heth)2909 uint32_t HAL_ETH_GetMACWakeUpSource(const ETH_HandleTypeDef *heth)
2910 {
2911   return heth->MACWakeUpEvent;
2912 }
2913 
2914 /**
2915   * @brief  Returns the ETH Tx Buffers in use number
2916   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2917   *         the configuration information for ETHERNET module
2918   * @retval ETH Tx Buffers in use number
2919   */
HAL_ETH_GetTxBuffersNumber(const ETH_HandleTypeDef * heth)2920 uint32_t HAL_ETH_GetTxBuffersNumber(const ETH_HandleTypeDef *heth)
2921 {
2922   uint32_t ch = heth->TxOpCH;
2923 
2924   return heth->TxDescList[ch].BuffersInUse;
2925 }
2926 /**
2927   * @}
2928   */
2929 
2930 /**
2931   * @}
2932   */
2933 
2934 /** @addtogroup ETH_Private_Functions   ETH Private Functions
2935   * @{
2936   */
2937 
ETH_SetMACConfig(ETH_HandleTypeDef * heth,const ETH_MACConfigTypeDef * macconf)2938 static void ETH_SetMACConfig(ETH_HandleTypeDef *heth, const ETH_MACConfigTypeDef *macconf)
2939 {
2940   uint32_t macregval;
2941 
2942   /*------------------------ MACCR Configuration --------------------*/
2943   macregval = (macconf->InterPacketGapVal |
2944                macconf->SourceAddrControl |
2945                ((uint32_t)macconf->ChecksumOffload << 27) |
2946                ((uint32_t)macconf->GiantPacketSizeLimitControl << 23) |
2947                ((uint32_t)macconf->Support2KPacket  << 22) |
2948                ((uint32_t)macconf->CRCStripTypePacket << 21) |
2949                ((uint32_t)macconf->AutomaticPadCRCStrip << 20) |
2950                ((uint32_t)((macconf->Watchdog == DISABLE) ? 1U : 0U) << 19) |
2951                ((uint32_t)macconf->PacketBurst << 18) |
2952                ((uint32_t)((macconf->Jabber == DISABLE) ? 1U : 0U) << 17) |
2953                ((uint32_t)macconf->JumboPacket << 16) |
2954                ((uint32_t)macconf->PortSelect << 15) |
2955                macconf->Speed |
2956                macconf->DuplexMode |
2957                ((uint32_t)macconf->LoopbackMode << 12) |
2958                ((uint32_t)macconf->CarrierSenseBeforeTransmit << 11) |
2959                ((uint32_t)((macconf->ReceiveOwn == DISABLE) ? 1U : 0U) << 10) |
2960                ((uint32_t)macconf->CarrierSenseDuringTransmit << 9) |
2961                ((uint32_t)((macconf->RetryTransmission == DISABLE) ? 1U : 0U) << 8) |
2962                macconf->BackOffLimit |
2963                ((uint32_t)macconf->DeferralCheck << 4) |
2964                macconf->PreambleLength);
2965 
2966   /* Write to MACCR */
2967   MODIFY_REG(heth->Instance->MACCR, ETH_MACCR_MASK, macregval);
2968 
2969   /*------------------------ MACECR Configuration --------------------*/
2970   macregval = ((macconf->ExtendedInterPacketGapVal << 25) |
2971                ((uint32_t)macconf->ExtendedInterPacketGap << 24) |
2972                ((uint32_t)macconf->UnicastSlowProtocolPacketDetect << 18) |
2973                ((uint32_t)macconf->SlowProtocolDetect << 17) |
2974                ((uint32_t)((macconf->CRCCheckingRxPackets == DISABLE) ? 1U : 0U) << 16) |
2975                macconf->GiantPacketSizeLimit);
2976 
2977   /* Write to MACECR */
2978   MODIFY_REG(heth->Instance->MACECR, ETH_MACECR_MASK, macregval);
2979 
2980   /*------------------------ MACWTR Configuration --------------------*/
2981   macregval = (((uint32_t)macconf->ProgrammableWatchdog << 8) |
2982                macconf->WatchdogTimeout);
2983 
2984   /* Write to MACWTR */
2985   MODIFY_REG(heth->Instance->MACWTR, ETH_MACWTR_MASK, macregval);
2986 
2987   /*------------------------ MACQ0TXFCR Configuration --------------------*/
2988   macregval = (((uint32_t)macconf->TransmitFlowControl << 1) |
2989                macconf->PauseLowThreshold |
2990                ((uint32_t)((macconf->ZeroQuantaPause == DISABLE) ? 1U : 0U) << 7) |
2991                (macconf->PauseTime << 16));
2992 
2993   /* Write to MACQ0TXFCR */
2994   MODIFY_REG(heth->Instance->MACQ0TXFCR, ETH_MACQ0TXFCR_MASK, macregval);
2995 
2996   /*------------------------ MACRXFCR Configuration --------------------*/
2997   macregval = ((uint32_t)macconf->ReceiveFlowControl |
2998                ((uint32_t)macconf->UnicastPausePacketDetect << 1));
2999 
3000   /* Write to MACRXFCR */
3001   MODIFY_REG(heth->Instance->MACRXFCR, ETH_MACRXFCR_MASK, macregval);
3002 
3003 }
3004 
ETH_SetDMAConfig(ETH_HandleTypeDef * heth,const ETH_DMAConfigTypeDef * dmaconf)3005 static void ETH_SetDMAConfig(ETH_HandleTypeDef *heth, const ETH_DMAConfigTypeDef *dmaconf)
3006 {
3007   uint32_t dmaregval;
3008   uint32_t ch;
3009 
3010   /*------------------------ DMAMR Configuration --------------------*/
3011   dmaregval = (dmaconf->TransmitArbitrationAlgorithm |
3012                ((uint32_t)dmaconf->TransmitPriority << 11)) ;
3013 
3014   MODIFY_REG(heth->Instance->DMAMR, ETH_DMAMR_MASK, dmaregval);
3015 
3016   /*------------------------ DMASBMR Configuration --------------------*/
3017   dmaregval = (((uint32_t)dmaconf->AddressAlignedBeats << 12) |
3018                dmaconf->BurstMode  |
3019                dmaconf->RxOSRLimit |
3020                dmaconf->TxOSRLimit |
3021                dmaconf->AXIBLENMaxSize);
3022 
3023   MODIFY_REG(heth->Instance->DMASBMR, ETH_DMASBMR_MASK, dmaregval);
3024 
3025   for (ch = 0; ch < ETH_DMA_CH_CNT; ch++)
3026   {
3027     /*------------------------ DMACCR Configuration --------------------*/
3028     dmaregval = (((uint32_t)(dmaconf->DMACh[ch]).PBLx8Mode << 16)          |
3029                  (dmaconf->DMACh[ch]).DescriptorSkipLength      |
3030                  (dmaconf->DMACh[ch]).MaximumSegmentSize);
3031 
3032     MODIFY_REG(heth->Instance->DMA_CH[ch].DMACCR, ETH_DMACxCR_MASK, dmaregval);
3033 
3034     /*------------------------ DMACTXCR Configuration --------------------*/
3035     dmaregval = (((dmaconf->DMACh[ch]).TxDMABurstLength) |
3036                  ((uint32_t)(dmaconf->DMACh[ch]).SecondPacketOperate << 4) |
3037                  ((uint32_t)(dmaconf->DMACh[ch]).TCPSegmentation << 12));
3038 
3039     MODIFY_REG(heth->Instance->DMA_CH[ch].DMACTXCR,
3040                (ETH_DMACxTXCR_TXPBL_Msk | ETH_DMACxTXCR_OSF_Msk | ETH_DMACxTXCR_TSE_Msk), dmaregval);
3041 
3042     /*------------------------ DMACRXCR Configuration --------------------*/
3043     dmaregval = (((uint32_t)(dmaconf->DMACh[ch]).FlushRxPacket  << 31) |
3044                  (dmaconf->DMACh[ch]).RxDMABurstLength);
3045 
3046     MODIFY_REG(heth->Instance->DMA_CH[ch].DMACRXCR, (ETH_DMACxRXCR_RXPBL_Msk | ETH_DMACxRXCR_RPF_Msk), dmaregval);
3047   }
3048 
3049 }
3050 
3051 /**
3052   * @brief  Configures Ethernet MAC and DMA with default parameters.
3053   *         called by HAL_ETH_Init() API.
3054   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
3055   *         the configuration information for ETHERNET module
3056   * @retval HAL status
3057   */
ETH_MACDMAConfig(ETH_HandleTypeDef * heth)3058 static void ETH_MACDMAConfig(ETH_HandleTypeDef *heth)
3059 {
3060   ETH_MACConfigTypeDef macDefaultConf = {0};
3061   ETH_MTLConfigTypeDef mtlDefaultConf = {0};
3062   ETH_DMAConfigTypeDef dmaDefaultConf;
3063   uint32_t queue;
3064   uint32_t ch;
3065 
3066   /*--------------- ETHERNET MAC registers default Configuration --------------*/
3067   macDefaultConf.AutomaticPadCRCStrip = ENABLE;
3068   macDefaultConf.BackOffLimit = ETH_BACKOFFLIMIT_10;
3069   macDefaultConf.CarrierSenseBeforeTransmit = DISABLE;
3070   macDefaultConf.CarrierSenseDuringTransmit = DISABLE;
3071   macDefaultConf.ChecksumOffload = ENABLE;
3072   macDefaultConf.CRCCheckingRxPackets = ENABLE;
3073   macDefaultConf.CRCStripTypePacket = ENABLE;
3074   macDefaultConf.DeferralCheck = DISABLE;
3075   macDefaultConf.DuplexMode = ETH_FULLDUPLEX_MODE;
3076   macDefaultConf.ExtendedInterPacketGap = DISABLE;
3077   macDefaultConf.ExtendedInterPacketGapVal = 0x0U;
3078   macDefaultConf.GiantPacketSizeLimit = 0x618U;
3079   macDefaultConf.GiantPacketSizeLimitControl = DISABLE;
3080   macDefaultConf.InterPacketGapVal = ETH_INTERPACKETGAP_96BIT;
3081   macDefaultConf.Jabber = ENABLE;
3082   macDefaultConf.JumboPacket = DISABLE;
3083   macDefaultConf.LoopbackMode = DISABLE;
3084   macDefaultConf.PacketBurst = DISABLE;
3085   if (heth->Init.MediaInterface == HAL_ETH_RGMII_MODE)
3086   {
3087     macDefaultConf.PortSelect = DISABLE;
3088   }
3089   else
3090   {
3091     /* force it for 10/100m */
3092     macDefaultConf.PortSelect = ENABLE;
3093   }
3094   macDefaultConf.PauseLowThreshold = ETH_PAUSELOWTHRESHOLD_MINUS_4;
3095   macDefaultConf.PauseTime = 0x0U;
3096   macDefaultConf.PreambleLength = ETH_PREAMBLELENGTH_7;
3097   macDefaultConf.ProgrammableWatchdog = DISABLE;
3098   macDefaultConf.ReceiveFlowControl = DISABLE;
3099   macDefaultConf.ReceiveOwn = ENABLE;
3100   macDefaultConf.RetryTransmission = ENABLE;
3101   macDefaultConf.SlowProtocolDetect = DISABLE;
3102   macDefaultConf.SourceAddrControl = ETH_MACCR_SARC_REPADDR0;
3103   macDefaultConf.Speed = ETH_SPEED_1000M;
3104   macDefaultConf.Support2KPacket = DISABLE;
3105   macDefaultConf.TransmitFlowControl = DISABLE;
3106   macDefaultConf.UnicastPausePacketDetect = DISABLE;
3107   macDefaultConf.UnicastSlowProtocolPacketDetect = DISABLE;
3108   macDefaultConf.Watchdog = ENABLE;
3109   macDefaultConf.WatchdogTimeout =  ETH_MACWTR_WTO_2KB;
3110   macDefaultConf.ZeroQuantaPause = ENABLE;
3111 
3112   /* MAC default configuration */
3113   ETH_SetMACConfig(heth, &macDefaultConf);
3114 
3115   /*--------------- ETHERNET MTL registers default Configuration --------------*/
3116   /* Common configuration for Q0 and Q1*/
3117   mtlDefaultConf.RxQ[0].MappedToDMACh = ETH_MTL_Q0_MAPPED_TO_DMA_CH0;
3118 #if ETH_MTL_RX_Q_CNT == 2
3119   mtlDefaultConf.RxQ[1].MappedToDMACh = ETH_MTL_Q1_MAPPED_TO_DMA_CH1;
3120 #endif /* ETH_MTL_TX_Q_CNT == 2 */
3121   mtlDefaultConf.ReceiveArbitrationAlgorithm = ETH_MTLOMR_RAA_SP;
3122   mtlDefaultConf.TxSchedulingAlgorithm = ETH_MTLOMR_SCHALG_SP;
3123   mtlDefaultConf.TransmitStatus = ENABLE;
3124 
3125   /* RxQ & TxQ configuration */
3126   mtlDefaultConf.RxQ[0].QueueOpMode = ETH_RX_QUEUE0_ENABLED;
3127   mtlDefaultConf.RxQ[1].QueueOpMode = ETH_RX_QUEUE1_ENABLED;
3128   mtlDefaultConf.TxQ[1].AVAlgorithm = ETH_TX_QUEUE_AV_ALGO_SP;
3129 
3130   for (queue = 0; queue < ETH_MTL_RX_Q_CNT; queue++)
3131   {
3132     /* RxQ configuration */
3133     mtlDefaultConf.RxQ[queue].DropTCPIPChecksumErrorPacket = ENABLE;
3134     mtlDefaultConf.RxQ[queue].ForwardRxErrorPacket = DISABLE;
3135     mtlDefaultConf.RxQ[queue].ForwardRxUndersizedGoodPacket = DISABLE;
3136     mtlDefaultConf.RxQ[queue].ReceiveQueueMode = ETH_RECEIVESTOREFORWARD;
3137     mtlDefaultConf.RxQ[queue].RxQueueSize = ETH_RECEIVE_QUEUE_SIZE_4096;
3138 
3139     /* TxQ configuration */
3140     mtlDefaultConf.TxQ[queue].TransmitQueueMode = ETH_TRANSMITSTOREFORWARD;
3141     mtlDefaultConf.TxQ[queue].QueueOpMode = ETH_TX_QUEUE_ENABLED;
3142     mtlDefaultConf.TxQ[queue].TxQueueSize = ETH_TRANSMIT_QUEUE_SIZE_2048;
3143   }
3144 
3145   /* MTL default configuration */
3146   ETHEx_SetMTLConfig(heth, &mtlDefaultConf);
3147 
3148   /*--------------- ETHERNET DMA registers default Configuration --------------*/
3149   /* Common DMA configuration */
3150   dmaDefaultConf.AddressAlignedBeats = ENABLE;
3151   dmaDefaultConf.AXIBLENMaxSize = ETH_BLEN_MAX_SIZE_4;
3152   dmaDefaultConf.BurstMode = ETH_BURSTLENGTH_FIXED;
3153   dmaDefaultConf.RxOSRLimit = ETH_RX_OSR_LIMIT_3;
3154   dmaDefaultConf.TxOSRLimit = ETH_TX_OSR_LIMIT_3;
3155   dmaDefaultConf.TransmitArbitrationAlgorithm = ETH_DMATXARBITRATION_FIXED_PRIO;
3156   dmaDefaultConf.TransmitPriority = DISABLE;
3157 
3158   for (ch = 0; ch < ETH_DMA_CH_CNT; ch++)
3159   {
3160     /* DMA CH configuration */
3161     dmaDefaultConf.DMACh[ch].FlushRxPacket = DISABLE;
3162     dmaDefaultConf.DMACh[ch].PBLx8Mode = DISABLE;
3163     dmaDefaultConf.DMACh[ch].RxDMABurstLength = ETH_RXDMABURSTLENGTH_32BEAT;
3164     dmaDefaultConf.DMACh[ch].SecondPacketOperate = DISABLE;
3165     dmaDefaultConf.DMACh[ch].TCPSegmentation = DISABLE;
3166     dmaDefaultConf.DMACh[ch].TxDMABurstLength = ETH_TXDMABURSTLENGTH_32BEAT;
3167     dmaDefaultConf.DMACh[ch].DescriptorSkipLength = ETH_DMA_DESC_SKIP_LENGTH_32;
3168     dmaDefaultConf.DMACh[ch].MaximumSegmentSize = ETH_SEGMENT_SIZE_DEFAULT;
3169   }
3170   /* DMA default configuration */
3171   ETH_SetDMAConfig(heth, &dmaDefaultConf);
3172 }
3173 
3174 
3175 /**
3176   * @brief  Initializes the DMA Tx descriptors.
3177   *         called by HAL_ETH_Init() API.
3178   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
3179   *         the configuration information for ETHERNET module
3180   * @retval None
3181   */
ETH_DMATxDescListInit(ETH_HandleTypeDef * heth)3182 static void ETH_DMATxDescListInit(ETH_HandleTypeDef *heth)
3183 {
3184   ETH_DMADescTypeDef *dmatxdesc;
3185   uint32_t i;
3186   uint32_t ch;
3187 
3188   /* Fill each DMATxDesc descriptor with the right values */
3189   for (ch = 0; ch < (uint32_t)ETH_DMA_TX_CH_CNT; ch++)
3190   {
3191     for (i = 0; i < (uint32_t)ETH_TX_DESC_CNT; i++)
3192     {
3193       dmatxdesc = heth->Init.TxDesc[ch] + i;
3194 
3195       WRITE_REG(dmatxdesc->DESC0, 0x0U);
3196       WRITE_REG(dmatxdesc->DESC1, 0x0U);
3197       WRITE_REG(dmatxdesc->DESC2, 0x0U);
3198       WRITE_REG(dmatxdesc->DESC3, 0x0U);
3199 
3200       WRITE_REG(heth->TxDescList[ch].TxDesc[i], (uint32_t)dmatxdesc);
3201     }
3202 
3203     heth->TxDescList[ch].CurTxDesc = 0;
3204   }
3205 
3206   for (ch = 0; ch < ETH_DMA_CH_CNT; ch++)
3207   {
3208     /* Set Transmit Descriptor Ring Length for DMA Channel  */
3209     WRITE_REG(heth->Instance->DMA_CH[ch].DMACTXRLR, (ETH_TX_DESC_CNT - 1U));
3210 
3211     /* Set Transmit Descriptor List Address for DMA Channel */
3212     WRITE_REG(heth->Instance->DMA_CH[ch].DMACTXDLAR, (uint32_t) heth->Init.TxDesc[ch]);
3213 
3214     /* Set Transmit Descriptor Tail pointer for DMA Channel  */
3215     WRITE_REG(heth->Instance->DMA_CH[ch].DMACTXDTPR, (uint32_t) heth->Init.TxDesc[ch]);
3216   }
3217 }
3218 
3219 /**
3220   * @brief  Initializes the DMA Rx descriptors in chain mode.
3221   *         called by HAL_ETH_Init() API.
3222   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
3223   *         the configuration information for ETHERNET module
3224   * @retval None
3225   */
ETH_DMARxDescListInit(ETH_HandleTypeDef * heth)3226 static void ETH_DMARxDescListInit(ETH_HandleTypeDef *heth)
3227 {
3228   ETH_DMADescTypeDef *dmarxdesc;
3229   uint32_t i;
3230   uint32_t ch;
3231 
3232   for (ch = 0; ch < (uint32_t)ETH_DMA_RX_CH_CNT; ch++)
3233   {
3234     /* Fill each DMACxRxDesc descriptor with the right values */
3235     for (i = 0; i < (uint32_t)ETH_RX_DESC_CNT; i++)
3236     {
3237       dmarxdesc =  heth->Init.RxDesc[ch] + i;
3238 
3239       WRITE_REG(dmarxdesc->DESC0, 0x0U);
3240       WRITE_REG(dmarxdesc->DESC1, 0x0U);
3241       WRITE_REG(dmarxdesc->DESC2, 0x0U);
3242       WRITE_REG(dmarxdesc->DESC3, 0x0U);
3243       WRITE_REG(dmarxdesc->BackupAddr0, 0x0U);
3244       WRITE_REG(dmarxdesc->BackupAddr1, 0x0U);
3245 
3246       /* Set Rx descritors addresses */
3247       WRITE_REG(heth->RxDescList[ch].RxDesc[i], (uint32_t)dmarxdesc);
3248     }
3249 
3250     /* Initialize DMA Ch Rx parameters */
3251     WRITE_REG(heth->RxDescList[ch].RxDescIdx, 0U);
3252     WRITE_REG(heth->RxDescList[ch].RxDescCnt, 0U);
3253     WRITE_REG(heth->RxDescList[ch].RxBuildDescIdx, 0U);
3254     WRITE_REG(heth->RxDescList[ch].RxBuildDescCnt, 0U);
3255     WRITE_REG(heth->RxDescList[ch].ItMode, 0U);
3256 
3257     /* Set Receive Descriptor Ring Length for DMA Channel */
3258     WRITE_REG(heth->Instance->DMA_CH[ch].DMACRXRLR, ((uint32_t)(ETH_RX_DESC_CNT - 1U)));
3259 
3260     /* Set Receive Descriptor List Address for DMA Channel */
3261     WRITE_REG(heth->Instance->DMA_CH[ch].DMACRXDLAR, (uint32_t) heth->Init.RxDesc[ch]);
3262 
3263     /* Set Receive Descriptor Tail pointer Address for DMA Channel */
3264     WRITE_REG(heth->Instance->DMA_CH[ch].DMACRXDTPR,
3265               ((uint32_t)(heth->Init.RxDesc[ch] + (uint32_t)(ETH_RX_DESC_CNT - 1U))));
3266   }
3267 }
3268 
3269 /**
3270   * @brief  Prepare Tx DMA descriptor before transmission.
3271   *         called by HAL_ETH_Transmit_IT and HAL_ETH_Transmit_IT() API.
3272   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
3273   *         the configuration information for ETHERNET module
3274   * @param  pTxConfig: Tx packet configuration
3275   * @param  ItMode: Enable or disable Tx EOT interrupt
3276   * @retval Status
3277   */
ETH_Prepare_Tx_Descriptors(ETH_HandleTypeDef * heth,const ETH_TxPacketConfigTypeDef * pTxConfig,uint32_t ItMode)3278 static uint32_t ETH_Prepare_Tx_Descriptors(ETH_HandleTypeDef *heth, const ETH_TxPacketConfigTypeDef *pTxConfig,
3279                                            uint32_t ItMode)
3280 {
3281   uint32_t ch = pTxConfig->TxDMACh;
3282 
3283   ETH_TxDescListTypeDef *dmatxdesclist = &heth->TxDescList[ch];
3284 
3285   uint32_t descidx = dmatxdesclist->CurTxDesc;
3286   uint32_t firstdescidx = dmatxdesclist->CurTxDesc;
3287 
3288   uint32_t idx;
3289   uint32_t descnbr = 0;
3290   ETH_DMADescTypeDef *dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[descidx];
3291 
3292   ETH_BufferTypeDef  *txbuffer = pTxConfig->TxBuffer;
3293   uint32_t           bd_count = 0;
3294   uint32_t primask_bit;
3295 
3296   /* Current Tx Descriptor Owned by DMA: cannot be used by the application  */
3297   if ((READ_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCWBF_OWN) == ETH_DMATXNDESCWBF_OWN)
3298       || (dmatxdesclist->PacketAddress[descidx] != NULL))
3299   {
3300     return HAL_ETH_ERROR_BUSY;
3301   }
3302 
3303   /***************************************************************************/
3304   /*****************    Context descriptor configuration (Optional) **********/
3305   /***************************************************************************/
3306   /* If VLAN tag is enabled for this packet */
3307   if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_VLANTAG) != (uint32_t)RESET)
3308   {
3309     /* Set vlan tag value */
3310     MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXCDESC_VT, pTxConfig->VlanTag);
3311     /* Set vlan tag valid bit */
3312     SET_BIT(dmatxdesc->DESC3, ETH_DMATXCDESC_VLTV);
3313     /* Set the descriptor as the vlan input source */
3314     SET_BIT(heth->Instance->MACVIR, ETH_MACVIR_VLTI);
3315 
3316     /* if inner VLAN is enabled */
3317     if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_INNERVLANTAG) != (uint32_t)RESET)
3318     {
3319       /* Set inner vlan tag value */
3320       MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXCDESC_IVT, (pTxConfig->InnerVlanTag << 16));
3321       /* Set inner vlan tag valid bit */
3322       SET_BIT(dmatxdesc->DESC3, ETH_DMATXCDESC_IVLTV);
3323 
3324       /* Set Vlan Tag control */
3325       MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXCDESC_IVTIR, pTxConfig->InnerVlanCtrl);
3326 
3327       /* Set the descriptor as the inner vlan input source */
3328       SET_BIT(heth->Instance->MACIVIR, ETH_MACIVIR_VLTI);
3329       /* Enable double VLAN processing */
3330       SET_BIT(heth->Instance->MACVTCR, ETH_MACVTCR_EDVLP);
3331     }
3332   }
3333 
3334   /* if tcp segmentation is enabled for this packet */
3335   if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_TSO) != (uint32_t)RESET)
3336   {
3337     /* Set MSS value */
3338     MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXCDESC_MSS, pTxConfig->MaxSegmentSize);
3339     /* Set MSS valid bit */
3340     SET_BIT(dmatxdesc->DESC3, ETH_DMATXCDESC_TCMSSV);
3341   }
3342 
3343   if ((READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_VLANTAG) != (uint32_t)RESET)
3344       || (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_TSO) != (uint32_t)RESET))
3345   {
3346     /* Set as context descriptor */
3347     SET_BIT(dmatxdesc->DESC3, ETH_DMATXCDESC_CTXT);
3348     /* Ensure rest of descriptor is written to RAM before the OWN bit */
3349     __DMB();
3350     /* Set own bit */
3351     SET_BIT(dmatxdesc->DESC3, ETH_DMATXCDESC_OWN);
3352     /* Increment current tx descriptor index */
3353     INCR_TX_DESC_INDEX(descidx, 1U);
3354     /* Get current descriptor address */
3355     dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[descidx];
3356 
3357     descnbr += 1U;
3358 
3359     /* Current Tx Descriptor Owned by DMA: cannot be used by the application  */
3360     if (READ_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCWBF_OWN) == ETH_DMATXNDESCWBF_OWN)
3361     {
3362       dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[firstdescidx];
3363       /* Ensure rest of descriptor is written to RAM before the OWN bit */
3364       __DMB();
3365       /* Clear own bit */
3366       CLEAR_BIT(dmatxdesc->DESC3, ETH_DMATXCDESC_OWN);
3367 
3368       return HAL_ETH_ERROR_BUSY;
3369     }
3370   }
3371 
3372   /***************************************************************************/
3373   /*****************    Normal descriptors configuration     *****************/
3374   /***************************************************************************/
3375 
3376   descnbr += 1U;
3377 
3378   /* Set header or buffer 1 address */
3379   WRITE_REG(dmatxdesc->DESC0, (uint32_t)txbuffer->buffer);
3380   /* Set header or buffer 1 Length */
3381   MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXNDESCRF_B1L, txbuffer->len);
3382 
3383   if (txbuffer->next != NULL)
3384   {
3385     txbuffer = txbuffer->next;
3386     /* Set buffer 2 address */
3387     WRITE_REG(dmatxdesc->DESC1, (uint32_t)txbuffer->buffer);
3388     /* Set buffer 2 Length */
3389     MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXNDESCRF_B2L, (txbuffer->len << 16));
3390   }
3391   else
3392   {
3393     WRITE_REG(dmatxdesc->DESC1, 0x0U);
3394     /* Set buffer 2 Length */
3395     MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXNDESCRF_B2L, 0x0U);
3396   }
3397 
3398   if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_TSO) != (uint32_t)RESET)
3399   {
3400     /* Set TCP Header length */
3401     MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_THL, (pTxConfig->TCPHeaderLen << 19));
3402     /* Set TCP payload length */
3403     MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_TPL, pTxConfig->PayloadLen);
3404     /* Set TCP Segmentation Enabled bit */
3405     SET_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_TSE);
3406   }
3407   else
3408   {
3409     MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_FL, pTxConfig->Length);
3410 
3411     if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_CSUM) != (uint32_t)RESET)
3412     {
3413       MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_CIC, pTxConfig->ChecksumCtrl);
3414     }
3415 
3416     if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_CRCPAD) != (uint32_t)RESET)
3417     {
3418       MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_CPC, pTxConfig->CRCPadCtrl);
3419     }
3420   }
3421 
3422   if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_VLANTAG) != (uint32_t)RESET)
3423   {
3424     /* Set Vlan Tag control */
3425     MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXNDESCRF_VTIR, pTxConfig->VlanCtrl);
3426   }
3427 
3428   /* Mark it as First Descriptor */
3429   SET_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_FD);
3430   /* Mark it as NORMAL descriptor */
3431   CLEAR_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_CTXT);
3432   /* Ensure rest of descriptor is written to RAM before the OWN bit */
3433   __DMB();
3434   /* set OWN bit of FIRST descriptor */
3435   SET_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_OWN);
3436 
3437   /* If source address insertion/replacement is enabled for this packet */
3438   if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_SAIC) != (uint32_t)RESET)
3439   {
3440     MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_SAIC, pTxConfig->SrcAddrCtrl);
3441   }
3442 
3443   /* only if the packet is split into more than one descriptors > 1 */
3444   while (txbuffer->next != NULL)
3445   {
3446     /* Clear the LD bit of previous descriptor */
3447     CLEAR_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_LD);
3448 
3449     /* Increment current tx descriptor index */
3450     INCR_TX_DESC_INDEX(descidx, 1U);
3451 
3452     /* Get current descriptor address */
3453     dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[descidx];
3454 
3455     /* Clear the FD bit of new Descriptor */
3456     CLEAR_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_FD);
3457 
3458     /* Current Tx Descriptor Owned by DMA: cannot be used by the application  */
3459     if ((READ_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_OWN) == ETH_DMATXNDESCRF_OWN)
3460         || (dmatxdesclist->PacketAddress[descidx] != NULL))
3461     {
3462       descidx = firstdescidx;
3463       dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[descidx];
3464 
3465       /* clear previous desc own bit */
3466       for (idx = 0; idx < descnbr; idx ++)
3467       {
3468         /* Ensure rest of descriptor is written to RAM before the OWN bit */
3469         __DMB();
3470 
3471         CLEAR_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_OWN);
3472 
3473         /* Increment current tx descriptor index */
3474         INCR_TX_DESC_INDEX(descidx, 1U);
3475         /* Get current descriptor address */
3476         dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[descidx];
3477       }
3478 
3479       return HAL_ETH_ERROR_BUSY;
3480     }
3481 
3482     descnbr += 1U;
3483 
3484     /* Get the next Tx buffer in the list */
3485     txbuffer = txbuffer->next;
3486 
3487     /* Set header or buffer 1 address */
3488     WRITE_REG(dmatxdesc->DESC0, (uint32_t)txbuffer->buffer);
3489     /* Set header or buffer 1 Length */
3490     MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXNDESCRF_B1L, txbuffer->len);
3491 
3492     if (txbuffer->next != NULL)
3493     {
3494       /* Get the next Tx buffer in the list */
3495       txbuffer = txbuffer->next;
3496       /* Set buffer 2 address */
3497       WRITE_REG(dmatxdesc->DESC1, (uint32_t)txbuffer->buffer);
3498       /* Set buffer 2 Length */
3499       MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXNDESCRF_B2L, (txbuffer->len << 16));
3500     }
3501     else
3502     {
3503       WRITE_REG(dmatxdesc->DESC1, 0x0U);
3504       /* Set buffer 2 Length */
3505       MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXNDESCRF_B2L, 0x0U);
3506     }
3507 
3508     if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_TSO) != (uint32_t)RESET)
3509     {
3510       /* Set TCP payload length */
3511       MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_TPL, pTxConfig->PayloadLen);
3512       /* Set TCP Segmentation Enabled bit */
3513       SET_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_TSE);
3514     }
3515     else
3516     {
3517       /* Set the packet length */
3518       MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_FL, pTxConfig->Length);
3519 
3520       if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_CSUM) != (uint32_t)RESET)
3521       {
3522         /* Checksum Insertion Control */
3523         MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_CIC, pTxConfig->ChecksumCtrl);
3524       }
3525     }
3526 
3527     bd_count += 1U;
3528 
3529     /* Ensure rest of descriptor is written to RAM before the OWN bit */
3530     __DMB();
3531     /* Set Own bit */
3532     SET_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_OWN);
3533     /* Mark it as NORMAL descriptor */
3534     CLEAR_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_CTXT);
3535   }
3536 
3537   if (ItMode != ((uint32_t)RESET))
3538   {
3539     /* Set Interrupt on completion bit */
3540     SET_BIT(dmatxdesc->DESC2, ETH_DMATXNDESCRF_IOC);
3541   }
3542   else
3543   {
3544     /* Clear Interrupt on completion bit */
3545     CLEAR_BIT(dmatxdesc->DESC2, ETH_DMATXNDESCRF_IOC);
3546   }
3547 
3548   /* Mark it as LAST descriptor */
3549   SET_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_LD);
3550   /* Save the current packet address to expose it to the application */
3551   dmatxdesclist->PacketAddress[descidx] = dmatxdesclist->CurrentPacketAddress;
3552 
3553   dmatxdesclist->CurTxDesc = descidx;
3554 
3555   /* Enter critical section */
3556   primask_bit = __get_PRIMASK();
3557   __set_PRIMASK(1);
3558 
3559   dmatxdesclist->BuffersInUse += bd_count + 1U;
3560 
3561   /* Exit critical section: restore previous priority mask */
3562   __set_PRIMASK(primask_bit);
3563 
3564   /* Return function status */
3565   return HAL_ETH_ERROR_NONE;
3566 }
3567 
3568 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
ETH_InitCallbacksToDefault(ETH_HandleTypeDef * heth)3569 static void ETH_InitCallbacksToDefault(ETH_HandleTypeDef *heth)
3570 {
3571   /* Init the ETH Callback settings */
3572   heth->TxCpltCallback   = HAL_ETH_TxCpltCallback;    /* Legacy weak TxCpltCallback   */
3573   heth->RxCpltCallback   = HAL_ETH_RxCpltCallback;    /* Legacy weak RxCpltCallback   */
3574   heth->ErrorCallback    = HAL_ETH_ErrorCallback;     /* Legacy weak ErrorCallback */
3575   heth->PMTCallback      = HAL_ETH_PMTCallback;       /* Legacy weak PMTCallback      */
3576   heth->EEECallback      = HAL_ETH_EEECallback;       /* Legacy weak EEECallback      */
3577   heth->WakeUpCallback   = HAL_ETH_WakeUpCallback;    /* Legacy weak WakeUpCallback   */
3578   heth->rxLinkCallback   = HAL_ETH_RxLinkCallback;    /* Legacy weak RxLinkCallback   */
3579   heth->txFreeCallback   = HAL_ETH_TxFreeCallback;    /* Legacy weak TxFreeCallback   */
3580 #ifdef HAL_ETH_USE_PTP
3581   heth->txPtpCallback    = HAL_ETH_TxPtpCallback;     /* Legacy weak TxPtpCallback   */
3582 #endif /* HAL_ETH_USE_PTP */
3583   heth->rxAllocateCallback = HAL_ETH_RxAllocateCallback; /* Legacy weak RxAllocateCallback */
3584 }
3585 #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */
3586 
3587 /**
3588   * @}
3589   */
3590 
3591 /**
3592   * @}
3593   */
3594 
3595 #endif /* ETH1 */
3596 
3597 #endif /* HAL_ETH_MODULE_ENABLED */
3598 
3599 /**
3600   * @}
3601   */
3602