/*====================================================================================================================*/
/* Project      = AUTOSAR Renesas X2x MCAL Components                                                                 */
/* Module       = Eth_ETNC_LLDriver.c                                                                                 */
/* SW-VERSION   = 1.6.0                                                                                               */
/*====================================================================================================================*/
/*                                                COPYRIGHT                                                           */
/*====================================================================================================================*/
/* (c) 2020,2021   Renesas Electronics Corporation. All rights reserved.                                              */
/*====================================================================================================================*/
/* Purpose:                                                                                                           */
/* This file contains ETNC 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.4.2: 24/08/2021    : Modify the format to 120 characters
 *        30/08/2021    : Updated QA-C 9.5.0 comments
 * 1.4.1: 07/05/2021    : Remove vendor ID from the file name, API names
 *                        and parameters according to BSW00347 requirement
 *        09/06/2021    : Add QAC 9.5.0 comment.
 *        06/07/2021    : Updated QA-C 9.5.0 comments.
 * 1.2.0: 13/07/2020    : Release
 *        29/07/2020    : Add QAC 9.3.1 comment.
 * 1.1.0: 19/06/2020    : Release
 * 1.0.1: 04/06/2020    : ETH_59_DEM_REPORT_ERROR replace to Eth_59_DemConfigCheck.
 *                        To support Transmit/Receive interrupts for each controller.
 *                        Updated static analysis result.
 * 1.0.0: 25/03/2020    : Initial Version
 */
/******************************************************************************/

/***********************************************************************************************************************
**                                         Include Section                                                            **
***********************************************************************************************************************/
#include "Eth.h"
#include "Eth_ETNC_Ram.h"
#include "Eth_ETNC_LLDriver.h"
#include "Eth_Filter.h"
#include "EthIf_Cbk.h"
#include "Dem.h"
#include "rh850_Types.h"
#if (ETH_CRITICAL_SECTION_PROTECTION == STD_ON)
/* Included for the declaration of the critical section protection functions */
#include "SchM_Eth.h"
#endif

#if (ETH_USING_MACRO == ETH_MACRO_ETNC)

/***********************************************************************************************************************
**                                          Version Information                                                       **
***********************************************************************************************************************/
/* AUTOSAR release version information */
#define ETH_ETNC_C_AR_RELEASE_MAJOR_VERSION ETH_AR_RELEASE_MAJOR_VERSION_VALUE
#define ETH_ETNC_C_AR_RELEASE_MINOR_VERSION ETH_AR_RELEASE_MINOR_VERSION_VALUE
#define ETH_ETNC_C_AR_RELEASE_REVISION_VERSION ETH_AR_RELEASE_REVISION_VERSION_VALUE

/* File version information */
#define ETH_ETNC_C_SW_MAJOR_VERSION    ETH_SW_MAJOR_VERSION_VALUE
#define ETH_ETNC_C_SW_MINOR_VERSION    ETH_SW_MINOR_VERSION_VALUE

/***********************************************************************************************************************
**                                          Version Check                                                             **
***********************************************************************************************************************/
#if (ETH_ETNC_AR_RELEASE_MAJOR_VERSION != ETH_ETNC_C_AR_RELEASE_MAJOR_VERSION)
#error "Eth_ETNC_LLDriver.c : Mismatch in Release Major Version"
#endif
#if (ETH_ETNC_AR_RELEASE_MINOR_VERSION != ETH_ETNC_C_AR_RELEASE_MINOR_VERSION)
#error "Eth_ETNC_LLDriver.c : Mismatch in Release Minor Version"
#endif
#if (ETH_ETNC_AR_RELEASE_REVISION_VERSION != ETH_ETNC_C_AR_RELEASE_REVISION_VERSION)
#error "Eth_ETNC_LLDriver.c : Mismatch in Release Revision Version"
#endif

#if (ETH_ETNC_SW_MAJOR_VERSION != ETH_ETNC_C_SW_MAJOR_VERSION)
#error "Eth_ETNC_LLDriver.c : Mismatch in Software Major Version"
#endif
#if (ETH_ETNC_SW_MINOR_VERSION != ETH_ETNC_C_SW_MINOR_VERSION)
#error "Eth_ETNC_LLDriver.c : Mismatch in Software Minor Version"
#endif

/***********************************************************************************************************************
**                                               Coding Rule Violations                                               **
***********************************************************************************************************************/
/* Message (2:0306)    : [I] Cast between a pointer to object and an integral type.                                   */
/* Rule                : CERTCCM INT36, MISRA C:2012 Rule-11.4                                                        */
/*                       REFERENCE - ISO:C90-6.3.4  Semantics                                                         */
/* JV-01 Justification : This cast is essential to declare a pointer which points an I/O register.                    */
/*       Verification  : These pointers are const values and only used for I/O accesses, any problem doesn't occur.   */
/**********************************************************************************************************************/
/* Message (2:3432)    : Simple macro argument expression is not parenthesized.                                       */
/* Rule                : MISRA C:2012 Rule-20.7                                                                       */
/*                       REFERENCE - ISO:C90-6.3.1 Primary Expressions                                                */
/* 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:3218)    : File scope static 'Lin_GstSleepPdu' is only accessed in one function.                        */
/* Rule                : CERTCCM DCL19, MISRA C:2012 Rule-8.9                                                         */
/* JV-01 Justification : This is for better readability of code and easier to maintence. There is no problem because  */
/*                       the code is reviewed.                                                                        */
/*       Verification  : However, part of the code is verified manually and it is not having any impact.              */
/**********************************************************************************************************************/
/* Message (2:0303)    : [I] Cast between a pointer to volatile object and an integral type.                          */
/* Rule                : CERTCCM INT36, MISRA C:2012 Rule-11.4                                                        */
/*                       REFERENCE - ISO-6.3.4 Semantics                                                              */
/* JV-01 Justification : This is necessary to compare register values and pointers.                                   */
/*       Verification  : However, part of the code is verified manually and it is not having any impact.              */
/**********************************************************************************************************************/
/* Message (4:5087)    : (4:5087) #include statements in a file should only be preceded by other preprocessor         */
/*                       directives or comments.                                                                      */
/* Rule                : MISRA C:2012 Rule-20.1                                                                       */
/* JV-01 Justification : This is accepted, due to implementation for include memmap is following AUTOSAR rule.        */
/*       Verification  : However, part of the code is verified manually and it is not having any impact.              */
/**********************************************************************************************************************/
/* 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: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 : As manual review, the assignment is necessary in specific of user configuration.             */
/*       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: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: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 char type.         */
/*       Verification  : However, part of the code is verified manually and it is not having any impact.              */
/**********************************************************************************************************************/
/* Message (2:3469)    : This usage of a function-like macro looks like it could be replaced by an equivalent         */
/*                       function call.                                                                               */
/* Rule                : MISRA C:2012 Dir-4.9                                                                         */
/* JV-01 Justification : To prevent overhead and speed up the processing, there is no need to call a function         */
/*                       here for such a small operation.                                                             */
/*       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 (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 (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:0488)    : Performing pointer arithmetic.                                                               */
/* Rule                : CERTCCM EXP08, MISRA C:2012 Rule-18.4                                                        */
/* JV-01 Justification : To simplify the register checking by using the table.                                        */
/*       Verification  : Both of the arithmetic operands are constant values, it can be verified by the static        */
/*                       code analysis.                                                                               */
/**********************************************************************************************************************/
/* 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 object addressed by this pointer change 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.              */
/**********************************************************************************************************************/
/* Message (3:2912)    : Apparent: Wraparound in unsigned arithmetic operation.                                       */
/* Rule                : CERTCCM INT30, INT08                                                                         */
/* JV-01 Justification : Since it is permitted by the AUTOSAR specifications, it has an implementation that may cause */
/*                       overflow. Overflow is checked later, so there is no problem.                                 */
/*       Verification  : However, part of the code is verified manually and it is not having any impact.              */
/**********************************************************************************************************************/
/* Message (7:2801)    : Definite: Overflow in signed arithmetic operation.                                           */
/* Rule                : MISRA-C:2012 Dir 4.1                                                                         */
/* JV-01 Justification : This is the buffer pool array used for the entire system of this module.                     */
/*       Verification  : There is no problem because it is an intended design considering the space-time tradeoff,    */
/*                       that is, scalability.                                                                        */
/**********************************************************************************************************************/
/* Message (7:2841)    : Definite: Dereference of an invalid pointer value.                                           */
/* Rule                : MISRA-C:2012 Dir 4.1                                                                         */
/* JV-01 Justification : This is the buffer pool array used for the entire system this module.                        */
/*       Verification  : There is no problem because it is an intended design considering the space-time tradeoff,    */
/*                       that is, scalability.                                                                        */
/**********************************************************************************************************************/

/***********************************************************************************************************************
**                      Global Data                                           **
***********************************************************************************************************************/
#define ETH_START_SEC_CONST_UNSPECIFIED
#include "Eth_MemMap.h"

/* ETNC register structure */
CONSTP2VAR(volatile Eth_ETNCRegType, ETH_CONST, REGSPACE)
  Eth_GaaETNCRegs[ETH_MAX_CTRLS_SUPPORTED] =
{
  (P2VAR(Eth_ETNCRegType, AUTOMATIC, ETH_APPL_DATA)) ETH_CTRL0_BASE_ADDRESS                                             /* PRQA S 0306, 3432 # JV-01, JV-01 */
};

/* EIC register */
CONSTP2VAR(volatile uint16, ETH_CONST, REGSPACE)
  Eth_GaaETNCEICRegs[ETH_MAX_CTRLS_SUPPORTED] =
{
  (P2VAR(uint16, AUTOMATIC, ETH_APPL_DATA)) ETH_CTRL0_EIC_BASE_ADDRESS                                                  /* PRQA S 0306, 3432 # JV-01, JV-01 */
};

#if (ETH_REGISTER_CHECK_INITTIME == STD_ON)
/* Check pattern to check sticking registers */
STATIC CONST(Eth_ETNCCheckRWRegType, ETH_CONST)
  Eth_GaaCSRDataRW[] =                                                                                                  /* PRQA S 3218 # JV-01 */
{
  /* Register offset,            Mask,         All 0 pat,    All 1 pat    */
  { ETH_ETNC_OFFSET_ECMR,     0x001F126FUL, 0x00000000UL, 0x001F126FUL },
  { ETH_ETNC_OFFSET_RFLR,     0x00000FFFUL, 0x00000000UL, 0x00000FFFUL },
  { ETH_ETNC_OFFSET_ECSIPR,   0x00000037UL, 0x00000000UL, 0x00000037UL },
  { ETH_ETNC_OFFSET_RDMLR,    0x000FFFFFUL, 0x00000000UL, 0x000FFFFFUL },
  { ETH_ETNC_OFFSET_IPGR,     0x0000001FUL, 0x00000000UL, 0x0000001FUL },
  { ETH_ETNC_OFFSET_APR,      0x0000FFFFUL, 0x00000000UL, 0x0000FFFFUL },
  { ETH_ETNC_OFFSET_TPAUSER,  0x0000FFFFUL, 0x00000000UL, 0x0000FFFFUL },
  { ETH_ETNC_OFFSET_BCFRR,    0x0000FFFFUL, 0x00000000UL, 0x0000FFFFUL },
  { ETH_ETNC_OFFSET_MAHR,     0xFFFFFFFFUL, 0x00000000UL, 0xFFFFFFFFUL },
  { ETH_ETNC_OFFSET_MALR,     0x0000FFFFUL, 0x00000000UL, 0x0000FFFFUL },
  /* EDMR: The lowest bit (SWR) is write only */
  { ETH_ETNC_OFFSET_EDMR,     0x00000071UL, 0x00000000UL, 0x00000070UL },
  /* TDLAR, RDLAR: The lower 4 bit must be 0 */
  { ETH_ETNC_OFFSET_TDLAR,    0xFFFFFFFFUL, 0x00000000UL, 0xFFFFFFF0UL },
  { ETH_ETNC_OFFSET_RDLAR,    0xFFFFFFFFUL, 0x00000000UL, 0xFFFFFFF0UL },
  { ETH_ETNC_OFFSET_EESIPR,   0x47FF0F9FUL, 0x00000000UL, 0x47FF0F9FUL },
  { ETH_ETNC_OFFSET_TRSCER,   0x00000090UL, 0x00000000UL, 0x00000090UL },
  /* TFTR: Only 0x000~0x200 are allowed, so test with 0x000, 0x1FF, 0x200 */
  { ETH_ETNC_OFFSET_TFTR,     0x000007FFUL, 0x00000000UL, 0x000001FFUL },
  { ETH_ETNC_OFFSET_TFTR,     0x000007FFUL, 0x00000000UL, 0x00000200UL },
  /* FDR: Only 0x0707 is allowed */
  { ETH_ETNC_OFFSET_FDR,      0x00001F1FUL, 0x00000707UL, 0x00000707UL },
  { ETH_ETNC_OFFSET_RMCR,     0x00000001UL, 0x00000000UL, 0x00000001UL },
  { ETH_ETNC_OFFSET_FCFTR,    0x00070007UL, 0x00000000UL, 0x00070007UL },
  { ETH_ETNC_OFFSET_RPADIR,   0x0003003FUL, 0x00000000UL, 0x0003003FUL },
  { ETH_ETNC_OFFSET_TRIMD,    0x00000011UL, 0x00000000UL, 0x00000011UL }
};

/* Reset default values for read only and clear only registers */
STATIC CONST(Eth_ETNCCheckRORegType, ETH_CONST)
  Eth_GaaCSRDataRO[] =                                                                                                  /* PRQA S 3218 # JV-01 */
{
  /* Register offset,            Mask,         Default val  */
  /* ECSR: ICD and LCHNG are out of scope, these can be changed by a PHY-LSI */
  { ETH_ETNC_OFFSET_ECSR,     0x00000032UL, 0x00000000UL },
  { ETH_ETNC_OFFSET_RFCF,     0x000000FFUL, 0x00000000UL },
  { ETH_ETNC_OFFSET_TPAUSECR, 0x000000FFUL, 0x00000000UL },
  { ETH_ETNC_OFFSET_TROCR,    0xFFFFFFFFUL, 0x00000000UL },
  { ETH_ETNC_OFFSET_CDCR,     0xFFFFFFFFUL, 0x00000000UL },
  { ETH_ETNC_OFFSET_LCCR,     0xFFFFFFFFUL, 0x00000000UL },
  { ETH_ETNC_OFFSET_CNDCR,    0xFFFFFFFFUL, 0x00000000UL },
  { ETH_ETNC_OFFSET_CEFCR,    0xFFFFFFFFUL, 0x00000000UL },
  { ETH_ETNC_OFFSET_FRECR,    0xFFFFFFFFUL, 0x00000000UL },
  { ETH_ETNC_OFFSET_TSFRCR,   0xFFFFFFFFUL, 0x00000000UL },
  { ETH_ETNC_OFFSET_TLFRCR,   0xFFFFFFFFUL, 0x00000000UL },
  { ETH_ETNC_OFFSET_RFCR,     0xFFFFFFFFUL, 0x00000000UL },
  { ETH_ETNC_OFFSET_MAFCR,    0xFFFFFFFFUL, 0x00000000UL },
  { ETH_ETNC_OFFSET_EDTRR,    0x00000001UL, 0x00000000UL },
  { ETH_ETNC_OFFSET_EDRRR,    0x00000001UL, 0x00000000UL },
  { ETH_ETNC_OFFSET_EESR,     0x47FF0F9FUL, 0x00000000UL },
  { ETH_ETNC_OFFSET_RMFCR,    0x0000FFFFUL, 0x00000000UL },
  { ETH_ETNC_OFFSET_TFUCR,    0x0000FFFFUL, 0x00000000UL },
  { ETH_ETNC_OFFSET_RFOCR,    0x0000FFFFUL, 0x00000000UL },
  { ETH_ETNC_OFFSET_RBWAR,    0xFFFFFFFFUL, 0x00000000UL },
  { ETH_ETNC_OFFSET_RDFAR,    0xFFFFFFFFUL, 0x00000000UL },
  { ETH_ETNC_OFFSET_TBRAR,    0xFFFFFFFFUL, 0x00000000UL },
  { ETH_ETNC_OFFSET_TDFAR,    0xFFFFFFFFUL, 0x00000000UL }
};
#endif /* (ETH_REGISTER_CHECK_INITTIME == STD_ON) */

#if (ETH_REGISTER_CHECK_RUNTIME == STD_ON)
/* Expected values of registers while the controller is ACTIVE */
STATIC CONST(Eth_ETNCCheckRORegType, ETH_CONST)
  Eth_GaaCBRData[] =                                                                                                    /* PRQA S 3218 # JV-01 */
{
  /* Register offset,           Mask,         Expected val */
  { ETH_ETNC_OFFSET_RFLR,    0x00000FFFUL,
    (uint32)ETH_CTRL_RX_BUF_LEN_BYTE_0 },
  { ETH_ETNC_OFFSET_ECSIPR,  0x00000037UL, 0x00000000UL },
  { ETH_ETNC_OFFSET_RDMLR,   0x000FFFFFUL, 0x00000000UL },
  { ETH_ETNC_OFFSET_IPGR,    0x0000001FUL, ETH_ETNC_IPGR_DEFAULT },
  { ETH_ETNC_OFFSET_BCFRR,   0x0000FFFFUL, 0x00000000UL },
  { ETH_ETNC_OFFSET_EDMR,    0x00000071UL,
    ETH_ETNC_DE_LITTLE | ETH_ETNC_DL_16 },
  { ETH_ETNC_OFFSET_TDLAR,   0xFFFFFFFFUL,
    (uint32)&Eth_GaaTxDescriptor[0] },                                                                                  /* PRQA S 0303 # JV-01 */
  { ETH_ETNC_OFFSET_RDLAR,   0xFFFFFFFFUL,
    (uint32)&Eth_GaaRxDescriptor[0] },                                                                                  /* PRQA S 0303 # JV-01 */
  { ETH_ETNC_OFFSET_EESIPR,  0x47FF0F9FUL,
    0UL
    #if (ETH_CTRL_ENABLE_TX_INTERRUPT == STD_ON)
    | ETH_ETNC_TWB
    #endif
    #if (ETH_CTRL_ENABLE_RX_INTERRUPT == STD_ON)
    | ETH_ETNC_FR
    #endif
  },
  { ETH_ETNC_OFFSET_TRSCER,  0x00000090UL, 0x00000000UL },
  { ETH_ETNC_OFFSET_TFTR,    0x000007FFUL, 0x00000000UL },
  { ETH_ETNC_OFFSET_FDR,     0x00001F1FUL, ETH_ETNC_FDR_DEFAULT },
  { ETH_ETNC_OFFSET_RMCR,    0x00000001UL, ETH_ETNC_RNR },
  { ETH_ETNC_OFFSET_RPADIR,  0x0003003FUL, ETH_ETNC_RPADIR_4BYTE_ALIGN },
  { ETH_ETNC_OFFSET_TRIMD,   0x00000011UL,
    ETH_ETNC_TIM | ETH_ETNC_TIS }
};
#endif /* (ETH_REGITER_CHECK_RUNTIME == STD_ON) */

#define ETH_STOP_SEC_CONST_UNSPECIFIED
#include "Eth_MemMap.h"                                                                                                 /* PRQA S 5087 # JV-01 */


/***********************************************************************************************************************
**                                         Function Definitions                                                       **
***********************************************************************************************************************/
#define ETH_START_SEC_PRIVATE_CODE
#include "Eth_MemMap.h"                                                                                                 /* PRQA S 5087 # JV-01 */

/* Prottypes for register checking functions */
#if (ETH_REGISTER_CHECK_INITTIME == STD_ON)
STATIC FUNC(Std_ReturnType, ETH_PRIVATE_CODE) Eth_HwCheckStuckRegister(
  CONST(uint32, AUTOMATIC) LulCtrlIdx);
#endif

#if (ETH_REGISTER_CHECK_RUNTIME == STD_ON)
STATIC FUNC(void, ETH_PRIVATE_CODE) Eth_HwCheckBrokenRegister(
  CONST(uint32, AUTOMATIC) LulCtrlIdx);
#endif

/***********************************************************************************************************************
** Function Name         : Eth_HwInit (ETNC)
**
** Service ID            : N/A
**
** Description           : Initialize a ETNC HWUnit
**
** Sync/Async            : Synchronous
**
** Reentrancy            : Non Reentrant
**
** Input Parameters      : LulCtrlIdx     : controller index
**
** InOut Parameters      : None
**
** Output Parameters     : None
**
** Return parameter      : None
**
** Preconditions         : None
**
** Global Variable(s)    : Eth_GaaTxDescriptor, Eth_GaaRxDescriptor,
**                         Eth_GaaETNCRegs, Eth_GaaETNCEICRegs
**
** Function(s) invoked   : Eth_HwDisableController,
**                         Eth_HwCheckStuckRegister
**
** Registers Used        : ETNCnTDLAR, ETNCnRDLAR, EIC(INTETNCn)
**
** Reference ID          : ETH_DUD_ACT_154, ETH_DUD_ACT_154_GBL001,
** Reference ID          : ETH_DUD_ACT_154_GBL002, ETH_DUD_ACT_154_REG001
***********************************************************************************************************************/
FUNC(Std_ReturnType, ETH_PRIVATE_CODE) Eth_HwInit(                                                                      /* PRQA S 1532 # JV-01 */
  CONST(uint32, AUTOMATIC) LulCtrlIdx)
{
  Std_ReturnType LucResult;
  LucResult = E_OK;                                                                                                     /* PRQA S 2982 # JV-01 */
  #if (ETH_REGISTER_CHECK_INITTIME == STD_ON)
  /* Reset a controller before the register checking */
  (void)Eth_HwDisableController(LulCtrlIdx);

  /* Check whether registers are not stucked */
  LucResult = Eth_HwCheckStuckRegister(LulCtrlIdx);
  if (E_NOT_OK == LucResult)
  {
    /* Return immediately */
  }
  else
  #endif
  {
    /* Reset a controller */
    (void)Eth_HwDisableController(LulCtrlIdx);

    /* Set descriptor bases */
    Eth_GaaETNCRegs[LulCtrlIdx]->pTDLAR = &Eth_GaaTxDescriptor[0];                                                      /* PRQA S 2844, 2814 # JV-01, JV-01 */
    Eth_GaaETNCRegs[LulCtrlIdx]->pRDLAR = &Eth_GaaRxDescriptor[0];

    /* Open the interrupt mask */
    #if ((ETH_CTRL_ENABLE_TX_INTERRUPT == STD_ON) || (ETH_CTRL_ENABLE_RX_INTERRUPT == STD_ON))
    /* Since EICnEIMK exists in the lower 8 bits, there is no problem casting to uint8. */
    RH850_SV_MODE_ICR_AND(8, Eth_GaaETNCEICRegs[LulCtrlIdx], (uint8)(~ETH_EIC_EIMK_MASK));                              /* PRQA S 2814, 0751, 2844 # JV-01, JV-01, JV-01 */

    RH850_SV_MODE_REG_READ_ONLY(16, Eth_GaaETNCEICRegs[LulCtrlIdx]);
    EXECUTE_SYNCP();
    #endif
  }
  return LucResult;
}

/***********************************************************************************************************************
** Function Name         : Eth_HwDisableController (ETNC)
**
** Service ID            : N/A
**
** Description           : Reset a ETNC HWUnit
**
** Sync/Async            : Synchronous
**
** Reentrancy            : Non Reentrant
**
** Input Parameters      : LulCtrlIdx     : controller index
**
** InOut Parameters      : None
**
** Output Parameters     : None
**
** Return parameter      : None
**
** Preconditions         : None
**
** Global Variable(s)    : Eth_GaaRxDescriptor, Eth_GaaCtrlStat,
**                         Eth_GaaTxDescriptor, Eth_GaaRxBuffer,
**                         Eth_GaaETNCRegs, Eth_GaaDemEventRegisterCorruption
**
** Function(s) invoked   : Eth_DemConfigCheck
**
** Registers Used        : ETNCnEESIPR, ETNCnEDTRR, ETNCnEDMR,
**                         ETNCnRMFCR, ETNCnTFUCR, ETNCnRFOCR
**
** Reference ID          : ETH_DUD_ACT_155, ETH_DUD_ACT_155_ERR001,
** Reference ID          : ETH_DUD_ACT_155_GBL001, ETH_DUD_ACT_155_GBL002,
** Reference ID          : ETH_DUD_ACT_155_GBL003, ETH_DUD_ACT_155_GBL004,
** Reference ID          : ETH_DUD_ACT_155_GBL005, ETH_DUD_ACT_155_GBL006,
** Reference ID          : ETH_DUD_ACT_155_GBL007, ETH_DUD_ACT_155_GBL008,
** Reference ID          : ETH_DUD_ACT_155_GBL009, ETH_DUD_ACT_155_GBL010,
** Reference ID          : ETH_DUD_ACT_155_GBL011, ETH_DUD_ACT_155_GBL012,
** Reference ID          : ETH_DUD_ACT_155_GBL013, ETH_DUD_ACT_155_GBL014,
** Reference ID          : ETH_DUD_ACT_155_GBL015, ETH_DUD_ACT_155_GBL016,
** Reference ID          : ETH_DUD_ACT_155_GBL017, ETH_DUD_ACT_155_GBL018,
** Reference ID          : ETH_DUD_ACT_155_GBL019, ETH_DUD_ACT_155_GBL020,
** Reference ID          : ETH_DUD_ACT_155_GBL021, ETH_DUD_ACT_155_GBL022,
** Reference ID          : ETH_DUD_ACT_155_GBL023, ETH_DUD_ACT_155_GBL024
***********************************************************************************************************************/
FUNC(Std_ReturnType, ETH_PRIVATE_CODE) Eth_HwDisableController(
  CONST(uint32, AUTOMATIC) LulCtrlIdx)
{
  uint32 LulCycle;
  uint32 LulDescIdx;
  uint32 LulTimeoutCount;

  /* If a transmission is on-going, wait the end of it to prevent a garbase
     frame from being output to the ETH bus.
     By contrast, the end of an on-going reception is not waited because
     there is no register which indicates whether a reception is on-going,
     and there is no affection even if a on-going reception is aborted.
     Any Tx, Rx and error from here are never informed to the upper layer. */

  /* Disable all ETH relevant interrupts */
  Eth_GaaETNCRegs[LulCtrlIdx]->ulEESIPR = 0UL;                                                                          /* PRQA S 2844, 2814 # JV-01, JV-01 */
  /* Do dummy read and SYNCP */
  Eth_GaaETNCRegs[LulCtrlIdx]->ulEESIPR;
  EXECUTE_SYNCP();

  /* Clear all TACT bits in Tx Descriptors */
  for (LulDescIdx = 0U; LulDescIdx < (uint32)ETH_TX_BUF_TOTAL_0; LulDescIdx++)
  {
    Eth_GaaTxDescriptor[LulDescIdx].ulTD0 &= ~ETH_ETNC_TACT;
  }

  /* Wait until the on-going transmission finishes.
     Even thought the timeout occurs, any error isn't reported here.
     EDTRR.TR bit will be re-check after the software reset. */
  LulTimeoutCount = 0UL;
  while ((0UL != Eth_GaaETNCRegs[LulCtrlIdx]->ulEDTRR) && (LulTimeoutCount <= ETH_TIMEOUT_COUNT))
  {
    LulTimeoutCount++;
    /* To stabilize the time of a loop, execute SYNCP for each loop */
    EXECUTE_SYNCP();
  }

  /* Perform software reset */
  Eth_GaaETNCRegs[LulCtrlIdx]->ulEDMR = ETH_ETNC_SWR;

  /* Wait at least 64 cycles of peripheral clock after software reset */
  for (LulCycle = 0U; LulCycle < ETH_ETNC_CYCLES_AFTER_RESET; LulCycle++)
  {
    /* Dummy read */
    Eth_GaaETNCRegs[LulCtrlIdx]->ulEDMR;
    /* To stabilize the time of a loop, execute SYNCP for each loop */
    EXECUTE_SYNCP();
  }

  #if (ETH_REGISTER_CHECK_RUNTIME == STD_ON)
  /* If EDTRR.TR bit is stuck after the software reset, raise DEM error */
  if (0UL != Eth_GaaETNCRegs[LulCtrlIdx]->ulEDTRR)
  {
    Eth_DemConfigCheck(Eth_GaaDemEventRegisterCorruption[LulCtrlIdx], DEM_EVENT_STATUS_FAILED);                         /* PRQA S 2844 # JV-01 */
    /* Set already reported flag to prevent the multiple report */
    Eth_GaaCtrlStat[LulCtrlIdx].stHwStat.blErrDetected = ETH_TRUE;                                                      /* PRQA S 2844 # JV-01 */
    Eth_GaaCtrlStat[LulCtrlIdx].stHwStat.blErrReported = ETH_TRUE;                                                      /* PRQA S 2844 # JV-01 */
  }
  else
  #endif
  {
    /* Clear counters which aren't reset automatically by software reset */
    Eth_GaaETNCRegs[LulCtrlIdx]->ulRMFCR = 0UL;
    Eth_GaaETNCRegs[LulCtrlIdx]->ulTFUCR = 0UL;
    Eth_GaaETNCRegs[LulCtrlIdx]->ulRFOCR = 0UL;
    Eth_GaaCtrlStat[LulCtrlIdx].stHwStat.ulPrevRMFCRVal = 0UL;                                                          /* PRQA S 2844 # JV-01 */
    #if (ETH_GET_ETHER_STATS_API == STD_ON)
    Eth_GaaCtrlStat[LulCtrlIdx].stTxRxStat.ulStatsBroadcastPkts = 0UL;                                                  /* PRQA S 2844 # JV-01 */
    #endif

    /* Initialize descriptors */
    for (LulDescIdx = 0U; LulDescIdx < ((uint32)ETH_TX_BUF_TOTAL_0 - 1UL); LulDescIdx++)
    {
      Eth_GaaTxDescriptor[LulDescIdx].ulTD0 = ETH_ETNC_TFP_ALL;
    }
    /* Set TDLE bit of the last descriptor */
    Eth_GaaTxDescriptor[(uint32)ETH_TX_BUF_TOTAL_0 - 1UL].ulTD0 = ETH_ETNC_TDLE | ETH_ETNC_TFP_ALL;

    for (LulDescIdx = 0U; LulDescIdx < (uint32)ETH_RX_BUF_TOTAL_0; LulDescIdx++)
    {
      Eth_GaaRxDescriptor[LulDescIdx].ulRD0 = ETH_ETNC_RACT;
      Eth_GaaRxDescriptor[LulDescIdx].ulRD1 = ETH_ETNC_RBL(ETH_INTERNAL_RX_BUFFER_BYTE) |                               /* PRQA S 3469 # JV-01 */
        /* Set 0xFFFF to RFL field as the workaround */
        ETH_ETNC_RFL_WORKAROUND_VALUE;
      Eth_GaaRxDescriptor[LulDescIdx].pRD2 = &Eth_GaaRxBuffer[LulCtrlIdx][LulDescIdx][0U];                              /* PRQA S 2801, 2841, 2844 # JV-01, JV-01, JV-01 */
    }
    /* Set RDLE bit of the last descriptor */
    Eth_GaaRxDescriptor[(uint32)ETH_RX_BUF_TOTAL_0 - 1UL].ulRD0 = ETH_ETNC_RACT | ETH_ETNC_RDLE;

    /* Initialize descriptor pointers */
    Eth_GaaCtrlStat[LulCtrlIdx].stHwStat.ucRxDescIdxHead = 0U;                                                          /* PRQA S 2844 # JV-01 */
    Eth_GaaCtrlStat[LulCtrlIdx].stHwStat.ucTxDescIdxConfirmed = 0U;                                                     /* PRQA S 2844 # JV-01 */
    Eth_GaaCtrlStat[LulCtrlIdx].stHwStat.ucTxDescIdxRequested = 0U;                                                     /* PRQA S 2844 # JV-01 */
    Eth_GaaCtrlStat[LulCtrlIdx].stHwStat.ucTxDescIdxQueued = 0U;                                                        /* PRQA S 2844 # JV-01 */
    /* Tx is IDLE */
    Eth_GaaCtrlStat[LulCtrlIdx].stHwStat.blTxOngoing = ETH_FALSE;                                                       /* PRQA S 2844 # JV-01 */

    #if (ETH_REGISTER_CHECK_RUNTIME == STD_ON)
    /* Reset the ackup of ECMR register value for the verification */
    Eth_GaaCtrlStat[LulCtrlIdx].stHwStat.ulECMRCopy = 0UL;                                                              /* PRQA S 2844 # JV-01 */
    Eth_GaaCtrlStat[LulCtrlIdx].stHwStat.blErrDetected = ETH_FALSE;                                                     /* PRQA S 2844 # JV-01 */
    Eth_GaaCtrlStat[LulCtrlIdx].stHwStat.blErrReported = ETH_FALSE;                                                     /* PRQA S 2844 # JV-01 */
    #endif
  }
  return E_OK;
}

/***********************************************************************************************************************
** Function Name         : Eth_HwEnableController (ETNC)
**
** Service ID            : N/A
**
** Description           : Activate a ETNC HWUnit
**
** Sync/Async            : Synchronous
**
** Reentrancy            : Non Reentrant
**
** Input Parameters      : LulCtrlIdx     : controller index
**
** InOut Parameters      : None
**
** Output Parameters     : None
**
** Return parameter      : None
**
** Preconditions         : None
**
** Global Variable(s)    : Eth_GaaCtrlStat, Eth_GaaETNCRegs
**
** Function(s) invoked   : None
**
** Registers Used        : ETNCnECMR, ETNCnRFLR, ETNCnECSIPR, ETNCnIPGR,
**                         ETNCnBCFRR, ETNCnMAHR, ETNCnMALR, ETNCnEDMR,
**                         ETNCnEESIPR, ETNCnFDR, ETNCnRPADIR, ETNCnEDRRR
**                         ETNCnTRIMD, ETNCnRMCR
**
** Reference ID          : ETH_DUD_ACT_156, ETH_DUD_ACT_156_GBL001,
** Reference ID          : ETH_DUD_ACT_156_GBL002, ETH_DUD_ACT_156_GBL003,
** Reference ID          : ETH_DUD_ACT_156_GBL004, ETH_DUD_ACT_156_GBL005,
** Reference ID          : ETH_DUD_ACT_156_GBL006, ETH_DUD_ACT_156_GBL007,
** Reference ID          : ETH_DUD_ACT_156_GBL008, ETH_DUD_ACT_156_GBL009,
** Reference ID          : ETH_DUD_ACT_156_GBL010, ETH_DUD_ACT_156_GBL011,
** Reference ID          : ETH_DUD_ACT_156_GBL012, ETH_DUD_ACT_156_GBL013,
** Reference ID          : ETH_DUD_ACT_156_GBL014, ETH_DUD_ACT_156_GBL015,
** Reference ID          : ETH_DUD_ACT_156_GBL016, ETH_DUD_ACT_156_GBL017,
** Reference ID          : ETH_DUD_ACT_156_GBL018, ETH_DUD_ACT_156_GBL019
***********************************************************************************************************************/
FUNC(Std_ReturnType, ETH_PRIVATE_CODE) Eth_HwEnableController(                                                          /* PRQA S 1532 # JV-01 */
  CONST(uint32, AUTOMATIC) LulCtrlIdx)
{
  uint32 LulECMRVal;

  /* Create ECMR register value */
  LulECMRVal = 0UL;
  #if (ETH_UPDATE_PHYS_ADDR_FILTER == STD_ON)
  /* If promiscuos mode is required, set PRM mode */
  if (ETH_TRUE == Eth_GaaCtrlStat[LulCtrlIdx].blPromiscuous)                                                            /* PRQA S 2844 # JV-01 */
  {
    LulECMRVal = ETH_ETNC_PRM;
  }
  else
  {
    /* No action required */
  }
  #endif
  /* Speed: this bit only affects when RMII mode */
  if (ETH_MAC_LAYER_SPEED_100M == Eth_GpEthConfigPtr[LulCtrlIdx].enEthSpeed)
  {
    LulECMRVal |= ETH_ETNC_RTM;
  }
  else
  {
    /* No action required */
  }
  /* Duplex: This bit only affects when RMII mode */
  if (ETH_FULL_DUPLEX == Eth_GpEthConfigPtr[LulCtrlIdx].enEthDuplex)
  {
    LulECMRVal |= ETH_ETNC_DM;
  }
  else
  {
    /* No action required */
  }
  /* InternalLoopBack mode */
  if (ETH_ENABLE == Eth_GpEthConfigPtr[LulCtrlIdx].enInternalLoopBackMode)
  {
    /* DM bit also should be set when loop back mode */
    LulECMRVal |= ETH_ETNC_ILB | ETH_ETNC_DM;
  }
  else
  {
    /* No action required */
  }
  Eth_GaaETNCRegs[LulCtrlIdx]->ulECMR = LulECMRVal;                                                                     /* PRQA S 2844, 2814 # JV-01, JV-01 */
  /* Maximum receive frame length */
  Eth_GaaETNCRegs[LulCtrlIdx]->ulRFLR = (uint32)ETH_CTRL_RX_BUF_LEN_BYTE_0;
  /* Disable special frame detections */
  Eth_GaaETNCRegs[LulCtrlIdx]->ulECSIPR = 0UL;
  /* Inter frame gap, set as default value (96 bits) */
  Eth_GaaETNCRegs[LulCtrlIdx]->ulIPGR = ETH_ETNC_IPGR_DEFAULT;
  /* Continues bradcast frame, no limit */
  Eth_GaaETNCRegs[LulCtrlIdx]->ulBCFRR = 0UL;
  /* MAC address */
  Eth_GaaETNCRegs[LulCtrlIdx]->ulMAHR = Eth_GaaCtrlStat[LulCtrlIdx].stMacAddr.ulH32;
  Eth_GaaETNCRegs[LulCtrlIdx]->ulMALR = Eth_GaaCtrlStat[LulCtrlIdx].stMacAddr.ulL16;
  /* Litle endian, 16 byte descriptor size */
  Eth_GaaETNCRegs[LulCtrlIdx]->ulEDMR = ETH_ETNC_DE_LITTLE | ETH_ETNC_DL_16;
  /* Enable interrupts */
  Eth_GaaETNCRegs[LulCtrlIdx]->ulEESIPR = 0UL
  #if (ETH_CTRL_ENABLE_TX_INTERRUPT == STD_ON)
    | ETH_ETNC_TWB
  #endif
  #if (ETH_CTRL_ENABLE_RX_INTERRUPT == STD_ON)
    | ETH_ETNC_FR
  #endif
    ;
  /* Raise interruption when Tx descriptor writeback completes.
     This settings is also required for polling-mode to activate EESR.TWB */
  Eth_GaaETNCRegs[LulCtrlIdx]->ulTRIMD = ETH_ETNC_TIM | ETH_ETNC_TIS;

  /* FIFO size, fixed as Tx:2048 Rx:1968 */
  Eth_GaaETNCRegs[LulCtrlIdx]->ulFDR = ETH_ETNC_FDR_DEFAULT;
  /* Padding, insert 2 bytes at top of receive buffers */
  Eth_GaaETNCRegs[LulCtrlIdx]->ulRPADIR = ETH_ETNC_RPADIR_4BYTE_ALIGN;
  /* Keep EDRRR.RR bit after a frame reception */
  Eth_GaaETNCRegs[LulCtrlIdx]->ulRMCR = ETH_ETNC_RNR;

  /* Activate Tx and Rx */
  LulECMRVal |= ETH_ETNC_RE | ETH_ETNC_TE;
  Eth_GaaETNCRegs[LulCtrlIdx]->ulECMR = LulECMRVal;

  #if (ETH_REGISTER_CHECK_RUNTIME == STD_ON)
  /* Backup ECMR register value for the verification */
  Eth_GaaCtrlStat[LulCtrlIdx].stHwStat.ulECMRCopy = LulECMRVal;                                                         /* PRQA S 2844 # JV-01 */
  #endif

  /* Synchronize descriptor on memory before invoke HW */
  EXECUTE_SYNCM();

  /* Start reception */
  Eth_GaaETNCRegs[LulCtrlIdx]->ulEDRRR = ETH_ETNC_RR;
  return E_OK;
}

/***********************************************************************************************************************
** Function Name         : Eth_HwTransmit (ETNC)
**
** Service ID            : N/A
**
** Description           : Transmit a frame on the HW.
**                         If the HW is idle, start transmission immediately.
**                         If the HW is busy, the following:
**                         - In interrupt mode, just set a descriptor.
**                         - In polling mode, chain the descriptor.
**
** Sync/Async            : Synchronous
**
** Reentrancy            : Non Reentrant
**
** Input Parameters      : LulCtrlIdx     : controller index
**                         LulBufIdx      : index of a tx buffer
**                         LulLenByte     : byte length of a frame
**                         LblConfiramtion: whether TxConfirmation is required
**
** InOut Parameters      : None
**
** Output Parameters     : None
**
** Return parameter      : None
**
** Preconditions         : None
**
** Global Variable(s)    : Eth_GaaCtrlStat, Eth_GaaTxDescriptor,
**                         Eth_GaaTxBuffer, Eth_GaaETNCRegs
**
** Function(s) invoked   : None
**
** Registers Used        : ETNCnEDTRR
**
** Reference ID          : ETH_DUD_ACT_157, ETH_DUD_ACT_157_CRT001,
** Reference ID          : ETH_DUD_ACT_157_CRT002, ETH_DUD_ACT_157_GBL001,
** Reference ID          : ETH_DUD_ACT_157_GBL002, ETH_DUD_ACT_157_GBL003,
** Reference ID          : ETH_DUD_ACT_157_GBL004, ETH_DUD_ACT_157_GBL005
***********************************************************************************************************************/
FUNC(Std_ReturnType, ETH_PRIVATE_CODE) Eth_HwTransmit(                                                                  /* PRQA S 1532 # JV-01 */
  CONST(uint32, AUTOMATIC) LulCtrlIdx, CONST(uint32, AUTOMATIC) LulBufIdx,
  CONST(uint32, AUTOMATIC) LulLenByte, CONST(boolean, AUTOMATIC) LblConfirmation)
{
  uint32 LulDescIdx;
  P2VAR(volatile Eth_ETNCTxDescriptorType, AUTOMATIC, ETH_VAR_NO_INIT)
    LpDesc;
  Std_ReturnType LucReturnValue;

  LulDescIdx = Eth_GaaCtrlStat[LulCtrlIdx].stHwStat.ucTxDescIdxQueued;                                                  /* PRQA S 2844 # JV-01 */
  LpDesc = &Eth_GaaTxDescriptor[LulDescIdx];                                                                            /* PRQA S 2934 # JV-01 */
  LucReturnValue = E_OK;

  /* Transmit Size: Header + Padding + Payload */
  LpDesc->ulTD1 = ETH_ETNC_TBL((uint32)ETH_HEADER_SIZE + ETH_TXRX_BUFFER_IN_PADDING + LulLenByte);                      /* PRQA S 2844, 3469, 3383 # JV-01, JV-01, JV-01 */
  /* Set the top of a buffer */
  LpDesc->pTD2 = &Eth_GaaTxBuffer[LulBufIdx][ETH_TXRX_BUFFER_PRE_PADDING];                                              /* PRQA S 2844 # JV-01 */

  /* Set additional informations to the descriptor */
  if (ETH_TRUE == LblConfirmation)
  {
    LpDesc->ucAttributes = ETH_ETNC_ATTR_CONFIRMATION;
  }
  else
  {
    LpDesc->ucAttributes = 0U;
  }
  /* Since the maximum value of buffer index is 254, casting to uint8 does no problem. */
  LpDesc->ucBufIdx = (uint8)LulBufIdx;

  /* Increment the descriptor index */
  LulDescIdx = (LulDescIdx + 1UL) % (uint32)ETH_TX_BUF_TOTAL_0;                                                         /* PRQA S 3383 # JV-01 */

  ETH_ENTER_CRITICAL_SECTION(ETH_RAM_DATA_PROTECTION);
  #if (ETH_CTRL_ENABLE_TX_INTERRUPT == STD_ON)
  if (ETH_TRUE == Eth_GaaCtrlStat[LulCtrlIdx].stHwStat.blTxOngoing)                                                     /* PRQA S 2844 # JV-01 */
  {
    /*
     * In interrupt mode, if the hardware is busy,
     * set except TACT and TWBI bits and do not start the transmission
     */
    LpDesc->ulTD0 = (LpDesc->ulTD0 & ETH_ETNC_TDLE) | ETH_ETNC_TFP_ALL;
  }
  else
  #endif
  {
    /*
     * In interrupt mode, if the hardware is idle,
     * set TACT and TWBI bits and start the transmission.
     * In polling mode, even if the hardware is busy, do them.
     */
    Eth_GaaCtrlStat[LulCtrlIdx].stHwStat.blTxOngoing = ETH_TRUE;                                                        /* PRQA S 2844 # JV-01 */
    LpDesc->ulTD0 = (LpDesc->ulTD0 & ETH_ETNC_TDLE) | ETH_ETNC_TACT | ETH_ETNC_TFP_ALL | ETH_ETNC_TWBI;
    EXECUTE_SYNCM();

    #if (ETH_CTRL_ENABLE_TX_POLLING == STD_ON)
    /*
    * In polling mode, wait slightly,
    * considering that TR may be cleared later if the hardware is stopping
    */
    (void)LpDesc->ulTD0;
    EXECUTE_SYNCP();
    #endif
    /* Set TR to start the transmission */
    Eth_GaaETNCRegs[LulCtrlIdx]->ulEDTRR = ETH_ETNC_TR;                                                                 /* PRQA S 2844, 2814 # JV-01, JV-01 */

    #if (ETH_CTRL_ENABLE_TX_POLLING == STD_ON)
    if (0UL == Eth_GaaETNCRegs[LulCtrlIdx]->ulEDTRR)
    {
      /* If TR was cleared by hardware after TR was set, set TR again */
      Eth_GaaETNCRegs[LulCtrlIdx]->ulEDTRR = ETH_ETNC_TR;
    }
    else
    {
      /* No action required */
    }
    #endif

    /* Update the index to the last requested descriptor */
    /* Since the maximum value of descriptor index is 254, casting to uint8 does no problem. */
    Eth_GaaCtrlStat[LulCtrlIdx].stHwStat.ucTxDescIdxRequested = (uint8)LulDescIdx;                                      /* PRQA S 2844 # JV-01 */
  }
  /* Update the descriptor index */
  /* Since the maximum value of descriptor index is 254, casting to uint8 does no problem. */
  Eth_GaaCtrlStat[LulCtrlIdx].stHwStat.ucTxDescIdxQueued = (uint8)LulDescIdx;                                           /* PRQA S 2844 # JV-01 */
  ETH_EXIT_CRITICAL_SECTION(ETH_RAM_DATA_PROTECTION);

  return LucReturnValue;
}

#if (ETH_CTRL_ENABLE_RX_POLLING == STD_ON)
/***********************************************************************************************************************
** Function Name         : Eth_HwReceive (ETNC)
**
** Service ID            : N/A
**
** Description           : Perform Rx ISR handling.
**                         When polling mode:
**                           Receive one frame and indicate it EthIf
**                         When interrupt mode:
**                           Receive all frames and indicate them to EthIf
**
** Sync/Async            : Synchronous
**
** Reentrancy            : Non Reentrant
**
** Input Parameters      : LulCtrlIdx     : controller index
**
** InOut Parameters      : None
**
** Output Parameters     : None
**
** Return parameter      : When polling mode:
**                           ETH_NOT_RECEIVED : there was no received frame
**                           ETH_RECEIVED     : there was one received frame
**                           ETH_RECEIVED_MORE_DATA_AVAILABLE:
**                                 there were more than one received frames
**                         When interrupt mode:
**                           always returns ETH_RECEIVED
**
**                         Note that this function returns RECEIVED even if
**                         a received frame was discarded.
**
** Preconditions         : None
**
** Global Variable(s)    : Eth_GaaCtrlStat, Eth_GaaRxDescriptor,
**                         Eth_GaaETNCRegs
**
** Function(s) invoked   : Eth_RxIndication
**
** Registers Used        : ETNCnEDRRR, ETNCnEESR
**
** Reference ID          : ETH_DUD_ACT_158, ETH_DUD_ACT_158_GBL001,
** Reference ID          : ETH_DUD_ACT_158_GBL002, ETH_DUD_ACT_158_GBL003
***********************************************************************************************************************/
FUNC(Eth_RxStatusType, ETH_PRIVATE_CODE) Eth_HwReceive(                                                                 /* PRQA S 1532 # JV-01 */
  CONST(uint32, AUTOMATIC) LulCtrlIdx
  #if (ETH_AR_VERSION >= ETH_AR_431_VERSION)
  , CONST(uint32, AUTOMATIC) LulFifoIdx
  #endif
)
{
  uint32 LulDescIdx;
  uint32 LulRD0;
  uint32 LulFrameLenByte;
  P2VAR(volatile Eth_ETNCRxDescriptorType, AUTOMATIC, ETH_VAR_NO_INIT)
    LpDesc;
  Eth_RxStatusType LenRetValue;
  #if (ETH_REGISTER_CHECK_RUNTIME == STD_ON)
  uint32 LulResult;
  uint32 LulExpectedRD0;

  /* Initialize the register error check result */
  LulResult = 0UL;
  #endif

  /* Load the global var to the local var to improve performance */
  LulDescIdx = Eth_GaaCtrlStat[LulCtrlIdx].stHwStat.ucRxDescIdxHead;                                                    /* PRQA S 2844 # JV-01 */

  /* Scan received frames */
  LulRD0 = Eth_GaaRxDescriptor[LulDescIdx].ulRD0;                                                                       /* PRQA S 2844 # JV-01 */
  /* When polling mode, scan a received frame */
  if (!((0UL == (LulRD0 & ETH_ETNC_RACT)) &&
    (ETH_ETNC_RFL_WORKAROUND_VALUE != ETH_ETNC_RFL_GET(Eth_GaaRxDescriptor[LulDescIdx].ulRD1))))                        /* PRQA S 3469 # JV-01 */
  {
    LenRetValue = ETH_NOT_RECEIVED;
  }
  else
  {
    LpDesc = &Eth_GaaRxDescriptor[LulDescIdx];                                                                          /* PRQA S 2934 # JV-01 */

    #if (ETH_REGISTER_CHECK_RUNTIME == STD_ON)
    /* Confirm RD0, RDLE has not be changed,
       RACT is cleared, RFP0, RFP1 are set by the HW */
    if (((uint32)ETH_RX_BUF_TOTAL_0 - 1UL) == LulDescIdx)
    {
      LulExpectedRD0 = ETH_ETNC_RDLE | ETH_ETNC_RFP1 | ETH_ETNC_RFP0;
    }
    else
    {
      LulExpectedRD0 = ETH_ETNC_RFP1 | ETH_ETNC_RFP0;
    }
    LulResult |= ((LulExpectedRD0 ^ LpDesc->ulRD0) & ETH_ETNC_RD0_CHECK_MASK);                                          /* PRQA S 2844 # JV-01 */
    #endif /* (ETH_REGISTER_CHECK_RUNTIME == STD_ON) */

    /* When the following error occurs, discard this frame:
       - CRC error
       - PHY-LSI receive error
       - Too long frame received
       - Too short frame received
       - Receive abort
       - Rx FIFO overflow
       The AUTOSAR only requires to discard a frame when CRC error occurs.
       However rx data is not available when the above errors occur,
       discard it also the above case. */
    if (0UL != (LulRD0 &
      (ETH_ETNC_RFS9_RFOF | ETH_ETNC_RFS8_RABT | ETH_ETNC_RFS3_RTLF |
        ETH_ETNC_RFS2_RTSF | ETH_ETNC_RFS1_PRE | ETH_ETNC_RFS0_CERF)))
    {
      /* If any error occurred, discard this frame */
    }
    else if ((0UL != (LulRD0 & ETH_ETNC_RFS7_RMAF))
    #if (ETH_UPDATE_PHYS_ADDR_FILTER == STD_ON)
      && (0UL == Eth_GaaCtrlStat[LulCtrlIdx].ulActiveFilterBits)
      && (ETH_FALSE == Eth_GaaCtrlStat[LulCtrlIdx].blPromiscuous)
    #endif
      )
    {
      /* Discard multicast frames when the filtering is off */
    }
    else
    {
      /* Indicate a frame to EthIf */
      LulFrameLenByte = ETH_ETNC_RFL_GET(LpDesc->ulRD1);                                                                /* PRQA S 3469 # JV-01 */
      /* The 2nd parameter is BufferIdx, it is same as DescIdx on Rx side */
      Eth_RxIndication(LulCtrlIdx, LulDescIdx, LulFrameLenByte);
    }
    /* Set 0xFFFF to RFL field as the workaround */
    LpDesc->ulRD1 = ETH_ETNC_RBL(ETH_INTERNAL_RX_BUFFER_BYTE) | ETH_ETNC_RFL_WORKAROUND_VALUE;                          /* PRQA S 3469 # JV-01 */
    /* Set RACT bit to mark this descriptor is empty */
    LpDesc->ulRD0 = (LpDesc->ulRD0 & ~ETH_ETNC_RFS_MASK) | ETH_ETNC_RACT;
    /* Increment the ring pointer */
    LulDescIdx = (LulDescIdx + 1UL) % (uint32)ETH_RX_BUF_TOTAL_0;                                                       /* PRQA S 3383 # JV-01 */
    /* Load RD0 of the next descriptor */
    LulRD0 = Eth_GaaRxDescriptor[LulDescIdx].ulRD0;
    /* When polling mode, check whether there is another available frame */
    if (0UL != (LulRD0 & ETH_ETNC_RACT))
    {
      /* There is no more received frame */
      LenRetValue = ETH_RECEIVED;
    }
    else
    {
      /* There are more received frames */
      LenRetValue = ETH_RECEIVED_MORE_DATA_AVAILABLE;
    }
  }

  /* Update the global var */
  /* Since the maximum value of descriptor index is 254, casting to uint8 does no problem. */
  Eth_GaaCtrlStat[LulCtrlIdx].stHwStat.ucRxDescIdxHead = (uint8)LulDescIdx;                                             /* PRQA S 2844 # JV-01 */

  /* If descriptor overflow has been occurred, the receive operation is stopped.
     Set RR bit hear in case of such case. */
  Eth_GaaETNCRegs[LulCtrlIdx]->ulEDRRR = ETH_ETNC_RR;                                                                   /* PRQA S 2844, 2814 # JV-01, JV-01 */


  #if (ETH_REGISTER_CHECK_RUNTIME == STD_ON)
  /* If any object didn't have expected values, set the error flag */
  if (0UL != LulResult)
  {
    /* Set the flag, DEM error will be reported at the next MainFunction */
    Eth_GaaCtrlStat[LulCtrlIdx].stHwStat.blErrDetected = ETH_TRUE;                                                      /* PRQA S 2844 # JV-01 */
  }
  else
  {
    /* No action required */
  }
  #endif /* (ETH_REGISTER_CHECK_RUNTIME == STD_ON) */

  return LenRetValue;
}
#endif /* (ETH_CTRL_ENABLE_RX_POLLING == STD_ON) */

#if (ETH_CTRL_ENABLE_TX_POLLING == STD_ON)
/***********************************************************************************************************************
** Function Name         : Eth_HwTxConfirmation (ETNC)
**
** Service ID            : N/A
**
** Description           : Perform Tx ISR handling.
**                         Check completed frame and indicate TxConfirmation if
**                         necessary.
**                         - In interrupt mode
**                           Initiate a transmission of the next one frame if
**                           exists.
**                         - In polling mode
**                           Initiate a transmission of the last frame if not
**                           sent.
**
** Sync/Async            : Synchronous
**
** Reentrancy            : Non Reentrant
**
** Input Parameters      : LulCtrlIdx     : controller index
**
** InOut Parameters      : None
**
** Output Parameters     : None
**
** Return parameter      : None
**
** Preconditions         : None
**
** Global Variable(s)    : Eth_GaaCtrlStat, Eth_GaaTxDescriptor,
**                         Eth_GaaETNCRegs
**
** Function(s) invoked   : EthIf_TxConfirmation, Eth_ReleaseTxBuffer
**
** Registers Used        : ETNCnEDTRR, ETNCnEESR
**
** Reference ID          : ETH_DUD_ACT_159, ETH_DUD_ACT_159_CRT001,
** Reference ID          : ETH_DUD_ACT_159_CRT002, ETH_DUD_ACT_159_GBL001,
** Reference ID          : ETH_DUD_ACT_159_GBL002, ETH_DUD_ACT_159_GBL003,
** Reference ID          : ETH_DUD_ACT_159_GBL004
***********************************************************************************************************************/
FUNC(void, ETH_PRIVATE_CODE) Eth_HwTxConfirmation(                                                                      /* PRQA S 1532 # JV-01 */
  CONST(uint32, AUTOMATIC) LulCtrlIdx)
{
  uint32 LulDescIdx;
  uint32 LulBufIdx;
  uint32 LulDescIdxCompleted;
  boolean LblNoNeedConfirm;
  #if (ETH_REGISTER_CHECK_RUNTIME == STD_ON)
  uint32 LulResult;
  uint32 LulExpectedTD0;
  /* Initialize the register error check result (Error flag) */
  LulResult = 0UL;
  #endif
  if (ETH_FALSE == Eth_GaaCtrlStat[LulCtrlIdx].stHwStat.blTxOngoing)                                                    /* PRQA S 2844 # JV-01 */
  {
    /* Nothing to do while the transmission is not started. */
  }
  else
  {
    /* Critical section to exclusive control between Eth_HwTransmit */
    ETH_ENTER_CRITICAL_SECTION(ETH_RAM_DATA_PROTECTION);

    /* All descriptors requested in the previous call should be completed */
    LulDescIdxCompleted = Eth_GaaCtrlStat[LulCtrlIdx].stHwStat.ucTxDescIdxRequested;                                    /* PRQA S 2844 # JV-01 */
    if (0UL != Eth_GaaETNCRegs[LulCtrlIdx]->ulEDTRR)                                                                    /* PRQA S 2844, 2814 # JV-01, JV-01 */
    {
      /* Do not release the last requested buffer during transmission. */
      LulDescIdxCompleted = (LulDescIdxCompleted + ((uint32)ETH_TX_BUF_TOTAL_0 - 1UL))                                  /* PRQA S 3383 # JV-01 */
        % (uint32)ETH_TX_BUF_TOTAL_0;
    }
    else
    {
      /* Check the TACT of the last requested descriptor */
      LulDescIdx = (LulDescIdxCompleted + ((uint32)ETH_TX_BUF_TOTAL_0 - 1UL)) % (uint32)ETH_TX_BUF_TOTAL_0;             /* PRQA S 3383 # JV-01 */
      if (0UL != (Eth_GaaTxDescriptor[LulDescIdx].ulTD0 & ETH_ETNC_TACT))
      {
        /*
         * If the last requested descriptor is TACT = 1, it stays not sent.
         * Therefore, revert the index to indicate it, and re-start hardware.
         */
        LulDescIdxCompleted = LulDescIdx;
        Eth_GaaETNCRegs[LulCtrlIdx]->ulEDTRR = ETH_ETNC_TR;
      }
      else
      {
        /* If there is no pending frame, clear the ongoing flag */
        Eth_GaaCtrlStat[LulCtrlIdx].stHwStat.blTxOngoing = ETH_FALSE;                                                   /* PRQA S 2844 # JV-01 */
      }
    }

    /* Perform TxConfirmation for completed descriptors */
    LulDescIdx = Eth_GaaCtrlStat[LulCtrlIdx].stHwStat.ucTxDescIdxConfirmed;                                             /* PRQA S 2844 # JV-01 */
    /* Do not release the last requested buffer during transmission. */
    if ((LulDescIdxCompleted == LulDescIdx) && (ETH_TRUE == Eth_GaaCtrlStat[LulCtrlIdx].stHwStat.blTxOngoing))
    {
      LblNoNeedConfirm = ETH_TRUE;
    }
    else
    {
      LblNoNeedConfirm = ETH_FALSE;
    }
    ETH_EXIT_CRITICAL_SECTION(ETH_RAM_DATA_PROTECTION);
    do
    {
      if ((ETH_TRUE == LblNoNeedConfirm) || (0UL != (Eth_GaaTxDescriptor[LulDescIdx].ulTD0 & ETH_ETNC_TACT)))           /* PRQA S 2844 # JV-01 */
      {
        /* Exit the loop if the descriptor is not TACT=0. */
        LulDescIdxCompleted = LulDescIdx;
      }
      else
      {
        #if (ETH_REGISTER_CHECK_RUNTIME == STD_ON)
        /* Confirm TxDescriptor has not been corrupted */
        if ((uint32)(ETH_TX_BUF_TOTAL_0 - 1UL) == LulDescIdx)
        {
          LulExpectedTD0 = ETH_ETNC_TDLE | ETH_ETNC_TFP_ALL;
        }
        else
        {
          LulExpectedTD0 = ETH_ETNC_TFP_ALL;
        }
        LulResult |= ((LulExpectedTD0 ^ Eth_GaaTxDescriptor[LulDescIdx].ulTD0) & ETH_ETNC_TD0_CHECK_MASK);
        #endif /* (ETH_REGISTER_CHECK_RUNTIME == STD_ON) */

        LulBufIdx = Eth_GaaTxDescriptor[LulDescIdx].ucBufIdx;
        /*
         * If this buffer was requested with TxConfirmation=true,
         * inform EthIf
         */
        if (0U != (Eth_GaaTxDescriptor[LulDescIdx].ucAttributes & ETH_ETNC_ATTR_CONFIRMATION))
        {
          /* Since the maximum value of controller index is 0, casting to uint8 does no problem. */
          EthIf_TxConfirmation((uint8)LulCtrlIdx, (Eth_BufIdxType)LulBufIdx);
        }
        else
        {
          /* No action required */
        }

        /* Release tx buffer */
        Eth_ReleaseTxBuffer(LulCtrlIdx, LulBufIdx);

        /* Increment the descriptor index */
        LulDescIdx = (LulDescIdx + 1UL) % (uint32)ETH_TX_BUF_TOTAL_0;                                                   /* PRQA S 3383 # JV-01 */
      }
    } while (LulDescIdx != LulDescIdxCompleted);
    /* Update the descriptor index */
    /* Since the maximum value of descriptor index is 254, casting to uint8 does no problem. */
    Eth_GaaCtrlStat[LulCtrlIdx].stHwStat.ucTxDescIdxConfirmed = (uint8)LulDescIdx;                                      /* PRQA S 2844 # JV-01 */

    #if (ETH_REGISTER_CHECK_RUNTIME == STD_ON)
    /* If any object didn't have expected valuds, raise the error flag */
    if (0UL != LulResult)
    {
      /* Set the flag, DEM error will be reported at the next MainFunction */
      Eth_GaaCtrlStat[LulCtrlIdx].stHwStat.blErrDetected = ETH_TRUE;                                                    /* PRQA S 2844 # JV-01 */
    }
    else
    {
      /* No action required */
    }
    #endif /* (ETH_REGISTER_CHECK_RUNTIME == STD_ON) */
  }
}
#endif /* (ETH_CTRL_ENABLE_TX_POLLING == STD_ON) */

#if (ETH_CTRL_ENABLE_MII == STD_ON)
/***********************************************************************************************************************
** Function Name         : Eth_HwReadMiiBit (ETNC)
**
** Service ID            : N/A
**
** Description           : Read one bit from the PHY management interface
**
** Sync/Async            : Synchronous
**
** Reentrancy            : Non Reentrant
**
** Input Parameters      : LulCtrlIdx     : controller index
**
** InOut Parameters      : None
**
** Output Parameters     : None
**
** Return parameter      : Result bit (0 or 1)
**
** Preconditions         : None
**
** Global Variable(s)    : Eth_GaaETNCRegs
**
** Function(s) invoked   : None
**
** Registers Used        : ETNCnPIR
**
** Reference ID          : ETH_DUD_ACT_160, ETH_DUD_ACT_160_GBL001,
** Reference ID          : ETH_DUD_ACT_160_GBL002
***********************************************************************************************************************/
FUNC(uint32, ETH_PRIVATE_CODE) Eth_HwReadMiiBit(                                                                        /* PRQA S 1532 # JV-01 */
  CONST(uint32, AUTOMATIC) LulCtrlIdx)
{
  uint32 LulBit;

  /* Acquire data at a rising edge of MDC */
  LulBit = ETH_ETNC_GET_MDI(Eth_GaaETNCRegs[LulCtrlIdx]->ulPIR);                                                        /* PRQA S 2814, 2844, 3469 # JV-01, JV-01, JV-01 */
  Eth_GaaETNCRegs[LulCtrlIdx]->ulPIR = ETH_ETNC_MDC;
  Eth_GaaETNCRegs[LulCtrlIdx]->ulPIR = 0UL;

  return LulBit;
}

/***********************************************************************************************************************
** Function Name         : Eth_HwWriteMiiBit (ETNC)
**
** Service ID            : N/A
**
** Description           : Write one bit to the PHY management interface
**
** Sync/Async            : Synchronous
**
** Reentrancy            : Non Reentrant
**
** Input Parameters      : LulCtrlIdx     : controller index
**                         LulBit         : a bit to be written (0 or 1)
**
** InOut Parameters      : None
**
** Output Parameters     : None
**
** Return parameter      : None
**
** Preconditions         : None
**
** Global Variable(s)    : Eth_GaaETNCRegs
**
** Function(s) invoked   : None
**
** Registers Used        : ETNCnPIR
**
** Reference ID          : ETH_DUD_ACT_161, ETH_DUD_ACT_161_GBL001,
** Reference ID          : ETH_DUD_ACT_161_GBL002, ETH_DUD_ACT_161_GBL003
***********************************************************************************************************************/
FUNC(void, ETH_PRIVATE_CODE) Eth_HwWriteMiiBit(                                                                         /* PRQA S 1532 # JV-01 */
  CONST(uint32, AUTOMATIC) LulCtrlIdx, CONST(uint32, AUTOMATIC) LulBit)
{
  CONST(uint32, AUTOMATIC) LulMDO = ETH_ETNC_MMD | (ETH_ETNC_MDO * LulBit);                                             /* PRQA S 3383 # JV-01 */

  Eth_GaaETNCRegs[LulCtrlIdx]->ulPIR = LulMDO;                                                                          /* PRQA S 2844, 2814 # JV-01, JV-01 */
  Eth_GaaETNCRegs[LulCtrlIdx]->ulPIR = LulMDO | ETH_ETNC_MDC;
  Eth_GaaETNCRegs[LulCtrlIdx]->ulPIR = LulMDO;
}
#endif /* (ETH_CTRL_ENABLE_MII == STD_ON) */

#if (ETH_GET_DROP_COUNT_API == STD_ON)
/***********************************************************************************************************************
** Function Name         : Eth_HwGetDropCount (ETNC)
**
** Service ID            : N/A
**
** Description           : Get drop frame counts for each error factor
**
** Sync/Async            : Synchronous
**
** Reentrancy            : Non Reentrant
**
** Input Parameters      : LulCtrlIdx     : controller index
**                         LulCountValue  : length of LpDropCount
**
** InOut Parameters      : None
**
** Output Parameters     : LpDropCount    : destination buffer
**
** Return parameter      : None
**
** Preconditions         : None
**
** Global Variable(s)    : Eth_GaaETNCRegs
**
** Function(s) invoked   : None
**
** Registers Used        : ETNCnCEFCR, ETNCnTSFRCR, ETNCnTLFRCR, ETNCnRFCR,
**                         ETNCnCDCR
**
** Reference ID          : ETH_DUD_ACT_162
***********************************************************************************************************************/
FUNC(void, ETH_PRIVATE_CODE) Eth_HwGetDropCount(                                                                        /* PRQA S 1532 # JV-01 */
  CONST(uint32, AUTOMATIC) LulCtrlIdx, CONST(uint32, AUTOMATIC) LulCountValues,
  CONSTP2VAR(uint32, AUTOMATIC, ETH_APPL_DATA) LpDropCount)                                                             /* PRQA S 3432 # JV-01 */
{
  uint32 LulIdx;
  uint32 LulVal;

  for (LulIdx = 0U; LulIdx < LulCountValues; LulIdx++)
  {
    switch (LulIdx)
    {
    case (uint32)ETH_DROP_CRC_ERR:
      LulVal = Eth_GaaETNCRegs[LulCtrlIdx]->ulCEFCR;                                                                    /* PRQA S 2844, 2814 # JV-01, JV-01 */
      break;

    case (uint32)ETH_DROP_UNDERSIZE:
      LulVal = Eth_GaaETNCRegs[LulCtrlIdx]->ulTSFRCR;
      break;

    case (uint32)ETH_DROP_OVERSIZE:
      LulVal = Eth_GaaETNCRegs[LulCtrlIdx]->ulTLFRCR;
      break;

    case (uint32)ETH_DROP_ALIGNMENT_ERR:
      LulVal = Eth_GaaETNCRegs[LulCtrlIdx]->ulRFCR;
      break;

    case (uint32)ETH_DROP_LATE_COLLISION:
      LulVal = Eth_GaaETNCRegs[LulCtrlIdx]->ulCDCR;
      break;

    default:
      /* Not Available on HW */
      LulVal = ETH_NOT_AVAILABLE;
      break;
    }
    LpDropCount[LulIdx] = LulVal;                                                                                       /* PRQA S 2824 # JV-01 */
  }
}
#endif /* (ETH_GET_DROP_COUNT_API == STD_ON) */

#if (ETH_GET_ETHER_STATS_API == STD_ON)
/***********************************************************************************************************************
** Function Name         : Eth_HwGetEtherStats (ETNC)
**
** Service ID            : N/A
**
** Description           : Get error statuses
**
** Sync/Async            : Synchronous
**
** Reentrancy            : Non Reentrant
**
** Input Parameters      : LulCtrlIdx     : controller index
**
** InOut Parameters      : None
**
** Output Parameters     : LpEtherStats   : destination buffer
**
** Return parameter      : None
**
** Preconditions         : None
**
** Global Variable(s)    : Eth_GaaCtrlStat, Eth_GaaETNCRegs
**
** Function(s) invoked   : None
**
** Registers Used        : ETNCnRMFCR, ETNCnMAFCR, ETNCnTSFRCR, ETNCnTLFRCR,
**                         ETNCnCDCR, ETNCnCEFCR, ETNCnRFCR
**
** Reference ID          : ETH_DUD_ACT_163
***********************************************************************************************************************/
FUNC(void, ETH_PRIVATE_CODE) Eth_HwGetEtherStats(                                                                       /* PRQA S 1532 # JV-01 */
  CONST(uint32, AUTOMATIC) LulCtrlIdx,
  CONSTP2VAR(uint32, AUTOMATIC, ETH_APPL_DATA) LpEtherStats)                                                            /* PRQA S 3432 # JV-01 */
{
  uint32 LulIdx;
  uint32 LulVal;
  uint32 LulCrcCount;
  uint32 LulAlignCount;

  for (LulIdx = 0U; LulIdx < (uint32)ETH_STATS_MAX_VALUE; LulIdx++)
  {
    switch (LulIdx)
    {
    case (uint32)ETH_STATS_DROP_EVENTS:
      LulVal = Eth_GaaETNCRegs[LulCtrlIdx]->ulRMFCR;                                                                    /* PRQA S 2844, 2814 # JV-01, JV-01 */
      break;

    case (uint32)ETH_STATS_BROADCAST_PKTS:
      LulVal = Eth_GaaCtrlStat[LulCtrlIdx].stTxRxStat.ulStatsBroadcastPkts;                                             /* PRQA S 2844 # JV-01 */
      break;

    case (uint32)ETH_STATS_MULTICAST_PKTS:
      LulVal = Eth_GaaETNCRegs[LulCtrlIdx]->ulMAFCR;
      break;

    case (uint32)ETH_STATS_CRC_ALIGN_ERRORS:
      LulCrcCount = Eth_GaaETNCRegs[LulCtrlIdx]->ulCEFCR;
      LulAlignCount = Eth_GaaETNCRegs[LulCtrlIdx]->ulRFCR;
      LulVal = LulCrcCount + LulAlignCount;                                                                             /* PRQA S 2912 # JV-01 */
      /* If overflow occurred in the addition, saturate it with 0xFFFFFFFF */
      if (LulVal < LulCrcCount)
      {
        LulVal = ETH_NOT_AVAILABLE;
      }
      else
      {
        /* No action required */
      }
      break;

    case (uint32)ETH_STATS_UNDERSIZE_PKTS:
      LulVal = Eth_GaaETNCRegs[LulCtrlIdx]->ulTSFRCR;
      break;

    case (uint32)ETH_STATS_OVERSIZE_PKTS:
      LulVal = Eth_GaaETNCRegs[LulCtrlIdx]->ulTLFRCR;
      break;

    case (uint32)ETH_STATS_COLLISIONS:
      LulVal = Eth_GaaETNCRegs[LulCtrlIdx]->ulCDCR;
      break;

    default:
      /* Not Available on HW */
      LulVal = ETH_NOT_AVAILABLE;
      break;
    }
    LpEtherStats[LulIdx] = LulVal;                                                                                      /* PRQA S 2824 # JV-01 */
  }
}
#endif /* (ETH_GET_ETHER_STATS_API == STD_ON) */

/***********************************************************************************************************************
** Function Name         : Eth_HwMainFunction (ETNC)
**
** Service ID            : N/A
**
** Description           : Check receive errors and report DEM if exist
**
** Sync/Async            : Synchronous
**
** Reentrancy            : Non Reentrant
**
** Input Parameters      : None
**
** InOut Parameters      : None
**
** Output Parameters     : None
**
** Return parameter      : None
**
** Preconditions         : None
**
** Global Variable(s)    : Eth_GaaCtrlStat, Eth_GaaETNCRegs,
**                         Eth_GaaDemEventCRC, Eth_GaaDemEventAlignment,
**                         Eth_GaaDemEventLatecollision, Eth_GaaDemEventOverSizeFrame,
**                         Eth_GaaDemEventUnderSizeFrame, Eth_GaaDemEventRxFramesLost,
**                         Eth_GaaDemEventDmaError
**
** Function(s) invoked   : Eth_DemConfigCheck, Eth_HwCheckBrokenRegister
**
** Registers Used        : ETNCnEESR, ETNCnRMFCR
**
** Reference ID          : ETH_DUD_ACT_164, ETH_DUD_ACT_164_ERR001,
** Reference ID          : ETH_DUD_ACT_164_ERR002, ETH_DUD_ACT_164_ERR003,
** Reference ID          : ETH_DUD_ACT_164_ERR004, ETH_DUD_ACT_164_ERR005,
** Reference ID          : ETH_DUD_ACT_164_ERR006, ETH_DUD_ACT_164_ERR007,
** Reference ID          : ETH_DUD_ACT_164_GBL001, ETH_DUD_ACT_164_GBL002,
** Reference ID          : ETH_DUD_ACT_164_GBL003, ETH_DUD_ACT_164_GBL004,
** Reference ID          : ETH_DUD_ACT_164_GBL005, ETH_DUD_ACT_164_GBL006,
** Reference ID          : ETH_DUD_ACT_164_GBL007
***********************************************************************************************************************/
FUNC(void, ETH_PRIVATE_CODE) Eth_HwMainFunction(void)                                                                   /* PRQA S 1532 # JV-01 */
{
  uint32 LulEESRVal;
  uint32 LulRMFCRVal;
  /* Only support single channel */
  CONST(uint32, AUTOMATIC) LulCtrlIdx = 0U;

  /* If this function is invoked during the state transition,
     the resigiter corruption check will raise error.
     To avoid it, skip this function while the Contrller is DOWN. */
  if (ETH_MODE_ACTIVE != Eth_GaaCtrlStat[LulCtrlIdx].enMode)
  {
    /* Nothing to do when the controller is DOWN */
  }
  else
  {
    LulEESRVal = Eth_GaaETNCRegs[LulCtrlIdx]->ulEESR;                                                                   /* PRQA S 2814 # JV-01 */

    /* CRC error */
    if (0UL != (LulEESRVal & ETH_ETNC_CERF))
    {
      Eth_GaaETNCRegs[LulCtrlIdx]->ulEESR = ETH_ETNC_CERF;
      Eth_DemConfigCheck(Eth_GaaDemEventCRC[LulCtrlIdx], DEM_EVENT_STATUS_PREFAILED);
    }
    else
    {
      /* No action required */
    }

    /* Alignment error */
    if (0UL != (LulEESRVal & ETH_ETNC_RRF))
    {
      Eth_GaaETNCRegs[LulCtrlIdx]->ulEESR = ETH_ETNC_RRF;
      Eth_DemConfigCheck(Eth_GaaDemEventAlignment[LulCtrlIdx], DEM_EVENT_STATUS_PREFAILED);
    }
    else
    {
      /* No action required */
    }

    /* Late Collision */
    if (0UL != (LulEESRVal & ETH_ETNC_CD))
    {
      Eth_GaaETNCRegs[LulCtrlIdx]->ulEESR = ETH_ETNC_CD;
      Eth_DemConfigCheck(Eth_GaaDemEventLatecollision[LulCtrlIdx], DEM_EVENT_STATUS_PREFAILED);
    }
    else
    {
      /* No action required */
    }

    /* Multiple Collision is not supported */

    /* Oversize Frame */
    if (0UL != (LulEESRVal & ETH_ETNC_RTLF))
    {
      Eth_GaaETNCRegs[LulCtrlIdx]->ulEESR = ETH_ETNC_RTLF;
      Eth_DemConfigCheck(Eth_GaaDemEventOverSizeFrame[LulCtrlIdx], DEM_EVENT_STATUS_PREFAILED);
    }
    else
    {
      /* No action required */
    }

    /* Single Collision is not supported */

    /* Undersize Frame */
    if (0UL != (LulEESRVal & ETH_ETNC_RTSF))
    {
      Eth_GaaETNCRegs[LulCtrlIdx]->ulEESR = ETH_ETNC_RTSF;
      Eth_DemConfigCheck(Eth_GaaDemEventUnderSizeFrame[LulCtrlIdx], DEM_EVENT_STATUS_PREFAILED);
    }
    else
    {
      /* No action required */
    }

    /* Frame Lost */
    /* Report DEM only if the counter was raised from the previous call */
    LulRMFCRVal = Eth_GaaETNCRegs[LulCtrlIdx]->ulRMFCR;
    if (LulRMFCRVal > Eth_GaaCtrlStat[LulCtrlIdx].stHwStat.ulPrevRMFCRVal)
    {
      Eth_GaaCtrlStat[LulCtrlIdx].stHwStat.ulPrevRMFCRVal = LulRMFCRVal;
      Eth_DemConfigCheck(Eth_GaaDemEventRxFramesLost[LulCtrlIdx], DEM_EVENT_STATUS_PREFAILED);
    }
    else
    {
      /* No action required */
    }

    /* Check DMA relevant errors.
       These errors mean there is something wrong on the system design or
       a critical malfunction occurred on the DMA or the bus. */
    if (0UL != (LulEESRVal & (ETH_ETNC_ADE | ETH_ETNC_RFCOF)))
    {
      Eth_GaaETNCRegs[LulCtrlIdx]->ulEESR = ETH_ETNC_ADE | ETH_ETNC_RFCOF;
      Eth_DemConfigCheck(Eth_GaaDemEventDmaError[LulCtrlIdx], DEM_EVENT_STATUS_FAILED);
    }
    else
    {
      /* No action required */
    }

    #if (ETH_REGISTER_CHECK_RUNTIME == STD_ON)
    /* Verify whether registers are not corrupted */
    Eth_HwCheckBrokenRegister(LulCtrlIdx);
    #endif
  }
}

#if (ETH_REGISTER_CHECK_INITTIME == STD_ON)
/***********************************************************************************************************************
** Function Name         : Eth_HwCheckStuckRegister (ETNC)
**
** Service ID            : N/A
**
** Description           : Check whether relevant registers can be written
**
** Sync/Async            : Synchronous
**
** Reentrancy            : Non Reentrant
**
** Input Parameters      : LulCtrlIdx     : controller index
**
** InOut Parameters      : None
**
** Output Parameters     : None
**
** Return parameter      : Std_ReturnType
**                         E_OK: No error was detected.
**                         E_NOT_OK: Any of errors were detected.
**
** Preconditions         : Controller must be DOWN and the state never changed
**                         during this function.
**
** Global Variable(s)    : Eth_GaaCSRDataRW, Eth_GaaETNCRegs,
**                         Eth_GaaCSRDataRO, Eth_GaaDemEventRegisterCorruption
**
** Function(s) invoked   : Eth_DemConfigCheck
**
** Registers Used        : See Eth_GaaCSRDataRW and Eth_GaaCSRDataRO
**
** Reference ID          : ETH_DUD_ACT_165,
** Reference ID          : ETH_DUD_ACT_165_ERR001
***********************************************************************************************************************/
STATIC FUNC(Std_ReturnType, ETH_PRIVATE_CODE) Eth_HwCheckStuckRegister(
  CONST(uint32, AUTOMATIC) LulCtrlIdx)
{
  Std_ReturnType LucResult;
  uint32 LulIndex;
  uint32 LulResult;
  P2VAR(volatile uint32, AUTOMATIC, REGSPACE) LpReg;

  /* Intialize the register error check result */
  LulResult = 0UL;

  /* Confirm R/W registers can be written with arbitrary value */
  for (LulIndex = 0UL;
    LulIndex <
      (uint32)(sizeof(Eth_GaaCSRDataRW) / sizeof(Eth_ETNCCheckRWRegType));
    LulIndex++)
  {
    LpReg = &Eth_GaaETNCRegs[LulCtrlIdx]->ulEDMR + (Eth_GaaCSRDataRW[LulIndex].ulOffset / (uint32)sizeof(uint32));      /* PRQA S 2844, 2814, 0488 # JV-01, JV-01, JV-01 */

    /* Write test pattern 1 */
    *LpReg = Eth_GaaCSRDataRW[LulIndex].ulWritePattern1;                                                                /* PRQA S 2814 # JV-01 */
    /* Accumulate the diff between the result and the expected value */
    LulResult |= ((*LpReg ^ Eth_GaaCSRDataRW[LulIndex].ulWritePattern1) & Eth_GaaCSRDataRW[LulIndex].ulMaskValue);
    /* Write test pattern 0 */
    *LpReg = Eth_GaaCSRDataRW[LulIndex].ulWritePattern0;
    /* Accumulate the diff between the result and the expected value */
    LulResult |= ((*LpReg ^ Eth_GaaCSRDataRW[LulIndex].ulWritePattern0) & Eth_GaaCSRDataRW[LulIndex].ulMaskValue);
  }

  /* Confirm Read-Only and Clear-Only regiters have the default value */
  for (LulIndex = 0UL; LulIndex < (uint32)(sizeof(Eth_GaaCSRDataRO) / sizeof(Eth_ETNCCheckRORegType)); LulIndex++)
  {
    LpReg = &Eth_GaaETNCRegs[LulCtrlIdx]->ulEDMR + (Eth_GaaCSRDataRO[LulIndex].ulOffset / (uint32)sizeof(uint32));      /* PRQA S 0488 # JV-01 */

    /* Accumulate the diff between the result and the expected value */
    LulResult |= ((*LpReg ^ Eth_GaaCSRDataRO[LulIndex].ulExpectedValue) & Eth_GaaCSRDataRO[LulIndex].ulMaskValue);      /* PRQA S 2814 # JV-01 */
  }

  /* If any register didn't have the expected value, report DEM */
  if (0UL != LulResult)
  {
    Eth_DemConfigCheck(Eth_GaaDemEventRegisterCorruption[LulCtrlIdx], DEM_EVENT_STATUS_FAILED);                         /* PRQA S 2844 # JV-01 */
    LucResult = E_NOT_OK;
  }
  else
  {
    LucResult = E_OK;
  }

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

#if (ETH_REGISTER_CHECK_RUNTIME == STD_ON)
/***********************************************************************************************************************
** Function Name         : Eth_HwCheckBrokenRegister (ETNC)
**
** Service ID            : N/A
**
** Description           : Check whether relevant registers have not been
**                         corrupted
**
** Sync/Async            : Synchronous
**
** Reentrancy            : Non Reentrant
**
** Input Parameters      : LulCtrlIdx     : controller index
**
** InOut Parameters      : None
**
** Output Parameters     : None
**
** Return parameter      : None
**
** Preconditions         : Controller must be ACTIVE and the state never changed
**                         during this function.
**
** Global Variable(s)    : Eth_GaaCtrlStat, Eth_GaaCBRData,
**                         Eth_GaaETNCRegs, Eth_GaaDemEventRegisterCorruption
**
** Function(s) invoked   : Eth_DemConfigCheck
**
** Registers Used        : See Eth_GaaCBRData
**
** Reference ID          : ETH_DUD_ACT_166,
** Reference ID          : ETH_DUD_ACT_166_ERR001
***********************************************************************************************************************/
STATIC FUNC(void, ETH_PRIVATE_CODE) Eth_HwCheckBrokenRegister(
  CONST(uint32, AUTOMATIC) LulCtrlIdx)
{
  uint32 LulIndex;
  uint32 LulResult;
  P2VAR(volatile uint32, AUTOMATIC, REGSPACE) LpReg;                                                                    /* PRQA S 3678 # JV-01 */

  /* Intialize the register error check result */
  LulResult = 0UL;

  /* Check registers which have const values */
  for (LulIndex = 0UL; LulIndex < (uint32)(sizeof(Eth_GaaCBRData) / sizeof(Eth_ETNCCheckRORegType)); LulIndex++)
  {
    LpReg = &Eth_GaaETNCRegs[LulCtrlIdx]->ulEDMR + (Eth_GaaCBRData[LulIndex].ulOffset / (uint32)sizeof(uint32));        /* PRQA S 2844, 2814, 0488 # JV-01, JV-01, JV-01 */

    LulResult |= ((*LpReg ^ Eth_GaaCBRData[LulIndex].ulExpectedValue) & Eth_GaaCBRData[LulIndex].ulMaskValue);          /* PRQA S 2814 # JV-01 */
  }

  /* Confirm ECMR has not been changed */
  LulResult |= ((Eth_GaaETNCRegs[LulCtrlIdx]->ulECMR ^ Eth_GaaCtrlStat[LulCtrlIdx].stHwStat.ulECMRCopy)                 /* PRQA S 2844 # JV-01 */
    & ETH_ETNC_ECMR_CHECK_MASK);

  /* Confirm MAC address registers have not been changed */
  LulResult |= (Eth_GaaETNCRegs[LulCtrlIdx]->ulMAHR ^ Eth_GaaCtrlStat[LulCtrlIdx].stMacAddr.ulH32);
  LulResult |= (Eth_GaaETNCRegs[LulCtrlIdx]->ulMALR ^ Eth_GaaCtrlStat[LulCtrlIdx].stMacAddr.ulL16);

  /* If any register didn't have the expected value, set the error flag */
  if (0UL != LulResult)
  {
    Eth_GaaCtrlStat[LulCtrlIdx].stHwStat.blErrDetected = ETH_TRUE;                                                      /* PRQA S 2844 # JV-01 */
  }
  else
  {
    /* No action required */
  }

  /* If any error has been detected and not reported yet, report DEM */
  if ((ETH_TRUE == Eth_GaaCtrlStat[LulCtrlIdx].stHwStat.blErrDetected) &&                                               /* PRQA S 2844 # JV-01 */
    (ETH_FALSE == Eth_GaaCtrlStat[LulCtrlIdx].stHwStat.blErrReported))
  {
    Eth_DemConfigCheck(Eth_GaaDemEventRegisterCorruption[LulCtrlIdx], DEM_EVENT_STATUS_FAILED);                         /* PRQA S 2844 # JV-01 */
    /* Set already reported flag to prevent repeated reports */
    Eth_GaaCtrlStat[LulCtrlIdx].stHwStat.blErrReported = ETH_TRUE;                                                      /* PRQA S 2844 # JV-01 */
  }
  else
  {
    /* No action required */
  }
}
#endif /* ETH_REGISTER_CHECK_RUNTIME */

#define ETH_STOP_SEC_PRIVATE_CODE
#include "Eth_MemMap.h"                                                                                                 /* PRQA S 5087 # JV-01 */

#endif /* (ETH_USE_ETNC == STD_ON) */

/***********************************************************************************************************************
**                                               End of File                                                          **
***********************************************************************************************************************/
