Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:07

0001 /**
0002   ******************************************************************************
0003   * @file    stm32h7xx_hal_eth.c
0004   * @author  MCD Application Team
0005   * @brief   ETH HAL module driver.
0006   *          This file provides firmware functions to manage the following
0007   *          functionalities of the Ethernet (ETH) peripheral:
0008   *           + Initialization and deinitialization functions
0009   *           + IO operation functions
0010   *           + Peripheral Control functions
0011   *           + Peripheral State and Errors functions
0012   *
0013   ******************************************************************************
0014   * @attention
0015   *
0016   * Copyright (c) 2017 STMicroelectronics.
0017   * All rights reserved.
0018   *
0019   * This software is licensed under terms that can be found in the LICENSE file
0020   * in the root directory of this software component.
0021   * If no LICENSE file comes with this software, it is provided AS-IS.
0022   *
0023   ******************************************************************************
0024   @verbatim
0025   ==============================================================================
0026                     ##### How to use this driver #####
0027   ==============================================================================
0028      [..]
0029      The ETH HAL driver can be used as follows:
0030 
0031       (#)Declare a ETH_HandleTypeDef handle structure, for example:
0032          ETH_HandleTypeDef  heth;
0033 
0034       (#)Fill parameters of Init structure in heth handle
0035 
0036       (#)Call HAL_ETH_Init() API to initialize the Ethernet peripheral (MAC, DMA, ...)
0037 
0038       (#)Initialize the ETH low level resources through the HAL_ETH_MspInit() API:
0039           (##) Enable the Ethernet interface clock using
0040                 (+++)  __HAL_RCC_ETH1MAC_CLK_ENABLE()
0041                 (+++)  __HAL_RCC_ETH1TX_CLK_ENABLE()
0042                 (+++)  __HAL_RCC_ETH1RX_CLK_ENABLE()
0043 
0044           (##) Initialize the related GPIO clocks
0045           (##) Configure Ethernet pinout
0046           (##) Configure Ethernet NVIC interrupt (in Interrupt mode)
0047 
0048       (#) Ethernet data reception is asynchronous, so call the following API
0049           to start the listening mode:
0050           (##) HAL_ETH_Start():
0051                This API starts the MAC and DMA transmission and reception process,
0052                without enabling end of transfer interrupts, in this mode user
0053                has to poll for data reception by calling HAL_ETH_ReadData()
0054           (##) HAL_ETH_Start_IT():
0055                This API starts the MAC and DMA transmission and reception process,
0056                end of transfer interrupts are enabled in this mode,
0057                HAL_ETH_RxCpltCallback() will be executed when an Ethernet packet is received
0058 
0059       (#) When data is received user can call the following API to get received data:
0060           (##) HAL_ETH_ReadData(): Read a received packet
0061 
0062       (#) For transmission path, two APIs are available:
0063          (##) HAL_ETH_Transmit(): Transmit an ETH frame in blocking mode
0064          (##) HAL_ETH_Transmit_IT(): Transmit an ETH frame in interrupt mode,
0065               HAL_ETH_TxCpltCallback() will be executed when end of transfer occur
0066 
0067       (#) Communication with an external PHY device:
0068          (##) HAL_ETH_ReadPHYRegister(): Read a register from an external PHY
0069          (##) HAL_ETH_WritePHYRegister(): Write data to an external RHY register
0070 
0071       (#) Configure the Ethernet MAC after ETH peripheral initialization
0072           (##) HAL_ETH_GetMACConfig(): Get MAC actual configuration into ETH_MACConfigTypeDef
0073           (##) HAL_ETH_SetMACConfig(): Set MAC configuration based on ETH_MACConfigTypeDef
0074 
0075       (#) Configure the Ethernet DMA after ETH peripheral initialization
0076           (##) HAL_ETH_GetDMAConfig(): Get DMA actual configuration into ETH_DMAConfigTypeDef
0077           (##) HAL_ETH_SetDMAConfig(): Set DMA configuration based on ETH_DMAConfigTypeDef
0078 
0079       (#) Configure the Ethernet PTP after ETH peripheral initialization
0080           (##) Define HAL_ETH_USE_PTP to use PTP APIs.
0081           (##) HAL_ETH_PTP_GetConfig(): Get PTP actual configuration into ETH_PTP_ConfigTypeDef
0082           (##) HAL_ETH_PTP_SetConfig(): Set PTP configuration based on ETH_PTP_ConfigTypeDef
0083           (##) HAL_ETH_PTP_GetTime(): Get Seconds and Nanoseconds for the Ethernet PTP registers
0084           (##) HAL_ETH_PTP_SetTime(): Set Seconds and Nanoseconds for the Ethernet PTP registers
0085           (##) HAL_ETH_PTP_AddTimeOffset(): Add Seconds and Nanoseconds offset for the Ethernet PTP registers
0086           (##) HAL_ETH_PTP_InsertTxTimestamp(): Insert Timestamp in transmission
0087           (##) HAL_ETH_PTP_GetTxTimestamp(): Get transmission timestamp
0088           (##) HAL_ETH_PTP_GetRxTimestamp(): Get reception timestamp
0089 
0090       -@- The ARP offload feature is not supported in this driver.
0091 
0092       -@- The PTP offload feature is not supported in this driver.
0093 
0094   *** Callback registration ***
0095   =============================================
0096 
0097   The compilation define  USE_HAL_ETH_REGISTER_CALLBACKS when set to 1
0098   allows the user to configure dynamically the driver callbacks.
0099   Use Function HAL_ETH_RegisterCallback() to register an interrupt callback.
0100 
0101   Function HAL_ETH_RegisterCallback() allows to register following callbacks:
0102     (+) TxCpltCallback   : Tx Complete Callback.
0103     (+) RxCpltCallback   : Rx Complete Callback.
0104     (+) ErrorCallback    : Error Callback.
0105     (+) PMTCallback      : Power Management Callback
0106     (+) EEECallback      : EEE Callback.
0107     (+) WakeUpCallback   : Wake UP Callback
0108     (+) MspInitCallback  : MspInit Callback.
0109     (+) MspDeInitCallback: MspDeInit Callback.
0110 
0111   This function takes as parameters the HAL peripheral handle, the Callback ID
0112   and a pointer to the user callback function.
0113 
0114   For specific callbacks RxAllocateCallback use dedicated register callbacks:
0115   respectively HAL_ETH_RegisterRxAllocateCallback().
0116 
0117   For specific callbacks RxLinkCallback use dedicated register callbacks:
0118   respectively HAL_ETH_RegisterRxLinkCallback().
0119 
0120   For specific callbacks TxFreeCallback use dedicated register callbacks:
0121   respectively HAL_ETH_RegisterTxFreeCallback().
0122 
0123   For specific callbacks TxPtpCallback use dedicated register callbacks:
0124   respectively HAL_ETH_RegisterTxPtpCallback().
0125 
0126   Use function HAL_ETH_UnRegisterCallback() to reset a callback to the default
0127   weak function.
0128   HAL_ETH_UnRegisterCallback takes as parameters the HAL peripheral handle,
0129   and the Callback ID.
0130   This function allows to reset following callbacks:
0131     (+) TxCpltCallback   : Tx Complete Callback.
0132     (+) RxCpltCallback   : Rx Complete Callback.
0133     (+) ErrorCallback    : Error Callback.
0134     (+) PMTCallback      : Power Management Callback
0135     (+) EEECallback      : EEE Callback.
0136     (+) WakeUpCallback   : Wake UP Callback
0137     (+) MspInitCallback  : MspInit Callback.
0138     (+) MspDeInitCallback: MspDeInit Callback.
0139 
0140   For specific callbacks RxAllocateCallback use dedicated unregister callbacks:
0141   respectively HAL_ETH_UnRegisterRxAllocateCallback().
0142 
0143   For specific callbacks RxLinkCallback use dedicated unregister callbacks:
0144   respectively HAL_ETH_UnRegisterRxLinkCallback().
0145 
0146   For specific callbacks TxFreeCallback use dedicated unregister callbacks:
0147   respectively HAL_ETH_UnRegisterTxFreeCallback().
0148 
0149   For specific callbacks TxPtpCallback use dedicated unregister callbacks:
0150   respectively HAL_ETH_UnRegisterTxPtpCallback().
0151 
0152   By default, after the HAL_ETH_Init and when the state is HAL_ETH_STATE_RESET
0153   all callbacks are set to the corresponding weak functions:
0154   examples HAL_ETH_TxCpltCallback(), HAL_ETH_RxCpltCallback().
0155   Exception done for MspInit and MspDeInit functions that are
0156   reset to the legacy weak function in the HAL_ETH_Init/ HAL_ETH_DeInit only when
0157   these callbacks are null (not registered beforehand).
0158   if not, MspInit or MspDeInit are not null, the HAL_ETH_Init/ HAL_ETH_DeInit
0159   keep and use the user MspInit/MspDeInit callbacks (registered beforehand)
0160 
0161   Callbacks can be registered/unregistered in HAL_ETH_STATE_READY state only.
0162   Exception done MspInit/MspDeInit that can be registered/unregistered
0163   in HAL_ETH_STATE_READY or HAL_ETH_STATE_RESET state,
0164   thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit.
0165   In that case first register the MspInit/MspDeInit user callbacks
0166   using HAL_ETH_RegisterCallback() before calling HAL_ETH_DeInit
0167   or HAL_ETH_Init function.
0168 
0169   When The compilation define USE_HAL_ETH_REGISTER_CALLBACKS is set to 0 or
0170   not defined, the callback registration feature is not available and all callbacks
0171   are set to the corresponding weak functions.
0172 
0173   @endverbatim
0174   ******************************************************************************
0175   */
0176 
0177 /* Includes ------------------------------------------------------------------*/
0178 #include "stm32h7xx_hal.h"
0179 
0180 /** @addtogroup STM32H7xx_HAL_Driver
0181   * @{
0182   */
0183 #ifdef HAL_ETH_MODULE_ENABLED
0184 
0185 #if defined(ETH)
0186 
0187 /** @defgroup ETH ETH
0188   * @ingroup RTEMSBSPsARMSTM32H7
0189   * @brief ETH HAL module driver
0190   * @{
0191   */
0192 
0193 /* Private typedef -----------------------------------------------------------*/
0194 /* Private define ------------------------------------------------------------*/
0195 /** @addtogroup ETH_Private_Constants ETH Private Constants
0196   * @{
0197   */
0198 #define ETH_MACCR_MASK                0xFFFB7F7CU
0199 #define ETH_MACECR_MASK               0x3F077FFFU
0200 #define ETH_MACPFR_MASK               0x800007FFU
0201 #define ETH_MACWTR_MASK               0x0000010FU
0202 #define ETH_MACTFCR_MASK              0xFFFF00F2U
0203 #define ETH_MACRFCR_MASK              0x00000003U
0204 #define ETH_MTLTQOMR_MASK             0x00000072U
0205 #define ETH_MTLRQOMR_MASK             0x0000007BU
0206 
0207 #define ETH_DMAMR_MASK                0x00007802U
0208 #define ETH_DMASBMR_MASK              0x0000D001U
0209 #define ETH_DMACCR_MASK               0x00013FFFU
0210 #define ETH_DMACTCR_MASK              0x003F1010U
0211 #define ETH_DMACRCR_MASK              0x803F0000U
0212 #define ETH_MACPCSR_MASK              (ETH_MACPCSR_PWRDWN | ETH_MACPCSR_RWKPKTEN | \
0213                                        ETH_MACPCSR_MGKPKTEN | ETH_MACPCSR_GLBLUCAST | \
0214                                        ETH_MACPCSR_RWKPFE)
0215 
0216 /* Timeout values */
0217 #define ETH_DMARXNDESCWBF_ERRORS_MASK ((uint32_t)(ETH_DMARXNDESCWBF_DE | ETH_DMARXNDESCWBF_RE | \
0218                                                   ETH_DMARXNDESCWBF_OE | ETH_DMARXNDESCWBF_RWT |\
0219                                                   ETH_DMARXNDESCWBF_GP | ETH_DMARXNDESCWBF_CE))
0220 
0221 #define ETH_MACTSCR_MASK              0x0087FF2FU
0222 
0223 #define ETH_MACSTSUR_VALUE            0xFFFFFFFFU
0224 #define ETH_MACSTNUR_VALUE            0xBB9ACA00U
0225 #define ETH_SEGMENT_SIZE_DEFAULT      0x218U
0226 /**
0227   * @}
0228   */
0229 
0230 /* Private macros ------------------------------------------------------------*/
0231 /** @defgroup ETH_Private_Macros ETH Private Macros
0232   * @ingroup RTEMSBSPsARMSTM32H7
0233   * @{
0234   */
0235 /* Helper macros for TX descriptor handling */
0236 #define INCR_TX_DESC_INDEX(inx, offset) do {\
0237                                              (inx) += (offset);\
0238                                              if ((inx) >= (uint32_t)ETH_TX_DESC_CNT){\
0239                                              (inx) = ((inx) - (uint32_t)ETH_TX_DESC_CNT);}\
0240                                            } while (0)
0241 
0242 /* Helper macros for RX descriptor handling */
0243 #define INCR_RX_DESC_INDEX(inx, offset) do {\
0244                                              (inx) += (offset);\
0245                                              if ((inx) >= (uint32_t)ETH_RX_DESC_CNT){\
0246                                              (inx) = ((inx) - (uint32_t)ETH_RX_DESC_CNT);}\
0247                                            } while (0)
0248 /**
0249   * @}
0250   */
0251 /* Private function prototypes -----------------------------------------------*/
0252 /** @defgroup ETH_Private_Functions   ETH Private Functions
0253   * @ingroup RTEMSBSPsARMSTM32H7
0254   * @{
0255   */
0256 static void ETH_SetMACConfig(ETH_HandleTypeDef *heth, const ETH_MACConfigTypeDef *macconf);
0257 static void ETH_SetDMAConfig(ETH_HandleTypeDef *heth, const ETH_DMAConfigTypeDef *dmaconf);
0258 static void ETH_MACDMAConfig(ETH_HandleTypeDef *heth);
0259 static void ETH_DMATxDescListInit(ETH_HandleTypeDef *heth);
0260 static void ETH_DMARxDescListInit(ETH_HandleTypeDef *heth);
0261 static uint32_t ETH_Prepare_Tx_Descriptors(ETH_HandleTypeDef *heth, const ETH_TxPacketConfigTypeDef *pTxConfig,
0262                                            uint32_t ItMode);
0263 static void ETH_UpdateDescriptor(ETH_HandleTypeDef *heth);
0264 
0265 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
0266 static void ETH_InitCallbacksToDefault(ETH_HandleTypeDef *heth);
0267 #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */
0268 /**
0269   * @}
0270   */
0271 
0272 /* Exported functions ---------------------------------------------------------*/
0273 /** @defgroup ETH_Exported_Functions ETH Exported Functions
0274   * @ingroup RTEMSBSPsARMSTM32H7
0275   * @{
0276   */
0277 
0278 /** @defgroup ETH_Exported_Functions_Group1 Initialization and deinitialization functions
0279   * @ingroup RTEMSBSPsARMSTM32H7
0280   *  @brief    Initialization and Configuration functions
0281   *
0282 @verbatim
0283 ===============================================================================
0284             ##### Initialization and Configuration functions #####
0285  ===============================================================================
0286     [..]  This subsection provides a set of functions allowing to initialize and
0287           deinitialize the ETH peripheral:
0288 
0289       (+) User must Implement HAL_ETH_MspInit() function in which he configures
0290           all related peripherals resources (CLOCK, GPIO and NVIC ).
0291 
0292       (+) Call the function HAL_ETH_Init() to configure the selected device with
0293           the selected configuration:
0294         (++) MAC address
0295         (++) Media interface (MII or RMII)
0296         (++) Rx DMA Descriptors Tab
0297         (++) Tx DMA Descriptors Tab
0298         (++) Length of Rx Buffers
0299 
0300       (+) Call the function HAL_ETH_DeInit() to restore the default configuration
0301           of the selected ETH peripheral.
0302 
0303 @endverbatim
0304   * @{
0305   */
0306 
0307 /**
0308   * @brief  Initialize the Ethernet peripheral registers.
0309   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
0310   *         the configuration information for ETHERNET module
0311   * @retval HAL status
0312   */
0313 HAL_StatusTypeDef HAL_ETH_Init(ETH_HandleTypeDef *heth)
0314 {
0315   uint32_t tickstart;
0316 
0317   if (heth == NULL)
0318   {
0319     return HAL_ERROR;
0320   }
0321   if (heth->gState == HAL_ETH_STATE_RESET)
0322   {
0323     heth->gState = HAL_ETH_STATE_BUSY;
0324 
0325 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
0326 
0327     ETH_InitCallbacksToDefault(heth);
0328 
0329     if (heth->MspInitCallback == NULL)
0330     {
0331       heth->MspInitCallback = HAL_ETH_MspInit;
0332     }
0333 
0334     /* Init the low level hardware */
0335     heth->MspInitCallback(heth);
0336 #else
0337     /* Init the low level hardware : GPIO, CLOCK, NVIC. */
0338     HAL_ETH_MspInit(heth);
0339 
0340 #endif /* (USE_HAL_ETH_REGISTER_CALLBACKS) */
0341   }
0342 
0343   __HAL_RCC_SYSCFG_CLK_ENABLE();
0344 
0345   if (heth->Init.MediaInterface == HAL_ETH_MII_MODE)
0346   {
0347     HAL_SYSCFG_ETHInterfaceSelect(SYSCFG_ETH_MII);
0348   }
0349   else
0350   {
0351     HAL_SYSCFG_ETHInterfaceSelect(SYSCFG_ETH_RMII);
0352   }
0353 
0354   /* Dummy read to sync with ETH */
0355   (void)SYSCFG->PMCR;
0356 
0357   /* Ethernet Software reset */
0358   /* Set the SWR bit: resets all MAC subsystem internal registers and logic */
0359   /* After reset all the registers holds their respective reset values */
0360   SET_BIT(heth->Instance->DMAMR, ETH_DMAMR_SWR);
0361 
0362   /* Get tick */
0363   tickstart = HAL_GetTick();
0364 
0365   /* Wait for software reset */
0366   while (READ_BIT(heth->Instance->DMAMR, ETH_DMAMR_SWR) > 0U)
0367   {
0368     if (((HAL_GetTick() - tickstart) > ETH_SWRESET_TIMEOUT))
0369     {
0370       /* Set Error Code */
0371       heth->ErrorCode = HAL_ETH_ERROR_TIMEOUT;
0372       /* Set State as Error */
0373       heth->gState = HAL_ETH_STATE_ERROR;
0374       /* Return Error */
0375       return HAL_ERROR;
0376     }
0377   }
0378 
0379   /*------------------ MDIO CSR Clock Range Configuration --------------------*/
0380   HAL_ETH_SetMDIOClockRange(heth);
0381 
0382   /*------------------ MAC LPI 1US Tic Counter Configuration --------------------*/
0383   WRITE_REG(heth->Instance->MAC1USTCR, (((uint32_t)HAL_RCC_GetHCLKFreq() / ETH_MAC_US_TICK) - 1U));
0384 
0385   /*------------------ MAC, MTL and DMA default Configuration ----------------*/
0386   ETH_MACDMAConfig(heth);
0387 
0388 #ifndef __rtems__
0389   /* SET DSL to 64 bit */
0390   MODIFY_REG(heth->Instance->DMACCR, ETH_DMACCR_DSL, ETH_DMACCR_DSL_64BIT);
0391 #endif /* __rtems__ */
0392 
0393   /* Set Receive Buffers Length (must be a multiple of 4) */
0394   if ((heth->Init.RxBuffLen % 0x4U) != 0x0U)
0395   {
0396     /* Set Error Code */
0397     heth->ErrorCode = HAL_ETH_ERROR_PARAM;
0398     /* Set State as Error */
0399     heth->gState = HAL_ETH_STATE_ERROR;
0400     /* Return Error */
0401     return HAL_ERROR;
0402   }
0403   else
0404   {
0405     MODIFY_REG(heth->Instance->DMACRCR, ETH_DMACRCR_RBSZ, ((heth->Init.RxBuffLen) << 1));
0406   }
0407 
0408   /*------------------ DMA Tx Descriptors Configuration ----------------------*/
0409   ETH_DMATxDescListInit(heth);
0410 
0411   /*------------------ DMA Rx Descriptors Configuration ----------------------*/
0412   ETH_DMARxDescListInit(heth);
0413 
0414   /*--------------------- ETHERNET MAC Address Configuration ------------------*/
0415   /* Set MAC addr bits 32 to 47 */
0416   heth->Instance->MACA0HR = (((uint32_t)(heth->Init.MACAddr[5]) << 8) | (uint32_t)heth->Init.MACAddr[4]);
0417   /* Set MAC addr bits 0 to 31 */
0418   heth->Instance->MACA0LR = (((uint32_t)(heth->Init.MACAddr[3]) << 24) | ((uint32_t)(heth->Init.MACAddr[2]) << 16) |
0419                              ((uint32_t)(heth->Init.MACAddr[1]) << 8) | (uint32_t)heth->Init.MACAddr[0]);
0420 
0421   /* Disable Rx MMC Interrupts */
0422   SET_BIT(heth->Instance->MMCRIMR, ETH_MMCRIMR_RXLPITRCIM | ETH_MMCRIMR_RXLPIUSCIM | \
0423           ETH_MMCRIMR_RXUCGPIM | ETH_MMCRIMR_RXALGNERPIM | ETH_MMCRIMR_RXCRCERPIM);
0424 
0425   /* Disable Tx MMC Interrupts */
0426   SET_BIT(heth->Instance->MMCTIMR, ETH_MMCTIMR_TXLPITRCIM | ETH_MMCTIMR_TXLPIUSCIM | \
0427           ETH_MMCTIMR_TXGPKTIM | ETH_MMCTIMR_TXMCOLGPIM | ETH_MMCTIMR_TXSCOLGPIM);
0428 
0429   heth->ErrorCode = HAL_ETH_ERROR_NONE;
0430   heth->gState = HAL_ETH_STATE_READY;
0431 
0432   return HAL_OK;
0433 }
0434 
0435 /**
0436   * @brief  DeInitializes the ETH peripheral.
0437   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
0438   *         the configuration information for ETHERNET module
0439   * @retval HAL status
0440   */
0441 HAL_StatusTypeDef HAL_ETH_DeInit(ETH_HandleTypeDef *heth)
0442 {
0443   /* Set the ETH peripheral state to BUSY */
0444   heth->gState = HAL_ETH_STATE_BUSY;
0445 
0446 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
0447 
0448   if (heth->MspDeInitCallback == NULL)
0449   {
0450     heth->MspDeInitCallback = HAL_ETH_MspDeInit;
0451   }
0452   /* DeInit the low level hardware */
0453   heth->MspDeInitCallback(heth);
0454 #else
0455 
0456   /* De-Init the low level hardware : GPIO, CLOCK, NVIC. */
0457   HAL_ETH_MspDeInit(heth);
0458 
0459 #endif /* (USE_HAL_ETH_REGISTER_CALLBACKS) */
0460 
0461   /* Set ETH HAL state to Disabled */
0462   heth->gState = HAL_ETH_STATE_RESET;
0463 
0464   /* Return function status */
0465   return HAL_OK;
0466 }
0467 
0468 #ifndef __rtems__
0469 /**
0470   * @brief  Initializes the ETH MSP.
0471   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
0472   *         the configuration information for ETHERNET module
0473   * @retval None
0474   */
0475 __weak void HAL_ETH_MspInit(ETH_HandleTypeDef *heth)
0476 {
0477   /* Prevent unused argument(s) compilation warning */
0478   UNUSED(heth);
0479   /* NOTE : This function Should not be modified, when the callback is needed,
0480   the HAL_ETH_MspInit could be implemented in the user file
0481   */
0482 }
0483 #endif /* __rtems__ */
0484 
0485 /**
0486   * @brief  DeInitializes ETH MSP.
0487   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
0488   *         the configuration information for ETHERNET module
0489   * @retval None
0490   */
0491 __weak void HAL_ETH_MspDeInit(ETH_HandleTypeDef *heth)
0492 {
0493   /* Prevent unused argument(s) compilation warning */
0494   UNUSED(heth);
0495   /* NOTE : This function Should not be modified, when the callback is needed,
0496   the HAL_ETH_MspDeInit could be implemented in the user file
0497   */
0498 }
0499 
0500 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
0501 /**
0502   * @brief  Register a User ETH Callback
0503   *         To be used instead of the weak predefined callback
0504   * @param heth eth handle
0505   * @param CallbackID ID of the callback to be registered
0506   *        This parameter can be one of the following values:
0507   *          @arg @ref HAL_ETH_TX_COMPLETE_CB_ID Tx Complete Callback ID
0508   *          @arg @ref HAL_ETH_RX_COMPLETE_CB_ID Rx Complete Callback ID
0509   *          @arg @ref HAL_ETH_ERROR_CB_ID       Error Callback ID
0510   *          @arg @ref HAL_ETH_PMT_CB_ID         Power Management Callback ID
0511   *          @arg @ref HAL_ETH_EEE_CB_ID         EEE Callback ID
0512   *          @arg @ref HAL_ETH_WAKEUP_CB_ID      Wake UP Callback ID
0513   *          @arg @ref HAL_ETH_MSPINIT_CB_ID     MspInit callback ID
0514   *          @arg @ref HAL_ETH_MSPDEINIT_CB_ID   MspDeInit callback ID
0515   * @param pCallback pointer to the Callback function
0516   * @retval status
0517   */
0518 HAL_StatusTypeDef HAL_ETH_RegisterCallback(ETH_HandleTypeDef *heth, HAL_ETH_CallbackIDTypeDef CallbackID,
0519                                            pETH_CallbackTypeDef pCallback)
0520 {
0521   HAL_StatusTypeDef status = HAL_OK;
0522 
0523   if (pCallback == NULL)
0524   {
0525     /* Update the error code */
0526     heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK;
0527     return HAL_ERROR;
0528   }
0529 
0530   if (heth->gState == HAL_ETH_STATE_READY)
0531   {
0532     switch (CallbackID)
0533     {
0534       case HAL_ETH_TX_COMPLETE_CB_ID :
0535         heth->TxCpltCallback = pCallback;
0536         break;
0537 
0538       case HAL_ETH_RX_COMPLETE_CB_ID :
0539         heth->RxCpltCallback = pCallback;
0540         break;
0541 
0542       case HAL_ETH_ERROR_CB_ID :
0543         heth->ErrorCallback = pCallback;
0544         break;
0545 
0546       case HAL_ETH_PMT_CB_ID :
0547         heth->PMTCallback = pCallback;
0548         break;
0549 
0550       case HAL_ETH_EEE_CB_ID :
0551         heth->EEECallback = pCallback;
0552         break;
0553 
0554       case HAL_ETH_WAKEUP_CB_ID :
0555         heth->WakeUpCallback = pCallback;
0556         break;
0557 
0558       case HAL_ETH_MSPINIT_CB_ID :
0559         heth->MspInitCallback = pCallback;
0560         break;
0561 
0562       case HAL_ETH_MSPDEINIT_CB_ID :
0563         heth->MspDeInitCallback = pCallback;
0564         break;
0565 
0566       default :
0567         /* Update the error code */
0568         heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK;
0569         /* Return error status */
0570         status =  HAL_ERROR;
0571         break;
0572     }
0573   }
0574   else if (heth->gState == HAL_ETH_STATE_RESET)
0575   {
0576     switch (CallbackID)
0577     {
0578       case HAL_ETH_MSPINIT_CB_ID :
0579         heth->MspInitCallback = pCallback;
0580         break;
0581 
0582       case HAL_ETH_MSPDEINIT_CB_ID :
0583         heth->MspDeInitCallback = pCallback;
0584         break;
0585 
0586       default :
0587         /* Update the error code */
0588         heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK;
0589         /* Return error status */
0590         status =  HAL_ERROR;
0591         break;
0592     }
0593   }
0594   else
0595   {
0596     /* Update the error code */
0597     heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK;
0598     /* Return error status */
0599     status =  HAL_ERROR;
0600   }
0601 
0602   return status;
0603 }
0604 
0605 /**
0606   * @brief  Unregister an ETH Callback
0607   *         ETH callback is redirected to the weak predefined callback
0608   * @param heth eth handle
0609   * @param CallbackID ID of the callback to be unregistered
0610   *        This parameter can be one of the following values:
0611   *          @arg @ref HAL_ETH_TX_COMPLETE_CB_ID Tx Complete Callback ID
0612   *          @arg @ref HAL_ETH_RX_COMPLETE_CB_ID Rx Complete Callback ID
0613   *          @arg @ref HAL_ETH_ERROR_CB_ID       Error Callback ID
0614   *          @arg @ref HAL_ETH_PMT_CB_ID         Power Management Callback ID
0615   *          @arg @ref HAL_ETH_EEE_CB_ID         EEE Callback ID
0616   *          @arg @ref HAL_ETH_WAKEUP_CB_ID      Wake UP Callback ID
0617   *          @arg @ref HAL_ETH_MSPINIT_CB_ID     MspInit callback ID
0618   *          @arg @ref HAL_ETH_MSPDEINIT_CB_ID   MspDeInit callback ID
0619   * @retval status
0620   */
0621 HAL_StatusTypeDef HAL_ETH_UnRegisterCallback(ETH_HandleTypeDef *heth, HAL_ETH_CallbackIDTypeDef CallbackID)
0622 {
0623   HAL_StatusTypeDef status = HAL_OK;
0624 
0625   if (heth->gState == HAL_ETH_STATE_READY)
0626   {
0627     switch (CallbackID)
0628     {
0629       case HAL_ETH_TX_COMPLETE_CB_ID :
0630         heth->TxCpltCallback = HAL_ETH_TxCpltCallback;
0631         break;
0632 
0633       case HAL_ETH_RX_COMPLETE_CB_ID :
0634         heth->RxCpltCallback = HAL_ETH_RxCpltCallback;
0635         break;
0636 
0637       case HAL_ETH_ERROR_CB_ID :
0638         heth->ErrorCallback = HAL_ETH_ErrorCallback;
0639         break;
0640 
0641       case HAL_ETH_PMT_CB_ID :
0642         heth->PMTCallback = HAL_ETH_PMTCallback;
0643         break;
0644 
0645       case HAL_ETH_EEE_CB_ID :
0646         heth->EEECallback = HAL_ETH_EEECallback;
0647         break;
0648 
0649       case HAL_ETH_WAKEUP_CB_ID :
0650         heth->WakeUpCallback = HAL_ETH_WakeUpCallback;
0651         break;
0652 
0653       case HAL_ETH_MSPINIT_CB_ID :
0654         heth->MspInitCallback = HAL_ETH_MspInit;
0655         break;
0656 
0657       case HAL_ETH_MSPDEINIT_CB_ID :
0658         heth->MspDeInitCallback = HAL_ETH_MspDeInit;
0659         break;
0660 
0661       default :
0662         /* Update the error code */
0663         heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK;
0664         /* Return error status */
0665         status =  HAL_ERROR;
0666         break;
0667     }
0668   }
0669   else if (heth->gState == HAL_ETH_STATE_RESET)
0670   {
0671     switch (CallbackID)
0672     {
0673       case HAL_ETH_MSPINIT_CB_ID :
0674         heth->MspInitCallback = HAL_ETH_MspInit;
0675         break;
0676 
0677       case HAL_ETH_MSPDEINIT_CB_ID :
0678         heth->MspDeInitCallback = HAL_ETH_MspDeInit;
0679         break;
0680 
0681       default :
0682         /* Update the error code */
0683         heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK;
0684         /* Return error status */
0685         status =  HAL_ERROR;
0686         break;
0687     }
0688   }
0689   else
0690   {
0691     /* Update the error code */
0692     heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK;
0693     /* Return error status */
0694     status =  HAL_ERROR;
0695   }
0696 
0697   return status;
0698 }
0699 #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */
0700 
0701 /**
0702   * @}
0703   */
0704 
0705 /** @defgroup ETH_Exported_Functions_Group2 IO operation functions
0706   * @ingroup RTEMSBSPsARMSTM32H7
0707   *  @brief ETH Transmit and Receive functions
0708   *
0709 @verbatim
0710   ==============================================================================
0711                       ##### IO operation functions #####
0712   ==============================================================================
0713   [..]
0714     This subsection provides a set of functions allowing to manage the ETH
0715     data transfer.
0716 
0717 @endverbatim
0718   * @{
0719   */
0720 
0721 /**
0722   * @brief  Enables Ethernet MAC and DMA reception and transmission
0723   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
0724   *         the configuration information for ETHERNET module
0725   * @retval HAL status
0726   */
0727 HAL_StatusTypeDef HAL_ETH_Start(ETH_HandleTypeDef *heth)
0728 {
0729   if (heth->gState == HAL_ETH_STATE_READY)
0730   {
0731     heth->gState = HAL_ETH_STATE_BUSY;
0732 
0733     /* Set number of descriptors to build */
0734     heth->RxDescList.RxBuildDescCnt = ETH_RX_DESC_CNT;
0735 
0736     /* Build all descriptors */
0737     ETH_UpdateDescriptor(heth);
0738 
0739     /* Enable the MAC transmission */
0740     SET_BIT(heth->Instance->MACCR, ETH_MACCR_TE);
0741 
0742     /* Enable the MAC reception */
0743     SET_BIT(heth->Instance->MACCR, ETH_MACCR_RE);
0744 
0745     /* Set the Flush Transmit FIFO bit */
0746     SET_BIT(heth->Instance->MTLTQOMR, ETH_MTLTQOMR_FTQ);
0747 
0748     /* Enable the DMA transmission */
0749     SET_BIT(heth->Instance->DMACTCR, ETH_DMACTCR_ST);
0750 
0751     /* Enable the DMA reception */
0752     SET_BIT(heth->Instance->DMACRCR, ETH_DMACRCR_SR);
0753 
0754     /* Clear Tx and Rx process stopped flags */
0755     heth->Instance->DMACSR |= (ETH_DMACSR_TPS | ETH_DMACSR_RPS);
0756 
0757     heth->gState = HAL_ETH_STATE_STARTED;
0758 
0759     return HAL_OK;
0760   }
0761   else
0762   {
0763     return HAL_ERROR;
0764   }
0765 }
0766 
0767 /**
0768   * @brief  Enables Ethernet MAC and DMA reception/transmission in Interrupt mode
0769   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
0770   *         the configuration information for ETHERNET module
0771   * @retval HAL status
0772   */
0773 HAL_StatusTypeDef HAL_ETH_Start_IT(ETH_HandleTypeDef *heth)
0774 {
0775   if (heth->gState == HAL_ETH_STATE_READY)
0776   {
0777     heth->gState = HAL_ETH_STATE_BUSY;
0778 
0779     /* save IT mode to ETH Handle */
0780     heth->RxDescList.ItMode = 1U;
0781 
0782     /* Set number of descriptors to build */
0783     heth->RxDescList.RxBuildDescCnt = ETH_RX_DESC_CNT;
0784 
0785     /* Build all descriptors */
0786     ETH_UpdateDescriptor(heth);
0787 
0788     /* Enable the DMA transmission */
0789     SET_BIT(heth->Instance->DMACTCR, ETH_DMACTCR_ST);
0790 
0791     /* Enable the DMA reception */
0792     SET_BIT(heth->Instance->DMACRCR, ETH_DMACRCR_SR);
0793 
0794     /* Clear Tx and Rx process stopped flags */
0795     heth->Instance->DMACSR |= (ETH_DMACSR_TPS | ETH_DMACSR_RPS);
0796 
0797     /* Set the Flush Transmit FIFO bit */
0798     SET_BIT(heth->Instance->MTLTQOMR, ETH_MTLTQOMR_FTQ);
0799 
0800     /* Enable the MAC transmission */
0801     SET_BIT(heth->Instance->MACCR, ETH_MACCR_TE);
0802 
0803     /* Enable the MAC reception */
0804     SET_BIT(heth->Instance->MACCR, ETH_MACCR_RE);
0805 
0806     /* Enable ETH DMA interrupts:
0807     - Tx complete interrupt
0808     - Rx complete interrupt
0809     - Fatal bus interrupt
0810     */
0811     __HAL_ETH_DMA_ENABLE_IT(heth, (ETH_DMACIER_NIE | ETH_DMACIER_RIE | ETH_DMACIER_TIE  |
0812                                    ETH_DMACIER_FBEE | ETH_DMACIER_AIE | ETH_DMACIER_RBUE));
0813 
0814     heth->gState = HAL_ETH_STATE_STARTED;
0815     return HAL_OK;
0816   }
0817   else
0818   {
0819     return HAL_ERROR;
0820   }
0821 }
0822 
0823 /**
0824   * @brief  Stop Ethernet MAC and DMA reception/transmission
0825   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
0826   *         the configuration information for ETHERNET module
0827   * @retval HAL status
0828   */
0829 HAL_StatusTypeDef HAL_ETH_Stop(ETH_HandleTypeDef *heth)
0830 {
0831   if (heth->gState == HAL_ETH_STATE_STARTED)
0832   {
0833     /* Set the ETH peripheral state to BUSY */
0834     heth->gState = HAL_ETH_STATE_BUSY;
0835 
0836     /* Disable the DMA transmission */
0837     CLEAR_BIT(heth->Instance->DMACTCR, ETH_DMACTCR_ST);
0838 
0839     /* Disable the DMA reception */
0840     CLEAR_BIT(heth->Instance->DMACRCR, ETH_DMACRCR_SR);
0841 
0842     /* Disable the MAC reception */
0843     CLEAR_BIT(heth->Instance->MACCR, ETH_MACCR_RE);
0844 
0845     /* Set the Flush Transmit FIFO bit */
0846     SET_BIT(heth->Instance->MTLTQOMR, ETH_MTLTQOMR_FTQ);
0847 
0848     /* Disable the MAC transmission */
0849     CLEAR_BIT(heth->Instance->MACCR, ETH_MACCR_TE);
0850 
0851     heth->gState = HAL_ETH_STATE_READY;
0852 
0853     /* Return function status */
0854     return HAL_OK;
0855   }
0856   else
0857   {
0858     return HAL_ERROR;
0859   }
0860 }
0861 
0862 /**
0863   * @brief  Stop Ethernet MAC and DMA reception/transmission in Interrupt mode
0864   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
0865   *         the configuration information for ETHERNET module
0866   * @retval HAL status
0867   */
0868 HAL_StatusTypeDef HAL_ETH_Stop_IT(ETH_HandleTypeDef *heth)
0869 {
0870   ETH_DMADescTypeDef *dmarxdesc;
0871   uint32_t descindex;
0872 
0873   if (heth->gState == HAL_ETH_STATE_STARTED)
0874   {
0875     /* Set the ETH peripheral state to BUSY */
0876     heth->gState = HAL_ETH_STATE_BUSY;
0877 
0878     /* Disable interrupts:
0879     - Tx complete interrupt
0880     - Rx complete interrupt
0881     - Fatal bus interrupt
0882     */
0883     __HAL_ETH_DMA_DISABLE_IT(heth, (ETH_DMACIER_NIE | ETH_DMACIER_RIE | ETH_DMACIER_TIE  |
0884                                     ETH_DMACIER_FBEE | ETH_DMACIER_AIE | ETH_DMACIER_RBUE));
0885 
0886     /* Disable the DMA transmission */
0887     CLEAR_BIT(heth->Instance->DMACTCR, ETH_DMACTCR_ST);
0888 
0889     /* Disable the DMA reception */
0890     CLEAR_BIT(heth->Instance->DMACRCR, ETH_DMACRCR_SR);
0891 
0892     /* Disable the MAC reception */
0893     CLEAR_BIT(heth->Instance->MACCR, ETH_MACCR_RE);
0894 
0895     /* Set the Flush Transmit FIFO bit */
0896     SET_BIT(heth->Instance->MTLTQOMR, ETH_MTLTQOMR_FTQ);
0897 
0898     /* Disable the MAC transmission */
0899     CLEAR_BIT(heth->Instance->MACCR, ETH_MACCR_TE);
0900 
0901     /* Clear IOC bit to all Rx descriptors */
0902     for (descindex = 0; descindex < (uint32_t)ETH_RX_DESC_CNT; descindex++)
0903     {
0904       dmarxdesc = (ETH_DMADescTypeDef *)heth->RxDescList.RxDesc[descindex];
0905       CLEAR_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCRF_IOC);
0906     }
0907 
0908     heth->RxDescList.ItMode = 0U;
0909 
0910     heth->gState = HAL_ETH_STATE_READY;
0911 
0912     /* Return function status */
0913     return HAL_OK;
0914   }
0915   else
0916   {
0917     return HAL_ERROR;
0918   }
0919 }
0920 
0921 /**
0922   * @brief  Sends an Ethernet Packet in polling mode.
0923   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
0924   *         the configuration information for ETHERNET module
0925   * @param  pTxConfig: Hold the configuration of packet to be transmitted
0926   * @param  Timeout: timeout value
0927   * @retval HAL status
0928   */
0929 HAL_StatusTypeDef HAL_ETH_Transmit(ETH_HandleTypeDef *heth, ETH_TxPacketConfigTypeDef *pTxConfig, uint32_t Timeout)
0930 {
0931   uint32_t tickstart;
0932   ETH_DMADescTypeDef *dmatxdesc;
0933 
0934   if (pTxConfig == NULL)
0935   {
0936     heth->ErrorCode |= HAL_ETH_ERROR_PARAM;
0937     return HAL_ERROR;
0938   }
0939 
0940   if (heth->gState == HAL_ETH_STATE_STARTED)
0941   {
0942     /* Config DMA Tx descriptor by Tx Packet info */
0943     if (ETH_Prepare_Tx_Descriptors(heth, pTxConfig, 0) != HAL_ETH_ERROR_NONE)
0944     {
0945       /* Set the ETH error code */
0946       heth->ErrorCode |= HAL_ETH_ERROR_BUSY;
0947       return HAL_ERROR;
0948     }
0949 
0950     /* Ensure completion of descriptor preparation before transmission start */
0951     __DSB();
0952 
0953     dmatxdesc = (ETH_DMADescTypeDef *)(&heth->TxDescList)->TxDesc[heth->TxDescList.CurTxDesc];
0954 
0955     /* Incr current tx desc index */
0956     INCR_TX_DESC_INDEX(heth->TxDescList.CurTxDesc, 1U);
0957 
0958     /* Start transmission */
0959     /* issue a poll command to Tx DMA by writing address of next immediate free descriptor */
0960     WRITE_REG(heth->Instance->DMACTDTPR, (uint32_t)(heth->TxDescList.TxDesc[heth->TxDescList.CurTxDesc]));
0961 
0962     tickstart = HAL_GetTick();
0963 
0964     /* Wait for data to be transmitted or timeout occurred */
0965     while ((dmatxdesc->DESC3 & ETH_DMATXNDESCWBF_OWN) != (uint32_t)RESET)
0966     {
0967       if ((heth->Instance->DMACSR & ETH_DMACSR_FBE) != (uint32_t)RESET)
0968       {
0969         heth->ErrorCode |= HAL_ETH_ERROR_DMA;
0970         heth->DMAErrorCode = heth->Instance->DMACSR;
0971         /* Return function status */
0972         return HAL_ERROR;
0973       }
0974 
0975       /* Check for the Timeout */
0976       if (Timeout != HAL_MAX_DELAY)
0977       {
0978         if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
0979         {
0980           heth->ErrorCode |= HAL_ETH_ERROR_TIMEOUT;
0981           /* Clear TX descriptor so that we can proceed */
0982           dmatxdesc->DESC3 = (ETH_DMATXNDESCWBF_FD | ETH_DMATXNDESCWBF_LD);
0983           return HAL_ERROR;
0984         }
0985       }
0986     }
0987 
0988     /* Return function status */
0989     return HAL_OK;
0990   }
0991   else
0992   {
0993     return HAL_ERROR;
0994   }
0995 }
0996 
0997 /**
0998   * @brief  Sends an Ethernet Packet in interrupt mode.
0999   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1000   *         the configuration information for ETHERNET module
1001   * @param  pTxConfig: Hold the configuration of packet to be transmitted
1002   * @retval HAL status
1003   */
1004 HAL_StatusTypeDef HAL_ETH_Transmit_IT(ETH_HandleTypeDef *heth, ETH_TxPacketConfigTypeDef *pTxConfig)
1005 {
1006   if (pTxConfig == NULL)
1007   {
1008     heth->ErrorCode |= HAL_ETH_ERROR_PARAM;
1009     return HAL_ERROR;
1010   }
1011 
1012   if (heth->gState == HAL_ETH_STATE_STARTED)
1013   {
1014     /* Save the packet pointer to release.  */
1015     heth->TxDescList.CurrentPacketAddress = (uint32_t *)pTxConfig->pData;
1016 
1017     /* Config DMA Tx descriptor by Tx Packet info */
1018     if (ETH_Prepare_Tx_Descriptors(heth, pTxConfig, 1) != HAL_ETH_ERROR_NONE)
1019     {
1020       heth->ErrorCode |= HAL_ETH_ERROR_BUSY;
1021       return HAL_ERROR;
1022     }
1023 
1024     /* Ensure completion of descriptor preparation before transmission start */
1025     __DSB();
1026 
1027     /* Incr current tx desc index */
1028     INCR_TX_DESC_INDEX(heth->TxDescList.CurTxDesc, 1U);
1029 
1030     /* Start transmission */
1031     /* issue a poll command to Tx DMA by writing address of next immediate free descriptor */
1032     WRITE_REG(heth->Instance->DMACTDTPR, (uint32_t)(heth->TxDescList.TxDesc[heth->TxDescList.CurTxDesc]));
1033 
1034     return HAL_OK;
1035 
1036   }
1037   else
1038   {
1039     return HAL_ERROR;
1040   }
1041 }
1042 
1043 /**
1044   * @brief  Read a received packet.
1045   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1046   *         the configuration information for ETHERNET module
1047   * @param  pAppBuff: Pointer to an application buffer to receive the packet.
1048   * @retval HAL status
1049   */
1050 HAL_StatusTypeDef HAL_ETH_ReadData(ETH_HandleTypeDef *heth, void **pAppBuff)
1051 {
1052   uint32_t descidx;
1053   ETH_DMADescTypeDef *dmarxdesc;
1054   uint32_t desccnt = 0U;
1055   uint32_t desccntmax;
1056   uint32_t bufflength;
1057   uint8_t rxdataready = 0U;
1058 
1059   if (pAppBuff == NULL)
1060   {
1061     heth->ErrorCode |= HAL_ETH_ERROR_PARAM;
1062     return HAL_ERROR;
1063   }
1064 
1065   if (heth->gState != HAL_ETH_STATE_STARTED)
1066   {
1067     return HAL_ERROR;
1068   }
1069 
1070   descidx = heth->RxDescList.RxDescIdx;
1071   dmarxdesc = (ETH_DMADescTypeDef *)heth->RxDescList.RxDesc[descidx];
1072   desccntmax = ETH_RX_DESC_CNT - heth->RxDescList.RxBuildDescCnt;
1073 
1074   /* Check if descriptor is not owned by DMA */
1075   while ((READ_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCWBF_OWN) == (uint32_t)RESET) && (desccnt < desccntmax)
1076          && (rxdataready == 0U))
1077   {
1078     if (READ_BIT(dmarxdesc->DESC3,  ETH_DMARXNDESCWBF_CTXT)  != (uint32_t)RESET)
1079     {
1080       /* Get timestamp high */
1081       heth->RxDescList.TimeStamp.TimeStampHigh = dmarxdesc->DESC1;
1082       /* Get timestamp low */
1083       heth->RxDescList.TimeStamp.TimeStampLow  = dmarxdesc->DESC0;
1084     }
1085     if ((READ_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCWBF_FD) != (uint32_t)RESET) || (heth->RxDescList.pRxStart != NULL))
1086     {
1087       /* Check if first descriptor */
1088       if (READ_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCWBF_FD) != (uint32_t)RESET)
1089       {
1090         heth->RxDescList.RxDescCnt = 0;
1091         heth->RxDescList.RxDataLength = 0;
1092       }
1093 
1094       /* Get the Frame Length of the received packet: substruct 4 bytes of the CRC */
1095       bufflength = READ_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCWBF_PL) - heth->RxDescList.RxDataLength;
1096 
1097       /* Check if last descriptor */
1098       if (READ_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCWBF_LD) != (uint32_t)RESET)
1099       {
1100         /* Save Last descriptor index */
1101         heth->RxDescList.pRxLastRxDesc = dmarxdesc->DESC3;
1102 
1103         /* Packet ready */
1104         rxdataready = 1;
1105       }
1106 
1107       /* Link data */
1108 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
1109       /*Call registered Link callback*/
1110       heth->rxLinkCallback(&heth->RxDescList.pRxStart, &heth->RxDescList.pRxEnd,
1111                            (uint8_t *)dmarxdesc->BackupAddr0, bufflength);
1112 #else
1113       /* Link callback */
1114       HAL_ETH_RxLinkCallback(&heth->RxDescList.pRxStart, &heth->RxDescList.pRxEnd,
1115                              (uint8_t *)dmarxdesc->BackupAddr0, (uint16_t) bufflength);
1116 #endif  /* USE_HAL_ETH_REGISTER_CALLBACKS */
1117       heth->RxDescList.RxDescCnt++;
1118       heth->RxDescList.RxDataLength += bufflength;
1119 
1120       /* Clear buffer pointer */
1121       dmarxdesc->BackupAddr0 = 0;
1122     }
1123 
1124     /* Increment current rx descriptor index */
1125     INCR_RX_DESC_INDEX(descidx, 1U);
1126     /* Get current descriptor address */
1127     dmarxdesc = (ETH_DMADescTypeDef *)heth->RxDescList.RxDesc[descidx];
1128     desccnt++;
1129   }
1130 
1131   heth->RxDescList.RxBuildDescCnt += desccnt;
1132   if ((heth->RxDescList.RxBuildDescCnt) != 0U)
1133   {
1134     /* Update Descriptors */
1135     ETH_UpdateDescriptor(heth);
1136   }
1137 
1138   heth->RxDescList.RxDescIdx = descidx;
1139 
1140   if (rxdataready == 1U)
1141   {
1142     /* Return received packet */
1143     *pAppBuff = heth->RxDescList.pRxStart;
1144     /* Reset first element */
1145     heth->RxDescList.pRxStart = NULL;
1146 
1147     return HAL_OK;
1148   }
1149 
1150   /* Packet not ready */
1151   return HAL_ERROR;
1152 }
1153 
1154 /**
1155   * @brief  This function gives back Rx Desc of the last received Packet
1156   *         to the DMA, so ETH DMA will be able to use these descriptors
1157   *         to receive next Packets.
1158   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1159   *         the configuration information for ETHERNET module
1160   * @retval HAL status
1161   */
1162 static void ETH_UpdateDescriptor(ETH_HandleTypeDef *heth)
1163 {
1164 #ifndef __rtems__
1165   uint32_t descidx;
1166   uint32_t tailidx;
1167   uint32_t desccount;
1168   ETH_DMADescTypeDef *dmarxdesc;
1169   uint8_t *buff = NULL;
1170   uint8_t allocStatus = 1U;
1171 
1172   descidx = heth->RxDescList.RxBuildDescIdx;
1173   dmarxdesc = (ETH_DMADescTypeDef *)heth->RxDescList.RxDesc[descidx];
1174   desccount = heth->RxDescList.RxBuildDescCnt;
1175 
1176   while ((desccount > 0U) && (allocStatus != 0U))
1177   {
1178     /* Check if a buffer's attached the descriptor */
1179     if (READ_REG(dmarxdesc->BackupAddr0) == 0U)
1180     {
1181       /* Get a new buffer. */
1182 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
1183       /*Call registered Allocate callback*/
1184       heth->rxAllocateCallback(&buff);
1185 #else
1186       /* Allocate callback */
1187       HAL_ETH_RxAllocateCallback(&buff);
1188 #endif  /* USE_HAL_ETH_REGISTER_CALLBACKS */
1189       if (buff == NULL)
1190       {
1191         allocStatus = 0U;
1192       }
1193       else
1194       {
1195         WRITE_REG(dmarxdesc->BackupAddr0, (uint32_t)buff);
1196         WRITE_REG(dmarxdesc->DESC0, (uint32_t)buff);
1197       }
1198     }
1199 
1200     if (allocStatus != 0U)
1201     {
1202 
1203       if (heth->RxDescList.ItMode != 0U)
1204       {
1205         WRITE_REG(dmarxdesc->DESC3, ETH_DMARXNDESCRF_OWN | ETH_DMARXNDESCRF_BUF1V | ETH_DMARXNDESCRF_IOC);
1206       }
1207       else
1208       {
1209         WRITE_REG(dmarxdesc->DESC3, ETH_DMARXNDESCRF_OWN | ETH_DMARXNDESCRF_BUF1V);
1210       }
1211 
1212       /* Increment current rx descriptor index */
1213       INCR_RX_DESC_INDEX(descidx, 1U);
1214       /* Get current descriptor address */
1215       dmarxdesc = (ETH_DMADescTypeDef *)heth->RxDescList.RxDesc[descidx];
1216       desccount--;
1217     }
1218   }
1219 
1220   if (heth->RxDescList.RxBuildDescCnt != desccount)
1221   {
1222     /* Set the tail pointer index */
1223     tailidx = (descidx + 1U) % ETH_RX_DESC_CNT;
1224 
1225     /* DMB instruction to avoid race condition */
1226     __DMB();
1227 
1228     /* Set the Tail pointer address */
1229     WRITE_REG(heth->Instance->DMACRDTPR, ((uint32_t)(heth->Init.RxDesc + (tailidx))));
1230 
1231     heth->RxDescList.RxBuildDescIdx = descidx;
1232     heth->RxDescList.RxBuildDescCnt = desccount;
1233   }
1234 #endif /* ! __rtems__ */
1235 }
1236 
1237 /**
1238   * @brief  Register the Rx alloc callback.
1239   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1240   *         the configuration information for ETHERNET module
1241   * @param  rxAllocateCallback: pointer to function to alloc buffer
1242   * @retval HAL status
1243   */
1244 HAL_StatusTypeDef HAL_ETH_RegisterRxAllocateCallback(ETH_HandleTypeDef *heth,
1245                                                      pETH_rxAllocateCallbackTypeDef rxAllocateCallback)
1246 {
1247   if (rxAllocateCallback == NULL)
1248   {
1249     /* No buffer to save */
1250     return HAL_ERROR;
1251   }
1252 
1253   /* Set function to allocate buffer */
1254   heth->rxAllocateCallback = rxAllocateCallback;
1255 
1256   return HAL_OK;
1257 }
1258 
1259 /**
1260   * @brief  Unregister the Rx alloc callback.
1261   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1262   *         the configuration information for ETHERNET module
1263   * @retval HAL status
1264   */
1265 HAL_StatusTypeDef HAL_ETH_UnRegisterRxAllocateCallback(ETH_HandleTypeDef *heth)
1266 {
1267   /* Set function to allocate buffer */
1268   heth->rxAllocateCallback = HAL_ETH_RxAllocateCallback;
1269 
1270   return HAL_OK;
1271 }
1272 
1273 /**
1274   * @brief  Rx Allocate callback.
1275   * @param  buff: pointer to allocated buffer
1276   * @retval None
1277   */
1278 __weak void HAL_ETH_RxAllocateCallback(uint8_t **buff)
1279 {
1280   /* Prevent unused argument(s) compilation warning */
1281   UNUSED(buff);
1282   /* NOTE : This function Should not be modified, when the callback is needed,
1283   the HAL_ETH_RxAllocateCallback could be implemented in the user file
1284   */
1285 }
1286 
1287 /**
1288   * @brief  Rx Link callback.
1289   * @param  pStart: pointer to packet start
1290   * @param  pEnd: pointer to packet end
1291   * @param  buff: pointer to received data
1292   * @param  Length: received data length
1293   * @retval None
1294   */
1295 __weak void HAL_ETH_RxLinkCallback(void **pStart, void **pEnd, uint8_t *buff, uint16_t Length)
1296 {
1297   /* Prevent unused argument(s) compilation warning */
1298   UNUSED(pStart);
1299   UNUSED(pEnd);
1300   UNUSED(buff);
1301   UNUSED(Length);
1302   /* NOTE : This function Should not be modified, when the callback is needed,
1303   the HAL_ETH_RxLinkCallback could be implemented in the user file
1304   */
1305 }
1306 
1307 /**
1308   * @brief  Set the Rx link data function.
1309   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1310   *         the configuration information for ETHERNET module
1311   * @param  rxLinkCallback: pointer to function to link data
1312   * @retval HAL status
1313   */
1314 HAL_StatusTypeDef HAL_ETH_RegisterRxLinkCallback(ETH_HandleTypeDef *heth, pETH_rxLinkCallbackTypeDef rxLinkCallback)
1315 {
1316   if (rxLinkCallback == NULL)
1317   {
1318     /* No buffer to save */
1319     return HAL_ERROR;
1320   }
1321 
1322   /* Set function to link data */
1323   heth->rxLinkCallback = rxLinkCallback;
1324 
1325   return HAL_OK;
1326 }
1327 
1328 /**
1329   * @brief  Unregister the Rx link callback.
1330   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1331   *         the configuration information for ETHERNET module
1332   * @retval HAL status
1333   */
1334 HAL_StatusTypeDef HAL_ETH_UnRegisterRxLinkCallback(ETH_HandleTypeDef *heth)
1335 {
1336   /* Set function to allocate buffer */
1337   heth->rxLinkCallback = HAL_ETH_RxLinkCallback;
1338 
1339   return HAL_OK;
1340 }
1341 
1342 /**
1343   * @brief  Get the error state of the last received packet.
1344   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1345   *         the configuration information for ETHERNET module
1346   * @param  pErrorCode: pointer to uint32_t to hold the error code
1347   * @retval HAL status
1348   */
1349 HAL_StatusTypeDef HAL_ETH_GetRxDataErrorCode(const ETH_HandleTypeDef *heth, uint32_t *pErrorCode)
1350 {
1351   /* Get error bits. */
1352   *pErrorCode = READ_BIT(heth->RxDescList.pRxLastRxDesc, ETH_DMARXNDESCWBF_ERRORS_MASK);
1353 
1354   return HAL_OK;
1355 }
1356 
1357 /**
1358   * @brief  Set the Tx free function.
1359   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1360   *         the configuration information for ETHERNET module
1361   * @param  txFreeCallback: pointer to function to release the packet
1362   * @retval HAL status
1363   */
1364 HAL_StatusTypeDef HAL_ETH_RegisterTxFreeCallback(ETH_HandleTypeDef *heth, pETH_txFreeCallbackTypeDef txFreeCallback)
1365 {
1366   if (txFreeCallback == NULL)
1367   {
1368     /* No buffer to save */
1369     return HAL_ERROR;
1370   }
1371 
1372   /* Set function to free transmmitted packet */
1373   heth->txFreeCallback = txFreeCallback;
1374 
1375   return HAL_OK;
1376 }
1377 
1378 /**
1379   * @brief  Unregister the Tx free callback.
1380   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1381   *         the configuration information for ETHERNET module
1382   * @retval HAL status
1383   */
1384 HAL_StatusTypeDef HAL_ETH_UnRegisterTxFreeCallback(ETH_HandleTypeDef *heth)
1385 {
1386   /* Set function to allocate buffer */
1387   heth->txFreeCallback = HAL_ETH_TxFreeCallback;
1388 
1389   return HAL_OK;
1390 }
1391 
1392 /**
1393   * @brief  Tx Free callback.
1394   * @param  buff: pointer to buffer to free
1395   * @retval None
1396   */
1397 __weak void HAL_ETH_TxFreeCallback(uint32_t *buff)
1398 {
1399   /* Prevent unused argument(s) compilation warning */
1400   UNUSED(buff);
1401   /* NOTE : This function Should not be modified, when the callback is needed,
1402   the HAL_ETH_TxFreeCallback could be implemented in the user file
1403   */
1404 }
1405 
1406 /**
1407   * @brief  Release transmitted Tx packets.
1408   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1409   *         the configuration information for ETHERNET module
1410   * @retval HAL status
1411   */
1412 HAL_StatusTypeDef HAL_ETH_ReleaseTxPacket(ETH_HandleTypeDef *heth)
1413 {
1414   ETH_TxDescListTypeDef *dmatxdesclist = &heth->TxDescList;
1415   uint32_t numOfBuf =  dmatxdesclist->BuffersInUse;
1416   uint32_t idx =       dmatxdesclist->releaseIndex;
1417   uint8_t pktTxStatus = 1U;
1418   uint8_t pktInUse;
1419 #ifdef HAL_ETH_USE_PTP
1420   ETH_TimeStampTypeDef *timestamp = &heth->TxTimestamp;
1421 #endif /* HAL_ETH_USE_PTP */
1422 
1423   /* Loop through buffers in use.  */
1424   while ((numOfBuf != 0U) && (pktTxStatus != 0U))
1425   {
1426     pktInUse = 1U;
1427     numOfBuf--;
1428     /* If no packet, just examine the next packet.  */
1429     if (dmatxdesclist->PacketAddress[idx] == NULL)
1430     {
1431       /* No packet in use, skip to next.  */
1432       INCR_TX_DESC_INDEX(idx, 1U);
1433       pktInUse = 0U;
1434     }
1435 
1436     if (pktInUse != 0U)
1437     {
1438       /* Determine if the packet has been transmitted.  */
1439       if ((heth->Init.TxDesc[idx].DESC3 & ETH_DMATXNDESCRF_OWN) == 0U)
1440       {
1441 #ifdef HAL_ETH_USE_PTP
1442 
1443         /* Disable Ptp transmission */
1444         CLEAR_BIT(heth->Init.TxDesc[idx].DESC3, (0x40000000U));
1445 
1446         if ((heth->Init.TxDesc[idx].DESC3 & ETH_DMATXNDESCWBF_LD)
1447             && (heth->Init.TxDesc[idx].DESC3 & ETH_DMATXNDESCWBF_TTSS))
1448         {
1449           /* Get timestamp low */
1450           timestamp->TimeStampLow = heth->Init.TxDesc[idx].DESC0;
1451           /* Get timestamp high */
1452           timestamp->TimeStampHigh = heth->Init.TxDesc[idx].DESC1;
1453         }
1454         else
1455         {
1456           timestamp->TimeStampHigh = timestamp->TimeStampLow = UINT32_MAX;
1457         }
1458 #endif /* HAL_ETH_USE_PTP */
1459 
1460 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
1461         /*Call registered callbacks*/
1462 #ifdef HAL_ETH_USE_PTP
1463         /* Handle Ptp  */
1464         if (timestamp->TimeStampHigh != UINT32_MAX && timestamp->TimeStampLow != UINT32_MAX)
1465         {
1466           heth->txPtpCallback(dmatxdesclist->PacketAddress[idx], timestamp);
1467         }
1468 #endif  /* HAL_ETH_USE_PTP */
1469         /* Release the packet.  */
1470         heth->txFreeCallback(dmatxdesclist->PacketAddress[idx]);
1471 #else
1472         /* Call callbacks */
1473 #ifdef HAL_ETH_USE_PTP
1474         /* Handle Ptp  */
1475         if (timestamp->TimeStampHigh != UINT32_MAX && timestamp->TimeStampLow != UINT32_MAX)
1476         {
1477           HAL_ETH_TxPtpCallback(dmatxdesclist->PacketAddress[idx], timestamp);
1478         }
1479 #endif  /* HAL_ETH_USE_PTP */
1480         /* Release the packet.  */
1481         HAL_ETH_TxFreeCallback(dmatxdesclist->PacketAddress[idx]);
1482 #endif  /* USE_HAL_ETH_REGISTER_CALLBACKS */
1483 
1484         /* Clear the entry in the in-use array.  */
1485         dmatxdesclist->PacketAddress[idx] = NULL;
1486 
1487         /* Update the transmit relesae index and number of buffers in use.  */
1488         INCR_TX_DESC_INDEX(idx, 1U);
1489         dmatxdesclist->BuffersInUse = numOfBuf;
1490         dmatxdesclist->releaseIndex = idx;
1491       }
1492       else
1493       {
1494         /* Get out of the loop!  */
1495         pktTxStatus = 0U;
1496       }
1497     }
1498   }
1499   return HAL_OK;
1500 }
1501 
1502 #ifdef HAL_ETH_USE_PTP
1503 /**
1504   * @brief  Set the Ethernet PTP configuration.
1505   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1506   *         the configuration information for ETHERNET module
1507   * @param  ptpconfig: pointer to a ETH_PTP_ConfigTypeDef structure that contains
1508   *         the configuration information for PTP
1509   * @retval HAL status
1510   */
1511 HAL_StatusTypeDef HAL_ETH_PTP_SetConfig(ETH_HandleTypeDef *heth, ETH_PTP_ConfigTypeDef *ptpconfig)
1512 {
1513   uint32_t tmpTSCR;
1514   ETH_TimeTypeDef time;
1515 
1516   if (ptpconfig == NULL)
1517   {
1518     return HAL_ERROR;
1519   }
1520 
1521   tmpTSCR = ptpconfig->Timestamp |
1522             ((uint32_t)ptpconfig->TimestampUpdate << ETH_MACTSCR_TSUPDT_Pos) |
1523             ((uint32_t)ptpconfig->TimestampAll << ETH_MACTSCR_TSENALL_Pos) |
1524             ((uint32_t)ptpconfig->TimestampRolloverMode << ETH_MACTSCR_TSCTRLSSR_Pos) |
1525             ((uint32_t)ptpconfig->TimestampV2 << ETH_MACTSCR_TSVER2ENA_Pos) |
1526             ((uint32_t)ptpconfig->TimestampEthernet << ETH_MACTSCR_TSIPENA_Pos) |
1527             ((uint32_t)ptpconfig->TimestampIPv6 << ETH_MACTSCR_TSIPV6ENA_Pos) |
1528             ((uint32_t)ptpconfig->TimestampIPv4 << ETH_MACTSCR_TSIPV4ENA_Pos) |
1529             ((uint32_t)ptpconfig->TimestampEvent << ETH_MACTSCR_TSEVNTENA_Pos) |
1530             ((uint32_t)ptpconfig->TimestampMaster << ETH_MACTSCR_TSMSTRENA_Pos) |
1531             ((uint32_t)ptpconfig->TimestampSnapshots << ETH_MACTSCR_SNAPTYPSEL_Pos) |
1532             ((uint32_t)ptpconfig->TimestampFilter << ETH_MACTSCR_TSENMACADDR_Pos) |
1533             ((uint32_t)ptpconfig->TimestampChecksumCorrection << ETH_MACTSCR_CSC_Pos) |
1534             ((uint32_t)ptpconfig->TimestampStatusMode << ETH_MACTSCR_TXTSSTSM_Pos);
1535 
1536   /* Write to MACTSCR */
1537   MODIFY_REG(heth->Instance->MACTSCR, ETH_MACTSCR_MASK, tmpTSCR);
1538 
1539   /* Enable Timestamp */
1540   SET_BIT(heth->Instance->MACTSCR, ETH_MACTSCR_TSENA);
1541   WRITE_REG(heth->Instance->MACSSIR, ptpconfig->TimestampSubsecondInc);
1542   WRITE_REG(heth->Instance->MACTSAR, ptpconfig->TimestampAddend);
1543 
1544   /* Enable Timestamp */
1545   if (ptpconfig->TimestampAddendUpdate == ENABLE)
1546   {
1547     SET_BIT(heth->Instance->MACTSCR, ETH_MACTSCR_TSADDREG);
1548     while ((heth->Instance->MACTSCR & ETH_MACTSCR_TSADDREG) != 0)
1549     {
1550 
1551     }
1552   }
1553 
1554   /* Ptp Init */
1555   SET_BIT(heth->Instance->MACTSCR, ETH_MACTSCR_TSINIT);
1556 
1557   /* Set PTP Configuration done */
1558   heth->IsPtpConfigured = HAL_ETH_PTP_CONFIGURED;
1559 
1560   /* Set Seconds */
1561   time.Seconds = heth->Instance->MACSTSR;
1562   /* Set NanoSeconds */
1563   time.NanoSeconds = heth->Instance->MACSTNR;
1564 
1565   HAL_ETH_PTP_SetTime(heth, &time);
1566 
1567   /* Return function status */
1568   return HAL_OK;
1569 }
1570 
1571 /**
1572   * @brief  Get the Ethernet PTP configuration.
1573   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1574   *         the configuration information for ETHERNET module
1575   * @param  ptpconfig: pointer to a ETH_PTP_ConfigTypeDef structure that contains
1576   *         the configuration information for PTP
1577   * @retval HAL status
1578   */
1579 HAL_StatusTypeDef HAL_ETH_PTP_GetConfig(ETH_HandleTypeDef *heth, ETH_PTP_ConfigTypeDef *ptpconfig)
1580 {
1581   if (ptpconfig == NULL)
1582   {
1583     return HAL_ERROR;
1584   }
1585   ptpconfig->Timestamp = READ_BIT(heth->Instance->MACTSCR, ETH_MACTSCR_TSENA);
1586   ptpconfig->TimestampUpdate = ((READ_BIT(heth->Instance->MACTSCR,
1587                                           ETH_MACTSCR_TSCFUPDT) >> ETH_MACTSCR_TSUPDT_Pos) > 0U) ? ENABLE : DISABLE;
1588   ptpconfig->TimestampAll = ((READ_BIT(heth->Instance->MACTSCR,
1589                                        ETH_MACTSCR_TSENALL) >> ETH_MACTSCR_TSENALL_Pos) > 0U) ? ENABLE : DISABLE;
1590   ptpconfig->TimestampRolloverMode = ((READ_BIT(heth->Instance->MACTSCR,
1591                                                 ETH_MACTSCR_TSCTRLSSR) >> ETH_MACTSCR_TSCTRLSSR_Pos) > 0U)
1592                                      ? ENABLE : DISABLE;
1593   ptpconfig->TimestampV2 = ((READ_BIT(heth->Instance->MACTSCR,
1594                                       ETH_MACTSCR_TSVER2ENA) >> ETH_MACTSCR_TSVER2ENA_Pos) > 0U) ? ENABLE : DISABLE;
1595   ptpconfig->TimestampEthernet = ((READ_BIT(heth->Instance->MACTSCR,
1596                                             ETH_MACTSCR_TSIPENA) >> ETH_MACTSCR_TSIPENA_Pos) > 0U) ? ENABLE : DISABLE;
1597   ptpconfig->TimestampIPv6 = ((READ_BIT(heth->Instance->MACTSCR,
1598                                         ETH_MACTSCR_TSIPV6ENA) >> ETH_MACTSCR_TSIPV6ENA_Pos) > 0U) ? ENABLE : DISABLE;
1599   ptpconfig->TimestampIPv4 = ((READ_BIT(heth->Instance->MACTSCR,
1600                                         ETH_MACTSCR_TSIPV4ENA) >> ETH_MACTSCR_TSIPV4ENA_Pos) > 0U) ? ENABLE : DISABLE;
1601   ptpconfig->TimestampEvent = ((READ_BIT(heth->Instance->MACTSCR,
1602                                          ETH_MACTSCR_TSEVNTENA) >> ETH_MACTSCR_TSEVNTENA_Pos) > 0U) ? ENABLE : DISABLE;
1603   ptpconfig->TimestampMaster = ((READ_BIT(heth->Instance->MACTSCR,
1604                                           ETH_MACTSCR_TSMSTRENA) >> ETH_MACTSCR_TSMSTRENA_Pos) > 0U) ? ENABLE : DISABLE;
1605   ptpconfig->TimestampSnapshots = ((READ_BIT(heth->Instance->MACTSCR,
1606                                              ETH_MACTSCR_SNAPTYPSEL) >> ETH_MACTSCR_SNAPTYPSEL_Pos) > 0U)
1607                                   ? ENABLE : DISABLE;
1608   ptpconfig->TimestampFilter = ((READ_BIT(heth->Instance->MACTSCR,
1609                                           ETH_MACTSCR_TSENMACADDR) >> ETH_MACTSCR_TSENMACADDR_Pos) > 0U)
1610                                ? ENABLE : DISABLE;
1611   ptpconfig->TimestampChecksumCorrection = ((READ_BIT(heth->Instance->MACTSCR,
1612                                                       ETH_MACTSCR_CSC) >> ETH_MACTSCR_CSC_Pos) > 0U) ? ENABLE : DISABLE;
1613   ptpconfig->TimestampStatusMode = ((READ_BIT(heth->Instance->MACTSCR,
1614                                               ETH_MACTSCR_TXTSSTSM) >> ETH_MACTSCR_TXTSSTSM_Pos) > 0U)
1615                                    ? ENABLE : DISABLE;
1616 
1617   /* Return function status */
1618   return HAL_OK;
1619 }
1620 
1621 /**
1622   * @brief  Set Seconds and Nanoseconds for the Ethernet PTP registers.
1623   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1624   *         the configuration information for ETHERNET module
1625   * @param  time: pointer to a ETH_TimeTypeDef structure that contains
1626   *         time to set
1627   * @retval HAL status
1628   */
1629 HAL_StatusTypeDef HAL_ETH_PTP_SetTime(ETH_HandleTypeDef *heth, ETH_TimeTypeDef *time)
1630 {
1631   if (heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURED)
1632   {
1633     /* Set Seconds */
1634     heth->Instance->MACSTSUR = time->Seconds;
1635 
1636     /* Set NanoSeconds */
1637     heth->Instance->MACSTNUR = time->NanoSeconds;
1638 
1639     /* the system time is updated */
1640     SET_BIT(heth->Instance->MACTSCR, ETH_MACTSCR_TSUPDT);
1641 
1642     /* Return function status */
1643     return HAL_OK;
1644   }
1645   else
1646   {
1647     /* Return function status */
1648     return HAL_ERROR;
1649   }
1650 }
1651 
1652 /**
1653   * @brief  Get Seconds and Nanoseconds for the Ethernet PTP registers.
1654   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1655   *         the configuration information for ETHERNET module
1656   * @param  time: pointer to a ETH_TimeTypeDef structure that contains
1657   *         time to get
1658   * @retval HAL status
1659   */
1660 HAL_StatusTypeDef HAL_ETH_PTP_GetTime(ETH_HandleTypeDef *heth, ETH_TimeTypeDef *time)
1661 {
1662   if (heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURED)
1663   {
1664     /* Get Seconds */
1665     time->Seconds = heth->Instance->MACSTSR;
1666     /* Get NanoSeconds */
1667     time->NanoSeconds = heth->Instance->MACSTNR;
1668 
1669     /* Return function status */
1670     return HAL_OK;
1671   }
1672   else
1673   {
1674     /* Return function status */
1675     return HAL_ERROR;
1676   }
1677 }
1678 
1679 /**
1680   * @brief  Update time for the Ethernet PTP registers.
1681   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1682   *         the configuration information for ETHERNET module
1683   * @param  timeoffset: pointer to a ETH_PtpUpdateTypeDef structure that contains
1684   *         the time update information
1685   * @retval HAL status
1686   */
1687 HAL_StatusTypeDef HAL_ETH_PTP_AddTimeOffset(ETH_HandleTypeDef *heth, ETH_PtpUpdateTypeDef ptpoffsettype,
1688                                             ETH_TimeTypeDef *timeoffset)
1689 {
1690   if (heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURED)
1691   {
1692     if (ptpoffsettype ==  HAL_ETH_PTP_NEGATIVE_UPDATE)
1693     {
1694       /* Set Seconds update */
1695       heth->Instance->MACSTSUR = ETH_MACSTSUR_VALUE - timeoffset->Seconds + 1U;
1696 
1697       if (READ_BIT(heth->Instance->MACTSCR, ETH_MACTSCR_TSCTRLSSR) == ETH_MACTSCR_TSCTRLSSR)
1698       {
1699         /* Set nanoSeconds update */
1700         heth->Instance->MACSTNUR = ETH_MACSTNUR_VALUE - timeoffset->NanoSeconds;
1701       }
1702       else
1703       {
1704         /* Set nanoSeconds update */
1705         heth->Instance->MACSTNUR = ETH_MACSTSUR_VALUE - timeoffset->NanoSeconds + 1U;
1706       }
1707     }
1708     else
1709     {
1710       /* Set Seconds update */
1711       heth->Instance->MACSTSUR = timeoffset->Seconds;
1712       /* Set nanoSeconds update */
1713       heth->Instance->MACSTNUR = timeoffset->NanoSeconds;
1714     }
1715 
1716     SET_BIT(heth->Instance->MACTSCR, ETH_MACTSCR_TSUPDT);
1717 
1718     /* Return function status */
1719     return HAL_OK;
1720   }
1721   else
1722   {
1723     /* Return function status */
1724     return HAL_ERROR;
1725   }
1726 }
1727 
1728 /**
1729   * @brief  Insert Timestamp in transmission.
1730   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1731   *         the configuration information for ETHERNET module
1732   * @retval HAL status
1733   */
1734 HAL_StatusTypeDef HAL_ETH_PTP_InsertTxTimestamp(ETH_HandleTypeDef *heth)
1735 {
1736   ETH_TxDescListTypeDef *dmatxdesclist = &heth->TxDescList;
1737   uint32_t descidx = dmatxdesclist->CurTxDesc;
1738   ETH_DMADescTypeDef *dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[descidx];
1739 
1740   if (heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURED)
1741   {
1742     /* Enable Time Stamp transmission */
1743     SET_BIT(dmatxdesc->DESC2, ETH_DMATXNDESCRF_TTSE);
1744 
1745     /* Return function status */
1746     return HAL_OK;
1747   }
1748   else
1749   {
1750     /* Return function status */
1751     return HAL_ERROR;
1752   }
1753 }
1754 
1755 /**
1756   * @brief  Get transmission timestamp.
1757   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1758   *         the configuration information for ETHERNET module
1759   * @param  timestamp: pointer to ETH_TIMESTAMPTypeDef structure that contains
1760   *         transmission timestamp
1761   * @retval HAL status
1762   */
1763 HAL_StatusTypeDef HAL_ETH_PTP_GetTxTimestamp(ETH_HandleTypeDef *heth, ETH_TimeStampTypeDef *timestamp)
1764 {
1765   ETH_TxDescListTypeDef *dmatxdesclist = &heth->TxDescList;
1766   uint32_t idx =       dmatxdesclist->releaseIndex;
1767   ETH_DMADescTypeDef *dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[idx];
1768 
1769   if (heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURED)
1770   {
1771     /* Get timestamp low */
1772     timestamp->TimeStampLow = dmatxdesc->DESC0;
1773     /* Get timestamp high */
1774     timestamp->TimeStampHigh = dmatxdesc->DESC1;
1775 
1776     /* Return function status */
1777     return HAL_OK;
1778   }
1779   else
1780   {
1781     /* Return function status */
1782     return HAL_ERROR;
1783   }
1784 }
1785 
1786 /**
1787   * @brief  Get receive timestamp.
1788   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1789   *         the configuration information for ETHERNET module
1790   * @param  timestamp: pointer to ETH_TIMESTAMPTypeDef structure that contains
1791   *         receive timestamp
1792   * @retval HAL status
1793   */
1794 HAL_StatusTypeDef HAL_ETH_PTP_GetRxTimestamp(ETH_HandleTypeDef *heth, ETH_TimeStampTypeDef *timestamp)
1795 {
1796   if (heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURED)
1797   {
1798     /* Get timestamp low */
1799     timestamp->TimeStampLow = heth->RxDescList.TimeStamp.TimeStampLow;
1800     /* Get timestamp high */
1801     timestamp->TimeStampHigh = heth->RxDescList.TimeStamp.TimeStampHigh;
1802 
1803     /* Return function status */
1804     return HAL_OK;
1805   }
1806   else
1807   {
1808     /* Return function status */
1809     return HAL_ERROR;
1810   }
1811 }
1812 
1813 /**
1814   * @brief  Register the Tx Ptp callback.
1815   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1816   *         the configuration information for ETHERNET module
1817   * @param  txPtpCallback: Function to handle Ptp transmission
1818   * @retval HAL status
1819   */
1820 HAL_StatusTypeDef HAL_ETH_RegisterTxPtpCallback(ETH_HandleTypeDef *heth, pETH_txPtpCallbackTypeDef txPtpCallback)
1821 {
1822   if (txPtpCallback == NULL)
1823   {
1824     /* No buffer to save */
1825     return HAL_ERROR;
1826   }
1827   /* Set Function to handle Tx Ptp */
1828   heth->txPtpCallback = txPtpCallback;
1829 
1830   return HAL_OK;
1831 }
1832 
1833 /**
1834   * @brief  Unregister the Tx Ptp callback.
1835   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1836   *         the configuration information for ETHERNET module
1837   * @retval HAL status
1838   */
1839 HAL_StatusTypeDef HAL_ETH_UnRegisterTxPtpCallback(ETH_HandleTypeDef *heth)
1840 {
1841   /* Set function to allocate buffer */
1842   heth->txPtpCallback = HAL_ETH_TxPtpCallback;
1843 
1844   return HAL_OK;
1845 }
1846 
1847 /**
1848   * @brief  Tx Ptp callback.
1849   * @param  buff: pointer to application buffer
1850   * @param  timestamp: pointer to ETH_TimeStampTypeDef structure that contains
1851   *         transmission timestamp
1852   * @retval None
1853   */
1854 __weak void HAL_ETH_TxPtpCallback(uint32_t *buff, ETH_TimeStampTypeDef *timestamp)
1855 {
1856   /* Prevent unused argument(s) compilation warning */
1857   UNUSED(buff);
1858   /* NOTE : This function Should not be modified, when the callback is needed,
1859   the HAL_ETH_TxPtpCallback could be implemented in the user file
1860   */
1861 }
1862 #endif  /* HAL_ETH_USE_PTP */
1863 
1864 /**
1865   * @brief  This function handles ETH interrupt request.
1866   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1867   *         the configuration information for ETHERNET module
1868   * @retval HAL status
1869   */
1870 void HAL_ETH_IRQHandler(ETH_HandleTypeDef *heth)
1871 {
1872   uint32_t mac_flag = READ_REG(heth->Instance->MACISR);
1873   uint32_t dma_flag = READ_REG(heth->Instance->DMACSR);
1874   uint32_t dma_itsource = READ_REG(heth->Instance->DMACIER);
1875   uint32_t exti_d1_flag = READ_REG(EXTI_D1->PR3);
1876 #if defined(DUAL_CORE)
1877   uint32_t exti_d2_flag = READ_REG(EXTI_D2->PR3);
1878 #endif /* DUAL_CORE */
1879 
1880   /* Packet received */
1881   if (((dma_flag & ETH_DMACSR_RI) != 0U) && ((dma_itsource & ETH_DMACIER_RIE) != 0U))
1882   {
1883     /* Clear the Eth DMA Rx IT pending bits */
1884     __HAL_ETH_DMA_CLEAR_IT(heth, ETH_DMACSR_RI | ETH_DMACSR_NIS);
1885 
1886 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
1887     /*Call registered Receive complete callback*/
1888     heth->RxCpltCallback(heth);
1889 #else
1890     /* Receive complete callback */
1891     HAL_ETH_RxCpltCallback(heth);
1892 #endif  /* USE_HAL_ETH_REGISTER_CALLBACKS */
1893   }
1894 
1895   /* Packet transmitted */
1896   if (((dma_flag & ETH_DMACSR_TI) != 0U) && ((dma_itsource & ETH_DMACIER_TIE) != 0U))
1897   {
1898     /* Clear the Eth DMA Tx IT pending bits */
1899     __HAL_ETH_DMA_CLEAR_IT(heth, ETH_DMACSR_TI | ETH_DMACSR_NIS);
1900 
1901 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
1902     /*Call registered Transmit complete callback*/
1903     heth->TxCpltCallback(heth);
1904 #else
1905     /* Transfer complete callback */
1906     HAL_ETH_TxCpltCallback(heth);
1907 #endif  /* USE_HAL_ETH_REGISTER_CALLBACKS */
1908   }
1909 
1910   /* ETH DMA Error */
1911   if (((dma_flag & ETH_DMACSR_AIS) != 0U) && ((dma_itsource & ETH_DMACIER_AIE) != 0U))
1912   {
1913     heth->ErrorCode |= HAL_ETH_ERROR_DMA;
1914     /* if fatal bus error occurred */
1915     if ((dma_flag & ETH_DMACSR_FBE) != 0U)
1916     {
1917       /* Get DMA error code  */
1918       heth->DMAErrorCode = READ_BIT(heth->Instance->DMACSR, (ETH_DMACSR_FBE | ETH_DMACSR_TPS | ETH_DMACSR_RPS));
1919 
1920       /* Disable all interrupts */
1921       __HAL_ETH_DMA_DISABLE_IT(heth, ETH_DMACIER_NIE | ETH_DMACIER_AIE);
1922 
1923       /* Set HAL state to ERROR */
1924       heth->gState = HAL_ETH_STATE_ERROR;
1925     }
1926     else
1927     {
1928       /* Get DMA error status  */
1929       heth->DMAErrorCode = READ_BIT(heth->Instance->DMACSR, (ETH_DMACSR_CDE | ETH_DMACSR_ETI | ETH_DMACSR_RWT |
1930                                                              ETH_DMACSR_RBU | ETH_DMACSR_AIS));
1931 
1932       /* Clear the interrupt summary flag */
1933       __HAL_ETH_DMA_CLEAR_IT(heth, (ETH_DMACSR_CDE | ETH_DMACSR_ETI | ETH_DMACSR_RWT |
1934                                     ETH_DMACSR_RBU | ETH_DMACSR_AIS));
1935     }
1936 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
1937     /* Call registered Error callback*/
1938     heth->ErrorCallback(heth);
1939 #else
1940     /* Ethernet DMA Error callback */
1941     HAL_ETH_ErrorCallback(heth);
1942 #endif  /* USE_HAL_ETH_REGISTER_CALLBACKS */
1943   }
1944 
1945   /* ETH MAC Error IT */
1946   if (((mac_flag & ETH_MACIER_RXSTSIE) == ETH_MACIER_RXSTSIE) || \
1947       ((mac_flag & ETH_MACIER_TXSTSIE) == ETH_MACIER_TXSTSIE))
1948   {
1949     heth->ErrorCode |= HAL_ETH_ERROR_MAC;
1950 
1951     /* Get MAC Rx Tx status and clear Status register pending bit */
1952     heth->MACErrorCode = READ_REG(heth->Instance->MACRXTXSR);
1953 
1954     heth->gState = HAL_ETH_STATE_ERROR;
1955 
1956 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
1957     /* Call registered Error callback*/
1958     heth->ErrorCallback(heth);
1959 #else
1960     /* Ethernet Error callback */
1961     HAL_ETH_ErrorCallback(heth);
1962 #endif  /* USE_HAL_ETH_REGISTER_CALLBACKS */
1963     heth->MACErrorCode = (uint32_t)(0x0U);
1964   }
1965 
1966   /* ETH PMT IT */
1967   if ((mac_flag & ETH_MAC_PMT_IT) != 0U)
1968   {
1969     /* Get MAC Wake-up source and clear the status register pending bit */
1970     heth->MACWakeUpEvent = READ_BIT(heth->Instance->MACPCSR, (ETH_MACPCSR_RWKPRCVD | ETH_MACPCSR_MGKPRCVD));
1971 
1972 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
1973     /* Call registered PMT callback*/
1974     heth->PMTCallback(heth);
1975 #else
1976     /* Ethernet PMT callback */
1977     HAL_ETH_PMTCallback(heth);
1978 #endif  /* USE_HAL_ETH_REGISTER_CALLBACKS */
1979 
1980     heth->MACWakeUpEvent = (uint32_t)(0x0U);
1981   }
1982 
1983   /* ETH EEE IT */
1984   if ((mac_flag & ETH_MAC_LPI_IT) != 0U)
1985   {
1986     /* Get MAC LPI interrupt source and clear the status register pending bit */
1987     heth->MACLPIEvent = READ_BIT(heth->Instance->MACLCSR, 0x0000000FU);
1988 
1989 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
1990     /* Call registered EEE callback*/
1991     heth->EEECallback(heth);
1992 #else
1993     /* Ethernet EEE callback */
1994     HAL_ETH_EEECallback(heth);
1995 #endif  /* USE_HAL_ETH_REGISTER_CALLBACKS */
1996 
1997     heth->MACLPIEvent = (uint32_t)(0x0U);
1998   }
1999 
2000 #if defined(DUAL_CORE)
2001   if (HAL_GetCurrentCPUID() == CM7_CPUID)
2002   {
2003     /* check ETH WAKEUP exti flag */
2004     if ((exti_d1_flag & ETH_WAKEUP_EXTI_LINE) != 0U)
2005     {
2006       /* Clear ETH WAKEUP Exti pending bit */
2007       __HAL_ETH_WAKEUP_EXTI_CLEAR_FLAG(ETH_WAKEUP_EXTI_LINE);
2008 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
2009       /* Call registered WakeUp callback*/
2010       heth->WakeUpCallback(heth);
2011 #else
2012       /* ETH WAKEUP callback */
2013       HAL_ETH_WakeUpCallback(heth);
2014 #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */
2015     }
2016   }
2017   else
2018   {
2019     /* check ETH WAKEUP exti flag */
2020     if ((exti_d2_flag & ETH_WAKEUP_EXTI_LINE) != 0U)
2021     {
2022       /* Clear ETH WAKEUP Exti pending bit */
2023       __HAL_ETH_WAKEUP_EXTID2_CLEAR_FLAG(ETH_WAKEUP_EXTI_LINE);
2024 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
2025       /* Call registered WakeUp callback*/
2026       heth->WakeUpCallback(heth);
2027 #else
2028       /* ETH WAKEUP callback */
2029       HAL_ETH_WakeUpCallback(heth);
2030 #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */
2031     }
2032   }
2033 #else /* DUAL_CORE not defined */
2034   /* check ETH WAKEUP exti flag */
2035   if ((exti_d1_flag & ETH_WAKEUP_EXTI_LINE) != 0U)
2036   {
2037     /* Clear ETH WAKEUP Exti pending bit */
2038     __HAL_ETH_WAKEUP_EXTI_CLEAR_FLAG(ETH_WAKEUP_EXTI_LINE);
2039 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
2040     /* Call registered WakeUp callback*/
2041     heth->WakeUpCallback(heth);
2042 #else
2043     /* ETH WAKEUP callback */
2044     HAL_ETH_WakeUpCallback(heth);
2045 #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */
2046   }
2047 #endif /* DUAL_CORE */
2048 }
2049 
2050 /**
2051   * @brief  Tx Transfer completed callbacks.
2052   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2053   *         the configuration information for ETHERNET module
2054   * @retval None
2055   */
2056 __weak void HAL_ETH_TxCpltCallback(ETH_HandleTypeDef *heth)
2057 {
2058   /* Prevent unused argument(s) compilation warning */
2059   UNUSED(heth);
2060   /* NOTE : This function Should not be modified, when the callback is needed,
2061   the HAL_ETH_TxCpltCallback could be implemented in the user file
2062   */
2063 }
2064 
2065 /**
2066   * @brief  Rx Transfer completed callbacks.
2067   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2068   *         the configuration information for ETHERNET module
2069   * @retval None
2070   */
2071 __weak void HAL_ETH_RxCpltCallback(ETH_HandleTypeDef *heth)
2072 {
2073   /* Prevent unused argument(s) compilation warning */
2074   UNUSED(heth);
2075   /* NOTE : This function Should not be modified, when the callback is needed,
2076   the HAL_ETH_RxCpltCallback could be implemented in the user file
2077   */
2078 }
2079 
2080 /**
2081   * @brief  Ethernet transfer error callbacks
2082   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2083   *         the configuration information for ETHERNET module
2084   * @retval None
2085   */
2086 __weak void HAL_ETH_ErrorCallback(ETH_HandleTypeDef *heth)
2087 {
2088   /* Prevent unused argument(s) compilation warning */
2089   UNUSED(heth);
2090   /* NOTE : This function Should not be modified, when the callback is needed,
2091   the HAL_ETH_ErrorCallback could be implemented in the user file
2092   */
2093 }
2094 
2095 /**
2096   * @brief  Ethernet Power Management module IT callback
2097   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2098   *         the configuration information for ETHERNET module
2099   * @retval None
2100   */
2101 __weak void HAL_ETH_PMTCallback(ETH_HandleTypeDef *heth)
2102 {
2103   /* Prevent unused argument(s) compilation warning */
2104   UNUSED(heth);
2105   /* NOTE : This function Should not be modified, when the callback is needed,
2106   the HAL_ETH_PMTCallback could be implemented in the user file
2107   */
2108 }
2109 
2110 /**
2111   * @brief  Energy Efficient Etherent IT callback
2112   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2113   *         the configuration information for ETHERNET module
2114   * @retval None
2115   */
2116 __weak void HAL_ETH_EEECallback(ETH_HandleTypeDef *heth)
2117 {
2118   /* Prevent unused argument(s) compilation warning */
2119   UNUSED(heth);
2120   /* NOTE : This function Should not be modified, when the callback is needed,
2121   the HAL_ETH_EEECallback could be implemented in the user file
2122   */
2123 }
2124 
2125 /**
2126   * @brief  ETH WAKEUP interrupt callback
2127   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2128   *         the configuration information for ETHERNET module
2129   * @retval None
2130   */
2131 __weak void HAL_ETH_WakeUpCallback(ETH_HandleTypeDef *heth)
2132 {
2133   /* Prevent unused argument(s) compilation warning */
2134   UNUSED(heth);
2135   /* NOTE : This function Should not be modified, when the callback is needed,
2136             the HAL_ETH_WakeUpCallback could be implemented in the user file
2137    */
2138 }
2139 
2140 /**
2141   * @brief  Read a PHY register
2142   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2143   *         the configuration information for ETHERNET module
2144   * @param  PHYAddr: PHY port address, must be a value from 0 to 31
2145   * @param  PHYReg: PHY register address, must be a value from 0 to 31
2146   * @param pRegValue: parameter to hold read value
2147   * @retval HAL status
2148   */
2149 HAL_StatusTypeDef HAL_ETH_ReadPHYRegister(ETH_HandleTypeDef *heth, uint32_t PHYAddr, uint32_t PHYReg,
2150                                           uint32_t *pRegValue)
2151 {
2152   uint32_t tickstart;
2153   uint32_t tmpreg;
2154 
2155   /* Check for the Busy flag */
2156   if (READ_BIT(heth->Instance->MACMDIOAR, ETH_MACMDIOAR_MB) != (uint32_t)RESET)
2157   {
2158     return HAL_ERROR;
2159   }
2160 
2161   /* Get the  MACMDIOAR value */
2162   WRITE_REG(tmpreg, heth->Instance->MACMDIOAR);
2163 
2164   /* Prepare the MDIO Address Register value
2165      - Set the PHY device address
2166      - Set the PHY register address
2167      - Set the read mode
2168      - Set the MII Busy bit */
2169 
2170   MODIFY_REG(tmpreg, ETH_MACMDIOAR_PA, (PHYAddr << 21));
2171   MODIFY_REG(tmpreg, ETH_MACMDIOAR_RDA, (PHYReg << 16));
2172   MODIFY_REG(tmpreg, ETH_MACMDIOAR_MOC, ETH_MACMDIOAR_MOC_RD);
2173   SET_BIT(tmpreg, ETH_MACMDIOAR_MB);
2174 
2175   /* Write the result value into the MDII Address register */
2176   WRITE_REG(heth->Instance->MACMDIOAR, tmpreg);
2177 
2178   tickstart = HAL_GetTick();
2179 
2180   /* Wait for the Busy flag */
2181   while (READ_BIT(heth->Instance->MACMDIOAR, ETH_MACMDIOAR_MB) > 0U)
2182   {
2183     if (((HAL_GetTick() - tickstart) > ETH_MDIO_BUS_TIMEOUT))
2184     {
2185       return HAL_ERROR;
2186     }
2187   }
2188 
2189   /* Get MACMIIDR value */
2190   WRITE_REG(*pRegValue, (uint16_t)heth->Instance->MACMDIODR);
2191 
2192   return HAL_OK;
2193 }
2194 
2195 /**
2196   * @brief  Writes to a PHY register.
2197   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2198   *         the configuration information for ETHERNET module
2199   * @param  PHYAddr: PHY port address, must be a value from 0 to 31
2200   * @param  PHYReg: PHY register address, must be a value from 0 to 31
2201   * @param  RegValue: the value to write
2202   * @retval HAL status
2203   */
2204 HAL_StatusTypeDef HAL_ETH_WritePHYRegister(const ETH_HandleTypeDef *heth, uint32_t PHYAddr, uint32_t PHYReg,
2205                                            uint32_t RegValue)
2206 {
2207   uint32_t tickstart;
2208   uint32_t tmpreg;
2209 
2210   /* Check for the Busy flag */
2211   if (READ_BIT(heth->Instance->MACMDIOAR, ETH_MACMDIOAR_MB) != (uint32_t)RESET)
2212   {
2213     return HAL_ERROR;
2214   }
2215 
2216   /* Get the  MACMDIOAR value */
2217   WRITE_REG(tmpreg, heth->Instance->MACMDIOAR);
2218 
2219   /* Prepare the MDIO Address Register value
2220      - Set the PHY device address
2221      - Set the PHY register address
2222      - Set the write mode
2223      - Set the MII Busy bit */
2224 
2225   MODIFY_REG(tmpreg, ETH_MACMDIOAR_PA, (PHYAddr << 21));
2226   MODIFY_REG(tmpreg, ETH_MACMDIOAR_RDA, (PHYReg << 16));
2227   MODIFY_REG(tmpreg, ETH_MACMDIOAR_MOC, ETH_MACMDIOAR_MOC_WR);
2228   SET_BIT(tmpreg, ETH_MACMDIOAR_MB);
2229 
2230   /* Give the value to the MII data register */
2231   WRITE_REG(ETH->MACMDIODR, (uint16_t)RegValue);
2232 
2233   /* Write the result value into the MII Address register */
2234   WRITE_REG(ETH->MACMDIOAR, tmpreg);
2235 
2236   tickstart = HAL_GetTick();
2237 
2238   /* Wait for the Busy flag */
2239   while (READ_BIT(heth->Instance->MACMDIOAR, ETH_MACMDIOAR_MB) > 0U)
2240   {
2241     if (((HAL_GetTick() - tickstart) > ETH_MDIO_BUS_TIMEOUT))
2242     {
2243       return HAL_ERROR;
2244     }
2245   }
2246 
2247   return HAL_OK;
2248 }
2249 
2250 /**
2251   * @}
2252   */
2253 
2254 /** @defgroup ETH_Exported_Functions_Group3 Peripheral Control functions
2255   * @ingroup RTEMSBSPsARMSTM32H7
2256   *  @brief   ETH control functions
2257   *
2258 @verbatim
2259   ==============================================================================
2260                       ##### Peripheral Control functions #####
2261   ==============================================================================
2262   [..]
2263     This subsection provides a set of functions allowing to control the ETH
2264     peripheral.
2265 
2266 @endverbatim
2267   * @{
2268   */
2269 /**
2270   * @brief  Get the configuration of the MAC and MTL subsystems.
2271   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2272   *         the configuration information for ETHERNET module
2273   * @param  macconf: pointer to a ETH_MACConfigTypeDef structure that will hold
2274   *         the configuration of the MAC.
2275   * @retval HAL Status
2276   */
2277 HAL_StatusTypeDef HAL_ETH_GetMACConfig(const ETH_HandleTypeDef *heth, ETH_MACConfigTypeDef *macconf)
2278 {
2279   if (macconf == NULL)
2280   {
2281     return HAL_ERROR;
2282   }
2283 
2284   /* Get MAC parameters */
2285   macconf->PreambleLength = READ_BIT(heth->Instance->MACCR, ETH_MACCR_PRELEN);
2286   macconf->DeferralCheck = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_DC) >> 4) > 0U) ? ENABLE : DISABLE;
2287   macconf->BackOffLimit = READ_BIT(heth->Instance->MACCR, ETH_MACCR_BL);
2288   macconf->RetryTransmission = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_DR) >> 8) == 0U) ? ENABLE : DISABLE;
2289   macconf->CarrierSenseDuringTransmit = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_DCRS) >> 9) > 0U)
2290                                         ? ENABLE : DISABLE;
2291   macconf->ReceiveOwn = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_DO) >> 10) == 0U) ? ENABLE : DISABLE;
2292   macconf->CarrierSenseBeforeTransmit = ((READ_BIT(heth->Instance->MACCR,
2293                                                    ETH_MACCR_ECRSFD) >> 11) > 0U) ? ENABLE : DISABLE;
2294   macconf->LoopbackMode = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_LM) >> 12) > 0U) ? ENABLE : DISABLE;
2295   macconf->DuplexMode = READ_BIT(heth->Instance->MACCR, ETH_MACCR_DM);
2296   macconf->Speed = READ_BIT(heth->Instance->MACCR, ETH_MACCR_FES);
2297   macconf->JumboPacket = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_JE) >> 16) > 0U) ? ENABLE : DISABLE;
2298   macconf->Jabber = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_JD) >> 17) == 0U) ? ENABLE : DISABLE;
2299   macconf->Watchdog = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_WD) >> 19) == 0U) ? ENABLE : DISABLE;
2300   macconf->AutomaticPadCRCStrip = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_ACS) >> 20) > 0U) ? ENABLE : DISABLE;
2301   macconf->CRCStripTypePacket = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_CST) >> 21) > 0U) ? ENABLE : DISABLE;
2302   macconf->Support2KPacket = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_S2KP) >> 22) > 0U) ? ENABLE : DISABLE;
2303   macconf->GiantPacketSizeLimitControl = ((READ_BIT(heth->Instance->MACCR,
2304                                                     ETH_MACCR_GPSLCE) >> 23) > 0U) ? ENABLE : DISABLE;
2305   macconf->InterPacketGapVal = READ_BIT(heth->Instance->MACCR, ETH_MACCR_IPG);
2306   macconf->ChecksumOffload = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_IPC) >> 27) > 0U) ? ENABLE : DISABLE;
2307   macconf->SourceAddrControl = READ_BIT(heth->Instance->MACCR, ETH_MACCR_SARC);
2308 
2309   macconf->GiantPacketSizeLimit = READ_BIT(heth->Instance->MACECR, ETH_MACECR_GPSL);
2310   macconf->CRCCheckingRxPackets = ((READ_BIT(heth->Instance->MACECR, ETH_MACECR_DCRCC) >> 16) == 0U) ? ENABLE : DISABLE;
2311   macconf->SlowProtocolDetect = ((READ_BIT(heth->Instance->MACECR, ETH_MACECR_SPEN) >> 17) > 0U) ? ENABLE : DISABLE;
2312   macconf->UnicastSlowProtocolPacketDetect = ((READ_BIT(heth->Instance->MACECR,
2313                                                         ETH_MACECR_USP) >> 18) > 0U) ? ENABLE : DISABLE;
2314   macconf->ExtendedInterPacketGap = ((READ_BIT(heth->Instance->MACECR, ETH_MACECR_EIPGEN) >> 24) > 0U)
2315                                     ? ENABLE : DISABLE;
2316   macconf->ExtendedInterPacketGapVal = READ_BIT(heth->Instance->MACECR, ETH_MACECR_EIPG) >> 25;
2317 
2318   macconf->ProgrammableWatchdog = ((READ_BIT(heth->Instance->MACWTR, ETH_MACWTR_PWE) >> 8) > 0U) ? ENABLE : DISABLE;
2319   macconf->WatchdogTimeout = READ_BIT(heth->Instance->MACWTR, ETH_MACWTR_WTO);
2320 
2321   macconf->TransmitFlowControl = ((READ_BIT(heth->Instance->MACTFCR, ETH_MACTFCR_TFE) >> 1) > 0U) ? ENABLE : DISABLE;
2322   macconf->ZeroQuantaPause = ((READ_BIT(heth->Instance->MACTFCR, ETH_MACTFCR_DZPQ) >> 7) == 0U) ? ENABLE : DISABLE;
2323   macconf->PauseLowThreshold = READ_BIT(heth->Instance->MACTFCR, ETH_MACTFCR_PLT);
2324   macconf->PauseTime = (READ_BIT(heth->Instance->MACTFCR, ETH_MACTFCR_PT) >> 16);
2325   macconf->ReceiveFlowControl = (READ_BIT(heth->Instance->MACRFCR, ETH_MACRFCR_RFE) > 0U) ? ENABLE : DISABLE;
2326   macconf->UnicastPausePacketDetect = ((READ_BIT(heth->Instance->MACRFCR, ETH_MACRFCR_UP) >> 1) > 0U)
2327                                       ? ENABLE : DISABLE;
2328 
2329   macconf->TransmitQueueMode = READ_BIT(heth->Instance->MTLTQOMR, (ETH_MTLTQOMR_TTC | ETH_MTLTQOMR_TSF));
2330 
2331   macconf->ReceiveQueueMode = READ_BIT(heth->Instance->MTLRQOMR, (ETH_MTLRQOMR_RTC | ETH_MTLRQOMR_RSF));
2332   macconf->ForwardRxUndersizedGoodPacket = ((READ_BIT(heth->Instance->MTLRQOMR,
2333                                                       ETH_MTLRQOMR_FUP) >> 3) > 0U) ? ENABLE : DISABLE;
2334   macconf->ForwardRxErrorPacket = ((READ_BIT(heth->Instance->MTLRQOMR, ETH_MTLRQOMR_FEP) >> 4) > 0U) ? ENABLE : DISABLE;
2335   macconf->DropTCPIPChecksumErrorPacket = ((READ_BIT(heth->Instance->MTLRQOMR,
2336                                                      ETH_MTLRQOMR_DISTCPEF) >> 6) == 0U) ? ENABLE : DISABLE;
2337 
2338   return HAL_OK;
2339 }
2340 
2341 /**
2342   * @brief  Get the configuration of the DMA.
2343   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2344   *         the configuration information for ETHERNET module
2345   * @param  dmaconf: pointer to a ETH_DMAConfigTypeDef structure that will hold
2346   *         the configuration of the ETH DMA.
2347   * @retval HAL Status
2348   */
2349 HAL_StatusTypeDef HAL_ETH_GetDMAConfig(const ETH_HandleTypeDef *heth, ETH_DMAConfigTypeDef *dmaconf)
2350 {
2351   if (dmaconf == NULL)
2352   {
2353     return HAL_ERROR;
2354   }
2355 
2356   dmaconf->AddressAlignedBeats = ((READ_BIT(heth->Instance->DMASBMR, ETH_DMASBMR_AAL) >> 12) > 0U) ? ENABLE : DISABLE;
2357   dmaconf->BurstMode = READ_BIT(heth->Instance->DMASBMR, ETH_DMASBMR_FB | ETH_DMASBMR_MB);
2358   dmaconf->RebuildINCRxBurst = ((READ_BIT(heth->Instance->DMASBMR, ETH_DMASBMR_RB) >> 15) > 0U) ? ENABLE : DISABLE;
2359 
2360   dmaconf->DMAArbitration = READ_BIT(heth->Instance->DMAMR, (ETH_DMAMR_TXPR | ETH_DMAMR_PR | ETH_DMAMR_DA));
2361 
2362   dmaconf->PBLx8Mode = ((READ_BIT(heth->Instance->DMACCR, ETH_DMACCR_8PBL) >> 16) > 0U) ? ENABLE : DISABLE;
2363   dmaconf->MaximumSegmentSize = READ_BIT(heth->Instance->DMACCR, ETH_DMACCR_MSS);
2364 
2365   dmaconf->FlushRxPacket = ((READ_BIT(heth->Instance->DMACRCR,  ETH_DMACRCR_RPF) >> 31) > 0U) ? ENABLE : DISABLE;
2366   dmaconf->RxDMABurstLength = READ_BIT(heth->Instance->DMACRCR, ETH_DMACRCR_RPBL);
2367 
2368   dmaconf->SecondPacketOperate = ((READ_BIT(heth->Instance->DMACTCR, ETH_DMACTCR_OSP) >> 4) > 0U) ? ENABLE : DISABLE;
2369   dmaconf->TCPSegmentation = ((READ_BIT(heth->Instance->DMACTCR, ETH_DMACTCR_TSE) >> 12) > 0U) ? ENABLE : DISABLE;
2370   dmaconf->TxDMABurstLength = READ_BIT(heth->Instance->DMACTCR, ETH_DMACTCR_TPBL);
2371 
2372   return HAL_OK;
2373 }
2374 
2375 /**
2376   * @brief  Set the MAC configuration.
2377   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2378   *         the configuration information for ETHERNET module
2379   * @param  macconf: pointer to a ETH_MACConfigTypeDef structure that contains
2380   *         the configuration of the MAC.
2381   * @retval HAL status
2382   */
2383 HAL_StatusTypeDef HAL_ETH_SetMACConfig(ETH_HandleTypeDef *heth,  ETH_MACConfigTypeDef *macconf)
2384 {
2385   if (macconf == NULL)
2386   {
2387     return HAL_ERROR;
2388   }
2389 
2390   if (heth->gState == HAL_ETH_STATE_READY)
2391   {
2392     ETH_SetMACConfig(heth, macconf);
2393 
2394     return HAL_OK;
2395   }
2396   else
2397   {
2398     return HAL_ERROR;
2399   }
2400 }
2401 
2402 /**
2403   * @brief  Set the ETH DMA configuration.
2404   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2405   *         the configuration information for ETHERNET module
2406   * @param  dmaconf: pointer to a ETH_DMAConfigTypeDef structure that will hold
2407   *         the configuration of the ETH DMA.
2408   * @retval HAL status
2409   */
2410 HAL_StatusTypeDef HAL_ETH_SetDMAConfig(ETH_HandleTypeDef *heth,  ETH_DMAConfigTypeDef *dmaconf)
2411 {
2412   if (dmaconf == NULL)
2413   {
2414     return HAL_ERROR;
2415   }
2416 
2417   if (heth->gState == HAL_ETH_STATE_READY)
2418   {
2419     ETH_SetDMAConfig(heth, dmaconf);
2420 
2421     return HAL_OK;
2422   }
2423   else
2424   {
2425     return HAL_ERROR;
2426   }
2427 }
2428 
2429 /**
2430   * @brief  Configures the Clock range of ETH MDIO interface.
2431   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2432   *         the configuration information for ETHERNET module
2433   * @retval None
2434   */
2435 void HAL_ETH_SetMDIOClockRange(ETH_HandleTypeDef *heth)
2436 {
2437   uint32_t hclk;
2438   uint32_t tmpreg;
2439 
2440   /* Get the ETHERNET MACMDIOAR value */
2441   tmpreg = (heth->Instance)->MACMDIOAR;
2442 
2443   /* Clear CSR Clock Range bits */
2444   tmpreg &= ~ETH_MACMDIOAR_CR;
2445 
2446   /* Get hclk frequency value */
2447   hclk = HAL_RCC_GetHCLKFreq();
2448 
2449   /* Set CR bits depending on hclk value */
2450   if (hclk < 35000000U)
2451   {
2452     /* CSR Clock Range between 0-35 MHz */
2453     tmpreg |= (uint32_t)ETH_MACMDIOAR_CR_DIV16;
2454   }
2455   else if (hclk < 60000000U)
2456   {
2457     /* CSR Clock Range between 35-60 MHz */
2458     tmpreg |= (uint32_t)ETH_MACMDIOAR_CR_DIV26;
2459   }
2460   else if (hclk < 100000000U)
2461   {
2462     /* CSR Clock Range between 60-100 MHz */
2463     tmpreg |= (uint32_t)ETH_MACMDIOAR_CR_DIV42;
2464   }
2465   else if (hclk < 150000000U)
2466   {
2467     /* CSR Clock Range between 100-150 MHz */
2468     tmpreg |= (uint32_t)ETH_MACMDIOAR_CR_DIV62;
2469   }
2470   else if (hclk < 250000000U)
2471   {
2472     /* CSR Clock Range between 150-250 MHz */
2473     tmpreg |= (uint32_t)ETH_MACMDIOAR_CR_DIV102;
2474   }
2475   else /* (hclk >= 250000000U) */
2476   {
2477     /* CSR Clock >= 250 MHz */
2478     tmpreg |= (uint32_t)(ETH_MACMDIOAR_CR_DIV124);
2479   }
2480 
2481   /* Configure the CSR Clock Range */
2482   (heth->Instance)->MACMDIOAR = (uint32_t)tmpreg;
2483 }
2484 
2485 /**
2486   * @brief  Set the ETH MAC (L2) Filters configuration.
2487   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2488   *         the configuration information for ETHERNET module
2489   * @param  pFilterConfig: pointer to a ETH_MACFilterConfigTypeDef structure that contains
2490   *         the configuration of the ETH MAC filters.
2491   * @retval HAL status
2492   */
2493 HAL_StatusTypeDef HAL_ETH_SetMACFilterConfig(ETH_HandleTypeDef *heth, const ETH_MACFilterConfigTypeDef *pFilterConfig)
2494 {
2495   uint32_t filterconfig;
2496 
2497   if (pFilterConfig == NULL)
2498   {
2499     return HAL_ERROR;
2500   }
2501 
2502   filterconfig = ((uint32_t)pFilterConfig->PromiscuousMode |
2503                   ((uint32_t)pFilterConfig->HashUnicast << 1) |
2504                   ((uint32_t)pFilterConfig->HashMulticast << 2)  |
2505                   ((uint32_t)pFilterConfig->DestAddrInverseFiltering << 3) |
2506                   ((uint32_t)pFilterConfig->PassAllMulticast << 4) |
2507                   ((uint32_t)((pFilterConfig->BroadcastFilter == DISABLE) ? 1U : 0U) << 5) |
2508                   ((uint32_t)pFilterConfig->SrcAddrInverseFiltering << 8) |
2509                   ((uint32_t)pFilterConfig->SrcAddrFiltering << 9) |
2510                   ((uint32_t)pFilterConfig->HachOrPerfectFilter << 10) |
2511                   ((uint32_t)pFilterConfig->ReceiveAllMode << 31) |
2512                   pFilterConfig->ControlPacketsFilter);
2513 
2514   MODIFY_REG(heth->Instance->MACPFR, ETH_MACPFR_MASK, filterconfig);
2515 
2516   return HAL_OK;
2517 }
2518 
2519 /**
2520   * @brief  Get the ETH MAC (L2) Filters configuration.
2521   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2522   *         the configuration information for ETHERNET module
2523   * @param  pFilterConfig: pointer to a ETH_MACFilterConfigTypeDef structure that will hold
2524   *         the configuration of the ETH MAC filters.
2525   * @retval HAL status
2526   */
2527 HAL_StatusTypeDef HAL_ETH_GetMACFilterConfig(const ETH_HandleTypeDef *heth, ETH_MACFilterConfigTypeDef *pFilterConfig)
2528 {
2529   if (pFilterConfig == NULL)
2530   {
2531     return HAL_ERROR;
2532   }
2533 
2534   pFilterConfig->PromiscuousMode = ((READ_BIT(heth->Instance->MACPFR, ETH_MACPFR_PR)) > 0U) ? ENABLE : DISABLE;
2535   pFilterConfig->HashUnicast = ((READ_BIT(heth->Instance->MACPFR, ETH_MACPFR_HUC) >> 1) > 0U) ? ENABLE : DISABLE;
2536   pFilterConfig->HashMulticast = ((READ_BIT(heth->Instance->MACPFR, ETH_MACPFR_HMC) >> 2) > 0U) ? ENABLE : DISABLE;
2537   pFilterConfig->DestAddrInverseFiltering = ((READ_BIT(heth->Instance->MACPFR,
2538                                                        ETH_MACPFR_DAIF) >> 3) > 0U) ? ENABLE : DISABLE;
2539   pFilterConfig->PassAllMulticast = ((READ_BIT(heth->Instance->MACPFR, ETH_MACPFR_PM) >> 4) > 0U) ? ENABLE : DISABLE;
2540   pFilterConfig->BroadcastFilter = ((READ_BIT(heth->Instance->MACPFR, ETH_MACPFR_DBF) >> 5) == 0U) ? ENABLE : DISABLE;
2541   pFilterConfig->ControlPacketsFilter = READ_BIT(heth->Instance->MACPFR, ETH_MACPFR_PCF);
2542   pFilterConfig->SrcAddrInverseFiltering = ((READ_BIT(heth->Instance->MACPFR,
2543                                                       ETH_MACPFR_SAIF) >> 8) > 0U) ? ENABLE : DISABLE;
2544   pFilterConfig->SrcAddrFiltering = ((READ_BIT(heth->Instance->MACPFR, ETH_MACPFR_SAF) >> 9) > 0U) ? ENABLE : DISABLE;
2545   pFilterConfig->HachOrPerfectFilter = ((READ_BIT(heth->Instance->MACPFR, ETH_MACPFR_HPF) >> 10) > 0U)
2546                                        ? ENABLE : DISABLE;
2547   pFilterConfig->ReceiveAllMode = ((READ_BIT(heth->Instance->MACPFR, ETH_MACPFR_RA) >> 31) > 0U) ? ENABLE : DISABLE;
2548 
2549   return HAL_OK;
2550 }
2551 
2552 /**
2553   * @brief  Set the source MAC Address to be matched.
2554   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2555   *         the configuration information for ETHERNET module
2556   * @param  AddrNbr: The MAC address to configure
2557   *          This parameter must be a value of the following:
2558   *            ETH_MAC_ADDRESS1
2559   *            ETH_MAC_ADDRESS2
2560   *            ETH_MAC_ADDRESS3
2561   * @param  pMACAddr: Pointer to MAC address buffer data (6 bytes)
2562   * @retval HAL status
2563   */
2564 HAL_StatusTypeDef HAL_ETH_SetSourceMACAddrMatch(const ETH_HandleTypeDef *heth, uint32_t AddrNbr,
2565                                                 const uint8_t *pMACAddr)
2566 {
2567   uint32_t macaddrlr;
2568   uint32_t macaddrhr;
2569 
2570   if (pMACAddr == NULL)
2571   {
2572     return HAL_ERROR;
2573   }
2574 
2575   /* Get mac addr high reg offset */
2576   macaddrhr = ((uint32_t) &(heth->Instance->MACA0HR) + AddrNbr);
2577   /* Get mac addr low reg offset */
2578   macaddrlr = ((uint32_t) &(heth->Instance->MACA0LR) + AddrNbr);
2579 
2580   /* Set MAC addr bits 32 to 47 */
2581   (*(__IO uint32_t *)macaddrhr) = (((uint32_t)(pMACAddr[5]) << 8) | (uint32_t)pMACAddr[4]);
2582   /* Set MAC addr bits 0 to 31 */
2583   (*(__IO uint32_t *)macaddrlr) = (((uint32_t)(pMACAddr[3]) << 24) | ((uint32_t)(pMACAddr[2]) << 16) |
2584                                    ((uint32_t)(pMACAddr[1]) << 8) | (uint32_t)pMACAddr[0]);
2585 
2586   /* Enable address and set source address bit */
2587   (*(__IO uint32_t *)macaddrhr) |= (ETH_MACAHR_SA | ETH_MACAHR_AE);
2588 
2589   return HAL_OK;
2590 }
2591 
2592 /**
2593   * @brief  Set the ETH Hash Table Value.
2594   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2595   *         the configuration information for ETHERNET module
2596   * @param  pHashTable: pointer to a table of two 32 bit values, that contains
2597   *         the 64 bits of the hash table.
2598   * @retval HAL status
2599   */
2600 HAL_StatusTypeDef HAL_ETH_SetHashTable(ETH_HandleTypeDef *heth, uint32_t *pHashTable)
2601 {
2602   if (pHashTable == NULL)
2603   {
2604     return HAL_ERROR;
2605   }
2606 
2607   heth->Instance->MACHT0R = pHashTable[0];
2608   heth->Instance->MACHT1R = pHashTable[1];
2609 
2610   return HAL_OK;
2611 }
2612 
2613 /**
2614   * @brief  Set the VLAN Identifier for Rx packets
2615   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2616   *         the configuration information for ETHERNET module
2617   * @param  ComparisonBits: 12 or 16 bit comparison mode
2618             must be a value of @ref ETH_VLAN_Tag_Comparison
2619   * @param  VLANIdentifier: VLAN Identifier value
2620   * @retval None
2621   */
2622 void HAL_ETH_SetRxVLANIdentifier(ETH_HandleTypeDef *heth, uint32_t ComparisonBits, uint32_t VLANIdentifier)
2623 {
2624   if (ComparisonBits == ETH_VLANTAGCOMPARISON_16BIT)
2625   {
2626     MODIFY_REG(heth->Instance->MACVTR, ETH_MACVTR_VL, VLANIdentifier);
2627     CLEAR_BIT(heth->Instance->MACVTR, ETH_MACVTR_ETV);
2628   }
2629   else
2630   {
2631     MODIFY_REG(heth->Instance->MACVTR, ETH_MACVTR_VL_VID, VLANIdentifier);
2632     SET_BIT(heth->Instance->MACVTR, ETH_MACVTR_ETV);
2633   }
2634 }
2635 
2636 /**
2637   * @brief  Enters the Power down mode.
2638   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2639   *         the configuration information for ETHERNET module
2640   * @param  pPowerDownConfig: a pointer to ETH_PowerDownConfigTypeDef structure
2641   *         that contains the Power Down configuration
2642   * @retval None.
2643   */
2644 void HAL_ETH_EnterPowerDownMode(ETH_HandleTypeDef *heth, const ETH_PowerDownConfigTypeDef *pPowerDownConfig)
2645 {
2646   uint32_t powerdownconfig;
2647 
2648   powerdownconfig = (((uint32_t)pPowerDownConfig->MagicPacket << 1) |
2649                      ((uint32_t)pPowerDownConfig->WakeUpPacket << 2) |
2650                      ((uint32_t)pPowerDownConfig->GlobalUnicast << 9) |
2651                      ((uint32_t)pPowerDownConfig->WakeUpForward << 10) |
2652                      ETH_MACPCSR_PWRDWN);
2653 
2654   /* Enable PMT interrupt */
2655   __HAL_ETH_MAC_ENABLE_IT(heth, ETH_MACIER_PMTIE);
2656 
2657   MODIFY_REG(heth->Instance->MACPCSR, ETH_MACPCSR_MASK, powerdownconfig);
2658 }
2659 
2660 /**
2661   * @brief  Exits from the Power down mode.
2662   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2663   *         the configuration information for ETHERNET module
2664   * @retval None.
2665   */
2666 void HAL_ETH_ExitPowerDownMode(ETH_HandleTypeDef *heth)
2667 {
2668   /* clear wake up sources */
2669   CLEAR_BIT(heth->Instance->MACPCSR, ETH_MACPCSR_RWKPKTEN | ETH_MACPCSR_MGKPKTEN | ETH_MACPCSR_GLBLUCAST |
2670             ETH_MACPCSR_RWKPFE);
2671 
2672   if (READ_BIT(heth->Instance->MACPCSR, ETH_MACPCSR_PWRDWN) != (uint32_t)RESET)
2673   {
2674     /* Exit power down mode */
2675     CLEAR_BIT(heth->Instance->MACPCSR, ETH_MACPCSR_PWRDWN);
2676   }
2677 
2678   /* Disable PMT interrupt */
2679   __HAL_ETH_MAC_DISABLE_IT(heth, ETH_MACIER_PMTIE);
2680 }
2681 
2682 /**
2683   * @brief  Set the WakeUp filter.
2684   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2685   *         the configuration information for ETHERNET module
2686   * @param  pFilter: pointer to filter registers values
2687   * @param  Count: number of filter registers, must be from 1 to 8.
2688   * @retval None.
2689   */
2690 HAL_StatusTypeDef HAL_ETH_SetWakeUpFilter(ETH_HandleTypeDef *heth, uint32_t *pFilter, uint32_t Count)
2691 {
2692   uint32_t regindex;
2693 
2694   if (pFilter == NULL)
2695   {
2696     return HAL_ERROR;
2697   }
2698 
2699   /* Reset Filter Pointer */
2700   SET_BIT(heth->Instance->MACPCSR, ETH_MACPCSR_RWKFILTRST);
2701 
2702   /* Wake up packet filter config */
2703   for (regindex = 0; regindex < Count; regindex++)
2704   {
2705     /* Write filter regs */
2706     WRITE_REG(heth->Instance->MACRWKPFR, pFilter[regindex]);
2707   }
2708 
2709   return HAL_OK;
2710 }
2711 
2712 /**
2713   * @}
2714   */
2715 
2716 /** @defgroup ETH_Exported_Functions_Group4 Peripheral State and Errors functions
2717   * @ingroup RTEMSBSPsARMSTM32H7
2718   *  @brief   ETH State and Errors functions
2719   *
2720 @verbatim
2721   ==============================================================================
2722                  ##### Peripheral State and Errors functions #####
2723   ==============================================================================
2724  [..]
2725    This subsection provides a set of functions allowing to return the State of
2726    ETH communication process, return Peripheral Errors occurred during communication
2727    process
2728 
2729 
2730 @endverbatim
2731   * @{
2732   */
2733 
2734 /**
2735   * @brief  Returns the ETH state.
2736   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2737   *         the configuration information for ETHERNET module
2738   * @retval HAL state
2739   */
2740 HAL_ETH_StateTypeDef HAL_ETH_GetState(const ETH_HandleTypeDef *heth)
2741 {
2742   return heth->gState;
2743 }
2744 
2745 /**
2746   * @brief  Returns the ETH error code
2747   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2748   *         the configuration information for ETHERNET module
2749   * @retval ETH Error Code
2750   */
2751 uint32_t HAL_ETH_GetError(const ETH_HandleTypeDef *heth)
2752 {
2753   return heth->ErrorCode;
2754 }
2755 
2756 /**
2757   * @brief  Returns the ETH DMA error code
2758   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2759   *         the configuration information for ETHERNET module
2760   * @retval ETH DMA Error Code
2761   */
2762 uint32_t HAL_ETH_GetDMAError(const ETH_HandleTypeDef *heth)
2763 {
2764   return heth->DMAErrorCode;
2765 }
2766 
2767 /**
2768   * @brief  Returns the ETH MAC error code
2769   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2770   *         the configuration information for ETHERNET module
2771   * @retval ETH MAC Error Code
2772   */
2773 uint32_t HAL_ETH_GetMACError(const ETH_HandleTypeDef *heth)
2774 {
2775   return heth->MACErrorCode;
2776 }
2777 
2778 /**
2779   * @brief  Returns the ETH MAC WakeUp event source
2780   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2781   *         the configuration information for ETHERNET module
2782   * @retval ETH MAC WakeUp event source
2783   */
2784 uint32_t HAL_ETH_GetMACWakeUpSource(const ETH_HandleTypeDef *heth)
2785 {
2786   return heth->MACWakeUpEvent;
2787 }
2788 
2789 /**
2790   * @}
2791   */
2792 
2793 /**
2794   * @}
2795   */
2796 
2797 /** @addtogroup ETH_Private_Functions   ETH Private Functions
2798   * @{
2799   */
2800 
2801 static void ETH_SetMACConfig(ETH_HandleTypeDef *heth, const ETH_MACConfigTypeDef *macconf)
2802 {
2803   uint32_t macregval;
2804 
2805   /*------------------------ MACCR Configuration --------------------*/
2806   macregval = (macconf->InterPacketGapVal |
2807                macconf->SourceAddrControl |
2808                ((uint32_t)macconf->ChecksumOffload << 27) |
2809                ((uint32_t)macconf->GiantPacketSizeLimitControl << 23) |
2810                ((uint32_t)macconf->Support2KPacket  << 22) |
2811                ((uint32_t)macconf->CRCStripTypePacket << 21) |
2812                ((uint32_t)macconf->AutomaticPadCRCStrip << 20) |
2813                ((uint32_t)((macconf->Watchdog == DISABLE) ? 1U : 0U) << 19) |
2814                ((uint32_t)((macconf->Jabber == DISABLE) ? 1U : 0U) << 17) |
2815                ((uint32_t)macconf->JumboPacket << 16) |
2816                macconf->Speed |
2817                macconf->DuplexMode |
2818                ((uint32_t)macconf->LoopbackMode << 12) |
2819                ((uint32_t)macconf->CarrierSenseBeforeTransmit << 11) |
2820                ((uint32_t)((macconf->ReceiveOwn == DISABLE) ? 1U : 0U) << 10) |
2821                ((uint32_t)macconf->CarrierSenseDuringTransmit << 9) |
2822                ((uint32_t)((macconf->RetryTransmission == DISABLE) ? 1U : 0U) << 8) |
2823                macconf->BackOffLimit |
2824                ((uint32_t)macconf->DeferralCheck << 4) |
2825                macconf->PreambleLength);
2826 
2827   /* Write to MACCR */
2828   MODIFY_REG(heth->Instance->MACCR, ETH_MACCR_MASK, macregval);
2829 
2830   /*------------------------ MACECR Configuration --------------------*/
2831   macregval = ((macconf->ExtendedInterPacketGapVal << 25) |
2832                ((uint32_t)macconf->ExtendedInterPacketGap << 24) |
2833                ((uint32_t)macconf->UnicastSlowProtocolPacketDetect << 18) |
2834                ((uint32_t)macconf->SlowProtocolDetect << 17) |
2835                ((uint32_t)((macconf->CRCCheckingRxPackets == DISABLE) ? 1U : 0U) << 16) |
2836                macconf->GiantPacketSizeLimit);
2837 
2838   /* Write to MACECR */
2839   MODIFY_REG(heth->Instance->MACECR, ETH_MACECR_MASK, macregval);
2840 
2841   /*------------------------ MACWTR Configuration --------------------*/
2842   macregval = (((uint32_t)macconf->ProgrammableWatchdog << 8) |
2843                macconf->WatchdogTimeout);
2844 
2845   /* Write to MACWTR */
2846   MODIFY_REG(heth->Instance->MACWTR, ETH_MACWTR_MASK, macregval);
2847 
2848   /*------------------------ MACTFCR Configuration --------------------*/
2849   macregval = (((uint32_t)macconf->TransmitFlowControl << 1) |
2850                macconf->PauseLowThreshold |
2851                ((uint32_t)((macconf->ZeroQuantaPause == DISABLE) ? 1U : 0U) << 7) |
2852                (macconf->PauseTime << 16));
2853 
2854   /* Write to MACTFCR */
2855   MODIFY_REG(heth->Instance->MACTFCR, ETH_MACTFCR_MASK, macregval);
2856 
2857   /*------------------------ MACRFCR Configuration --------------------*/
2858   macregval = ((uint32_t)macconf->ReceiveFlowControl |
2859                ((uint32_t)macconf->UnicastPausePacketDetect << 1));
2860 
2861   /* Write to MACRFCR */
2862   MODIFY_REG(heth->Instance->MACRFCR, ETH_MACRFCR_MASK, macregval);
2863 
2864   /*------------------------ MTLTQOMR Configuration --------------------*/
2865   /* Write to MTLTQOMR */
2866   MODIFY_REG(heth->Instance->MTLTQOMR, ETH_MTLTQOMR_MASK, macconf->TransmitQueueMode);
2867 
2868   /*------------------------ MTLRQOMR Configuration --------------------*/
2869   macregval = (macconf->ReceiveQueueMode |
2870                ((uint32_t)((macconf->DropTCPIPChecksumErrorPacket == DISABLE) ? 1U : 0U) << 6) |
2871                ((uint32_t)macconf->ForwardRxErrorPacket << 4) |
2872                ((uint32_t)macconf->ForwardRxUndersizedGoodPacket << 3));
2873 
2874   /* Write to MTLRQOMR */
2875   MODIFY_REG(heth->Instance->MTLRQOMR, ETH_MTLRQOMR_MASK, macregval);
2876 }
2877 
2878 static void ETH_SetDMAConfig(ETH_HandleTypeDef *heth, const ETH_DMAConfigTypeDef *dmaconf)
2879 {
2880   uint32_t dmaregval;
2881 
2882   /*------------------------ DMAMR Configuration --------------------*/
2883   MODIFY_REG(heth->Instance->DMAMR, ETH_DMAMR_MASK, dmaconf->DMAArbitration);
2884 
2885   /*------------------------ DMASBMR Configuration --------------------*/
2886   dmaregval = (((uint32_t)dmaconf->AddressAlignedBeats << 12) |
2887                dmaconf->BurstMode |
2888                ((uint32_t)dmaconf->RebuildINCRxBurst << 15));
2889 
2890   MODIFY_REG(heth->Instance->DMASBMR, ETH_DMASBMR_MASK, dmaregval);
2891 
2892   /*------------------------ DMACCR Configuration --------------------*/
2893   dmaregval = (((uint32_t)dmaconf->PBLx8Mode << 16) |
2894                dmaconf->MaximumSegmentSize);
2895   MODIFY_REG(heth->Instance->DMACCR, ETH_DMACCR_MASK, dmaregval);
2896 
2897   /*------------------------ DMACTCR Configuration --------------------*/
2898   dmaregval = (dmaconf->TxDMABurstLength |
2899                ((uint32_t)dmaconf->SecondPacketOperate << 4) |
2900                ((uint32_t)dmaconf->TCPSegmentation << 12));
2901 
2902   MODIFY_REG(heth->Instance->DMACTCR, ETH_DMACTCR_MASK, dmaregval);
2903 
2904   /*------------------------ DMACRCR Configuration --------------------*/
2905   dmaregval = (((uint32_t)dmaconf->FlushRxPacket  << 31) |
2906                dmaconf->RxDMABurstLength);
2907 
2908   /* Write to DMACRCR */
2909   MODIFY_REG(heth->Instance->DMACRCR, ETH_DMACRCR_MASK, dmaregval);
2910 }
2911 
2912 /**
2913   * @brief  Configures Ethernet MAC and DMA with default parameters.
2914   *         called by HAL_ETH_Init() API.
2915   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2916   *         the configuration information for ETHERNET module
2917   * @retval HAL status
2918   */
2919 static void ETH_MACDMAConfig(ETH_HandleTypeDef *heth)
2920 {
2921   ETH_MACConfigTypeDef macDefaultConf;
2922   ETH_DMAConfigTypeDef dmaDefaultConf;
2923 
2924   /*--------------- ETHERNET MAC registers default Configuration --------------*/
2925   macDefaultConf.AutomaticPadCRCStrip = ENABLE;
2926   macDefaultConf.BackOffLimit = ETH_BACKOFFLIMIT_10;
2927   macDefaultConf.CarrierSenseBeforeTransmit = DISABLE;
2928   macDefaultConf.CarrierSenseDuringTransmit = DISABLE;
2929   macDefaultConf.ChecksumOffload = ENABLE;
2930   macDefaultConf.CRCCheckingRxPackets = ENABLE;
2931   macDefaultConf.CRCStripTypePacket = ENABLE;
2932   macDefaultConf.DeferralCheck = DISABLE;
2933   macDefaultConf.DropTCPIPChecksumErrorPacket = ENABLE;
2934   macDefaultConf.DuplexMode = ETH_FULLDUPLEX_MODE;
2935   macDefaultConf.ExtendedInterPacketGap = DISABLE;
2936   macDefaultConf.ExtendedInterPacketGapVal = 0x0U;
2937   macDefaultConf.ForwardRxErrorPacket = DISABLE;
2938   macDefaultConf.ForwardRxUndersizedGoodPacket = DISABLE;
2939   macDefaultConf.GiantPacketSizeLimit = 0x618U;
2940   macDefaultConf.GiantPacketSizeLimitControl = DISABLE;
2941   macDefaultConf.InterPacketGapVal = ETH_INTERPACKETGAP_96BIT;
2942   macDefaultConf.Jabber = ENABLE;
2943   macDefaultConf.JumboPacket = DISABLE;
2944   macDefaultConf.LoopbackMode = DISABLE;
2945   macDefaultConf.PauseLowThreshold = ETH_PAUSELOWTHRESHOLD_MINUS_4;
2946   macDefaultConf.PauseTime = 0x0U;
2947   macDefaultConf.PreambleLength = ETH_PREAMBLELENGTH_7;
2948   macDefaultConf.ProgrammableWatchdog = DISABLE;
2949   macDefaultConf.ReceiveFlowControl = DISABLE;
2950   macDefaultConf.ReceiveOwn = ENABLE;
2951   macDefaultConf.ReceiveQueueMode = ETH_RECEIVESTOREFORWARD;
2952   macDefaultConf.RetryTransmission = ENABLE;
2953   macDefaultConf.SlowProtocolDetect = DISABLE;
2954   macDefaultConf.SourceAddrControl = ETH_SOURCEADDRESS_REPLACE_ADDR0;
2955   macDefaultConf.Speed = ETH_SPEED_100M;
2956   macDefaultConf.Support2KPacket = DISABLE;
2957   macDefaultConf.TransmitQueueMode = ETH_TRANSMITSTOREFORWARD;
2958   macDefaultConf.TransmitFlowControl = DISABLE;
2959   macDefaultConf.UnicastPausePacketDetect = DISABLE;
2960   macDefaultConf.UnicastSlowProtocolPacketDetect = DISABLE;
2961   macDefaultConf.Watchdog = ENABLE;
2962   macDefaultConf.WatchdogTimeout =  ETH_MACWTR_WTO_2KB;
2963   macDefaultConf.ZeroQuantaPause = ENABLE;
2964 
2965   /* MAC default configuration */
2966   ETH_SetMACConfig(heth, &macDefaultConf);
2967 
2968   /*--------------- ETHERNET DMA registers default Configuration --------------*/
2969   dmaDefaultConf.AddressAlignedBeats = ENABLE;
2970   dmaDefaultConf.BurstMode = ETH_BURSTLENGTH_FIXED;
2971   dmaDefaultConf.DMAArbitration = ETH_DMAARBITRATION_RX1_TX1;
2972   dmaDefaultConf.FlushRxPacket = DISABLE;
2973   dmaDefaultConf.PBLx8Mode = DISABLE;
2974   dmaDefaultConf.RebuildINCRxBurst = DISABLE;
2975   dmaDefaultConf.RxDMABurstLength = ETH_RXDMABURSTLENGTH_32BEAT;
2976   dmaDefaultConf.SecondPacketOperate = DISABLE;
2977   dmaDefaultConf.TxDMABurstLength = ETH_TXDMABURSTLENGTH_32BEAT;
2978   dmaDefaultConf.TCPSegmentation = DISABLE;
2979   dmaDefaultConf.MaximumSegmentSize = ETH_SEGMENT_SIZE_DEFAULT;
2980 
2981   /* DMA default configuration */
2982   ETH_SetDMAConfig(heth, &dmaDefaultConf);
2983 }
2984 
2985 /**
2986   * @brief  Initializes the DMA Tx descriptors.
2987   *         called by HAL_ETH_Init() API.
2988   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
2989   *         the configuration information for ETHERNET module
2990   * @retval None
2991   */
2992 static void ETH_DMATxDescListInit(ETH_HandleTypeDef *heth)
2993 {
2994 #ifndef __rtems__
2995   ETH_DMADescTypeDef *dmatxdesc;
2996   uint32_t i;
2997 
2998   /* Fill each DMATxDesc descriptor with the right values */
2999   for (i = 0; i < (uint32_t)ETH_TX_DESC_CNT; i++)
3000   {
3001     dmatxdesc = heth->Init.TxDesc + i;
3002 
3003     WRITE_REG(dmatxdesc->DESC0, 0x0U);
3004     WRITE_REG(dmatxdesc->DESC1, 0x0U);
3005     WRITE_REG(dmatxdesc->DESC2, 0x0U);
3006     WRITE_REG(dmatxdesc->DESC3, 0x0U);
3007 
3008     WRITE_REG(heth->TxDescList.TxDesc[i], (uint32_t)dmatxdesc);
3009 
3010   }
3011 
3012   heth->TxDescList.CurTxDesc = 0;
3013 
3014   /* Set Transmit Descriptor Ring Length */
3015   WRITE_REG(heth->Instance->DMACTDRLR, (ETH_TX_DESC_CNT - 1U));
3016 
3017   /* Set Transmit Descriptor List Address */
3018   WRITE_REG(heth->Instance->DMACTDLAR, (uint32_t) heth->Init.TxDesc);
3019 
3020   /* Set Transmit Descriptor Tail pointer */
3021   WRITE_REG(heth->Instance->DMACTDTPR, (uint32_t) heth->Init.TxDesc);
3022 #endif /* __rtems__ */
3023 }
3024 
3025 /**
3026   * @brief  Initializes the DMA Rx descriptors in chain mode.
3027   *         called by HAL_ETH_Init() API.
3028   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
3029   *         the configuration information for ETHERNET module
3030   * @retval None
3031   */
3032 static void ETH_DMARxDescListInit(ETH_HandleTypeDef *heth)
3033 {
3034 #ifndef __rtems__
3035   ETH_DMADescTypeDef *dmarxdesc;
3036   uint32_t i;
3037 
3038   for (i = 0; i < (uint32_t)ETH_RX_DESC_CNT; i++)
3039   {
3040     dmarxdesc =  heth->Init.RxDesc + i;
3041 
3042     WRITE_REG(dmarxdesc->DESC0, 0x0U);
3043     WRITE_REG(dmarxdesc->DESC1, 0x0U);
3044     WRITE_REG(dmarxdesc->DESC2, 0x0U);
3045     WRITE_REG(dmarxdesc->DESC3, 0x0U);
3046     WRITE_REG(dmarxdesc->BackupAddr0, 0x0U);
3047     WRITE_REG(dmarxdesc->BackupAddr1, 0x0U);
3048 
3049     /* Set Rx descritors addresses */
3050     WRITE_REG(heth->RxDescList.RxDesc[i], (uint32_t)dmarxdesc);
3051 
3052   }
3053 
3054   WRITE_REG(heth->RxDescList.RxDescIdx, 0U);
3055   WRITE_REG(heth->RxDescList.RxDescCnt, 0U);
3056   WRITE_REG(heth->RxDescList.RxBuildDescIdx, 0U);
3057   WRITE_REG(heth->RxDescList.RxBuildDescCnt, 0U);
3058   WRITE_REG(heth->RxDescList.ItMode, 0U);
3059 
3060   /* Set Receive Descriptor Ring Length */
3061   WRITE_REG(heth->Instance->DMACRDRLR, ((uint32_t)(ETH_RX_DESC_CNT - 1U)));
3062 
3063   /* Set Receive Descriptor List Address */
3064   WRITE_REG(heth->Instance->DMACRDLAR, (uint32_t) heth->Init.RxDesc);
3065 
3066   /* Set Receive Descriptor Tail pointer Address */
3067   WRITE_REG(heth->Instance->DMACRDTPR, ((uint32_t)(heth->Init.RxDesc + (uint32_t)(ETH_RX_DESC_CNT - 1U))));
3068 #endif /* __rtems__ */
3069 }
3070 
3071 /**
3072   * @brief  Prepare Tx DMA descriptor before transmission.
3073   *         called by HAL_ETH_Transmit_IT and HAL_ETH_Transmit_IT() API.
3074   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
3075   *         the configuration information for ETHERNET module
3076   * @param  pTxConfig: Tx packet configuration
3077   * @param  ItMode: Enable or disable Tx EOT interrept
3078   * @retval Status
3079   */
3080 static uint32_t ETH_Prepare_Tx_Descriptors(ETH_HandleTypeDef *heth, const ETH_TxPacketConfigTypeDef *pTxConfig,
3081                                            uint32_t ItMode)
3082 {
3083   ETH_TxDescListTypeDef *dmatxdesclist = &heth->TxDescList;
3084   uint32_t descidx = dmatxdesclist->CurTxDesc;
3085   uint32_t firstdescidx = dmatxdesclist->CurTxDesc;
3086   uint32_t idx;
3087   uint32_t descnbr = 0;
3088   ETH_DMADescTypeDef *dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[descidx];
3089 
3090   ETH_BufferTypeDef  *txbuffer = pTxConfig->TxBuffer;
3091   uint32_t           bd_count = 0;
3092   uint32_t primask_bit;
3093 
3094   /* Current Tx Descriptor Owned by DMA: cannot be used by the application  */
3095   if ((READ_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCWBF_OWN) == ETH_DMATXNDESCWBF_OWN)
3096       || (dmatxdesclist->PacketAddress[descidx] != NULL))
3097   {
3098     return HAL_ETH_ERROR_BUSY;
3099   }
3100 
3101   /***************************************************************************/
3102   /*****************    Context descriptor configuration (Optional) **********/
3103   /***************************************************************************/
3104   /* If VLAN tag is enabled for this packet */
3105   if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_VLANTAG) != (uint32_t)RESET)
3106   {
3107     /* Set vlan tag value */
3108     MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXCDESC_VT, pTxConfig->VlanTag);
3109     /* Set vlan tag valid bit */
3110     SET_BIT(dmatxdesc->DESC3, ETH_DMATXCDESC_VLTV);
3111     /* Set the descriptor as the vlan input source */
3112     SET_BIT(heth->Instance->MACVIR, ETH_MACVIR_VLTI);
3113 
3114     /* if inner VLAN is enabled */
3115     if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_INNERVLANTAG) != (uint32_t)RESET)
3116     {
3117       /* Set inner vlan tag value */
3118       MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXCDESC_IVT, (pTxConfig->InnerVlanTag << 16));
3119       /* Set inner vlan tag valid bit */
3120       SET_BIT(dmatxdesc->DESC3, ETH_DMATXCDESC_IVLTV);
3121 
3122       /* Set Vlan Tag control */
3123       MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXCDESC_IVTIR, pTxConfig->InnerVlanCtrl);
3124 
3125       /* Set the descriptor as the inner vlan input source */
3126       SET_BIT(heth->Instance->MACIVIR, ETH_MACIVIR_VLTI);
3127       /* Enable double VLAN processing */
3128       SET_BIT(heth->Instance->MACVTR, ETH_MACVTR_EDVLP);
3129     }
3130   }
3131 
3132   /* if tcp segmentation is enabled for this packet */
3133   if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_TSO) != (uint32_t)RESET)
3134   {
3135     /* Set MSS value */
3136     MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXCDESC_MSS, pTxConfig->MaxSegmentSize);
3137     /* Set MSS valid bit */
3138     SET_BIT(dmatxdesc->DESC3, ETH_DMATXCDESC_TCMSSV);
3139   }
3140 
3141   if ((READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_VLANTAG) != (uint32_t)RESET)
3142       || (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_TSO) != (uint32_t)RESET))
3143   {
3144     /* Set as context descriptor */
3145     SET_BIT(dmatxdesc->DESC3, ETH_DMATXCDESC_CTXT);
3146     /* Ensure rest of descriptor is written to RAM before the OWN bit */
3147     __DMB();
3148     /* Set own bit */
3149     SET_BIT(dmatxdesc->DESC3, ETH_DMATXCDESC_OWN);
3150     /* Increment current tx descriptor index */
3151     INCR_TX_DESC_INDEX(descidx, 1U);
3152     /* Get current descriptor address */
3153     dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[descidx];
3154 
3155     descnbr += 1U;
3156 
3157     /* Current Tx Descriptor Owned by DMA: cannot be used by the application  */
3158     if (READ_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCWBF_OWN) == ETH_DMATXNDESCWBF_OWN)
3159     {
3160       dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[firstdescidx];
3161       /* Ensure rest of descriptor is written to RAM before the OWN bit */
3162       __DMB();
3163       /* Clear own bit */
3164       CLEAR_BIT(dmatxdesc->DESC3, ETH_DMATXCDESC_OWN);
3165 
3166       return HAL_ETH_ERROR_BUSY;
3167     }
3168   }
3169 
3170   /***************************************************************************/
3171   /*****************    Normal descriptors configuration     *****************/
3172   /***************************************************************************/
3173 
3174   descnbr += 1U;
3175 
3176   /* Set header or buffer 1 address */
3177   WRITE_REG(dmatxdesc->DESC0, (uint32_t)txbuffer->buffer);
3178   /* Set header or buffer 1 Length */
3179   MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXNDESCRF_B1L, txbuffer->len);
3180 
3181   if (txbuffer->next != NULL)
3182   {
3183     txbuffer = txbuffer->next;
3184     /* Set buffer 2 address */
3185     WRITE_REG(dmatxdesc->DESC1, (uint32_t)txbuffer->buffer);
3186     /* Set buffer 2 Length */
3187     MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXNDESCRF_B2L, (txbuffer->len << 16));
3188   }
3189   else
3190   {
3191     WRITE_REG(dmatxdesc->DESC1, 0x0U);
3192     /* Set buffer 2 Length */
3193     MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXNDESCRF_B2L, 0x0U);
3194   }
3195 
3196   if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_TSO) != (uint32_t)RESET)
3197   {
3198     /* Set TCP Header length */
3199     MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_THL, (pTxConfig->TCPHeaderLen << 19));
3200     /* Set TCP payload length */
3201     MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_TPL, pTxConfig->PayloadLen);
3202     /* Set TCP Segmentation Enabled bit */
3203     SET_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_TSE);
3204   }
3205   else
3206   {
3207     MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_FL, pTxConfig->Length);
3208 
3209     if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_CSUM) != (uint32_t)RESET)
3210     {
3211       MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_CIC, pTxConfig->ChecksumCtrl);
3212     }
3213 
3214     if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_CRCPAD) != (uint32_t)RESET)
3215     {
3216       MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_CPC, pTxConfig->CRCPadCtrl);
3217     }
3218   }
3219 
3220   if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_VLANTAG) != (uint32_t)RESET)
3221   {
3222     /* Set Vlan Tag control */
3223     MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXNDESCRF_VTIR, pTxConfig->VlanCtrl);
3224   }
3225 
3226   /* Mark it as First Descriptor */
3227   SET_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_FD);
3228   /* Mark it as NORMAL descriptor */
3229   CLEAR_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_CTXT);
3230   /* Ensure rest of descriptor is written to RAM before the OWN bit */
3231   __DMB();
3232   /* set OWN bit of FIRST descriptor */
3233   SET_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_OWN);
3234 
3235   /* If source address insertion/replacement is enabled for this packet */
3236   if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_SAIC) != (uint32_t)RESET)
3237   {
3238     MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_SAIC, pTxConfig->SrcAddrCtrl);
3239   }
3240 
3241   /* only if the packet is split into more than one descriptors > 1 */
3242   while (txbuffer->next != NULL)
3243   {
3244     /* Clear the LD bit of previous descriptor */
3245     CLEAR_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_LD);
3246     /* Increment current tx descriptor index */
3247     INCR_TX_DESC_INDEX(descidx, 1U);
3248     /* Get current descriptor address */
3249     dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[descidx];
3250 
3251     /* Clear the FD bit of new Descriptor */
3252     CLEAR_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_FD);
3253 
3254     /* Current Tx Descriptor Owned by DMA: cannot be used by the application  */
3255     if ((READ_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_OWN) == ETH_DMATXNDESCRF_OWN)
3256         || (dmatxdesclist->PacketAddress[descidx] != NULL))
3257     {
3258       descidx = firstdescidx;
3259       dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[descidx];
3260 
3261       /* clear previous desc own bit */
3262       for (idx = 0; idx < descnbr; idx ++)
3263       {
3264         /* Ensure rest of descriptor is written to RAM before the OWN bit */
3265         __DMB();
3266 
3267         CLEAR_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_OWN);
3268 
3269         /* Increment current tx descriptor index */
3270         INCR_TX_DESC_INDEX(descidx, 1U);
3271         /* Get current descriptor address */
3272         dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[descidx];
3273       }
3274 
3275       return HAL_ETH_ERROR_BUSY;
3276     }
3277 
3278     descnbr += 1U;
3279 
3280     /* Get the next Tx buffer in the list */
3281     txbuffer = txbuffer->next;
3282 
3283     /* Set header or buffer 1 address */
3284     WRITE_REG(dmatxdesc->DESC0, (uint32_t)txbuffer->buffer);
3285     /* Set header or buffer 1 Length */
3286     MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXNDESCRF_B1L, txbuffer->len);
3287 
3288     if (txbuffer->next != NULL)
3289     {
3290       /* Get the next Tx buffer in the list */
3291       txbuffer = txbuffer->next;
3292       /* Set buffer 2 address */
3293       WRITE_REG(dmatxdesc->DESC1, (uint32_t)txbuffer->buffer);
3294       /* Set buffer 2 Length */
3295       MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXNDESCRF_B2L, (txbuffer->len << 16));
3296     }
3297     else
3298     {
3299       WRITE_REG(dmatxdesc->DESC1, 0x0U);
3300       /* Set buffer 2 Length */
3301       MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXNDESCRF_B2L, 0x0U);
3302     }
3303 
3304     if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_TSO) != (uint32_t)RESET)
3305     {
3306       /* Set TCP payload length */
3307       MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_TPL, pTxConfig->PayloadLen);
3308       /* Set TCP Segmentation Enabled bit */
3309       SET_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_TSE);
3310     }
3311     else
3312     {
3313       /* Set the packet length */
3314       MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_FL, pTxConfig->Length);
3315 
3316       if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_CSUM) != (uint32_t)RESET)
3317       {
3318         /* Checksum Insertion Control */
3319         MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_CIC, pTxConfig->ChecksumCtrl);
3320       }
3321     }
3322 
3323     bd_count += 1U;
3324 
3325     /* Ensure rest of descriptor is written to RAM before the OWN bit */
3326     __DMB();
3327     /* Set Own bit */
3328     SET_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_OWN);
3329     /* Mark it as NORMAL descriptor */
3330     CLEAR_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_CTXT);
3331   }
3332 
3333   if (ItMode != ((uint32_t)RESET))
3334   {
3335     /* Set Interrupt on completion bit */
3336     SET_BIT(dmatxdesc->DESC2, ETH_DMATXNDESCRF_IOC);
3337   }
3338   else
3339   {
3340     /* Clear Interrupt on completion bit */
3341     CLEAR_BIT(dmatxdesc->DESC2, ETH_DMATXNDESCRF_IOC);
3342   }
3343 
3344   /* Mark it as LAST descriptor */
3345   SET_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_LD);
3346   /* Save the current packet address to expose it to the application */
3347   dmatxdesclist->PacketAddress[descidx] = dmatxdesclist->CurrentPacketAddress;
3348 
3349   dmatxdesclist->CurTxDesc = descidx;
3350 
3351   /* Enter critical section */
3352   primask_bit = __get_PRIMASK();
3353   __set_PRIMASK(1);
3354 
3355   dmatxdesclist->BuffersInUse += bd_count + 1U;
3356 
3357   /* Exit critical section: restore previous priority mask */
3358   __set_PRIMASK(primask_bit);
3359 
3360   /* Return function status */
3361   return HAL_ETH_ERROR_NONE;
3362 }
3363 
3364 #if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
3365 static void ETH_InitCallbacksToDefault(ETH_HandleTypeDef *heth)
3366 {
3367   /* Init the ETH Callback settings */
3368   heth->TxCpltCallback   = HAL_ETH_TxCpltCallback;    /* Legacy weak TxCpltCallback   */
3369   heth->RxCpltCallback   = HAL_ETH_RxCpltCallback;    /* Legacy weak RxCpltCallback   */
3370   heth->ErrorCallback    = HAL_ETH_ErrorCallback;     /* Legacy weak ErrorCallback */
3371   heth->PMTCallback      = HAL_ETH_PMTCallback;       /* Legacy weak PMTCallback      */
3372   heth->EEECallback      = HAL_ETH_EEECallback;       /* Legacy weak EEECallback      */
3373   heth->WakeUpCallback   = HAL_ETH_WakeUpCallback;    /* Legacy weak WakeUpCallback   */
3374   heth->rxLinkCallback   = HAL_ETH_RxLinkCallback;    /* Legacy weak RxLinkCallback   */
3375   heth->txFreeCallback   = HAL_ETH_TxFreeCallback;    /* Legacy weak TxFreeCallback   */
3376 #ifdef HAL_ETH_USE_PTP
3377   heth->txPtpCallback    = HAL_ETH_TxPtpCallback;     /* Legacy weak TxPtpCallback   */
3378 #endif /* HAL_ETH_USE_PTP */
3379   heth->rxAllocateCallback = HAL_ETH_RxAllocateCallback; /* Legacy weak RxAllocateCallback */
3380 }
3381 #endif /* USE_HAL_ETH_REGISTER_CALLBACKS */
3382 
3383 /**
3384   * @}
3385   */
3386 
3387 /**
3388   * @}
3389   */
3390 
3391 #endif /* ETH */
3392 
3393 #endif /* HAL_ETH_MODULE_ENABLED */
3394 
3395 /**
3396   * @}
3397   */