/**
*   @file    Eth.c
*   @version 1.0.0
*
*   @brief   AUTOSAR Eth driver interface.
*   @details This file contains implementation of the AUTOSAR Ethernet driver
*            and provides whole API except the interrupt handlers.
*
*   @addtogroup ETH_DRIVER
*   @{
*/
/*==================================================================================================
*   Project              : AUTOSAR 4.3 MCAL
*   Platform             : PA
*   Peripheral           : FEC
*   Dependencies         : 
*
*   Autosar Version      : 4.3.1
*   Autosar Revision     : ASR_REL_4_3_REV_0001
*   Autosar Conf.Variant :
*   SW Version           : 1.0.0
*   Build Version        : MPC5777C_MCAL_1_0_0_RTM_ASR_REL_4_3_REV_0001_20190315
*
*   (c) Copyright 2006-2016 Freescale Semiconductor, Inc. 
*       Copyright 2017-2019 NXP
*   All Rights Reserved.
==================================================================================================*/
/*==================================================================================================
==================================================================================================*/

#ifdef __cplusplus
extern "C"{
#endif

/**
* @page misra_violations MISRA-C:2012 violations
* 
* @section Eth_c_REF_1
* Violates MISRA 2012 Required Directive 4.10, Precautions shall be taken in order to prevent the contents
* of a header file being included more than once. This comes from the order of includes in the .c file
* and from include dependencies. As a safe approach, any file must include all its dependencies.
* Header files are already protected against double inclusions. The inclusion of Eth_Memmap.h is as
* per AUTOSAR requirement (SWS_MemMap_00003)
*
* @section [global]
*          Violates MISRA 2012 Required Rule 5.1, External identifiers shall be distinct.
*          The used compilers use more than 31 chars for identifiers.
*
* @section [global]
*          Violates MISRA 2012 Required Rule 5.2, Identifiers declared in the same scope and name space shall be distinct.
*          The used compilers use more than 31 chars for identifiers.
*
* @section [global]
*          Violates MISRA 2012 Required Rule 5.4, Macro identifiers shall be distinct.
*          The used compilers use more than 31 chars for identifiers.
*
* @section [global]
*          Violates MISRA 2012 Required Rule 5.5, Identifiers shall be distinct from macro names.
*          The used compilers use more than 31 chars for identifiers.
*
* @section Eth_c_REF_2
* Violates MISRA 2012 Advisory Rule 20.1, #include directives should only be preceded by preprocessor 
* directives or comments. AUTOSAR imposes the specification of the sections in which certain parts
* of the driver must be placed.
*
* @section Eth_c_REF_3
* Violates MISRA 2012 Advisory Rule 8.7,  Functions and objects should not be defined with external 
* linkage if they are referenced in only one translation unit.
*
* @section Eth_c_REF_4
* Violates MISRA 2012 Required Rule 1.3, There shall be no occurrence of undefined or critical unspecified behaviour
*
* @section Eth_c_REF_5
* Violates MISRA 2012 Required Rule 14.3, Controlling expressions shall not be invariant.
*
*/

/*==================================================================================================
*                                        INCLUDE FILES
* 1) system and project includes
* 2) needed interfaces from external units
* 3) internal and external interfaces from this unit
==================================================================================================*/

#include "Eth.h" /* Includes also Eth_GeneralTypes.h, Eth_Cfg.h,  
                    Eth_ComStack_Types.h, Dem.h, Det.h and Mcal.h */
#include "Eth_Ipw.h"     /* LLD driver API */
#if STD_ON == ETH_CTRLENABLE_MII
#include "EthTrcv.h"    /* Include EthTrcv.h to reports Mii indication */
#endif
#if STD_ON == ETH_SWT_MANAGEMENT_SUPPORT_API
    #include "EthSwt.h"
#endif

/*==================================================================================================
*                              SOURCE FILE VERSION INFORMATION
==================================================================================================*/

#define ETH_VENDOR_ID_C                      43
#define ETH_MODULE_ID_C                      88
#define ETH_AR_RELEASE_MAJOR_VERSION_C       4
#define ETH_AR_RELEASE_MINOR_VERSION_C       3
#define ETH_AR_RELEASE_REVISION_VERSION_C    1
#define ETH_SW_MAJOR_VERSION_C               1
#define ETH_SW_MINOR_VERSION_C               0
#define ETH_SW_PATCH_VERSION_C               0

/*==================================================================================================
*                                     FILE VERSION CHECKS
==================================================================================================*/
/* Check if current file and ETH header file are of the same vendor */
#if(ETH_VENDOR_ID_C != ETH_VENDOR_ID)
    #error "Eth.c and Eth.h have different vendor ids"
#endif
/* Check if current file and ETH header file are of the same module */
#if(ETH_MODULE_ID_C != ETH_MODULE_ID)
    #error "Eth.c and Eth.h have different module ids"
#endif
/* Check if current file and ETH header file are of the same Autosar version */
#if((ETH_AR_RELEASE_MAJOR_VERSION_C    != ETH_AR_RELEASE_MAJOR_VERSION) || \
     (ETH_AR_RELEASE_MINOR_VERSION_C    != ETH_AR_RELEASE_MINOR_VERSION) || \
     (ETH_AR_RELEASE_REVISION_VERSION_C != ETH_AR_RELEASE_REVISION_VERSION))
    #error "AutoSar Version Numbers of Eth.c and Eth.h are different"
#endif
/* Check if current file and ETH header file are of the same Software version */
#if((ETH_SW_MAJOR_VERSION_C != ETH_SW_MAJOR_VERSION) || \
     (ETH_SW_MINOR_VERSION_C != ETH_SW_MINOR_VERSION) || \
     (ETH_SW_PATCH_VERSION_C != ETH_SW_PATCH_VERSION))
    #error "Software Version Numbers of Eth.c and Eth.h are different"
#endif
/* Check if current file and Eth_LLD header file are of the same Autosar version */
#if ((ETH_AR_RELEASE_MAJOR_VERSION_C    != ETH_AR_RELEASE_MAJOR_VERSION_ETHIPW_H) || \
     (ETH_AR_RELEASE_MINOR_VERSION_C    != ETH_AR_RELEASE_MINOR_VERSION_ETHIPW_H) || \
     (ETH_AR_RELEASE_REVISION_VERSION_C != ETH_AR_RELEASE_REVISION_VERSION_ETHIPW_H))
    #error "AutoSar Version Numbers of Eth.c and Eth_Ipw.h are different"
#endif
/* Check if current file and Eth_LLD header file are of the same Software version */
#if ((ETH_SW_MAJOR_VERSION_C != ETH_SW_MAJOR_VERSION_ETHIPW_H) || \
     (ETH_SW_MINOR_VERSION_C != ETH_SW_MINOR_VERSION_ETHIPW_H) || \
     (ETH_SW_PATCH_VERSION_C != ETH_SW_PATCH_VERSION_ETHIPW_H))
    #error "Software Version Numbers of Eth.c and Eth_Ipw.h are different"
#endif
#ifndef DISABLE_MCAL_INTERMODULE_ASR_CHECK
    #if STD_ON == ETH_CTRLENABLE_MII
    /* Check if current file and EthTrcv header file are of the same AutoSar version */
    #if ((ETH_AR_RELEASE_MAJOR_VERSION_C != ETHTRCV_AR_RELEASE_MAJOR_VERSION) || \
         (ETH_AR_RELEASE_MINOR_VERSION_C != ETHTRCV_AR_RELEASE_MINOR_VERSION))
        #error "AutoSar Version Numbers of Eth.c and EthTrcv.h are different"
    #endif
    #endif
    #if STD_ON == ETH_SWT_MANAGEMENT_SUPPORT_API
     /* Check if current file and EthSWT header file are of the same AutoSar version */
    #if ((ETH_AR_RELEASE_MAJOR_VERSION_C != ETHSWT_AR_RELEASE_MAJOR_VERSION) || \
         (ETH_AR_RELEASE_MINOR_VERSION_C != ETHSWT_AR_RELEASE_MINOR_VERSION))
        #error "AutoSar Version Numbers of Eth.c and EthSwt.h are different"
    #endif
    #endif
#endif /* DISABLE_MCAL_INTERMODULE_ASR_CHECK */
/*==================================================================================================
*                          LOCAL TYPEDEFS (STRUCTURES, UNIONS, ENUMS)
==================================================================================================*/


/*==================================================================================================
*                                       LOCAL MACROS
==================================================================================================*/


/*==================================================================================================
*                                      LOCAL CONSTANTS
==================================================================================================*/


/*==================================================================================================
*                                      LOCAL VARIABLES
==================================================================================================*/


/*==================================================================================================
*                                      GLOBAL CONSTANTS
==================================================================================================*/


/*==================================================================================================
*                                      GLOBAL VARIABLES
==================================================================================================*/
#define ETH_START_SEC_VAR_INIT_UNSPECIFIED
/* @violates @ref Eth_c_REF_1 This violation is not fixed since the inclusion of Eth_MemMap.h is as per AUTOSAR requirement*/
#include "Eth_MemMap.h"
/**
* @brief         State of the Eth module
* @details       Used to store state of the Ethernet controller driver i.e Eth
*                module. It is initialized to ETH_STATE_UNINIT
*/

VAR(volatile Eth_StateType, ETH_VAR) Eth_CtrlState[ETH_MAXCTRLS_SUPPORTED] = {ETH_STATE_UNINIT};


#define ETH_STOP_SEC_VAR_INIT_UNSPECIFIED
/* @violates @ref Eth_c_REF_1 This violation is not fixed since the inclusion of Eth_MemMap.h is as per AUTOSAR requirement*/
/* @violates @ref Eth_c_REF_2 Eth_MemMap.h is included after each section define in order to set the current memory section as defined by AUTOSAR */
#include "Eth_MemMap.h"

#if STD_ON == DEBUG_VARIABLES
#define ETH_START_SEC_VAR_INIT_32
/* @violates @ref Eth_c_REF_1 This violation is not fixed since the inclusion of Eth_MemMap.h is as per AUTOSAR requirement*/
#include "Eth_MemMap.h"
/**
* @brief         Debug variable counting receive buffer ring overflows
* @details       Debug variable used to count events of receive buffer ring
*                overflow due to reception of too long frame which does not fit
*                into the whole ring.
*/
VAR(uint32, ETH_VAR) Eth_RxBuffersOverflow[ETH_MAXCTRLS_SUPPORTED] = {0U};

/**
* @brief         Debug variable counting MII transactions finished too late
* @details       Debug variable incremented each time when MII transaction is
*                not finished successfully
*/
VAR(uint32, ETH_VAR) Eth_MiiFailed[ETH_MAXCTRLS_SUPPORTED] = {0U};
#define ETH_STOP_SEC_VAR_INIT_32
/* @violates @ref Eth_c_REF_1 This violation is not fixed since the inclusion of Eth_MemMap.h is as per AUTOSAR requirement*/
#include "Eth_MemMap.h"
#endif 


/*==================================================================================================
*                                   LOCAL FUNCTION PROTOTYPES
==================================================================================================*/


/*==================================================================================================
*                                       LOCAL FUNCTIONS
==================================================================================================*/
#define ETH_START_SEC_CODE
/* @violates @ref Eth_c_REF_1 This violation is not fixed since the inclusion of Eth_MemMap.h is as per AUTOSAR requirement*/
/* @violates @ref Eth_c_REF_2 Eth_MemMap.h is included after each section define in order to set the current memory section as defined by AUTOSAR */
#include "Eth_MemMap.h"

/*==================================================================================================
*                                       GLOBAL FUNCTIONS
==================================================================================================*/

/*================================================================================================*/
/**
* @brief         Initializes the Ethernet Driver
* @details       Passed configuration pointer is internally stored and
*                the driver is initialized. The Ethernet controller is not
*                touched.
* @note          Function should be called only once.
* @warning       Second call can cause undefined behavior.
*                Call the Eth_SetControllerMode() and pass ETH_MODE_DOWN to
*                the CtrlMode argument before the second Eth_Init call to avoid
*                problems.
* @api
* @param[in]     CfgPtr Points to the implementation specific structure containing
*                the Eth driver configuration
* Compiler_Warning: this warning due to behavior of compiler depend on configs.
* @violates @ref Eth_c_REF_3 For API functions (Eth.c): These functions represent the API of the driver. External linkage is needed to "export" the API. 
* @implements    Eth_Init_Activity
*/
FUNC(void, ETH_CODE) Eth_Init(P2CONST(Eth_ConfigType, AUTOMATIC, ETH_APPL_CONST) CfgPtr)
{
    VAR(uint8, AUTOMATIC) u8CtrlCount = 0;
#if STD_ON == ETH_DEV_ERROR_DETECT   
#if STD_ON == ETH_PRECOMPILE_SUPPORT
    if(NULL_PTR != CfgPtr)
#else
    if(NULL_PTR == CfgPtr)
#endif
    {           
        (void)Det_ReportError ( \
            (VAR(uint8, AUTOMATIC)) ETH_MODULE_ID, \
            ETH_DRIVER_INSTANCE, (VAR(uint8, AUTOMATIC)) ETH_SID_INIT, \
            ETH_E_PARAM_POINTER \
                              );
    }    
    else
    {   
#endif /* ETH_DEV_ERROR_DETECT  */
        /* Set the state to ETH_STATE_UNINIT before doing any changes to
           ensure that any preempting function (interrupt handler) will
           ensure that any preempting function (interrupt handler) will
           correctly stop its execution even if the state had been 
           ETH_STATE_ACTIVE when the Eth_Init was called. */
        for (u8CtrlCount=0U; u8CtrlCount < (VAR(uint8, AUTOMATIC))ETH_MAXCTRLS_SUPPORTED; u8CtrlCount++)
        {
            Eth_CtrlState[u8CtrlCount] = ETH_STATE_UNINIT;
        }
     /* Store the configuration pointer to internal global variable 
        for future usage */
    #if STD_ON == ETH_PRECOMPILE_SUPPORT
        Eth_InternalCfgPtr = &Eth_PBCfgVariantPredefined;
        (void)CfgPtr;
    #else
        Eth_InternalCfgPtr = CfgPtr;
    #endif
        for (u8CtrlCount = ETH_MIN_CTRLIDX; u8CtrlCount <= (VAR(uint8, AUTOMATIC))ETH_MAX_CTRLIDX; u8CtrlCount++)
        { 
            /* Try to reset the controller */
            Eth_Ipw_ResetController(u8CtrlCount);
            /*  Check whether the controller is available */
            if(((VAR(boolean, AUTOMATIC))TRUE) == Eth_Ipw_CheckAccessToController(u8CtrlCount))
            {
                Eth_Ipw_ConfigureController(u8CtrlCount);
                /* Only when debug variables are used */
                #if STD_ON == DEBUG_VARIABLES
                    /* Clear debug variables */ 
                    Eth_RxBuffersOverflow[u8CtrlCount] = 0U;
                    Eth_MiiFailed[u8CtrlCount] = 0U;
                #endif                     
                /* Set controller to init state */
                Eth_CtrlState[u8CtrlCount] = ETH_STATE_INIT; 
                /* Yes, the controller is available, report as passed */
                #if(STD_ON == ETH_DEM_EVENT_DETECT)
                /* @violates @ref Eth_c_REF_5 */
                if((VAR(uint32, AUTOMATIC))STD_ON == (uint32)ETH_CFG_DEM_E_ACCESS_ENABLED(u8CtrlCount))
                {
                   
                    (void)Dem_SetEventStatus   ( \
                       (VAR(Dem_EventIdType, AUTOMATIC)) \
                       ETH_CFG_DEM_E_ACCESS(u8CtrlCount), \
                       DEM_EVENT_STATUS_PREPASSED  \
                                           );
                }
                #endif
            }
            else
            {
                /* No, the controller is not available, report an error */
              #if(STD_ON == ETH_DEM_EVENT_DETECT)
                /* @violates @ref Eth_c_REF_5 */
                if((VAR(uint32, AUTOMATIC))STD_ON == (uint32)ETH_CFG_DEM_E_ACCESS_ENABLED(u8CtrlCount))
                {
                    (void)Dem_SetEventStatus   ( \
                        (VAR(Dem_EventIdType, AUTOMATIC)) \
                        ETH_CFG_DEM_E_ACCESS(u8CtrlCount), \
                        DEM_EVENT_STATUS_PREFAILED \
                                            );
                }
              #endif
            Eth_CtrlState[u8CtrlCount] = ETH_STATE_UNINIT;
            }       
        }
    #if STD_ON == ETH_DEV_ERROR_DETECT
    }
    #endif /* ETH_DEV_ERROR_DETECT  */
}

/*================================================================================================*/
/**
* @brief         Enables or disables the given controller
* @warning       Disabling the controller clears all receive and transmit
*                buffers. The application should ensure that no data is lost.
* @api
* @param[in]     CtrlIdx Index of the controller to be enabled or disabled.
*                The index is valid within the context of the Ethernet Driver
*                only.
* @param[in]     CtrlMode Mode which shall be entered
*                - ETH_MODE_DOWN: disable the controller
*                - ETH_MODE_ACTIVE: enable the controller
* @return        Error status
* @retval        E_OK No error was detected during the function execution.
* @retval        E_NOT_OK Development error was detected and the function
*                failed.
* @violates @ref Eth_c_REF_3 For API functions (Eth.c): These functions represent the API of the driver. External linkage is needed to "export" the API.
* @implements    Eth_SetControllerMode_Activity
*/


FUNC(Std_ReturnType, ETH_CODE) Eth_SetControllerMode(VAR(uint8, AUTOMATIC) CtrlIdx, VAR(Eth_ModeType, AUTOMATIC) CtrlMode)
{
    VAR(Std_ReturnType, AUTOMATIC) u8FunctionSuccess = (Std_ReturnType)E_NOT_OK; /* Variable used to track the
                                           function execution success status */

    #if STD_ON == ETH_DEV_ERROR_DETECT
    if(CtrlIdx >= (VAR(uint8, AUTOMATIC))ETH_MAXCTRLS_SUPPORTED)
    {        
        (void)Det_ReportError ( \
            (VAR(uint8, AUTOMATIC)) ETH_MODULE_ID, \
            ETH_DRIVER_INSTANCE, (VAR(uint8, AUTOMATIC)) \
            ETH_SID_SETCONTROLLERMODE, ETH_E_INV_CTRL_IDX \
                              );
    }
    else
    {
        if(ETH_STATE_INIT != Eth_CtrlState[CtrlIdx])
        {     
            (void)Det_ReportError ( \
                (VAR(uint8, AUTOMATIC)) ETH_MODULE_ID, \
                ETH_DRIVER_INSTANCE, (VAR(uint8, AUTOMATIC)) \
                ETH_SID_SETCONTROLLERMODE, ETH_E_UNINIT \
                                  );
        }
        else
        {
    #endif /* ETH_DEV_ERROR_DETECT  */
            if(ETH_MODE_ACTIVE == CtrlMode)
            {
                Eth_Ipw_EnableController(CtrlIdx);
            }
            else
            {
                Eth_Ipw_DisableController(CtrlIdx);
            }
            u8FunctionSuccess = (VAR(Std_ReturnType, AUTOMATIC))E_OK;
        #if(STD_ON == ETH_DEM_EVENT_DETECT)
                /* @violates @ref Eth_c_REF_5 */
                if((VAR(uint32, AUTOMATIC))STD_ON == (uint32)ETH_CFG_DEM_E_ACCESS_ENABLED(CtrlIdx))
                { 
                    (void)Dem_SetEventStatus   ( \
                        (VAR(Dem_EventIdType, AUTOMATIC)) \
                        ETH_CFG_DEM_E_ACCESS(CtrlIdx), \
                        DEM_EVENT_STATUS_PREPASSED  \
                                            );
                }
        #endif
    #if STD_ON == ETH_DEV_ERROR_DETECT
        }
    }
    #endif /* ETH_DEV_ERROR_DETECT  */
    return u8FunctionSuccess;
}

/*================================================================================================*/
/**
* @brief         Obtains the mode of the given controller
* @api
* @param[in]     CtrlIdx Index of the controller which state shall be read.
*                The index is valid within the context of the Ethernet Driver
*                only.
* @param[out]    CtrlModePtr Pointer where to store the current controller mode.
* @return        Error status
* @retval        E_OK No error was detected during the function execution.
* @retval        E_NOT_OK Development error was detected and the function
*                failed.
* @violates @ref Eth_c_REF_3 For API functions (Eth.c): These functions represent the API of the driver. External linkage is needed to "export" the API.
* @implements    Eth_GetControllerMode_Activity
*/
FUNC(Std_ReturnType, ETH_CODE) Eth_GetControllerMode( \
                            VAR(uint8, AUTOMATIC) CtrlIdx, \
                            P2VAR(Eth_ModeType, AUTOMATIC, ETH_APPL_DATA) CtrlModePtr \
                                                    )
{
    VAR(Std_ReturnType, AUTOMATIC) u8FunctionSuccess = (VAR(Std_ReturnType, AUTOMATIC))E_NOT_OK; /* Variable used to track
                                      the function execution success status */

    #if STD_ON == ETH_DEV_ERROR_DETECT
    if(CtrlIdx >= (VAR(uint8, AUTOMATIC))ETH_MAXCTRLS_SUPPORTED)
    {
        (void)Det_ReportError ( \
            (VAR(uint8, AUTOMATIC)) ETH_MODULE_ID, \
            ETH_DRIVER_INSTANCE, (VAR(uint8, AUTOMATIC)) \
            ETH_SID_GETCONTROLLERMODE, ETH_E_INV_CTRL_IDX \
                              );
    }
    else
    {
       if(NULL_PTR == CtrlModePtr)
        {

            (void)Det_ReportError ( \
                (VAR(uint8, AUTOMATIC)) ETH_MODULE_ID, \
                ETH_DRIVER_INSTANCE, (VAR(uint8, AUTOMATIC)) \
                ETH_SID_GETCONTROLLERMODE, ETH_E_PARAM_POINTER \
                                  );

        }
        else
        {
           if(ETH_STATE_INIT != Eth_CtrlState[CtrlIdx])
            {
                (void)Det_ReportError ( \
                    (VAR(uint8, AUTOMATIC)) ETH_MODULE_ID, \
                    ETH_DRIVER_INSTANCE, (VAR(uint8, AUTOMATIC)) \
                    ETH_SID_GETCONTROLLERMODE, ETH_E_UNINIT \
                                      );
            }
            else
            {
    #endif /* ETH_DEV_ERROR_DETECT  */
                * CtrlModePtr = Eth_Ipw_CheckControllerIsActive(CtrlIdx);
                u8FunctionSuccess = (VAR(Std_ReturnType, AUTOMATIC))E_OK;
    #if STD_ON == ETH_DEV_ERROR_DETECT
            }
        }
    }
    #endif /* ETH_DEV_ERROR_DETECT  */
    return u8FunctionSuccess;
}
  
/*================================================================================================*/
/**
* @brief         Obtains the physical source address used by the indexed
*                controller (the node MAC address).
* @api
* @param[in]     CtrlIdx Index of the controller which MAC address should be
*                read. The index is valid within the context of the Ethernet
*                Driver only.
* @param[out]    PhysAddrPtr Pointer where to store physical source address
*                (MAC address). The address in network byte order is stored into
*                6 bytes at the given memory address.
* @violates @ref Eth_c_REF_3 For API functions (Eth.c): These functions represent the API of the driver. External linkage is needed to "export" the API.
* @implements    Eth_GetPhysAddr_Activity
*/
FUNC(void, ETH_CODE) Eth_GetPhysAddr(VAR(uint8, AUTOMATIC) CtrlIdx, P2VAR(uint8, AUTOMATIC, ETH_APPL_DATA) PhysAddrPtr)
{
    VAR(uint32, AUTOMATIC) u32AddressHolder; /* Used to hold the addres value */
    
    #if STD_ON == ETH_DEV_ERROR_DETECT
    if(CtrlIdx >= (VAR(uint8, AUTOMATIC))ETH_MAXCTRLS_SUPPORTED)
    {
        (void)Det_ReportError ( \
            (VAR(uint8, AUTOMATIC)) ETH_MODULE_ID, \
            ETH_DRIVER_INSTANCE, (VAR(uint8, AUTOMATIC)) ETH_SID_GETPHYSADDR, \
            ETH_E_INV_CTRL_IDX \
                              );
    }
    else
    {
        if(NULL_PTR == PhysAddrPtr)
        {
            (void)Det_ReportError ( \
                (VAR(uint8, AUTOMATIC)) ETH_MODULE_ID, \
                ETH_DRIVER_INSTANCE, (VAR(uint8, AUTOMATIC)) \
                ETH_SID_GETPHYSADDR, ETH_E_PARAM_POINTER \
                                  );

        }
        else
        {
           if(ETH_STATE_INIT != Eth_CtrlState[CtrlIdx])
            {
                (void)Det_ReportError ( \
                    (VAR(uint8, AUTOMATIC)) ETH_MODULE_ID, \
                    ETH_DRIVER_INSTANCE, (VAR(uint8, AUTOMATIC)) \
                    ETH_SID_GETPHYSADDR, ETH_E_UNINIT \
                                      );
            }
            else
            {
    #endif /* ETH_DEV_ERROR_DETECT  */
                /* Get the first four bytes of the address */
                u32AddressHolder = Eth_Ipw_GetPhysicalAddressLow(CtrlIdx);
                /* Saved as four uint8 values instead of one uint32 value 
                   because the proper uint32 alignment is not ensured by the 
                   function prototype 
                */                
                /* Store the LSB */
                PhysAddrPtr[3U] = (uint8)(u32AddressHolder & 0xFFU);
                u32AddressHolder = u32AddressHolder >> 8U; /* Prepare the next bit */
                
                PhysAddrPtr[2U] = (uint8)(u32AddressHolder & 0xFFU);
                u32AddressHolder = u32AddressHolder >> 8U; /* Prepare the next bit */
                
                PhysAddrPtr[1U] = (uint8)(u32AddressHolder & 0xFFU);
                u32AddressHolder = u32AddressHolder >> 8U; /* Prepare the next bit */
                /* Store the MSB */
                PhysAddrPtr[0U] = (uint8)(u32AddressHolder & 0xFFU);
                /* Get the last two bytes of the address */
                u32AddressHolder = (uint32)Eth_Ipw_GetPhysicalAddressHigh(CtrlIdx);
                /* Saved as four uint8 values instead of one uint32 value 
                   because the proper uint16 alignment is not ensured by the 
                   function prototype 
                */                
                 /* Store the LSB */
                PhysAddrPtr[5U] = (uint8)(u32AddressHolder & 0xFFU);
                u32AddressHolder = u32AddressHolder >> 8U; /* Prepare the next bit */
                /* Store the MSB */
                PhysAddrPtr[4U] = (uint8)(u32AddressHolder & 0xFFU);         
    #if STD_ON == ETH_DEV_ERROR_DETECT
            }      
        }  
    }
    #endif /* ETH_DEV_ERROR_DETECT  */
}  

/*================================================================================================*/
/**
* @brief         Set or change physical address to the defined controller.
* @api
* @param[in]     CtrlIdx Index of the controller which PHY address should be
*                changed. The index is valid within the context of the Ethernet
*                Driver only.
* @param[in]     PhysAddrPtr Pointer to PHY address which should be set to
*                the controller. The address is stored in 6 bytes of memory
*                in network byte order.
* @caution       This function may be called only when the controller is down.
*                Call of function Eth_ControllerInit change MAC address
*                to the default value!
* @violates @ref Eth_c_REF_3 For API functions (Eth.c): These functions represent the API of the driver. External linkage is needed to "export" the API.
* @implements    Eth_SetPhysAddr_Activity
*/
FUNC(void, ETH_CODE) Eth_SetPhysAddr(VAR(uint8, AUTOMATIC) CtrlIdx, P2CONST(uint8, AUTOMATIC, ETH_APPL_CONST) PhysAddrPtr)
{
    #if STD_ON == ETH_DEV_ERROR_DETECT
    if(CtrlIdx >= (VAR(uint8, AUTOMATIC))ETH_MAXCTRLS_SUPPORTED)
    {
        (void)Det_ReportError ( \
            (VAR(uint8, AUTOMATIC)) ETH_MODULE_ID, \
            ETH_DRIVER_INSTANCE, (VAR(uint8, AUTOMATIC)) ETH_SID_SETPHYSADDR, \
            ETH_E_INV_CTRL_IDX \
                              );
    }
    else
    {
        if(NULL_PTR == PhysAddrPtr)
        {
            (void)Det_ReportError ( \
                (VAR(uint8, AUTOMATIC)) ETH_MODULE_ID, \
                ETH_DRIVER_INSTANCE, (VAR(uint8, AUTOMATIC)) \
                ETH_SID_SETPHYSADDR, ETH_E_PARAM_POINTER \
                                  );

        }
        else
        {
           if(ETH_STATE_INIT != Eth_CtrlState[CtrlIdx])
            {
                (void)Det_ReportError ( \
                    (VAR(uint8, AUTOMATIC)) ETH_MODULE_ID, \
                    ETH_DRIVER_INSTANCE, (VAR(uint8, AUTOMATIC)) \
                    ETH_SID_SETPHYSADDR, ETH_E_UNINIT \
                                      );
            }
            else
            {
    #endif /* ETH_DEV_ERROR_DETECT  */
                (void)Eth_Ipw_SetPhysAddr(CtrlIdx, PhysAddrPtr);
    #if STD_ON == ETH_DEV_ERROR_DETECT
            }
        }
    }
    #endif /* ETH_DEV_ERROR_DETECT  */
}


#if STD_ON == ETH_UPDATE_PHYS_ADDR_FILTER
/*================================================================================================*/
/**
* @brief         Adds or removes the specific @c PhysAddrPtr address to or from
*                a multicast address pool at controller specified by @c CtrlIdx
*                index.
* @api
* @details       Enables or disables reception for specified unicast
*                physical address.
*                Operations for special Physical addresses follow.
*                If Physical Address ff:ff:ff:ff:ff:ff is added into a filter
*                (Action=ETH_ADD_TO_FILTER) the filter is completely open
*                and any address is accepted at reception. Later on when
*                Physical Address ff:ff:ff:ff:ff:ff is removed from the filter
*                (Action=ETH_REMOVE_FROM_FILTER) the filtering is recovered
*                and the reception is allowed again only for addresses remaining
*                in the filter.
*                If Physical Address 00:00:00:00:00:00 is added into a filter,
*                no matter whether action is ETH_ADD_TO_FILTER
*                or ETH_REMOVE_FROM_FILTER,
*                the filter is completely closed and all items from table
*                are removed.
*                Note that operations of full open or close are in exclusive
*                disjunction. Operation of full open excludes full close and
*                vice versa.
* @param[in]     CtrlIdx Index of the controller. The index is valid within
*                the context of the Ethernet Driver only.
* @param[in]     PhysAddrPtr Pointer to PHY address which shall be added
*                or removed to or from multicast pool.
*                The address in network byte order stored into 6 bytes of
*                memory.
* @param[in]     Action Determine whenever the defined address will be added
*                to the pool ETH_ADD_TO_FILTER or removed from it
*                ETH_REMOVE_FROM_FILTER.
* @violates @ref Eth_c_REF_3 For API functions (Eth.c): These functions represent the API of the driver. External linkage is needed to "export" the API.
* @implements    Eth_UpdatePhysAddrFilter_Activity
*/
FUNC(Std_ReturnType, ETH_CODE) Eth_UpdatePhysAddrFilter ( \
                                VAR(uint8, AUTOMATIC) CtrlIdx, \
                                P2CONST(uint8, AUTOMATIC, ETH_APPL_CONST) PhysAddrPtr, \
                                VAR(Eth_FilterActionType, AUTOMATIC) Action \
                                                        )
{
    VAR(Std_ReturnType, AUTOMATIC) eReturnStatus = (VAR(Std_ReturnType, AUTOMATIC))E_NOT_OK;

    #if STD_ON == ETH_DEV_ERROR_DETECT
    if(CtrlIdx >= (VAR(uint8, AUTOMATIC))ETH_MAXCTRLS_SUPPORTED)
    {
        (void)Det_ReportError ( \
          (VAR(uint8, AUTOMATIC)) ETH_MODULE_ID, ETH_DRIVER_INSTANCE, \
          (VAR(uint8, AUTOMATIC)) ETH_SID_UPDATEADDRFILTER, \
          ETH_E_INV_CTRL_IDX \
                              );
    }
    else
    {
        if(NULL_PTR == PhysAddrPtr)
        {           
            (void)Det_ReportError ( \
                (VAR(uint8, AUTOMATIC)) ETH_MODULE_ID, \
                ETH_DRIVER_INSTANCE, (VAR(uint8, AUTOMATIC)) \
                ETH_SID_UPDATEADDRFILTER, ETH_E_PARAM_POINTER \
                                  );

        }
        else
        {
           if(ETH_STATE_INIT != Eth_CtrlState[CtrlIdx])
            {
                (void)Det_ReportError ( \
                    (VAR(uint8, AUTOMATIC)) ETH_MODULE_ID, \
                    ETH_DRIVER_INSTANCE, (VAR(uint8, AUTOMATIC)) \
                    ETH_SID_UPDATEADDRFILTER, ETH_E_UNINIT \
                                      );
            }
            else
            {
    #endif /* ETH_DEV_ERROR_DETECT  */
                Eth_Ipw_UpdatePhysAddrFilter(CtrlIdx, PhysAddrPtr, Action);
                /* Check whenever is added multicast address. I/G bit is set */
                if(1U == (*(PhysAddrPtr) & 1U))
                {
                    eReturnStatus = (VAR(Std_ReturnType, AUTOMATIC))E_OK;
                }
    #if STD_ON == ETH_DEV_ERROR_DETECT
            }
        }
    }
    #endif /* ETH_DEV_ERROR_DETECT  */
    return eReturnStatus;
}

#endif /* STD_ON == ETH_UPDATE_PHYS_ADDR_FILTER */


#if STD_ON == ETH_CTRLENABLE_MII

/*================================================================================================*/
/**
* @brief         Writes to a transceiver (physical layer driver) register.
* @details       The management frame is assembled and the MII bus transaction
*                is issued in order to transfer the data. Function waits until
*                the bus transaction finishes.
* @warning       This function is blocking the execution until the MII bus
*                transaction is finished.
* @api
* @param[in]     CtrlIdx Index of the controller which transceiver register
*                shall be written. The index is valid within the context of
*                the Ethernet Driver only.
* @param[in]     TrcvIdx Index of the transceiver connected the MII. The value
*                shall be within the range 0..31.
* @param[in]     RegIdx Index of the transceiver register to be written. The
*                value shall be withing the range 0..31.
* @param[in]     RegVal Value to be written into the indexed register.
* @retval        E_OK No error was detected during the function execution.
* @retval        E_NOT_OK Development error or the function failed.
* @retval        ETH_E_NO_ACCESS Inaccessible to tranceiver.
* @violates @ref Eth_c_REF_3 For API functions (Eth.c): These functions represent the API of the driver. External linkage is needed to "export" the API.
* @implements    Eth_WriteMii_Activity
*/
FUNC(Std_ReturnType, ETH_CODE) Eth_WriteMii ( \
                                    VAR(uint8, AUTOMATIC) CtrlIdx, \
                                    VAR(uint8, AUTOMATIC) TrcvIdx, \
                                    VAR(uint8, AUTOMATIC) RegIdx, \
                                    VAR(uint16, AUTOMATIC) RegVal \
                                            )
{
    VAR(Std_ReturnType, AUTOMATIC) eReturnStatus = (VAR(Std_ReturnType, AUTOMATIC))E_NOT_OK;

#if STD_ON == ETH_DEV_ERROR_DETECT
    /* @violates @ref Eth_c_REF_5 */
    if(CtrlIdx >= (uint8)ETH_MAXCTRLS_SUPPORTED)
    {
        (void)Det_ReportError ( \
            (VAR(uint8, AUTOMATIC)) ETH_MODULE_ID, \
            ETH_DRIVER_INSTANCE, (VAR(uint8, AUTOMATIC)) ETH_SID_WRITEMII, \
            ETH_E_INV_CTRL_IDX \
                              );
    }
    else
    {
       if(ETH_STATE_INIT != Eth_CtrlState[CtrlIdx])
        {
            (void)Det_ReportError ( \
                (VAR(uint8, AUTOMATIC)) ETH_MODULE_ID, \
                ETH_DRIVER_INSTANCE, (VAR(uint8, AUTOMATIC)) ETH_SID_WRITEMII, \
                ETH_E_UNINIT \
                                  );
        }
        else
        {
#endif /* ETH_DEV_ERROR_DETECT  */
            /* @violates @ref Eth_c_REF_4 */
            if((VAR(boolean, AUTOMATIC))TRUE == Eth_Ipw_WriteMii(CtrlIdx, TrcvIdx, RegIdx, &RegVal))
            {
                EthTrcv_WriteMiiIndication(CtrlIdx, TrcvIdx, RegIdx);
                eReturnStatus = (VAR(Std_ReturnType, AUTOMATIC))E_OK;
            }
#if STD_ON == ETH_DEV_ERROR_DETECT
        }
    }
#endif /* ETH_DEV_ERROR_DETECT  */
    return eReturnStatus;
}

/*================================================================================================*/
/**
* @brief          Reads a transceiver (physical layer driver) register.
* @api
* @param[in]      CtrlIdx Index of the controller which transceiver register
*                 shall be read. The index is valid within the context of
*                 the Ethernet Driver only.
* @param[in]      TrcvIdx Index of the transceiver connected on the MII. The
*                 value shall be within the range 0..31.
* @param[in]      RegIdx Index of the transceiver register to be read. The
*                 Value shall be within the range 0..31.
* @param[out]     RegValPtr Filled with the register content of the indexed register
* @retval        E_OK No error was detected during the function execution.
* @retval        E_NOT_OK Development error or the function failed.
* @retval        ETH_E_NO_ACCESS Inaccessible to tranceiver.
* @details        The management frame is assembled and the MII bus transaction
*                 is issued in order to transfer the data. Function waits until
*                 the bus transaction finishes and then returns the read data.
* @warning        This function is blocking the execution until the MII bus
*                 transaction is finished.
* @violates @ref Eth_c_REF_3 For API functions (Eth.c): These functions represent the API of the driver. External linkage is needed to "export" the API.
* @implements     Eth_ReadMii_Activity
*/
FUNC(Std_ReturnType, ETH_CODE) Eth_ReadMii  ( \
                            VAR(uint8, AUTOMATIC) CtrlIdx, \
                            VAR(uint8, AUTOMATIC) TrcvIdx, \
                            VAR(uint8, AUTOMATIC) RegIdx, \
                            P2VAR(uint16, AUTOMATIC, ETH_APPL_DATA) RegValPtr \
                                            )
{
    VAR(Std_ReturnType, AUTOMATIC) eReturnStatus = (VAR(Std_ReturnType, AUTOMATIC))E_NOT_OK;

#if STD_ON == ETH_DEV_ERROR_DETECT
    /* @violates @ref Eth_c_REF_5 */
    if(CtrlIdx >= (uint8)ETH_MAXCTRLS_SUPPORTED)
    {
        (void)Det_ReportError ( \
            (VAR(uint8, AUTOMATIC)) ETH_MODULE_ID, \
            ETH_DRIVER_INSTANCE, (VAR(uint8, AUTOMATIC)) ETH_SID_READMII, \
            ETH_E_INV_CTRL_IDX \
                              );
    }
    else
    {
        if(NULL_PTR == RegValPtr)
        {
            (void)Det_ReportError ( \
                (VAR(uint8, AUTOMATIC)) ETH_MODULE_ID, \
                ETH_DRIVER_INSTANCE, (VAR(uint8, AUTOMATIC)) \
                ETH_SID_READMII, ETH_E_PARAM_POINTER \
                                  );
        }
        else
        {
           if(ETH_STATE_INIT != Eth_CtrlState[CtrlIdx])
            {
                (void)Det_ReportError ( \
                    (VAR(uint8, AUTOMATIC)) ETH_MODULE_ID, \
                    ETH_DRIVER_INSTANCE, (VAR(uint8, AUTOMATIC)) \
                    ETH_SID_READMII, ETH_E_UNINIT \
                                      );
            }
            else
            {
#endif /* ETH_DEV_ERROR_DETECT  */
                if((VAR(boolean, AUTOMATIC))TRUE == Eth_Ipw_ReadMii(CtrlIdx, TrcvIdx, RegIdx, RegValPtr))
                {
                    EthTrcv_ReadMiiIndication(CtrlIdx, TrcvIdx, RegIdx, *RegValPtr);
                    eReturnStatus = (VAR(Std_ReturnType, AUTOMATIC))E_OK;
                }
#if STD_ON == ETH_DEV_ERROR_DETECT
            }
        }  
    }
#endif /* ETH_DEV_ERROR_DETECT  */

    return eReturnStatus;
}
#endif /* ETH_CTRLENABLE_MII */

#if STD_ON == ETH_GETCOUNTVALAPI
/*================================================================================================*/
/**
* @brief            Reads a list with drop counter values of the corresponding controller.
* @api
* @param[in]        CtrlIdx Index of the controller which shall be be read the drop
*                   package counts.
* @param[in,out]    CountValues The number of values which return.
*                   -In: Maximal number of values which can be written from DropCount.
*                   -Out: Number of values which are returned in the DropCount list.
* @param[out]       DropCount The interpretation of this list of values is hardware 
*                   dependent
* @return           Error status
* @retval           E_OK No error was detected during the function execution.
* @retval           E_NOT_OK Development error was detected or inaccessible to counters register 
*                   and the function.
* @details          Reads a list with drop counter values of the corresponding controller. The meaning 
*                   of these values is hardware dependent. However, the list DropCount[] shall 
*                   contain the following values in the given order, where the maximal possible value 
*                   shall denote an invalid value, e.g. if this counter is not available:
*                   1.) dropped packets due to buffer overrun
*                   2.) dropped packets due to CRC errors
*                   3.) number of undersize packets which were less than 64 octets long (excluding 
*                   framing bits, but including FCS octets) and were otherwise will formed. (see IETF 
*                   RFC 1757)
*                   4.) number of oversize packets which are longer than 1518 octets (excluding 
*                   framing bits, but including FCS octets) and were otherwise well formed. (see IETF 
*                   RFC 1757)
*                   5.) number of alignment errors, i.e. packets which are received and are not an 
*                   integral number of octets in length and do not pass the CRC.
*                   6.) SQE test error according to IETF RFC1643 dot3StatsSQETestErrors
*                   7.) The number of inbound packets which were chosen to be discarded even 
*                   though no errors had been detected to prevent their being deliverable to a higher layer protocol. 
*                   One possible reason for discarding such a packet could be to free 
*                   up buffer space. (see IETF RFC 2233 ifInDiscards)
*                   8.) total number of erroneous inbound packets
*                   9.) The number of outbound packets which were chosen to be discarded even 
*                   though no errors had been detected to prevent their being transmitted. One 
*                   possible reason for discarding such a packet could be to free up buffer space. 
*                   (see IETF RFC 2233 ifOutDiscards)
*                   10.) total number of erroneous outbound packets
*                   11.) Single collision frames: A count of successfully transmitted frames on a 
*                   particular interface for which transmission is inhibited by exactly one collision. (see 
*                   IETF RFC1643 dot3StatsSingleCollisionFrames)
*                   12.) Multiple collision frames: A count of successfully transmitted frames on a 
*                   particular interface for which transmission is inhibited by more than one collision. 
*                   (see IETF RFC1643 dot3StatsMultipleCollisionFrames)
*                   13.) Number of deferred transmission: A count of frames for which the first 
*                   transmission attempt on a particular interface is delayed because the medium is 
*                   busy. (see IETF RFC1643 dot3StatsDeferredTransmissions)
*                   14.) Number of late collisions: The number of times that a collision is detected on 
*                   a particular interface later than 512 bit times into the transmission of a packet. 
*                   (see IETF RFC1643 dot3StatsLateCollisions)
*                   15.) the following positions in the list can contain hardware dependent counter 
*                   values
* @violates @ref Eth_c_REF_3 For API functions (Eth.c): These functions represent the API of the driver. External linkage is needed to "export" the API.
* @implements       Eth_GetCounterValues_Activity
*/
FUNC(Std_ReturnType, ETH_CODE) Eth_GetCounterValues ( \
                                        VAR(uint8, AUTOMATIC) CtrlIdx, \
                                        P2VAR(Eth_CounterType, AUTOMATIC, ETH_APPL_DATA) CounterPtr \
                                                )
{
    VAR(Std_ReturnType, AUTOMATIC) eReturnStatus = (VAR(Std_ReturnType, AUTOMATIC)) E_NOT_OK;
    
#if STD_ON == ETH_DEV_ERROR_DETECT
    if(CtrlIdx >= ETH_MAXCTRLS_SUPPORTED)
    {
        (void)Det_ReportError ( \
            (VAR(uint8, AUTOMATIC)) ETH_MODULE_ID, \
            ETH_DRIVER_INSTANCE, (VAR(uint8, AUTOMATIC)) \
            ETH_SID_GETCOUNTERVALUE, ETH_E_INV_CTRL_IDX \
                              );
    }
    else
    {
        if(ETH_STATE_INIT != Eth_CtrlState[CtrlIdx])
        {
            (void)Det_ReportError ( \
                (VAR(uint8, AUTOMATIC)) ETH_MODULE_ID, \
                ETH_DRIVER_INSTANCE, (VAR(uint8, AUTOMATIC)) \
                ETH_SID_GETCOUNTERVALUE, ETH_E_UNINIT \
                                  );
        }
        else
        {
            if(NULL_PTR == CounterPtr)
            {
                (void)Det_ReportError ( \
                    (VAR(uint8, AUTOMATIC)) ETH_MODULE_ID, \
                    ETH_DRIVER_INSTANCE, (VAR(uint8, AUTOMATIC)) \
                    ETH_SID_GETCOUNTERVALUE, ETH_E_PARAM_POINTER \
                                      );
            }
            else
            {
#endif /* ETH_DEV_ERROR_DETECT  */
                Eth_Ipw_GetCounterValues(CtrlIdx, CounterPtr);
                eReturnStatus = (VAR(Std_ReturnType, AUTOMATIC))E_OK;
#if STD_ON == ETH_DEV_ERROR_DETECT
            } 
        }
    }
#endif /* ETH_DEV_ERROR_DETECT  */
    return(eReturnStatus);
}
#endif /* ETH_GETCOUNTVALAPI */

#if STD_ON == ETH_GET_RXSTATS_API
/*================================================================================================*/
/**
* @brief        Read the status of a controller
* @detail       Returns the following list according to IETF RFC2819, where the maximal possible 
*               value shall denote an invalid value, e.g. if this counter is not available:
*               1. etherStatsDropEvents
*               2. etherStatsOctets
*               3. etherStatsPkts
*               4. etherStatsBroadcastPkts
*               5. etherStatsMulticastPkts
*               6. etherStatsCrcAlignErrors
*               7. etherStatsUndersizePkts
*               8. etherStatsOversizePkts
*               9. etherStatsFragments
*               10. etherStatsJabbers
*               11. etherStatsCollisions
*               12. etherStatsPkts64Octets
*               13. etherStatsPkts65to127Octets
*               14. etherStatsPkts128to255Octets
*               15. etherStatsPkts256to511Octets
*               16. etherStatsPkts512to1023Octets
*               17. etherStatsPkts1024to1518Octets
* @api
* @param[in]    CtrlIdx Index of the controller which shall be read the status register.
* @param[out]   etherStats Pointer to 32 bit long memory space to be filled with
*               the list values according to IETF RFC 2819 (Remote Network 
*               Monitoring Management Information Base). 
* @return       Error status
* @retval       E_OK No error was detected during the function execution.
* @retval       E_NOT_OK Development error was detected or inaccessible to counters register 
*               and the function.
* @violates @ref Eth_c_REF_3 For API functions (Eth.c): These functions represent the API of the driver. External linkage is needed to "export" the API.
* @implements   Eth_GetRxStats_Activity
*/
FUNC(Std_ReturnType, ETH_CODE) Eth_GetRxStats ( \
                                VAR(uint8, AUTOMATIC) CtrlIdx, \
                                P2VAR(Eth_RxStatsType, AUTOMATIC, ETH_APPL_DATA) RxStats \
                                              )
{
    VAR(Std_ReturnType, AUTOMATIC) eReturnStatus = (VAR(Std_ReturnType, AUTOMATIC)) E_NOT_OK;

#if STD_ON == ETH_DEV_ERROR_DETECT
    if(CtrlIdx >= ETH_MAXCTRLS_SUPPORTED)
    {
        (void)Det_ReportError ( \
            (VAR(uint8, AUTOMATIC)) ETH_MODULE_ID, \
            ETH_DRIVER_INSTANCE, (VAR(uint8, AUTOMATIC)) \
            ETH_SID_GETRXSTATS, ETH_E_INV_CTRL_IDX \
                              );
    }
    else
    {
        if(ETH_STATE_INIT != Eth_CtrlState[CtrlIdx])
        {
            (void)Det_ReportError ( \
                (VAR(uint8, AUTOMATIC)) ETH_MODULE_ID, \
                ETH_DRIVER_INSTANCE, (VAR(uint8, AUTOMATIC)) \
                ETH_SID_GETRXSTATS, ETH_E_UNINIT \
                                  );
        }
        else
        {
            if(NULL_PTR == RxStats)
            {
                (void)Det_ReportError ( \
                    (VAR(uint8, AUTOMATIC)) ETH_MODULE_ID, \
                    ETH_DRIVER_INSTANCE, (VAR(uint8, AUTOMATIC)) \
                    ETH_SID_GETRXSTATS, ETH_E_PARAM_POINTER \
                                      );
            }
            else
            {
#endif /* ETH_DEV_ERROR_DETECT  */
                Eth_Ipw_GetRxStats(CtrlIdx, RxStats);
                eReturnStatus = (VAR(Std_ReturnType, AUTOMATIC)) E_OK;
#if STD_ON == ETH_DEV_ERROR_DETECT
            } 
        }
    }
#endif /* ETH_DEV_ERROR_DETECT  */
    return(eReturnStatus);
}
#endif /*ETH_GET_RXSTATS_API*/

#if STD_ON == ETH_GET_TXSTATS_API
/*================================================================================================*/
/**
* @brief         Return the list of Transmission Statistics.
* @param[in]     u8CtrlIdx Index of controller within the context of the Ethernet Driver.
* @param[out]     TxStats List of the controller within the context of the Ethernet Driver.
* @details       Return the list of Transmission Sratistics out of IETF RFC1213
*                defined with Eth_TxStatsType, where the maximal possible value shall
*                denote an invalid value.
*                e.g. this counter is not available..
* @return        The search status
* @retval        E_OK Success
* @retval        E_NOTOK Tx-statistics could not be obtained.
* @violates @ref Eth_c_REF_3 For API functions (Eth.c): These functions represent the API of the driver. External linkage is needed to "export" the API.
* @implements    Eth_GetTxStats_Activity
*/
FUNC(Std_ReturnType, ETH_CODE) Eth_GetTxStats ( \
                                VAR(uint8, AUTOMATIC) CtrlIdx, \
                                P2VAR(Eth_TxStatsType, AUTOMATIC, ETH_APPL_DATA) TxStats \
                                              )
{
    VAR(Std_ReturnType, AUTOMATIC) eReturnStatus = (VAR(Std_ReturnType, AUTOMATIC)) E_NOT_OK;

#if STD_ON == ETH_DEV_ERROR_DETECT
    if(CtrlIdx >= ETH_MAXCTRLS_SUPPORTED)
    {
        (void)Det_ReportError ( \
            (VAR(uint8, AUTOMATIC)) ETH_MODULE_ID, \
            ETH_DRIVER_INSTANCE, (VAR(uint8, AUTOMATIC)) \
            ETH_SID_GETTXSTATS, ETH_E_INV_CTRL_IDX \
                              );
    }
    else
    {
        if(ETH_STATE_INIT != Eth_CtrlState[CtrlIdx])
        {
            (void)Det_ReportError ( \
                (VAR(uint8, AUTOMATIC)) ETH_MODULE_ID, \
                ETH_DRIVER_INSTANCE, (VAR(uint8, AUTOMATIC)) \
                ETH_SID_GETTXSTATS, ETH_E_UNINIT \
                                  );
        }
        else
        {
            if(NULL_PTR == TxStats)
            {
                (void)Det_ReportError ( \
                    (VAR(uint8, AUTOMATIC)) ETH_MODULE_ID, \
                    ETH_DRIVER_INSTANCE, (VAR(uint8, AUTOMATIC)) \
                    ETH_SID_GETTXSTATS, ETH_E_PARAM_POINTER \
                                      );
            }
            else
            {
#endif /* ETH_DEV_ERROR_DETECT  */
                Eth_Ipw_GetTxStats(CtrlIdx, TxStats);
                eReturnStatus = (VAR(Std_ReturnType, AUTOMATIC)) E_OK;
#if STD_ON == ETH_DEV_ERROR_DETECT
            } 
        }
    }
#endif /* ETH_DEV_ERROR_DETECT  */
    return(eReturnStatus);
}
#endif /*ETH_GET_TXSTATS_API*/

#if STD_ON == ETH_GET_GETTXCOUNT_API
/*================================================================================================*/
/**
* @brief         Return the list of Transmission Statistics.
* @param[in]     u8CtrlIdx Index of controller within the context of the Ethernet Driver.
* @param[out]    TxErrorCounterValues List of values to read statistic error counter values for transmission.
* @details       Return the list of Transmission Error Counters out of IETF RFC1213 and RFC1643
*                defined with  Eth_TxErrorCounterValuesType, where the maximal possible value shall
*                denote an invalid value.
*                e.g. this counter is not available..
* @return        The search status
* @retval        E_OK Success
* @retval        E_NOTOK Tx-statistics could not be obtained.
* @violates @ref Eth_c_REF_3 For API functions (Eth.c): These functions represent the API of the driver. External linkage is needed to "export" the API.
* @implements    Eth_GetTxErrorCounterValues_Activity
*/
FUNC(Std_ReturnType, ETH_CODE) Eth_GetTxErrorCounterValues ( \
                                VAR(uint8, AUTOMATIC) CtrlIdx, \
                                P2VAR(Eth_TxErrorCounterValuesType, AUTOMATIC, ETH_APPL_DATA) TxErrorCounterValues \
                                              )
{
    VAR(Std_ReturnType, AUTOMATIC) eReturnStatus = (Std_ReturnType) E_NOT_OK;

#if STD_ON == ETH_DEV_ERROR_DETECT
    if(ETH_STATE_INIT != Eth_CtrlState[CtrlIdx])
    {
        (void)Det_ReportError ( \
                (VAR(uint8, AUTOMATIC)) ETH_MODULE_ID, \
                ETH_DRIVER_INSTANCE, (VAR(uint8, AUTOMATIC)) \
                ETH_SID_GETTXERRORCOUNTERVALUE, ETH_E_UNINIT \
                                  );
    }
    else
    {
        if(CtrlIdx >= ETH_MAXCTRLS_SUPPORTED)
        {
            (void)Det_ReportError ( \
                (VAR(uint8, AUTOMATIC)) ETH_MODULE_ID, \
                ETH_DRIVER_INSTANCE, (VAR(uint8, AUTOMATIC)) \
                ETH_SID_GETTXERRORCOUNTERVALUE, ETH_E_INV_CTRL_IDX \
                                  );
        }
        else
        {
            if(ETH_STATE_INIT != Eth_CtrlState[CtrlIdx])
            {
                (void)Det_ReportError ( \
                    (VAR(uint8, AUTOMATIC)) ETH_MODULE_ID, \
                    ETH_DRIVER_INSTANCE, (VAR(uint8, AUTOMATIC)) \
                    ETH_SID_GETTXERRORCOUNTERVALUE, ETH_E_UNINIT \
                                      );
            }
            else
            {
                if(NULL_PTR == TxErrorCounterValues)
                {
                    (void)Det_ReportError ( \
                        (VAR(uint8, AUTOMATIC)) ETH_MODULE_ID, \
                        ETH_DRIVER_INSTANCE, (VAR(uint8, AUTOMATIC)) \
                        ETH_SID_GETTXERRORCOUNTERVALUE, ETH_E_PARAM_POINTER \
                                          );
                }
                else
                {
#endif /* ETH_DEV_ERROR_DETECT  */
                    Eth_Ipw_GetTxErrorCounterValues(CtrlIdx, TxErrorCounterValues);
                    eReturnStatus = (Std_ReturnType) E_OK;
#if STD_ON == ETH_DEV_ERROR_DETECT
                } 
            }
        }
    }
#endif /* ETH_DEV_ERROR_DETECT  */

    return eReturnStatus;
}
#endif /*ETH_GET_GETTXCOUNT_API*/

#if STD_ON == ETH_GLOBALTIME_SUPPORT
/*================================================================================================*/
/**
* @brief         Returns a time value out of the HW registers according to the capability of the HW.
* @note          Is the HW  resolution is lower than the Eth_TimeStampType resolution resp. range, 
*                than an the remaining bits will be filled with 0.
* @api
* @param[in]     CtrlIdx Index of the controller shall be read the time value.
* @param[out]    timeQualPtr quality of HW time stamp, e.g. based on current drift
* @param[out]    timeStampPtr current time stamp
* @return        Error status
* @retval        +E_OK: successfully read the timestamp
* @retval        +E_NOT_OK: development error was detected or fail to read the TimeStamp.
* @violates @ref Eth_c_REF_3 For API functions (Eth.c): These functions represent the API of the driver. External linkage is needed to "export" the API.
* @implements    Eth_GetCurrentTime_Activity
*/
FUNC(Std_ReturnType, ETH_CODE) Eth_GetCurrentTime  ( \
                                VAR(uint8, AUTOMATIC) CtrlIdx, \
                                P2VAR(Eth_TimeStampQualType, AUTOMATIC, ETH_APPL_DATA) timeQualPtr, \
                                P2VAR(Eth_TimeStampType, AUTOMATIC, ETH_APPL_DATA) timeStampPtr \
                                                    )
{
    VAR(Std_ReturnType, AUTOMATIC) eReturnStatus = (VAR(Std_ReturnType, AUTOMATIC))E_NOT_OK;
    
    #if STD_ON == ETH_DEV_ERROR_DETECT
    if(CtrlIdx >= ETH_MAXCTRLS_SUPPORTED)
    {
        (void)Det_ReportError ( \
            (VAR(uint8, AUTOMATIC)) ETH_MODULE_ID, \
            ETH_DRIVER_INSTANCE, (VAR(uint8, AUTOMATIC)) \
            ETH_SID_GETCURRENTTIME, ETH_E_INV_CTRL_IDX \
                              );
    }
    else
    {
        if(ETH_STATE_INIT != Eth_CtrlState[CtrlIdx])
        {
            (void)Det_ReportError ( \
                (VAR(uint8, AUTOMATIC)) ETH_MODULE_ID, \
                ETH_DRIVER_INSTANCE, (VAR(uint8, AUTOMATIC)) \
                ETH_SID_GETCURRENTTIME, ETH_E_UNINIT \
                                  );
        }
        else
        {
            if ((NULL_PTR == timeQualPtr)||(NULL_PTR == timeStampPtr))
            {
                (void)Det_ReportError ( \
                    (VAR(uint8, AUTOMATIC)) ETH_MODULE_ID, \
                    ETH_DRIVER_INSTANCE, (VAR(uint8, AUTOMATIC)) \
                    ETH_SID_GETCURRENTTIME, ETH_E_PARAM_POINTER \
                                      );
            }
            else
            {
    #endif /* ETH_DEV_ERROR_DETECT  */
                Eth_Ipw_GetCurrentTime(CtrlIdx, timeQualPtr, timeStampPtr);
                eReturnStatus = (VAR(Std_ReturnType, AUTOMATIC))E_OK;
    #if STD_ON == ETH_DEV_ERROR_DETECT
            }
        } 
    }
    #endif /* ETH_DEV_ERROR_DETECT  */
    return(eReturnStatus);
}

/*================================================================================================*/
/**
* @brief         Activates egress time stamping on a dedicated message object.
* @note          Some HW does store once the egress time stamp marker and some HW needs it 
*                always before transmission. There will be no disable functionality, due to the fact, 
*                that the message type is always "time stamped" by network design.
* @api
* @param[in]     CtrlIdx Index of the controller which counter state shall be
*                enable the TimeStamp
* @param[in]     BufIdx Index of the message buffer, where Application expects egress time 
*                stamping
* @violates @ref Eth_c_REF_3 For API functions (Eth.c): These functions represent the API of the driver. External linkage is needed to "export" the API.
* @implements    Eth_EnableEgressTimeStamp_Activity
*/
FUNC(void, ETH_CODE) Eth_EnableEgressTimeStamp  ( \
                                VAR(uint8, AUTOMATIC) CtrlIdx, \
                                VAR(Eth_BufIdxType, AUTOMATIC) BufIdx \
                                                )
{
    #if STD_ON == ETH_DEV_ERROR_DETECT
    if(CtrlIdx >= ETH_MAXCTRLS_SUPPORTED)
    {
        (void)Det_ReportError ( \
            (VAR(uint8, AUTOMATIC)) ETH_MODULE_ID, \
            ETH_DRIVER_INSTANCE, (VAR(uint8, AUTOMATIC)) \
            ETH_SID_ENABLEEGRESSTIMESTAMP, ETH_E_INV_CTRL_IDX \
                              );
    }
    else
    {
        if(ETH_STATE_INIT != Eth_CtrlState[CtrlIdx])
        {
            (void)Det_ReportError ( \
                (VAR(uint8, AUTOMATIC)) ETH_MODULE_ID, \
                ETH_DRIVER_INSTANCE, (VAR(uint8, AUTOMATIC)) \
                ETH_SID_ENABLEEGRESSTIMESTAMP, ETH_E_UNINIT \
                                  );
        }
        else
        {
    #endif /* ETH_DEV_ERROR_DETECT  */
            Eth_Ipw_EnableEgressTimeStamp(CtrlIdx, BufIdx);
    #if STD_ON == ETH_DEV_ERROR_DETECT
        } 
    }
    #endif /* ETH_DEV_ERROR_DETECT  */
}

/*================================================================================================*/
/**
* @brief         Reads back the egress time stamp on a dedicated message object.
* @note          It must be called within the TxConfirmation() function.
* @api
* @param[in]     CtrlIdx Index of the controller which the egress timestamp shall be
*                read. 
* @param[in]     BufIdx Index of the message buffer, where Application expects egress time 
*                stamping
* @param[out]    timeQualPtr quality of HW time stamp, e.g. based on current drift
* @param[out]    timeStampPtr current time stamp
* @violates @ref Eth_c_REF_3 For API functions (Eth.c): These functions represent the API of the driver. External linkage is needed to "export" the API.
* @implements    Eth_GetEgressTimeStamp_Activity
*/
FUNC(void, ETH_CODE) Eth_GetEgressTimeStamp ( \
                                VAR(uint8, AUTOMATIC) CtrlIdx, \
                                VAR(Eth_BufIdxType, AUTOMATIC) BufIdx, \
                                P2VAR(Eth_TimeStampQualType, AUTOMATIC, ETH_APPL_DATA) timeQualPtr, \
                                P2VAR(Eth_TimeStampType, AUTOMATIC, ETH_APPL_DATA) timeStampPtr \
                                            )
{
    #if STD_ON == ETH_DEV_ERROR_DETECT

    if(CtrlIdx >= ETH_MAXCTRLS_SUPPORTED)
    {
        (void)Det_ReportError ( \
            (VAR(uint8, AUTOMATIC)) ETH_MODULE_ID, \
            ETH_DRIVER_INSTANCE, (VAR(uint8, AUTOMATIC)) \
            ETH_SID_GETEGRESSTIMESTAMP, ETH_E_INV_CTRL_IDX \
                              );
    }
    else
    {
        if(ETH_STATE_INIT != Eth_CtrlState[CtrlIdx])
        {
            (void)Det_ReportError ( \
                (VAR(uint8, AUTOMATIC)) ETH_MODULE_ID, \
                ETH_DRIVER_INSTANCE, (VAR(uint8, AUTOMATIC)) \
                ETH_SID_GETEGRESSTIMESTAMP, ETH_E_UNINIT \
                                  );
        }
        else
        {
            if ((NULL_PTR == timeQualPtr)||(NULL_PTR == timeStampPtr))
            {
                (void)Det_ReportError ( \
                    (VAR(uint8, AUTOMATIC)) ETH_MODULE_ID, \
                    ETH_DRIVER_INSTANCE, (VAR(uint8, AUTOMATIC)) \
                    ETH_SID_GETEGRESSTIMESTAMP, ETH_E_PARAM_POINTER \
                                      );
            }
            else
            {
    #endif /* ETH_DEV_ERROR_DETECT  */
                Eth_Ipw_GetEgressTimeStamp(CtrlIdx, BufIdx, timeQualPtr, timeStampPtr);
    #if STD_ON == ETH_DEV_ERROR_DETECT
            }
        } 
    }
    #endif /* ETH_DEV_ERROR_DETECT  */
}

/*================================================================================================*/
/**
* @brief         Reads back the egress time stamp on a dedicated message object.
* @note          It must be called within the TxConfirmation() function.
* @api
* @param[in]     CtrlIdx Index of the controller which the egress timestamp shall be
*                read. 
* @param[in]     DataPtr Pointer to the message buffer, where Application expects ingress 
*                time stamping
* @param[out]    timeQualPtr quality of HW time stamp, e.g. based on current drift
* @param[out]    timeStampPtr current time stamp
* @violates @ref Eth_c_REF_3 For API functions (Eth.c): These functions represent the API of the driver. External linkage is needed to "export" the API.
* @implements    Eth_GetIngressTimeStamp_Activity
*/
FUNC(void, ETH_CODE) Eth_GetIngressTimeStamp ( \
                                VAR(uint8, AUTOMATIC) CtrlIdx, \
                                P2VAR(Eth_DataType, AUTOMATIC, ETH_APPL_DATA) DataPtr, \
                                P2VAR(Eth_TimeStampQualType, AUTOMATIC, ETH_APPL_DATA) timeQualPtr, \
                                P2VAR(Eth_TimeStampType, AUTOMATIC, ETH_APPL_DATA) timeStampPtr \
                                             )
{
    #if STD_ON == ETH_DEV_ERROR_DETECT
    if(CtrlIdx >= ETH_MAXCTRLS_SUPPORTED)
    {
        (void)Det_ReportError ( \
            (VAR(uint8, AUTOMATIC)) ETH_MODULE_ID, \
            ETH_DRIVER_INSTANCE, (VAR(uint8, AUTOMATIC)) \
            ETH_SID_GETINGRESSTIMESTAMP, ETH_E_INV_CTRL_IDX \
                              );
    }
    else
    {
        if(ETH_STATE_INIT != Eth_CtrlState[CtrlIdx])
        {
            (void)Det_ReportError ( \
                (VAR(uint8, AUTOMATIC)) ETH_MODULE_ID, \
                ETH_DRIVER_INSTANCE, (VAR(uint8, AUTOMATIC)) \
                ETH_SID_GETINGRESSTIMESTAMP, ETH_E_UNINIT \
                                  );
        }
        else
        {
            if ((NULL_PTR == DataPtr)||(NULL_PTR == timeQualPtr)||(NULL_PTR == timeStampPtr))
            {
                (void)Det_ReportError ( \
                    (VAR(uint8, AUTOMATIC)) ETH_MODULE_ID, \
                    ETH_DRIVER_INSTANCE, (VAR(uint8, AUTOMATIC)) \
                    ETH_SID_GETINGRESSTIMESTAMP, ETH_E_PARAM_POINTER \
                                      );
            }
            else
            {
    #endif /* ETH_DEV_ERROR_DETECT  */
                Eth_Ipw_GetIngressTimeStamp(CtrlIdx, DataPtr, timeQualPtr, timeStampPtr);
    #if STD_ON == ETH_DEV_ERROR_DETECT
            }
        } 
    }
    #endif /* ETH_DEV_ERROR_DETECT  */
}
#endif /* ETH_GLOBALTIME_SUPPORT */

/*================================================================================================*/
/**
* @brief         Provides access to a transmit buffer of the specified
*                controller.
* @warning       The application should handle possible difference between the
*                requested and granted buffer lengths. It is not necessary to
*                use whole granted buffer i.e. some space at the end may not
*                be written.
* @api
* @param[in]     CtrlIdx Index of the controller which buffer shall be provided.
*                The index is valid within the context of the Ethernet Driver
*                only.
* @param[out]    BufIdxPtr Index to the granted transmit buffer resource.
*                It uniquely identifies the buffer in all subsequent calls of
*                functions Eth_Transmit() and Eth_TxConfirmation().
* @param[out]    BufPtr Pointer to the granted buffer. This is the space where
*                the data to be transmitted shall be stored.
* @param[in,out] LenBytePtr Buffer payload length
*                - In: desired length in bytes
*                - Out: granted length in bytes
* @return        Error and buffer status
* @retval        BUFREQ_OK: Buffer was successfully granted and no error has
*                occurred.
* @retval        BUFREQ_E_NOT_OK: A development error was detected and no buffer
*                was granted.
* @retval        BUFREQ_E_BUSY: All available buffers in use therefore no
*                buffer was granted. No error has been detected.
* @violates @ref Eth_c_REF_3 For API functions (Eth.c): These functions represent the API of the driver. External linkage is needed to "export" the API.
* @implements    Eth_ProvideTxBuffer_Activity
*/
FUNC(BufReq_ReturnType, ETH_CODE) Eth_ProvideTxBuffer( \
                            VAR(uint8, AUTOMATIC) CtrlIdx, \
                            VAR(uint8, AUTOMATIC) Priority, \
                            P2VAR(Eth_BufIdxType, AUTOMATIC, ETH_APPL_DATA) BufIdxPtr, \
                            P2P2VAR(uint8, AUTOMATIC, ETH_APPL_DATA) BufPtr, \
                            P2VAR(uint16, AUTOMATIC, ETH_APPL_DATA) LenBytePtr \
                                                     )
{
    /* Variable used to track function success status */
    VAR(BufReq_ReturnType, AUTOMATIC) eFunctionSuccess = BUFREQ_E_NOT_OK;
    VAR(uint16, AUTOMATIC) u16TempLenByte; /* Avoid changes of input
                                              parameters in case of an error */
    VAR(uint32, AUTOMATIC) u32MaxLenByte; /* Maximum available buffer length that
                                              drivers can provide*/
    VAR(uint8, AUTOMATIC) u8QueueIdx;
    VAR(uint16, AUTOMATIC) u16LenByte;
#if STD_ON == ETH_USE_MULTIBUFFER_TX_FRAMES
    VAR(uint8, AUTOMATIC) u8TotalBuf;
#endif   
#if (STD_ON == ETH_SWT_MANAGEMENT_SUPPORT_API)
    VAR(uint16, AUTOMATIC) u16Length;
    VAR(uint16, AUTOMATIC) u16ExtLength = 0U;
#endif

    #if STD_ON == ETH_DEV_ERROR_DETECT
    if(CtrlIdx >= (VAR(uint8, AUTOMATIC))ETH_MAXCTRLS_SUPPORTED)
    {
        (void)Det_ReportError ( \
            (VAR(uint8, AUTOMATIC)) ETH_MODULE_ID, \
            ETH_DRIVER_INSTANCE, (VAR(uint8, AUTOMATIC)) \
            ETH_SID_PROVIDETXBUFFER, ETH_E_INV_CTRL_IDX \
                              );
    }
    else
    {
        if(NULL_PTR == BufIdxPtr)
        {
            (void)Det_ReportError ( \
                (VAR(uint8, AUTOMATIC)) ETH_MODULE_ID, \
                ETH_DRIVER_INSTANCE, (VAR(uint8, AUTOMATIC)) \
                ETH_SID_PROVIDETXBUFFER, ETH_E_PARAM_POINTER \
                                  );
        }
        else
        {
            if(NULL_PTR == BufPtr)
            {
                (void)Det_ReportError ( \
                    (VAR(uint8, AUTOMATIC)) ETH_MODULE_ID, \
                    ETH_DRIVER_INSTANCE, (VAR(uint8, AUTOMATIC)) \
                    ETH_SID_PROVIDETXBUFFER, ETH_E_PARAM_POINTER \
                                      );
            }
            else
            {
                if(NULL_PTR == LenBytePtr)
                {
                    (void)Det_ReportError ( \
                        (VAR(uint8, AUTOMATIC)) ETH_MODULE_ID, \
                        ETH_DRIVER_INSTANCE, (VAR(uint8, AUTOMATIC)) \
                        ETH_SID_PROVIDETXBUFFER, ETH_E_PARAM_POINTER \
                                          );
                }
                else
                {
                    if(ETH_STATE_INIT != Eth_CtrlState[CtrlIdx])
                    {
                        (void)Det_ReportError ( \
                            (VAR(uint8, AUTOMATIC)) ETH_MODULE_ID, \
                            ETH_DRIVER_INSTANCE, (VAR(uint8, AUTOMATIC)) \
                            ETH_SID_PROVIDETXBUFFER, ETH_E_UNINIT \
                                              );
                    }
                    else
                    {
    #endif /* ETH_DEV_ERROR_DETECT  */
                        if (Priority < ETH_MAX_TX_PRIO_NUM)
                        {
                    #if (ETH_MAX_TXFIFO_CONFIG > 1U)
                            u8QueueIdx =  (uint8)((*(Eth_InternalCfgPtr->pController[CtrlIdx])).pDMACfg->EthTxPrioFifoMap[Priority]);
                    #else
                            u8QueueIdx = 0U;
                    #endif
                            /* Check whether the requested length is greater than
                           maximal configured one */
                            u16LenByte = (uint16)((*(Eth_InternalCfgPtr->pController[CtrlIdx])).pEgressCfg[u8QueueIdx].EthCtrlConfigEgressFifoBufLenByte);
                    #if STD_ON == ETH_USE_MULTIBUFFER_TX_FRAMES
                            u8TotalBuf = (uint8)((*(Eth_InternalCfgPtr->pController[CtrlIdx])).pEgressCfg[u8QueueIdx].EthCtrlConfigEgressFifoBufTotal);
                            u32MaxLenByte = (uint32)((uint32)((uint32)u8TotalBuf * (uint32)u16LenByte) - (uint32)14U);
                    #else
                            u32MaxLenByte = (uint32)((uint32)u16LenByte - (uint32)14U);
                    #endif  
                    #if (STD_ON == ETH_SWT_MANAGEMENT_SUPPORT_API)
                            u16Length = *LenBytePtr;
                            /*Because there're management information which is inserted so size of payload will be decreased.*/
                            /* @violates @ref Eth_c_REF_4 */
                            EthSwt_EthTxAdaptBufferLength (&u16Length);
                            if (u16Length > (uint16)(*LenBytePtr))
                            {
                                u16ExtLength = (uint16)(u16Length - (uint16)(*LenBytePtr));
                            }
                            if (u16Length > u32MaxLenByte)
                            {
                    #else
                            if (*LenBytePtr > u32MaxLenByte)
                            {
                    #endif
                               /* Requested size is too long, do not lock buffer */
                                /* Set length to maximal available payload length */
                               *LenBytePtr = (uint16)u32MaxLenByte;
                                eFunctionSuccess = BUFREQ_E_OVFL;
                            }
                            else
                            {   /* Good, the requested size fits into buffer size */
                                /* Get some space to put data in, check success */
                                u16TempLenByte = *LenBytePtr;
                                /* @violates @ref Eth_c_REF_4 */
                                if (((boolean)TRUE) == Eth_Ipw_ProvideBufferDataArea(CtrlIdx, u8QueueIdx, BufIdxPtr, BufPtr, &u16TempLenByte))
                                { /* Data space is available */
                            #if (STD_ON == ETH_SWT_MANAGEMENT_SUPPORT_API)
                                    /*Return valid value of payload field*/
                                    *LenBytePtr = (uint16)(u16TempLenByte - u16ExtLength);
                            #else
                                    *LenBytePtr = u16TempLenByte;
                            #endif
                                    eFunctionSuccess = BUFREQ_OK;
                                }
                                else
                                { /* Data space is not available */
                                    eFunctionSuccess = BUFREQ_E_BUSY;
                                }
                            }
                        }
    #if STD_ON == ETH_DEV_ERROR_DETECT
                    }
                }
            }
        }
    }
    #endif /* ETH_DEV_ERROR_DETECT  */
    
    return eFunctionSuccess;
}

/*================================================================================================*/
/**
* @brief         Triggers transmission of a previously granted and then filled
*                transmit buffer.
* @api
* @param[in]     CtrlIdx Index of the controller which buffer shall be
*                transmitted. The index is valid within the context of
*                the Ethernet Driver only.
* @param[in]     BufIdx Index of the buffer resource to be transmitted.
* @param[in]     FrameType Desired value of the Ethernet frame type in the
*                frame header.
* @param[in]     TxConfirmation Activates transmission confirmation.
* @param[in]     LenByte Buffer data length in bytes (payload length).
* @param[in]     PhysAddrPtr Physical target address (MAC address) in network
*                byte order.
* @return        Error status
* @retval        E_OK No error was detected during the function execution.
* @retval        E_NOT_OK Development error was detected and the function
*                failed.
* @violates @ref Eth_c_REF_3 For API functions (Eth.c): These functions represent the API of the driver. External linkage is needed to "export" the API.
* @implements    Eth_Transmit_Activity
*/
FUNC(Std_ReturnType, ETH_CODE) Eth_Transmit     (
                            VAR(uint8, AUTOMATIC) CtrlIdx,
                            VAR(Eth_BufIdxType, AUTOMATIC) BufIdx,
                            Eth_FrameType FrameType,
                            VAR(boolean, AUTOMATIC) TxConfirmation,
                            VAR(uint16, AUTOMATIC) LenByte,
                            P2CONST(uint8, AUTOMATIC, ETH_APPL_DATA) PhysAddrPtr
#if STD_ON == ETH_BRIDGE_SUPPORT
                          , P2CONST(uint8, AUTOMATIC, ETH_APPL_DATA) PhysSourceAddrPtr
#endif /* ETH_BRIDGE_SUPPORT  */
                                                )
{
    VAR(Std_ReturnType, AUTOMATIC) u8FunctionSuccess = (Std_ReturnType)E_NOT_OK; /* Used to track
                                                     function success */
    VAR(uint8, AUTOMATIC) u8FifoIdx;
    
    #if STD_ON == ETH_DEV_ERROR_DETECT
    if(CtrlIdx >= (VAR(uint8, AUTOMATIC))ETH_MAXCTRLS_SUPPORTED)
    {
        (void)Det_ReportError ((uint8) ETH_MODULE_ID, ETH_DRIVER_INSTANCE, (uint8) ETH_SID_TRANSMIT, ETH_E_INV_CTRL_IDX );
    }
    else
    {
        if(NULL_PTR == PhysAddrPtr)
        {
            (void)Det_ReportError ( \
                (uint8) ETH_MODULE_ID, \
                ETH_DRIVER_INSTANCE, (uint8) \
                ETH_SID_TRANSMIT, ETH_E_PARAM_POINTER \
                                  );
        }
        else
        {
            if(ETH_STATE_INIT != Eth_CtrlState[CtrlIdx])
            {
                (void)Det_ReportError ( \
                    (uint8) ETH_MODULE_ID, \
                    ETH_DRIVER_INSTANCE, (uint8) \
                    ETH_SID_TRANSMIT, ETH_E_UNINIT \
                                      );
            }
            else
            {
                if(ETH_MODE_ACTIVE != Eth_Ipw_CheckControllerIsActive(CtrlIdx))
                {
                    (void)Det_ReportError ( \
                        (uint8) ETH_MODULE_ID, \
                        ETH_DRIVER_INSTANCE, (uint8) \
                        ETH_SID_TRANSMIT, ETH_E_INV_MODE \
                                          );
                }
                else
                {
                    if (BufIdx >= ETH_TX_BUFF_MAX)
                    {
                        (void)Det_ReportError ( \
                            (uint8) \
                            ETH_MODULE_ID,  ETH_DRIVER_INSTANCE, \
                            (uint8) ETH_SID_TRANSMIT, \
                            ETH_E_INV_PARAM \
                                              );
                    }
                    else
                    {
    #endif /* ETH_DEV_ERROR_DETECT  */
    #if (STD_ON == ETH_TXFIFO_SINGLE_MODE)
                        u8FifoIdx = 0U;
    #else
                        u8FifoIdx = Eth_Ipw_FindFifoIdx (CtrlIdx, BufIdx);
    #endif
                        /* Check whether the buffer was previously locked
                           and has not been transmitted yet */
                        if((boolean)TRUE == Eth_Ipw_IsTxBufLockedBT(CtrlIdx, u8FifoIdx, BufIdx))
                        { /* Yes, transmit the buffer */
                            Eth_Ipw_Transmit(CtrlIdx, u8FifoIdx, BufIdx, FrameType, LenByte, TxConfirmation, PhysAddrPtr
    #if STD_ON == ETH_BRIDGE_SUPPORT
                                                , PhysSourceAddrPtr
    #endif /* ETH_BRIDGE_SUPPORT  */
                                            );
                            u8FunctionSuccess = (Std_ReturnType)E_OK;
                        }
                        else
                        { /* No, report an error, do not transmit buffer */
    #if STD_ON == ETH_DEV_ERROR_DETECT
                            (void)Det_ReportError ( \
                                (uint8) ETH_MODULE_ID, \
                                ETH_DRIVER_INSTANCE, (uint8) \
                                ETH_SID_TRANSMIT, ETH_E_INV_PARAM \
                                                  );
    #endif /* ETH_DEV_ERROR_DETECT  */
                            u8FunctionSuccess = (Std_ReturnType)E_NOT_OK;
                        }
    #if STD_ON == ETH_DEV_ERROR_DETECT
                    }
                }
            }
        }
    }
    #endif /* ETH_DEV_ERROR_DETECT  */
    
    return u8FunctionSuccess; 
}

/*================================================================================================*/
/**
* @brief         Triggers frames reception notifications.
* @details       All receive buffers are checked and the first received frame is
*                passed to the EthIf module. The caller is notified whether any
*                frame was received and whether more frames are available in the
*                receive queue.
* @api
* @param[in]     CtrlIdx Index of the controller which shall be checked whether
*                any new frames were received. The index is valid within
*                the context of the Ethernet Driver only.
* @param[out]    RxStatusPtr Informs the caller whether a frame was received 
*                (@c ETH_RECEIVED or @c ETH_NOT_RECEIVED) and whether more frames
*                are available in the queue (@c ETH_RECEIVED or 
*                @c ETH_RECEIVED_MORE_DATA_AVAILABLE).
* @violates @ref Eth_c_REF_3 For API functions (Eth.c): These functions represent the API of the driver. External linkage is needed to "export" the API.
* @implements    Eth_Receive_Activity
*/
FUNC(void, ETH_CODE) Eth_Receive(VAR(uint8, AUTOMATIC) CtrlIdx, \
                                    VAR(uint8, AUTOMATIC) FifoIdx,  \
                                    P2VAR(Eth_RxStatusType, AUTOMATIC, ETH_APPL_DATA) RxStatusPtr   \
                                 )   
{
    #if STD_ON == ETH_DEV_ERROR_DETECT
    if(CtrlIdx >= (VAR(uint8, AUTOMATIC))ETH_MAXCTRLS_SUPPORTED)
    {
        (void)Det_ReportError ( \
            (VAR(uint8, AUTOMATIC)) ETH_MODULE_ID, \
            ETH_DRIVER_INSTANCE, (VAR(uint8, AUTOMATIC)) ETH_SID_RECEIVE, \
            ETH_E_INV_CTRL_IDX \
                              );
    }
    else
    {
        if(ETH_STATE_INIT != Eth_CtrlState[CtrlIdx])
        {
            (void)Det_ReportError ( \
                (VAR(uint8, AUTOMATIC)) ETH_MODULE_ID, \
                ETH_DRIVER_INSTANCE, (VAR(uint8, AUTOMATIC)) ETH_SID_RECEIVE, \
                ETH_E_UNINIT \
                                  );
        }
        else
        {
            if(ETH_MODE_ACTIVE != Eth_Ipw_CheckControllerIsActive(CtrlIdx))
            {
                (void)Det_ReportError ( \
                    (VAR(uint8, AUTOMATIC)) ETH_MODULE_ID, \
                    ETH_DRIVER_INSTANCE, (VAR(uint8, AUTOMATIC)) \
                    ETH_SID_RECEIVE, ETH_E_INV_MODE \
                                      );
            }
            else
            {
    #endif /* ETH_DEV_ERROR_DETECT  */
                /* @violates @ref Eth_c_REF_5 */
                if((VAR(boolean, AUTOMATIC))FALSE == ETH_CFG_ENABLERXINTERRUPT(CtrlIdx))
                {
                    /* Check all buffers and report them - returned error
                    status is ignored because there is no mean to report errors
                    in the AUTOSAR specification */
                    *RxStatusPtr = Eth_Ipw_ReportReception(CtrlIdx, FifoIdx, (VAR(boolean, AUTOMATIC))FALSE);
                }/*ETH_CFG_ENABLERXINTERRUPT*/
    #if STD_ON == ETH_DEV_ERROR_DETECT
            }
        } 
    }
    #endif /* ETH_DEV_ERROR_DETECT  */
}

/*================================================================================================*/
/**
* @brief         Triggers frame transmission confirmations.
* @api
* @param[in]     CtrlIdx Index of the controller which shall be checked whether
*                any frame transmission has finished. The index is valid within
*                the context of the Ethernet Driver only.
* @details       All transmit buffers are checked and upper layers are informed
*                about successfully transmitted frames. Buffers containing
*                transmitted frames are unlocked after the confirmation.
* @violates @ref Eth_c_REF_3 For API functions (Eth.c): These functions represent the API of the driver. External linkage is needed to "export" the API.
* @implements    Eth_TxConfirmation_Activity
*/
FUNC(void, ETH_CODE) Eth_TxConfirmation(VAR(uint8, AUTOMATIC) CtrlIdx)
{
    VAR(boolean, AUTOMATIC) bIsInterrupt;
    VAR(uint8, AUTOMATIC) u8FifoIdx;
    
    bIsInterrupt = ETH_CFG_ENABLETXINTERRUPT(CtrlIdx);
    #if STD_ON == ETH_DEV_ERROR_DETECT
    if(CtrlIdx >= (VAR(uint8, AUTOMATIC))ETH_MAXCTRLS_SUPPORTED)
    {
        (void)Det_ReportError ( \
            (VAR(uint8, AUTOMATIC)) ETH_MODULE_ID, \
            ETH_DRIVER_INSTANCE, (VAR(uint8, AUTOMATIC)) \
            ETH_SID_TXCONFIRMATION, ETH_E_INV_CTRL_IDX \
                              );
    }
    else
    {
        if(ETH_STATE_INIT != Eth_CtrlState[CtrlIdx])
        {
            (void)Det_ReportError ( \
                (VAR(uint8, AUTOMATIC)) ETH_MODULE_ID, \
                ETH_DRIVER_INSTANCE, (VAR(uint8, AUTOMATIC)) \
                ETH_SID_TXCONFIRMATION, ETH_E_UNINIT \
                                  );
        }
        else
        {
            if(ETH_MODE_ACTIVE != Eth_Ipw_CheckControllerIsActive(CtrlIdx))
            {
                (void)Det_ReportError ( \
                    (VAR(uint8, AUTOMATIC)) ETH_MODULE_ID, \
                    ETH_DRIVER_INSTANCE, (VAR(uint8, AUTOMATIC)) \
                    ETH_SID_TXCONFIRMATION, ETH_E_INV_MODE \
                                      );
            }
            else
            {

    #endif /* ETH_DEV_ERROR_DETECT  */
                /* @violates @ref Eth_c_REF_5 */
                if((VAR(boolean, AUTOMATIC))FALSE == bIsInterrupt)
                {
                    for (u8FifoIdx = 0U; u8FifoIdx < ETH_MAX_TXFIFO_CONFIG; u8FifoIdx++)
                    {
                        /* Check all buffers and report them - returned error 
                        status is ignored because there is no mean to report errors
                        in the AUTOSAR specification */
                        Eth_Ipw_ReportTransmission(CtrlIdx, u8FifoIdx);
                    }
                   
                }/*ETH_CFG_ENABLETXINTERRUPT*/
    #if STD_ON == ETH_DEV_ERROR_DETECT
            }
        } 
    }
    #endif /* ETH_DEV_ERROR_DETECT  */
}

#if STD_ON == ETH_VERSION_INFO_API
#if STD_OFF == ETH_VERSION_INFO_API_MACRO
/*================================================================================================*/
/**
* @brief         Returns the version information of this module.
* @api
* @param[out]    VersionInfoPtr Pointer where to store the version information
*                of this particular module instance.
* @violates @ref Eth_c_REF_3 For API functions (Eth.c): These functions represent the API of the driver. External linkage is needed to "export" the API.
* @implements    Eth_GetVersionInfo_Activity
*/
FUNC(void, ETH_CODE) Eth_GetVersionInfo(P2VAR(Std_VersionInfoType, AUTOMATIC, ETH_APPL_DATA) VersionInfoPtr) 
{
    #if STD_ON == ETH_DEV_ERROR_DETECT
    if(NULL_PTR == VersionInfoPtr)
    {
        (void)Det_ReportError ( \
            (VAR(uint8, AUTOMATIC)) ETH_MODULE_ID, \
            ETH_DRIVER_INSTANCE, (VAR(uint8, AUTOMATIC)) ETH_SID_GETVERSIONINFO, ETH_E_PARAM_POINTER \
                              );
    }
    else
    {
    #endif /* ETH_DEV_ERROR_DETECT */
        VersionInfoPtr->moduleID = (VAR(uint16, AUTOMATIC))ETH_MODULE_ID;
        VersionInfoPtr->vendorID = (VAR(uint16, AUTOMATIC))ETH_VENDOR_ID;
        VersionInfoPtr->sw_major_version = (VAR(uint8, AUTOMATIC))ETH_SW_MAJOR_VERSION;
        VersionInfoPtr->sw_minor_version = (VAR(uint8, AUTOMATIC))ETH_SW_MINOR_VERSION;
        VersionInfoPtr->sw_patch_version = (VAR(uint8, AUTOMATIC))ETH_SW_PATCH_VERSION;

    #if STD_ON == ETH_DEV_ERROR_DETECT
    }
    #endif /* ETH_DEV_ERROR_DETECT */
}
#endif /* STD_OFF == ETH_VERSION_INFO_API_MACRO */
#endif /* ETH_VERSION_INFO_API */
/*================================================================================================*/
/**
* @brief         The function checks for controller errors and lost frames. Used for polling state 
*                changes. Calls EthIf_CtrlModeIndication when the controller mode changed.
* @api
* @violates @ref Eth_c_REF_3 For API functions (Eth.c): These functions represent the API of the driver. External linkage is needed to "export" the API.
* @implements    Eth_MainFunction_Activity
*/
FUNC(void, ETH_CODE) Eth_MainFunction(VAR(void, AUTOMATIC))
{
    Eth_Ipw_MainFunction();
}

#define ETH_STOP_SEC_CODE
/* @violates @ref Eth_c_REF_1 This violation is not fixed since the inclusion of Eth_MemMap.h is as per AUTOSAR requirement*/
/* @violates @ref Eth_c_REF_2 Eth_MemMap.h is included after each section define in order to set the current memory section as defined by AUTOSAR */
#include "Eth_MemMap.h"

#ifdef __cplusplus
}
#endif
/** @} */
