/*====================================================================================================================*/
/* Project      = AUTOSAR Renesas X2x MCAL Components                                                                 */
/* Module       = Eth_ETND_LLDriver.c                                                                                 */
/* SW-VERSION   = 1.5.4                                                                                               */
/*====================================================================================================================*/
/*                                                     COPYRIGHT                                                      */
/*====================================================================================================================*/
/* (c) 2021,2022 Renesas Electronics Corporation. All rights reserved.                                                */
/*====================================================================================================================*/
/* Purpose:                                                                                                           */
/* This file contains ETNDE specific operations of Eth Driver Component.                                              */
/*                                                                                                                    */
/*====================================================================================================================*/
/*                                                                                                                    */
/* Unless otherwise agreed upon in writing between your company and Renesas Electronics Corporation the following     */
/* shall apply!                                                                                                       */
/*                                                                                                                    */
/* Warranty Disclaimer                                                                                                */
/*                                                                                                                    */
/* There is no warranty of any kind whatsoever granted by Renesas. Any warranty is expressly disclaimed and excluded  */
/* by Renesas, either expressed or implied, including but not limited to those for non-infringement of intellectual   */
/* property, merchantability and/or fitness for the particular purpose.                                               */
/*                                                                                                                    */
/* Renesas shall not have any obligation to maintain, service or provide bug fixes for the supplied Product(s) and/or */
/* the Application.                                                                                                   */
/*                                                                                                                    */
/* Each User is solely responsible for determining the appropriateness of using the Product(s) and assumes all risks  */
/* associated with its exercise of rights under this Agreement, including, but not limited to the risks and costs of  */
/* program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and             */
/* unavailability or interruption of operations.                                                                      */
/*                                                                                                                    */
/* Limitation of Liability                                                                                            */
/*                                                                                                                    */
/* In no event shall Renesas be liable to the User for any incidental, consequential, indirect, or punitive damage    */
/* (including but not limited to lost profits) regardless of whether such liability is based on breach of contract,   */
/* tort, strict liability, breach of warranties, failure of essential purpose or otherwise and even if advised of the */
/* possibility of such damages. Renesas shall not be liable for any services or products provided by third party      */
/* vendors, developers or consultants identified or referred to the User by Renesas in connection with the Product(s) */
/* and/or the Application.                                                                                            */
/*                                                                                                                    */
/*====================================================================================================================*/
/* Environment:                                                                                                       */
/*              Devices:        X2x                                                                                   */
/*====================================================================================================================*/

/***********************************************************************************************************************
**                                              Revision Control History                                              **
***********************************************************************************************************************/
/*
 * 1.5.4: 03/08/2022    : Change the setting of the maximum size of received frames from each queue to each MAC
 * 1.5.3: 05/04/2022    : Update to support U2Bx End Station functions
 * 1.5.0: 20/10/2021    : Initial Version
 */
/**********************************************************************************************************************/

/***********************************************************************************************************************
**                                                  Include Section                                                   **
***********************************************************************************************************************/
#include "Eth.h"
#include "Eth_ETNDE_Ram.h"
#include "Eth_ETND_LLDriver.h"
#include "Eth_ETNDE_LLDriver.h"

#if (ETH_CRITICAL_SECTION_PROTECTION == STD_ON)
/* Included for the declaration of the critical section protection functions */
#include "SchM_Eth.h"
#endif

/***********************************************************************************************************************
**                                                Version Information                                                 **
***********************************************************************************************************************/
/* AUTOSAR release version information */
#define ETH_ETND_C_AR_RELEASE_MAJOR_VERSION ETH_AR_RELEASE_MAJOR_VERSION_VALUE
#define ETH_ETND_C_AR_RELEASE_MINOR_VERSION ETH_AR_RELEASE_MINOR_VERSION_VALUE
#define ETH_ETND_C_AR_RELEASE_REVISION_VERSION ETH_AR_RELEASE_REVISION_VERSION_VALUE

/* File version information */
#define ETH_ETND_C_SW_MAJOR_VERSION    ETH_SW_MAJOR_VERSION_VALUE
#define ETH_ETND_C_SW_MINOR_VERSION    ETH_SW_MINOR_VERSION_VALUE

/***********************************************************************************************************************
**                                                   Version Check                                                    **
***********************************************************************************************************************/
#if (ETH_ETND_AR_RELEASE_MAJOR_VERSION != ETH_ETND_C_AR_RELEASE_MAJOR_VERSION)
#error "Eth_ETND_LLDriver.c : Mismatch in Release Major Version"
#endif
#if (ETH_ETND_AR_RELEASE_MINOR_VERSION != ETH_ETND_C_AR_RELEASE_MINOR_VERSION)
#error "Eth_ETND_LLDriver.c : Mismatch in Release Minor Version"
#endif
#if (ETH_ETND_AR_RELEASE_REVISION_VERSION != ETH_ETND_C_AR_RELEASE_REVISION_VERSION)
#error "Eth_ETND_LLDriver.c : Mismatch in Release Revision Version"
#endif

#if (ETH_ETND_SW_MAJOR_VERSION != ETH_ETND_C_SW_MAJOR_VERSION)
#error "Eth_ETND_LLDriver.c : Mismatch in Software Major Version"
#endif
#if (ETH_ETND_SW_MINOR_VERSION != ETH_ETND_C_SW_MINOR_VERSION)
#error "Eth_ETND_LLDriver.c : Mismatch in Software Minor Version"
#endif

/***********************************************************************************************************************
**                                               Coding Rule Violations                                               **
***********************************************************************************************************************/
/* Message (1:1532)    : The function '%1s' is only referenced in one translation unit - but not the one in which it  */
/*                       is defined.                                                                                  */
/* Rule                : CERTCCM DCL19, MISRA C:2012 Rule-8.7                                                         */
/* JV-01 Justification : This is accepted, due to the specific coding rule, function of each hardware unit is         */
/*                       implemented in separated files for this hardware unit. Could not be static function.         */
/*       Verification  : However, part of the code is verified manually and it is not having any impact.              */
/**********************************************************************************************************************/
/* Message (2:3432)    : Simple macro argument expression is not parenthesized.                                       */
/* Rule                : MISRA C:2012 Rule-20.7                                                                       */
/* JV-01 Justification : Compiler keyword (macro) is defined and used followed AUTOSAR standard rule. It is accepted. */
/*       Verification  : However, part of the code is verified manually and it is not having any impact.              */
/**********************************************************************************************************************/
/* Message (2:2844)    : Possible: Dereference of an invalid pointer value.                                           */
/* Rule                : CERTCCM ARR30                                                                                */
/* JV-01 Justification : To prevent overhead and excessive nesting of condition statements, this pointer has been     */
/*                       tested valid with many test cases, so there is no problem with the current implementation.   */
/*       Verification  : However, part of the code is verified manually and it is not having any impact.              */
/**********************************************************************************************************************/
/* Message (2:0316)    : Cast from a pointer to void to a pointer to object type.                                     */
/* Rule                : MISRA C:2012 Rule-11.5                                                                       */
/* JV-01 Justification : Typecasting from void* is necessary to hide internal types from the header files which are   */
/*                       exposed to user.                                                                             */
/*       Verification  : However, part of the code is verified manually and it is not having any impact.              */
/**********************************************************************************************************************/
/* Message (2:2934)    : Possible: Computing an invalid pointer value.                                                */
/* Rule                : CERTCCM ARR30, ARR37, ARR38, EXP08                                                           */
/* JV-01 Justification : To prevent overhead and excessive nesting of condition statements, this pointer has been     */
/*                       tested valid with many test cases, so there is no problem with the current implementation.   */
/*       Verification  : However, part of the code is verified manually and it is not having any impact.              */
/**********************************************************************************************************************/
/* Message (2:0306)    : Cast between a pointer to object and an integral type.                                       */
/* Rule                : CERTCCM INT36, MISRA C:2012 Rule-11.4                                                        */
/* JV-01 Justification : Typecasting is done as per the register size or hardware specific structure.                 */
/*       Verification  : However, part of the code is verified manually and it is not having any impact.              */
/**********************************************************************************************************************/
/* Message (2:2814)    : Possible: Dereference of NULL pointer.                                                       */
/* Rule                : CERTCCM EXP34                                                                                */
/* JV-01 Justification : To prevent overhead and excessive nesting of condition statements, this pointer has been     */
/*                       tested valid with many test cases, so there is no problem with the current implementation.   */
/*       Verification  : However, part of the code is verified manually and it is not having any impact.              */
/**********************************************************************************************************************/
/* Message (2:2824)    : Possible: Arithmetic operation on NULL pointer.                                              */
/* Rule                : CERTCCM EXP34                                                                                */
/* JV-01 Justification : To prevent overhead and excessive nesting of condition statements, this pointer has been     */
/*                       tested valid with many test cases, so there is no problem with the current implementation.   */
/*       Verification  : However, part of the code is verified manually and it is not having any impact.              */
/**********************************************************************************************************************/
/* Message (2:0315)    : Implicit conversion from a pointer to object type to a pointer to void.                      */
/* Rule                : MISRA C:2012 Dir-1.1                                                                         */
/* JV-01 Justification : Pointer to a void is a generic pointer type which can be use cast to any other pointer type. */
/*       Verification  : However, part of the code is verified manually and it is not having any impact.              */
/**********************************************************************************************************************/
/* Message (1:3383)    : Cannot identify wraparound guard for unsigned arithmetic expression.                         */
/* Rule                : CERTCCM INT30                                                                                */
/* JV-01 Justification : Wraparound can't be occur in this unsigned integer arithmetic so there is no need to add a   */
/*                       wraparound guard here.                                                                       */
/*       Verification  : However, part of the code is verified manually and it is not having any impact.              */
/**********************************************************************************************************************/
/* Message (7:0404)    : More than one read access to volatile objects between sequence points.                       */
/* Rule                : CERTCCM EXP10, EXP30, MISRA C:2012 Rule-1.3, Rule-13.2                                       */
/* JV-01 Justification : This is to get elements in the global structure through the volatile global pointer. The     */
/*                       order in which it is used is not significant, so there is no problem using it.               */
/*       Verification  : However, part of the code is verified manually and it is not having any impact.              */
/**********************************************************************************************************************/
/* Message (2:0751)    : Casting to char pointer type.                                                                */
/* Rule                : CERTCCM EXP11, EXP39                                                                         */
/* JV-01 Justification : Since EICnEIMK exists in the lower 8 bits, there is no problem casting to uint8.             */
/*       Verification  : However, part of the code is verified manually and it is not having any impact.              */
/**********************************************************************************************************************/
/* Message (2:3464)    : Argument to macro '%s' contains a side effect that will be evaluated more than once.         */
/* Rule                : CERTCCM PRE31                                                                                */
/* JV-01 Justification : After reviewing coding, it is concluded that this implementation is okay as it is since the  */
/*                       memory used to access this volatile variable is user RAM, not a specific HW register, so     */
/*                       there is no worry about potential side effects in this case.                                 */
/*       Verification  : However, part of the code is verified manually and it is not having any impact.              */
/**********************************************************************************************************************/
/* Message (2:0314)    : Cast from a pointer to object type to a pointer to void.                                     */
/* Rule                : MISRA C:2012 Dir-1.1                                                                         */
/* JV-01 Justification : This is necessary for the free allocated heap memory process at the pointer address.         */
/*       Verification  : However, part of the code is verified manually and it is not having any impact.              */
/**********************************************************************************************************************/
/* Message (2:2982)    : This assignment is redundant. The value of this object is never used before being modified.  */
/* Rule                : CERTCCM MSC07, MSC13, MISRA C:2012 Rule-2.2                                                  */
/* JV-01 Justification : The variable needs to be initialized before using it.                                        */
/*       Verification  : However, part of the code is verified manually and it is not having any impact.              */
/**********************************************************************************************************************/
/* Message (2:3678)    : The object referenced by '%1s' is not modified through it, so '%1s' could be declared with   */
/*                       type '%2s'.                                                                                  */
/* Rule                : MISRA C:2012 Rule-8.13                                                                       */
/* JV-01 Justification : The allocated memory addressed by this pointer will be freed so it can not be of type        */
/*                       "pointer to const"                                                                           */
/*       Verification  : However, part of the code is verified manually and it is not having any impact.              */
/**********************************************************************************************************************/

/***********************************************************************************************************************
**                                                    Global Data                                                     **
***********************************************************************************************************************/

/***********************************************************************************************************************
**                                                Function Definitions                                                **
***********************************************************************************************************************/
#define ETH_START_SEC_PRIVATE_CODE
#include "Eth_MemMap.h"

STATIC FUNC(Std_ReturnType, ETH_PRIVATE_CODE) Eth_TxRamInit(CONST(uint32, AUTOMATIC) LulCtrlIdx);
STATIC FUNC(Std_ReturnType, ETH_PRIVATE_CODE) Eth_AXIBMI_Init(CONST(uint32, AUTOMATIC) LulCtrlIdx);
STATIC FUNC(void, ETH_PRIVATE_CODE) Eth_MHD_Init(CONST(uint32, AUTOMATIC) LulCtrlIdx);
STATIC FUNC(void, ETH_PRIVATE_CODE) Eth_RMAC_Init(CONST(uint32, AUTOMATIC) LulCtrlIdx);

/***********************************************************************************************************************
** Function Name         : Eth_HwCommonInit (ETND)
**
** Service ID            : N/A
**
** Description           : Initialize the common parts of ETND HWUnit
**
** Sync/Async            : Synchronous
**
** Reentrancy            : Non-Reentrant
**
** Input Parameters      : None
**
** InOut Parameters      : None
**
** Output Parameters     : None
**
** Return parameter      : E_OK : Success
**
** Preconditions         : None
**
** Global Variable(s)    : Eth_GstETND_Regs
**
** Function(s) invoked   : None
**
** Registers Used        : GTIVt, TME, GTOVt0, GTOVt1, GTOVt2
**
** Reference ID          : ETH_DUD_ACT_341
** Reference ID          : ETH_DUD_ACT_341_REG001, ETH_DUD_ACT_341_REG002
** Reference ID          : ETH_DUD_ACT_341_REG003, ETH_DUD_ACT_341_REG004
** Reference ID          : ETH_DUD_ACT_341_REG005
***********************************************************************************************************************/
FUNC(Std_ReturnType, ETH_PRIVATE_CODE) Eth_HwCommonInit(void)                                                           /* PRQA S 1532 # JV-01 */
{
  /*-------------------------------------------------------------------------*/
  /* gPTP timer initialization for TSNES                                     */
  /*-------------------------------------------------------------------------*/
  #if (ETH_GLOBAL_TIME_SUPPORT == STD_ON)
  /* Assigning the configured timer increment value to the GPTP timer GTIVt (t = 0 to PTPTN-1) */
  Eth_GstETND_Regs.pGPTMA->stGptpCfg[ETH_GPTP_TIMER_DOMAIN].ulGTIVt = (uint32)ETH_GPTP_SET_GTIV(ETH_PERI_CLOCK_HZ);

  /* GPTP Timer Enable */
  Eth_GstETND_Regs.pGPTMA->ulTME = ETH_GPTP_TIMER_DOMAIN_ENABLE;

  /* Set the nanosecond part of the GPTP timer GTOVt0 (t = 0 to PTPTN-1) */
  Eth_GstETND_Regs.pGPTMA->stGptpCfg[ETH_GPTP_TIMER_DOMAIN].ulGTOVt0 = 0UL;

  /* Set the lower 32 bit of second part of the GPTP timer GTOVt1 (t = 0 to PTPTN-1) */
  Eth_GstETND_Regs.pGPTMA->stGptpCfg[ETH_GPTP_TIMER_DOMAIN].ulGTOVt1 = 0UL;

  /* Set the upper 16 bit of second part of the GPTP timer GTOVt1 (t = 0 to PTPTN-1) */
  Eth_GstETND_Regs.pGPTMA->stGptpCfg[ETH_GPTP_TIMER_DOMAIN].ulGTOVt2 = 0UL;
  #endif

  return E_OK;
}

/***********************************************************************************************************************
** Function Name         : Eth_TxRamInit
**
** Service ID            : N/A
**
** Description           : TxRAM initialization
**
** Sync/Async            : Synchronous
**
** Reentrancy            : Non-Reentrant
**
** Input Parameters      : LulCtrlIdx     : Index of a controller
**
** InOut Parameters      : None
**
** Output Parameters     : None
**
** Return parameter      : E_OK : Success
**                         E_NOT_OK : Failure
**
** Preconditions         : None
**
** Global Variable(s)    : Eth_GaaHeap, Eth_GstETND_Regs, Eth_GaaTxRamInitState
**
** Function(s) invoked   : Eth_Util_RamAlloc, Eth_TxDescLearning, Eth_Util_RamFree
**
** Registers Used        : TDPC, TFT, AXIWC, AXIRC,
**                         TFS, TMS, TGC1/2, TDISi
**                         MCC, TRCR, SWR, GIS
**
** Reference ID          : ETH_DUD_ACT_344
** Reference ID          : ETH_DUD_ACT_344_GBL001
** Reference ID          : ETH_DUD_ACT_344_REG001, ETH_DUD_ACT_344_REG002
** Reference ID          : ETH_DUD_ACT_344_REG003, ETH_DUD_ACT_344_REG004
** Reference ID          : ETH_DUD_ACT_344_REG005, ETH_DUD_ACT_344_REG006
** Reference ID          : ETH_DUD_ACT_344_REG007, ETH_DUD_ACT_344_REG008
** Reference ID          : ETH_DUD_ACT_344_REG009, ETH_DUD_ACT_344_REG010
** Reference ID          : ETH_DUD_ACT_344_REG011, ETH_DUD_ACT_344_REG012
** Reference ID          : ETH_DUD_ACT_344_REG013
***********************************************************************************************************************/
STATIC FUNC(Std_ReturnType, ETH_PRIVATE_CODE) Eth_TxRamInit(CONST(uint32, AUTOMATIC) LulCtrlIdx)
{
  P2VAR(Eth_ExtDescType, AUTOMATIC, ETH_APPL_DATA) LpDescChain;                                                         /* PRQA S 3432 # JV-01 */
  P2VAR(Eth_ExtDescType, AUTOMATIC, ETH_APPL_DATA) LpDescChainTemp;                                                     /* PRQA S 3432, 3678 # JV-01, JV-01 */
  P2VAR(uint8, AUTOMATIC, ETH_APPL_DATA) LpDataPtr;                                                                     /* PRQA S 3432, 3678 # JV-01, JV-01 */
  uint32 LulCntI;
  uint32 LulCntJ;
  TickType LulTickStart;
  TickType LulTickElap;
  Std_ReturnType LucResult;

  LucResult = E_OK;                                                                                                     /* PRQA S 2982 # JV-01 */
  LpDescChain = NULL_PTR;
  LpDataPtr = NULL_PTR;
  LpDescChainTemp = NULL_PTR;

  LucResult = Eth_MHD_ModeSetting(LulCtrlIdx, ETH_ETND_MHD_DISABLE_MODE);
  LucResult |= Eth_MHD_ModeSetting(LulCtrlIdx, ETH_ETND_MHD_CONFIG_MODE);
  if (E_OK == LucResult)
  {
    /* Configure AXIBMI */
    /* Set AXI Write and Read Outstanding Number */
    Eth_GstETND_Regs.pES[LulCtrlIdx]->stAXIBMI.ulAXIWC = ETH_ETNDE_AXIWC_CONFIG;                                        /* PRQA S 2844 # JV-01 */
    Eth_GstETND_Regs.pES[LulCtrlIdx]->stAXIBMI.ulAXIRC = ETH_ETNDE_AXIRC_CONFIG;
    /* Set Tx Queue priority and Frame type */
    /* The supported Tx Queue is 0-7 */
    Eth_GstETND_Regs.pES[LulCtrlIdx]->stAXIBMI.ulTDPC[0] = 0UL;
    /* AXIBMI execute TFTP0-2 with p-frame statements and TFTP3-7 with e-frame statements */
    /* Since each statement operates as an independent core, it operates faster by enabling all statements */
    Eth_GstETND_Regs.pES[LulCtrlIdx]->stAXIBMI.ulTFT = (uint32)0UL;

    /* Configure MHD */
    Eth_GstETND_Regs.pES[LulCtrlIdx]->stMHD.ulTFS[0] = ETH_ETND_INIT_TFS0_CONFIG;
    Eth_GstETND_Regs.pES[LulCtrlIdx]->stMHD.ulTFS[1] = (uint32)0UL;
    Eth_GstETND_Regs.pES[LulCtrlIdx]->stMHD.ulTFS[2] = (uint32)0UL;
    Eth_GstETND_Regs.pES[LulCtrlIdx]->stMHD.ulTFS[3] = (uint32)0UL;
    Eth_GstETND_Regs.pES[LulCtrlIdx]->stMHD.ulTGC1 = ETH_ETND_TGC1_CONFIG;
    Eth_GstETND_Regs.pES[LulCtrlIdx]->stMHD.ulTGC2 = 0UL;
    /* This register must be configured in other to send a 16KB frame */
    Eth_GstETND_Regs.pES[LulCtrlIdx]->stMHD.ulTMS[0] = ETH_ETND_INIT_TMS_CONFIG;

    /* Configure RMAC.MCC register to prevent the frame to come out of RMAC */
    Eth_GstETND_Regs.pES[LulCtrlIdx]->stRMACSys.stRMAC.ulMCC &= ~ETH_ETND_MCC_TXE_MASK;

    /* Allocate memory for 2KB frame size (which will be used 16 times) */
    LpDataPtr = (P2VAR(uint8, AUTOMATIC, ETH_APPL_DATA))                                                                /* PRQA S 0316, 3432 # JV-01, JV-01 */
      Eth_Util_RamAlloc(&Eth_GaaHeap[LulCtrlIdx], ETH_ETND_2KB_FRAME_SIZE);                                             /* PRQA S 2934 # JV-01 */

    /* Allocate memory for 17 descriptors used to transmit 16KB frame */
    LpDescChain = (P2VAR(Eth_ExtDescType, AUTOMATIC, ETH_APPL_DATA))                                                    /* PRQA S 0316, 3432 # JV-01, JV-01 */
      Eth_Util_RamAlloc(&Eth_GaaHeap[LulCtrlIdx],                                                                       /* PRQA S 2934 # JV-01 */
      (ETH_ETND_INIT_DESC_NUM + ETH_ETND_EOS_DESC_NUM) * ETH_EXT_DESC_SIZE);
  } /* else: No action required */

  if ((NULL_PTR != LpDescChain) && (NULL_PTR != LpDataPtr))
  {
    /* Copy the original address of the descriptor */
    LpDescChainTemp = LpDescChain;

    /* Configure descriptors used for transmission */
    for (LulCntI = 0UL; LulCntI < ETH_ETND_INIT_DESC_LOOP_NUM; LulCntI++)
    {
      /* Set start frame type */
      ETH_TXRAM_INIT_DESC_CONFIG(LpDescChain, (uint32)LpDataPtr);                                                       /* PRQA S 0306 # JV-01 */
      LpDescChain->stHeader.ulDt = (uint32)ETH_DESC_FSTART;
      /* Next data descriptor */
      LpDescChain++;

      /* Set middle frame type */
      for (LulCntJ = 0UL; LulCntJ < ETH_ETND_MIDDLE_DESC_NUM; LulCntJ++)
      {
        ETH_TXRAM_INIT_DESC_CONFIG(LpDescChain, (uint32)LpDataPtr);                                                     /* PRQA S 0306 # JV-01 */
        LpDescChain->stHeader.ulDt = (uint32)ETH_DESC_FMID;                                                             /* PRQA S 2814 # JV-01 */
        /* Next data descriptor */
        LpDescChain++;                                                                                                  /* PRQA S 2824 # JV-01 */
      }

      /* Set end frame type */
      ETH_TXRAM_INIT_DESC_CONFIG(LpDescChain, (uint32)LpDataPtr);                                                       /* PRQA S 0306 # JV-01 */
      LpDescChain->stHeader.ulDt = (uint32)ETH_DESC_FEND;                                                               /* PRQA S 2814 # JV-01 */
      /* Next data descriptor */
      LpDescChain++;                                                                                                    /* PRQA S 2824 # JV-01 */
    }
    /* Set EOS frame type */
    ETH_TXRAM_INIT_EOS_DESC_CONFIG(LpDescChain, (uint32)LpDescChainTemp);                                               /* PRQA S 0306 # JV-01 */
    LpDescChain->stHeader.ulDt = (uint32)ETH_DESC_EOS;                                                                  /* PRQA S 2814 # JV-01 */

    LucResult = Eth_TxDescLearning(&Eth_GstETND_Regs.pES[LulCtrlIdx]->stAXIBMI, 0UL, (uint32)LpDescChainTemp);          /* PRQA S 0306 # JV-01 */

    /* Transmission Request */
    if (E_OK == LucResult)
    {
      LucResult = Eth_MHD_ModeSetting(LulCtrlIdx, ETH_ETND_MHD_DISABLE_MODE);
      LucResult |= Eth_MHD_ModeSetting(LulCtrlIdx, ETH_ETND_MHD_OPERATION_MODE);
      if (E_OK == LucResult)
      {
        /* Transmit start request */
        Eth_GstETND_Regs.pES[LulCtrlIdx]->stAXIBMI.ulTRCR[0] = ETH_ETND_TRCR0_TRANSMIT_ENABLE;
        LulTickStart = 0UL;
        (void)GetCounterValue(ETH_OS_COUNTER_ID, &LulTickStart);
        do
        {
          LulTickElap = Eth_GetTimeOutValue(LulTickStart);
        } while ((ETH_ETND_TDIS_0_MASK !=
                (Eth_GstETND_Regs.pES[LulCtrlIdx]->stAXIBMI.stTXDI[0].ulTDISi & ETH_ETND_TDIS_0_MASK)) &&
                (LulTickElap <= ETH_TIMEOUT_COUNT));
        if (ETH_TIMEOUT_COUNT < LulTickElap)
        {
          LucResult = E_NOT_OK;
        }
        else
        {
          /* Clear the interrupt status bit */
          Eth_GstETND_Regs.pES[LulCtrlIdx]->stAXIBMI.stTXDI[0].ulTDISi = ETH_ETND_TDIS_0_MASK;
        }
      } /* else: No action required */
    } /* else: No action required */
  }
  else
  {
    LucResult = E_NOT_OK;
  }

  /* Software Reset */
  if (E_OK == LucResult)
  {
    LucResult = Eth_MHD_ModeSetting(LulCtrlIdx, ETH_ETND_MHD_DISABLE_MODE);
    if (E_OK == LucResult)
    {
      Eth_GstETND_Regs.pES[LulCtrlIdx]->stMHD.ulSWR = ETH_ETND_SOFTWARE_RESET_ENABLE;

      LulTickStart = 0UL;
      (void)GetCounterValue(ETH_OS_COUNTER_ID, &LulTickStart);
      do
      {
        LulTickElap = Eth_GetTimeOutValue(LulTickStart);
      } while ((ETH_ETND_GIS_SWRCF_MASK != (Eth_GstETND_Regs.pES[LulCtrlIdx]->stMHD.ulGIS & ETH_ETND_GIS_SWRCF_MASK)) &&
        (LulTickElap <= ETH_TIMEOUT_COUNT));

      if (ETH_TIMEOUT_COUNT < LulTickElap)
      {
        LucResult = E_NOT_OK;
      }
      else
      {
        /* Clear SoftWare Reset Completion Flag */
        Eth_GstETND_Regs.pES[LulCtrlIdx]->stMHD.ulGIS = ETH_ETND_GIS_SWRCF_MASK;

        Eth_GaaTxRamInitState[LulCtrlIdx] = ETH_TRUE;                                                                   /* PRQA S 2844 # JV-01 */
      }
    } /* else: No action required */
  } /* else: No action required */

  /* Free allocated RAM memories */
  if (NULL_PTR != LpDataPtr)
  {
    Eth_Util_RamFree(&Eth_GaaHeap[LulCtrlIdx], (void *)LpDataPtr);                                                      /* PRQA S 2934, 0314 # JV-01, JV-01 */
  } /* else: No action required */

  if (NULL_PTR != LpDescChainTemp)
  {
    Eth_Util_RamFree(&Eth_GaaHeap[LulCtrlIdx], (void *)LpDescChainTemp);                                                /* PRQA S 2934, 0314 # JV-01, JV-01 */
  } /* else: No action required */

  return LucResult;
}

#ifdef ETH_HW_COMMON_DEINIT
/***********************************************************************************************************************
** Function Name         : Eth_HwCommonDeInit (ETND)
**
** Service ID            : N/A
**
** Description           : Initialize the common parts of ETND HwDeInit
**
** Sync/Async            : Synchronous
**
** Reentrancy            : Non-Reentrant
**
** Input Parameters      : None
**
** InOut Parameters      : None
**
** Output Parameters     : None
**
** Return parameter      : E_OK : Success
**
** Preconditions         : None
**
** Global Variable(s)    : None
**
** Function(s) invoked   : None
**
** Registers Used        : None
**
** Reference ID          : ETH_DUD_ACT_346
***********************************************************************************************************************/
FUNC(Std_ReturnType, ETH_PRIVATE_CODE) Eth_HwCommonDeInit(void)
{
  return E_OK;
}
#endif /* ETH_HW_COMMON_DEINIT*/

#if (ETH_DEINIT_API == STD_ON)
/***********************************************************************************************************************
** Function Name         : Eth_HwDeInit (ETND)
**
** Service ID            : N/A
**
** Description           : Perform SW Reset for the ETND controller
**
** Sync/Async            : Synchronous
**
** Reentrancy            : Non-Reentrant
**
** Input Parameters      : LulCtrlIdx     : Index of a controller
**                         ForceReset     : Indicate the reset flow to follow (normal/emergency)
**
** InOut Parameters      : None
**
** Output Parameters     : None
**
** Return parameter      : E_OK : Success
**                         E_NOT_OK : Failure
**
** Preconditions         : None
**
** Global Variable(s)    : Eth_GstETND_Regs, Eth_GaaCtrlStat
**
** Function(s) invoked   : None
**
** Registers Used        : GIS, SWR
**
** Reference ID          : ETH_DUD_ACT_345
** Reference ID          : ETH_DUD_ACT_345_REG001, ETH_DUD_ACT_345_REG002
** Reference ID          : ETH_DUD_ACT_345_GBL001
***********************************************************************************************************************/
FUNC(Std_ReturnType, ETH_PRIVATE_CODE) Eth_HwDeInit(                                                                    /* PRQA S 1532 # JV-01 */
  CONST(uint32, AUTOMATIC) LulCtrlIdx, CONST(boolean, AUTOMATIC) ForceReset)
{
  TickType LulTickStart;
  TickType LulTickElap;
  Std_ReturnType LucResult;

  LucResult = E_OK;                                                                                                     /* PRQA S 2982 # JV-01 */
  (void)ForceReset;

  LucResult = Eth_MHD_ModeSetting(LulCtrlIdx, ETH_ETND_MHD_DISABLE_MODE);
  if (E_OK == LucResult)
  {
    Eth_GstETND_Regs.pES[LulCtrlIdx]->stMHD.ulSWR = ETH_ETND_SOFTWARE_RESET_ENABLE;                                     /* PRQA S 2844 # JV-01 */
    LulTickStart = 0UL;
    (void)GetCounterValue(ETH_OS_COUNTER_ID, &LulTickStart);
    do
    {
      LulTickElap = Eth_GetTimeOutValue(LulTickStart);
    } while ((ETH_ETND_GIS_SWRCF_MASK != (Eth_GstETND_Regs.pES[LulCtrlIdx]->stMHD.ulGIS & ETH_ETND_GIS_SWRCF_MASK)) &&
      (LulTickElap <= ETH_TIMEOUT_COUNT));
    if (ETH_TIMEOUT_COUNT < LulTickElap)
    {
      LucResult = E_NOT_OK;
    }
    else
    {
      /* Clear SoftWare Reset Completion Flag */
      Eth_GstETND_Regs.pES[LulCtrlIdx]->stMHD.ulGIS = ETH_ETND_GIS_SWRCF_MASK;

      /* Set controller state as DOWN */
      Eth_GaaCtrlStat[LulCtrlIdx].enMode = ETH_MODE_DOWN;                                                               /* PRQA S 2844 # JV-01 */
    }
  } /* else: No action required */

  return LucResult;
}
#endif /* (ETH_DEINIT_API == STD_ON) */

/***********************************************************************************************************************
** Function Name         : Eth_HwInit (ETND)
**
** Service ID            : N/A
**
** Description           : Initialize a ETND HWUnit
**
** Sync/Async            : Synchronous
**
** Reentrancy            : Non-Reentrant
**
** Input Parameters      : LulCtrlIdx     : Index of a controller
**
** InOut Parameters      : None
**
** Output Parameters     : None
**
** Return parameter      : E_OK : Success
**                         E_NOT_OK : Failure
**
** Preconditions         : None
**
** Global Variable(s)    : Eth_GaaCtrlStat, Eth_GaaTxRamInitState
**                         Eth_GaaHeap, Eth_GaaMemPoolBufferTable, Eth_GaaRamSize
**
** Function(s) invoked   : Eth_Util_RamInit, Eth_TxRamInit
**                         Eth_AXIBMI_Init, Eth_MHD_Init, Eth_RMAC_Init
**
** Registers Used        : EICn
**
** Reference ID          : ETH_DUD_ACT_342
** Reference ID          : ETH_DUD_ACT_342_GBL001, ETH_DUD_ACT_342_GBL002
** Reference ID          : ETH_DUD_ACT_342_GBL003, ETH_DUD_ACT_342_GBL004
** Reference ID          : ETH_DUD_ACT_342_GBL005, ETH_DUD_ACT_342_GBL006
** Reference ID          : ETH_DUD_ACT_342_GBL007, ETH_DUD_ACT_342_GBL008
** Reference ID          : ETH_DUD_ACT_342_GBL009, ETH_DUD_ACT_342_GBL010
** Reference ID          : ETH_DUD_ACT_342_GBL011, ETH_DUD_ACT_342_GBL012
** Reference ID          : ETH_DUD_ACT_342_GBL013, ETH_DUD_ACT_342_GBL014
** Reference ID          : ETH_DUD_ACT_342_GBL015, ETH_DUD_ACT_342_GBL016
** Reference ID          : ETH_DUD_ACT_342_GBL017, ETH_DUD_ACT_342_GBL018
** Reference ID          : ETH_DUD_ACT_342_GBL019, ETH_DUD_ACT_342_GBL020
** Reference ID          : ETH_DUD_ACT_342_GBL021
** Reference ID          : ETH_DUD_ACT_342_REG001, ETH_DUD_ACT_342_REG002
** Reference ID          : ETH_DUD_ACT_342_REG003, ETH_DUD_ACT_342_REG004
** Reference ID          : ETH_DUD_ACT_342_REG005, ETH_DUD_ACT_342_REG006
***********************************************************************************************************************/
FUNC(Std_ReturnType, ETH_PRIVATE_CODE) Eth_HwInit(CONST(uint32, AUTOMATIC) LulCtrlIdx)                                  /* PRQA S 1532 # JV-01 */
{
  P2CONST(Eth_ETNDEConfigType, AUTOMATIC, ETH_APPL_DATA) LpHwUnitConfig;
  Std_ReturnType LucResult;

  LucResult = E_OK;
  LpHwUnitConfig =
    (P2CONST(Eth_ETNDEConfigType, AUTOMATIC, ETH_APPL_DATA))Eth_GpCtrlConfigPtr[LulCtrlIdx].pHwUnitConfig;              /* PRQA S 0316 # JV-01 */

  #if (ETH_GLOBAL_TIME_SUPPORT == STD_ON)
  Eth_GaaCtrlStat[LulCtrlIdx].ulTsDescTail = 0UL;                                                                       /* PRQA S 2844 # JV-01 */
  #endif

  /* Initialize Statistics */
  #if (ETH_GET_COUNTER_VALUES_API == STD_ON || ETH_GET_TX_STATS_API == STD_ON || ETH_GET_RX_STATS_API == STD_ON)
  Eth_GaaCtrlStat[LulCtrlIdx].stTxRxStat.ulStatsBroadcastPkts = 0UL;                                                    /* PRQA S 2844 # JV-01 */
  Eth_GaaCtrlStat[LulCtrlIdx].stTxRxStat.ulRxStatsPkts = 0UL;                                                           /* PRQA S 2844 # JV-01 */
  Eth_GaaCtrlStat[LulCtrlIdx].stTxRxStat.ulRxStatsOctets = 0UL;                                                         /* PRQA S 2844 # JV-01 */
  Eth_GaaCtrlStat[LulCtrlIdx].stTxRxStat.ulRxStatsCrcAlignErrors = 0UL;                                                 /* PRQA S 2844 # JV-01 */
  Eth_GaaCtrlStat[LulCtrlIdx].stTxRxStat.ulRxStatsUndersizePkts = 0UL;                                                  /* PRQA S 2844 # JV-01 */
  Eth_GaaCtrlStat[LulCtrlIdx].stTxRxStat.ulRxStatsOversizePkts = 0UL;                                                   /* PRQA S 2844 # JV-01 */
  Eth_GaaCtrlStat[LulCtrlIdx].stTxRxStat.ulRxStatsPkts64Octets = 0UL;                                                   /* PRQA S 2844 # JV-01 */
  Eth_GaaCtrlStat[LulCtrlIdx].stTxRxStat.ulRxStatsPkts65to127Octets = 0UL;                                              /* PRQA S 2844 # JV-01 */
  Eth_GaaCtrlStat[LulCtrlIdx].stTxRxStat.ulRxStatsPkts128to255Octets = 0UL;                                             /* PRQA S 2844 # JV-01 */
  Eth_GaaCtrlStat[LulCtrlIdx].stTxRxStat.ulRxStatsPkts256to511Octets = 0UL;                                             /* PRQA S 2844 # JV-01 */
  Eth_GaaCtrlStat[LulCtrlIdx].stTxRxStat.ulRxStatsPkts512to1023Octets = 0UL;                                            /* PRQA S 2844 # JV-01 */
  Eth_GaaCtrlStat[LulCtrlIdx].stTxRxStat.ulRxStatsPkts1024to1518Octets = 0UL;                                           /* PRQA S 2844 # JV-01 */
  Eth_GaaCtrlStat[LulCtrlIdx].stTxRxStat.ulRxUnicastFrames = 0UL;                                                       /* PRQA S 2844 # JV-01 */
  Eth_GaaCtrlStat[LulCtrlIdx].stTxRxStat.ulTxNumberOfOctets = 0UL;                                                      /* PRQA S 2844 # JV-01 */
  Eth_GaaCtrlStat[LulCtrlIdx].stTxRxStat.ulTxNUcastPkts = 0UL;                                                          /* PRQA S 2844 # JV-01 */
  Eth_GaaCtrlStat[LulCtrlIdx].stTxRxStat.ulTxUniCastPkts = 0UL;                                                         /* PRQA S 2844 # JV-01 */
  Eth_GaaCtrlStat[LulCtrlIdx].stTxRxStat.ulDropPktCrc = 0UL;                                                            /* PRQA S 2844 # JV-01 */
  Eth_GaaCtrlStat[LulCtrlIdx].stTxRxStat.ulUndersizePkt = 0UL;                                                          /* PRQA S 2844 # JV-01 */
  Eth_GaaCtrlStat[LulCtrlIdx].stTxRxStat.ulOversizePkt = 0UL;                                                           /* PRQA S 2844 # JV-01 */
  Eth_GaaCtrlStat[LulCtrlIdx].stTxRxStat.ulAlgnmtErr = 0UL;                                                             /* PRQA S 2844 # JV-01 */
  #endif

  Eth_GaaHeap[LulCtrlIdx] = Eth_Util_RamInit(Eth_GaaMemPoolBufferTable[LulCtrlIdx], Eth_GaaRamSize[LulCtrlIdx]);        /* PRQA S 2844, 0315 # JV-01, JV-01 */
  if (NULL_PTR != Eth_GaaHeap[LulCtrlIdx])
  {
    if (ETH_TRUE != Eth_GaaTxRamInitState[LulCtrlIdx])                                                                  /* PRQA S 2844 # JV-01 */
    {
      LucResult = Eth_TxRamInit(LulCtrlIdx);
    } /* else: No action required */

    if (E_OK == LucResult)
    {
      /*-------------------------------------------------------------------------*/
      /* Initialization for TSNES                                                */
      /*-------------------------------------------------------------------------*/
      LucResult = Eth_AXIBMI_Init(LulCtrlIdx);
      if (E_OK == LucResult)
      {
        Eth_MHD_Init(LulCtrlIdx);
        Eth_RMAC_Init(LulCtrlIdx);

        /* Enable Interrupt */
        #if (ETH_GLOBAL_TIME_SUPPORT == STD_ON)
        /* Enable TS Descriptor Data Interrupt */
        RH850_SV_MODE_ICR_AND(8, &Eth_GaaETND_EICRegs[LulCtrlIdx]->usINTETNDw0, (uint8)(~ETH_EIC_EIMK_MASK));           /* PRQA S 0404, 2844, 0751, 2814, 3464 # JV-01, JV-01, JV-01, JV-01, JV-01 */
        #endif

        /* General Interrupt Enable */
        RH850_SV_MODE_ICR_AND(8, &Eth_GaaETND_EICRegs[LulCtrlIdx]->usINTETNDw6, (uint8)(~ETH_EIC_EIMK_MASK));           /* PRQA S 0404, 0751, 3464 # JV-01, JV-01, JV-01 */

        /* Tx/Rx Descriptor Data Interrupt Enable */
        if (0UL != ((LpHwUnitConfig->stQueueConfig.ulTxIntConfig | LpHwUnitConfig->stQueueConfig.ulRxIntConfig)         /* PRQA S 2814 # JV-01 */
          & ETH_QUEUE_ID_0_4_MASK))
        {
          RH850_SV_MODE_ICR_AND(8, &Eth_GaaETND_EICRegs[LulCtrlIdx]->usINTETNDw0, (uint8)(~ETH_EIC_EIMK_MASK));         /* PRQA S 0404, 0751, 3464 # JV-01, JV-01, JV-01 */
        } /* else: No action required */

        if (0UL != ((LpHwUnitConfig->stQueueConfig.ulTxIntConfig | LpHwUnitConfig->stQueueConfig.ulRxIntConfig)
          & ETH_QUEUE_ID_1_5_MASK))
        {
          RH850_SV_MODE_ICR_AND(8, &Eth_GaaETND_EICRegs[LulCtrlIdx]->usINTETNDw1, (uint8)(~ETH_EIC_EIMK_MASK));         /* PRQA S 0751, 0404, 3464 # JV-01, JV-01, JV-01 */
        } /* else: No action required */

        if (0UL != ((LpHwUnitConfig->stQueueConfig.ulTxIntConfig | LpHwUnitConfig->stQueueConfig.ulRxIntConfig)
          & ETH_QUEUE_ID_2_6_MASK))
        {
          RH850_SV_MODE_ICR_AND(8, &Eth_GaaETND_EICRegs[LulCtrlIdx]->usINTETNDw2, (uint8)(~ETH_EIC_EIMK_MASK));         /* PRQA S 0751, 0404, 3464 # JV-01, JV-01, JV-01 */
        } /* else: No action required */

        if (0UL != ((LpHwUnitConfig->stQueueConfig.ulTxIntConfig | LpHwUnitConfig->stQueueConfig.ulRxIntConfig)
          & ETH_QUEUE_ID_3_7_MASK))
        {
          RH850_SV_MODE_ICR_AND(8, &Eth_GaaETND_EICRegs[LulCtrlIdx]->usINTETNDw3, (uint8)(~ETH_EIC_EIMK_MASK));         /* PRQA S 0751, 0404, 3464 # JV-01, JV-01, JV-01 */
        } /* else: No action required */

        if (ETH_SGMII == Eth_GpEthConfigPtr[LulCtrlIdx].enEthPHYInterface)
        {
          LucResult = Eth_SGMIIInit(LulCtrlIdx, LpHwUnitConfig->enBypassMode);
        } /* else: No action required */
      } /* else: No action required */
    } /* else: No action required */
  }
  else
  {
    LucResult = E_NOT_OK;
  }

  return LucResult;
}

/***********************************************************************************************************************
** Function Name         : Eth_AXIBMI_Init
**
** Service ID            : NA
**
** Description           : Initialization process for AXIBMI
**
** Sync/Async            : Synchronous
**
** Reentrancy            : Non-Reentrant
**
** Input Parameters      : LulCtrlIdx : Index of a controller
**
** InOut Parameters      : None
**
** Output Parameters     : None
**
** Return parameter      : E_OK : Success
**                         E_NOT_OK : Failure
**
** Preconditions         : None
**
** Global Variable(s)    : Eth_GstETND_Regs, Eth_GaaETND_EICRegs
**                         Eth_GpCtrlConfigPtr, Eth_GpEthConfigPtr
**                         Eth_GaaHeap
**
** Function(s) invoked   : GetCounterValue, Eth_GetTimeOutValue, Eth_MHD_ModeSetting
**                         Eth_Util_RamSetCircularAddr, Eth_TsDescConfig, Eth_TxRxDescConfig
**
** Registers Used        : RR, AXIWC, AXIRC, TDPC, TFT, EIE0, TMS
**                         TSDIE, TDIEi, RDIEi
**
** Reference ID          : ETH_DUD_ACT_361
** Reference ID          : ETH_DUD_ACT_361_REG001, ETH_DUD_ACT_361_REG002
** Reference ID          : ETH_DUD_ACT_361_REG003, ETH_DUD_ACT_361_REG004
** Reference ID          : ETH_DUD_ACT_361_REG005, ETH_DUD_ACT_361_REG006
** Reference ID          : ETH_DUD_ACT_361_REG007, ETH_DUD_ACT_361_REG008
** Reference ID          : ETH_DUD_ACT_361_REG009
***********************************************************************************************************************/
STATIC FUNC(Std_ReturnType, ETH_PRIVATE_CODE) Eth_AXIBMI_Init(CONST(uint32, AUTOMATIC) LulCtrlIdx)
{
  P2CONST(Eth_ETNDEConfigType, AUTOMATIC, ETH_APPL_DATA) LpHwUnitConfig;
  TickType LulTickStart;
  TickType LulTickElap;
  uint32 LulQPriorityVal;
  uint32 LulFrameTypeVal;
  uint32 LulCnt;
  Std_ReturnType LucResult;

  LucResult = E_OK;                                                                                                     /* PRQA S 2982 # JV-01 */
  LpHwUnitConfig =
    (P2CONST(Eth_ETNDEConfigType, AUTOMATIC, ETH_APPL_DATA))Eth_GpCtrlConfigPtr[LulCtrlIdx].pHwUnitConfig;              /* PRQA S 0316 # JV-01 */

  /* Configure AXIBMI */
  LucResult = Eth_MHD_ModeSetting(LulCtrlIdx, ETH_ETND_MHD_DISABLE_MODE);
  LucResult |= Eth_MHD_ModeSetting(LulCtrlIdx, ETH_ETND_MHD_CONFIG_MODE);
  if (E_OK == LucResult)
  {
    /* Clear RAM Reset Register Bits */
    Eth_GstETND_Regs.pES[LulCtrlIdx]->stAXIBMI.ulRR = ETH_ETNDE_RATRR_RESET | ETH_ETNDE_TATRR_RESET;                    /* PRQA S 2844 # JV-01 */

    /* RAM Reset Waiting */
    LulTickStart = 0UL;
    (void)GetCounterValue(ETH_OS_COUNTER_ID, &LulTickStart);
    do
    {
      LulTickElap = Eth_GetTimeOutValue(LulTickStart);
    } while (((ETH_ETNDE_RATRR_RESET | ETH_ETNDE_TATRR_RESET) != Eth_GstETND_Regs.pES[LulCtrlIdx]->stAXIBMI.ulRR)
      && (LulTickElap <= ETH_TIMEOUT_COUNT));

    if (ETH_TIMEOUT_COUNT < LulTickElap)
    {
      LucResult = E_NOT_OK;
    } /* else: No action required */
  } /* else: No action required */

  if (E_OK == LucResult)
  {
    /* Set AXI Write and Read Outstanding Number */
    Eth_GstETND_Regs.pES[LulCtrlIdx]->stAXIBMI.ulAXIWC = ETH_ETNDE_AXIWC_CONFIG;
    Eth_GstETND_Regs.pES[LulCtrlIdx]->stAXIBMI.ulAXIRC = ETH_ETNDE_AXIRC_CONFIG;

    /* Set Tx Queue priority and Frame type */
    LulQPriorityVal = 0UL;
    LulFrameTypeVal = 0UL;
    for (LulCnt = 0UL; LulCnt < (uint32)LpHwUnitConfig->stQueueConfig.ucNumberOfTxQueue; LulCnt++)                      /* PRQA S 2814 # JV-01 */
    {
      LulQPriorityVal |= LpHwUnitConfig->stQueueConfig.pTxQueueConfig[LulCnt].ulQueueId << (4UL * LulCnt);              /* PRQA S 2824, 3383 # JV-01, JV-01 */
      LulFrameTypeVal |= (uint32)LpHwUnitConfig->stQueueConfig.pTxQueueConfig[LulCnt].enFrameType << LulCnt;
    }
    /* The supported Tx Queue is 0-7 */
    Eth_GstETND_Regs.pES[LulCtrlIdx]->stAXIBMI.ulTDPC[0] = LulQPriorityVal;
    /* AXIBMI execute TFTP0-2 with p-frame statements and TFTP3-7 with e-frame statements */
    /* Since each statement operates as an independent core, it operates faster by enabling all statements */
    Eth_GstETND_Regs.pES[LulCtrlIdx]->stAXIBMI.ulTFT = LulFrameTypeVal;

    /* Tx/Rx descriptor chain setting */
    LucResult = Eth_TxRxDescConfig(LulCtrlIdx);
    if (E_OK == LucResult)
    {
      /* Set circular address for Tx bufffers */
      Eth_Util_RamSetCircularAddr(Eth_GaaHeap[LulCtrlIdx]);                                                             /* PRQA S 2844 # JV-01 */
    } /* else: No action required */

    #if (ETH_GLOBAL_TIME_SUPPORT == STD_ON)
    /* TS descriptor chain setting */
    Eth_TsDescConfig(LulCtrlIdx);

    /* TS Descriptor Data Interrupt */
    Eth_GstETND_Regs.pES[LulCtrlIdx]->stAXIBMI.ulTSDIE = ETH_ETNDE_TSDIE_CONFIG;
    #endif

    /* Set AXIBMI Error Interrupt */
    Eth_GstETND_Regs.pES[LulCtrlIdx]->stAXIBMI.ulEIE0 = ETH_ETND_EIE0_CONFIG;

    /* TX Descriptor Data Interrupt */
    if (ETH_ENABLE == Eth_GpEthConfigPtr[LulCtrlIdx].enTxInterruptMode)
    {
      Eth_GstETND_Regs.pES[LulCtrlIdx]->stAXIBMI.stTXDI[0].ulTDIEi = LpHwUnitConfig->stQueueConfig.ulTxIntConfig;
    } /* else: No action required */

    /* RX Descriptor Data Interrupt */
    if (ETH_ENABLE == Eth_GpEthConfigPtr[LulCtrlIdx].enRxInterruptMode)
    {
      Eth_GstETND_Regs.pES[LulCtrlIdx]->stAXIBMI.stRXDI[0].ulRDIEi = LpHwUnitConfig->stQueueConfig.ulRxIntConfig;
    } /* else: No action required */
  } /* else: No action required */

  return LucResult;
}

/***********************************************************************************************************************
** Function Name         : Eth_MHD_Init
**
** Service ID            : NA
**
** Description           : Initialization process of MHD, TAS, CBS Function
**
** Sync/Async            : Synchronous
**
** Reentrancy            : Non-Reentrant
**
** Input Parameters      : LulCtrlIdx : Index of a controller
**
** InOut Parameters      : None
**
** Output Parameters     : None
**
** Return parameter      : None
**
** Preconditions         : None
**
** Global Variable(s)    : Eth_GstETND_Regs, Eth_GpCtrlConfigPtr
**
** Function(s) invoked   : None
**
** Registers Used        : TMS, TSF, TGC1, TGC2, TCR1, TCR2, TCR3, TCR4, RGC, RDFCR, RCFCR
**                         TCIE, TIE2, RIE, TFT
**                         TPTPC, TTML, TTJ
**                         CACC, CAIV, CAUL, CCS
**
** Reference ID          : ETH_DUD_ACT_362
** Reference ID          : ETH_DUD_ACT_362_REG001, ETH_DUD_ACT_362_REG002
** Reference ID          : ETH_DUD_ACT_362_REG003, ETH_DUD_ACT_362_REG004
** Reference ID          : ETH_DUD_ACT_362_REG005, ETH_DUD_ACT_362_REG006
** Reference ID          : ETH_DUD_ACT_362_REG007, ETH_DUD_ACT_362_REG008
** Reference ID          : ETH_DUD_ACT_362_REG009, ETH_DUD_ACT_362_REG010
** Reference ID          : ETH_DUD_ACT_362_REG011, ETH_DUD_ACT_362_REG012
** Reference ID          : ETH_DUD_ACT_362_REG013, ETH_DUD_ACT_362_REG014
** Reference ID          : ETH_DUD_ACT_362_REG015, ETH_DUD_ACT_362_REG016
** Reference ID          : ETH_DUD_ACT_362_REG017, ETH_DUD_ACT_362_REG018
** Reference ID          : ETH_DUD_ACT_362_REG019, ETH_DUD_ACT_362_REG020
** Reference ID          : ETH_DUD_ACT_362_REG021
***********************************************************************************************************************/
STATIC FUNC(void, ETH_PRIVATE_CODE) Eth_MHD_Init(CONST(uint32, AUTOMATIC) LulCtrlIdx)
{
  P2CONST(Eth_ETNDEConfigType, AUTOMATIC, ETH_APPL_DATA) LpHwUnitConfig;
  uint32 LulCnt;

  LpHwUnitConfig =
    (P2CONST(Eth_ETNDEConfigType, AUTOMATIC, ETH_APPL_DATA))Eth_GpCtrlConfigPtr[LulCtrlIdx].pHwUnitConfig;              /* PRQA S 0316 # JV-01 */

  /* Configure MHD */
  /* Interrupt settings */
  /* TAS CBS Interrupt Enable register config */
  Eth_GstETND_Regs.pES[LulCtrlIdx]->stMHD.ulTCIE = ETH_ETND_TCIE_CONFIG;                                               /* PRQA S 2844 # JV-01 */

  /* Transmission Interrupt Enable register config */
  Eth_GstETND_Regs.pES[LulCtrlIdx]->stMHD.ulTIE2 = ETH_ETND_TIE2_CONFIG;

  /* Reception Interrupt Enable register config */
  Eth_GstETND_Regs.pES[LulCtrlIdx]->stMHD.ulRIE  = ETH_ETND_RIE_CONFIG;

  for (LulCnt = 0UL; LulCnt < (uint32)LpHwUnitConfig->stQueueConfig.ucNumberOfTxQueue; LulCnt++)                        /* PRQA S 2814 # JV-01 */
  {
    /* This frame size does not include FCS size */
    Eth_GstETND_Regs.pES[LulCtrlIdx]->stMHD.ulTMS[LulCnt] =
      LpHwUnitConfig->stQueueConfig.pTxQueueConfig[LulCnt].ulMaxFrameSize;                                              /* PRQA S 2824 # JV-01 */
  }

  /* Tx General Setting */
  for (LulCnt = 0UL; LulCnt < ETH_ETND_MAX_TFS; LulCnt++)
  {
    Eth_GstETND_Regs.pES[LulCtrlIdx]->stMHD.ulTFS[LulCnt] = ETH_ETND_TFS_CONFIG;
  }
  Eth_GstETND_Regs.pES[LulCtrlIdx]->stMHD.ulTGC1 = ETH_ETND_TGC1_CONFIG;
  Eth_GstETND_Regs.pES[LulCtrlIdx]->stMHD.ulTGC2 = ((uint32)LpHwUnitConfig->enTxFragment << 16UL) |
                                                   Eth_GstETND_Regs.pES[LulCtrlIdx]->stAXIBMI.ulTFT;

  /* Tx data fifo warning level */
  Eth_GstETND_Regs.pES[LulCtrlIdx]->stMHD.ulTCR1 = ETH_ETND_TCR1_CONFIG;
  Eth_GstETND_Regs.pES[LulCtrlIdx]->stMHD.ulTCR2 = ETH_ETND_TCR2_CONFIG;
  Eth_GstETND_Regs.pES[LulCtrlIdx]->stMHD.ulTCR3 = ETH_ETND_TCR3_CONFIG;
  Eth_GstETND_Regs.pES[LulCtrlIdx]->stMHD.ulTCR4 = ETH_ETND_TCR4_CONFIG;

  /* Rx General Setting */
  Eth_GstETND_Regs.pES[LulCtrlIdx]->stMHD.ulRGC  = ETH_ETND_RGC_CONFIG;

  /* Rx data fifo warning level */
  Eth_GstETND_Regs.pES[LulCtrlIdx]->stMHD.ulRDFCR = ETH_ETND_RDFCR_CONFIG;
  Eth_GstETND_Regs.pES[LulCtrlIdx]->stMHD.ulRCFCR = ETH_ETND_RCFCR_CONFIG;

  /* TAS configuration */
  Eth_GstETND_Regs.pES[LulCtrlIdx]->stMHD.ulTPTPC = ETH_GPTP_TIMER_DOMAIN;
  Eth_GstETND_Regs.pES[LulCtrlIdx]->stMHD.ulTTML = LpHwUnitConfig->stTASConfig.ulTxMiniLatency;
  Eth_GstETND_Regs.pES[LulCtrlIdx]->stMHD.ulTTJ = LpHwUnitConfig->stTASConfig.ulTxJitter;

  /* CBS configuration */
  for (LulCnt = 0UL; LulCnt < (uint32)LpHwUnitConfig->stQueueConfig.ucNumberOfTxQueue; LulCnt++)
  {
    Eth_GstETND_Regs.pES[LulCtrlIdx]->stMHD.ulCACC |=
      (uint32)LpHwUnitConfig->stQueueConfig.pTxQueueConfig[LulCnt].stCBSConfig.enCE << LulCnt;
    Eth_GstETND_Regs.pES[LulCtrlIdx]->stMHD.ulCAIV[LulCnt] =
      LpHwUnitConfig->stQueueConfig.pTxQueueConfig[LulCnt].stCBSConfig.ulCIV;
    Eth_GstETND_Regs.pES[LulCtrlIdx]->stMHD.ulCAUL[LulCnt] =
      LpHwUnitConfig->stQueueConfig.pTxQueueConfig[LulCnt].stCBSConfig.ulCUL;
    Eth_GstETND_Regs.pES[LulCtrlIdx]->stMHD.ulCCS |=
      (uint32)LpHwUnitConfig->stQueueConfig.pTxQueueConfig[LulCnt].stCBSConfig.enCE << LulCnt;
  }
}

/***********************************************************************************************************************
** Function Name         : Eth_RMAC_Init
**
** Service ID            : NA
**
** Description           : Initialization process of RMAC System
**
** Sync/Async            : Synchronous
**
** Reentrancy            : Non-Reentrant
**
** Input Parameters      : LulCtrlIdx : Index of a controller
**
** InOut Parameters      : None
**
** Output Parameters     : None
**
** Return parameter      : None
**
** Preconditions         : None
**
** Global Variable(s)    : Eth_GstETND_Regs, Eth_GpCtrlConfigPtr
**
** Function(s) invoked   : None
**
** Registers Used        : MRMAC0, MRMAC1, MLBC, MPIC, MTFFC, MTPFC, MTATC, MRGC
**                         MRFSCE, MRFSCP, MTRC, MRSCE, MRSCP, MRAFC
**
** Reference ID          : ETH_DUD_ACT_363
** Reference ID          : ETH_DUD_ACT_363_REG001, ETH_DUD_ACT_363_REG002
** Reference ID          : ETH_DUD_ACT_363_REG003, ETH_DUD_ACT_363_REG004
** Reference ID          : ETH_DUD_ACT_363_REG005, ETH_DUD_ACT_363_REG006
** Reference ID          : ETH_DUD_ACT_363_REG008
** Reference ID          : ETH_DUD_ACT_363_REG009, ETH_DUD_ACT_363_REG010
** Reference ID          : ETH_DUD_ACT_363_REG011, ETH_DUD_ACT_363_REG012
** Reference ID          : ETH_DUD_ACT_363_REG013, ETH_DUD_ACT_363_REG014
** Reference ID          : ETH_DUD_ACT_363_REG015
***********************************************************************************************************************/
STATIC FUNC(void, ETH_PRIVATE_CODE) Eth_RMAC_Init(CONST(uint32, AUTOMATIC) LulCtrlIdx)
{
  P2CONST(Eth_ETNDEConfigType, AUTOMATIC, ETH_APPL_DATA) LpHwUnitConfig;

  LpHwUnitConfig =
    (P2CONST(Eth_ETNDEConfigType, AUTOMATIC, ETH_APPL_DATA))Eth_GpCtrlConfigPtr[LulCtrlIdx].pHwUnitConfig;              /* PRQA S 0316 # JV-01 */

  /* RMAC System configuration */
  /* Set MAC address */
  /* When MAC address is 01-23-45-67-89-AB, set 0x0123 */
  Eth_GstETND_Regs.pES[LulCtrlIdx]->stRMACSys.stRMAC.ulMRMAC0 =                                                         /* PRQA S 2844 # JV-01 */
    Eth_GaaCtrlStat[LulCtrlIdx].stMacAddr.ulH32 >> 16UL;                                                                /* PRQA S 2844 # JV-01 */
  /* When MAC address is 01-23-45-67-89-AB, set 0x456789AB */
  Eth_GstETND_Regs.pES[LulCtrlIdx]->stRMACSys.stRMAC.ulMRMAC1 =
    (Eth_GaaCtrlStat[LulCtrlIdx].stMacAddr.ulH32 << 16UL) | Eth_GaaCtrlStat[LulCtrlIdx].stMacAddr.ulL16;
  /* Config MAC Loopback mode */
  if (ETH_ENABLE == Eth_GpEthConfigPtr[LulCtrlIdx].enInternalLoopBackMode)
  {
    Eth_GstETND_Regs.pES[LulCtrlIdx]->stRMACSys.stRMAC.ulMLBC = ETH_ETNDE_MLBC_CONFIG;
  } /* else: No action required */

  /* Set Tx function */
  Eth_GstETND_Regs.pES[LulCtrlIdx]->stRMACSys.stRMAC.ulMTFFC = 0UL;
  if (ETH_ENABLE == LpHwUnitConfig->stMACConfig.enPauseFrame)                                                      /* PRQA S 2814 # JV-01 */
  {
    Eth_GstETND_Regs.pES[LulCtrlIdx]->stRMACSys.stRMAC.ulMTPFC =
      (uint32)(((uint32)LpHwUnitConfig->stMACConfig.enPauseTimeZero << 24UL) |
      (LpHwUnitConfig->stMACConfig.ulRetransmissionTime << 16UL) |
        LpHwUnitConfig->stMACConfig.ulPauseTime);
  } /* else: No action required */
  /* Do not use automatic timestamp */
  Eth_GstETND_Regs.pES[LulCtrlIdx]->stRMACSys.stRMAC.ulMTATC[ETH_GPTP_TIMER_DOMAIN] = ETH_ETNDE_MTATC_CONFIG;

  /* Set Rx function */
  Eth_GstETND_Regs.pES[LulCtrlIdx]->stRMACSys.stRMAC.ulMRGC =
    (uint32)(((uint32)LpHwUnitConfig->stMACConfig.enPauseTimeZero << 2UL) |
    ((uint32)LpHwUnitConfig->stMACConfig.enPauseFrame << 1UL));
  Eth_GstETND_Regs.pES[LulCtrlIdx]->stRMACSys.stRMAC.ulMRFSCE = LpHwUnitConfig->stRxConfig.ulMaxFrameSize;              /* PRQA S 2824 # JV-01 */
  Eth_GstETND_Regs.pES[LulCtrlIdx]->stRMACSys.stRMAC.ulMRFSCP = LpHwUnitConfig->stRxConfig.ulMaxFrameSize;
  /* Timestamp capture settings for Rx descriptor */
  Eth_GstETND_Regs.pES[LulCtrlIdx]->stRMACSys.stRMAC.ulMTRC = ETH_ETNDE_MTRC_CONFIG;

  /* Set Address Filtering function */
  Eth_GstETND_Regs.pES[LulCtrlIdx]->stRMACSys.stRMAC.ulMRSCE =
    (LpHwUnitConfig->stRxConfig.ulBcastThreshold << 16UL) | LpHwUnitConfig->stRxConfig.ulMcastThreshold;
  Eth_GstETND_Regs.pES[LulCtrlIdx]->stRMACSys.stRMAC.ulMRSCP =
    (LpHwUnitConfig->stRxConfig.ulBcastThreshold << 16UL) | LpHwUnitConfig->stRxConfig.ulMcastThreshold;
  Eth_GstETND_Regs.pES[LulCtrlIdx]->stRMACSys.stRMAC.ulMRAFC =
    ETH_ETNDE_MRAFC_CONFIG | (uint32)(((uint32)LpHwUnitConfig->stRxConfig.enBcastStormFilter << 20UL) |
                            ((uint32)LpHwUnitConfig->stRxConfig.enMcastStormFilter << 19UL) |
                            ((uint32)LpHwUnitConfig->stRxConfig.enBcastStormFilter << 4UL) |
                            ((uint32)LpHwUnitConfig->stRxConfig.enMcastStormFilter << 3UL));

  /* PSFP configuration */

  /* PTP Filtering function is not supported */

  /* PHY Interface configuration */
  Eth_GstETND_Regs.pES[LulCtrlIdx]->stRMACSys.stRMAC.ulMPIC =
    (uint32)(((uint32)Eth_GpEthConfigPtr[LulCtrlIdx].enEthSpeed << 2UL) |
    (uint32)Eth_GpEthConfigPtr[LulCtrlIdx].enEthPHYInterface);
}

/***********************************************************************************************************************
** Function Name         : Eth_MHD_ModeSetting
**
** Service ID            : NA
**
** Description           : Set the mode of MHD
**
** Sync/Async            : Synchronous
**
** Reentrancy            : Non-Reentrant
**
** Input Parameters      : LulCtrlIdx : Index of a controller
**                         LulMode : MHD Mode
**
** InOut Parameters      : None
**
** Output Parameters     : None
**
** Return parameter      : E_OK : Success
**                         E_NOT_OK : Failure
**
** Preconditions         : None
**
** Global Variable(s)    : Eth_GstETND_Regs
**
** Function(s) invoked   : GetCounterValue, Eth_GetTimeOutValue
**
** Registers Used        : OCR, OSR
**
** Reference ID          : ETH_DUD_ACT_343
** Reference ID          : ETH_DUD_ACT_343_REG001, ETH_DUD_ACT_343_REG002
***********************************************************************************************************************/
FUNC(Std_ReturnType, ETH_PRIVATE_CODE) Eth_MHD_ModeSetting(
  CONST(uint32, AUTOMATIC) LulCtrlIdx, CONST(uint32, AUTOMATIC) LulMode)
{
  TickType LulTickStart;
  TickType LulTickElap;
  Std_ReturnType LucResult;

  /* Switch to CONFIG mode (OSR.OPS bit) */
  Eth_GstETND_Regs.pES[LulCtrlIdx]->stMHD.ulOCR = LulMode;                                                              /* PRQA S 2844 # JV-01 */

  /* Wait while CONFIG mode is achieved */
  LulTickStart = 0UL;
  (void)GetCounterValue(ETH_OS_COUNTER_ID, &LulTickStart);
  do
  {
    LulTickElap = Eth_GetTimeOutValue(LulTickStart);
  } while ((Eth_GstETND_Regs.pES[LulCtrlIdx]->stMHD.ulOSR != (1UL << LulMode)) &&
           (LulTickElap <= ETH_TIMEOUT_COUNT));

  if (ETH_TIMEOUT_COUNT < LulTickElap)
  {
    LucResult = E_NOT_OK;
  }
  else
  {
    LucResult = E_OK;
  }

  return LucResult;
}

#define ETH_STOP_SEC_PRIVATE_CODE
#include "Eth_MemMap.h"
/***********************************************************************************************************************
**                                                    End of File                                                     **
***********************************************************************************************************************/
