Back to home page

LXR

 
 

    


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

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