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

/***********************************************************************************************************************
**                                              Revision Control History                                              **
***********************************************************************************************************************/
/*
 * 1.5.3: 04/11/2022    : Update QA-C comments
 * 1.5.1: 07/10/2021    : Initial Version
 */
/**********************************************************************************************************************/

/***********************************************************************************************************************
**                                                  Include Section                                                   **
***********************************************************************************************************************/
/* Included for Eth.h inclusion and macro definitions */
#include "Eth.h"
/* Header file inclusion */
#include "Eth_ETNDE_Ram.h"

#if (ETH_ETHSWITCH_MANAGEMENT_SUPPORT == STD_ON)
#include "EthSwt_Cbk.h"
#endif

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

/***********************************************************************************************************************
**                                                Version Information                                                 **
***********************************************************************************************************************/
/* AUTOSAR release version information */
#define ETH_ETNDE_RAM_C_AR_RELEASE_MAJOR_VERSION ETH_AR_RELEASE_MAJOR_VERSION_VALUE
#define ETH_ETNDE_RAM_C_AR_RELEASE_MINOR_VERSION ETH_AR_RELEASE_MINOR_VERSION_VALUE
#define ETH_ETNDE_RAM_C_AR_RELEASE_REVISION_VERSION ETH_AR_RELEASE_REVISION_VERSION_VALUE

/* File version information */
#define ETH_ETNDE_RAM_C_SW_MAJOR_VERSION    ETH_SW_MAJOR_VERSION_VALUE
#define ETH_ETNDE_RAM_C_SW_MINOR_VERSION    ETH_SW_MINOR_VERSION_VALUE

/***********************************************************************************************************************
**                                                   Version Check                                                    **
***********************************************************************************************************************/

#if (ETH_ETNDE_RAM_AR_RELEASE_MAJOR_VERSION != ETH_ETNDE_RAM_C_AR_RELEASE_MAJOR_VERSION)
  #error "Eth_ETNDE_Ram.c : Mismatch in Release Major Version"
#endif
#if (ETH_ETNDE_RAM_AR_RELEASE_MINOR_VERSION != ETH_ETNDE_RAM_C_AR_RELEASE_MINOR_VERSION)
  #error "Eth_ETNDE_Ram.c : Mismatch in Release Minor Version"
#endif
#if (ETH_ETNDE_RAM_AR_RELEASE_REVISION_VERSION != ETH_ETNDE_RAM_C_AR_RELEASE_REVISION_VERSION)
  #error "Eth_ETNDE_Ram.c : Mismatch in Release Revision Version"
#endif


#if (ETH_ETNDE_RAM_SW_MAJOR_VERSION != ETH_ETNDE_RAM_C_SW_MAJOR_VERSION)
   #error "Eth_ETNDE_Ram.c : Mismatch in Software Major Version"
#endif
#if (ETH_ETNDE_RAM_SW_MINOR_VERSION != ETH_ETNDE_RAM_C_SW_MINOR_VERSION)
   #error "Eth_ETNDE_Ram.c : Mismatch in Software Minor Version"
#endif
/***********************************************************************************************************************
**                                               Coding Rule Violations                                               **
***********************************************************************************************************************/
/* Message (1:1531)    : The object '%1s' is referenced in only one translation unit - but not the one in which it    */
/*                       is defined.                                                                                  */
/* Rule                : CERTCCM DCL15, DCL19, MISRA C:2012 Rule-8.7                                                  */
/* JV-01 Justification : Followed coding rules, the objects (global variable/const) is define in separated source     */
/*                       file, so this could be accepted                                                              */
/*       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:3432)    : Simple macro argument expression is not parenthesized.                                       */
/* Rule                : MISRA C:2012 Rule-20.7                                                                       */
/* JV-01 Justification : Compiler keyword (macro) is defined and used followed AUTOSAR standard rule. It is accepted. */
/*       Verification  : However, part of the code is verified manually and it is not having any impact.              */
/**********************************************************************************************************************/
/* Message (2:2844)    : Possible: Dereference of an invalid pointer value.                                           */
/* Rule                : CERTCCM ARR30                                                                                */
/* JV-01 Justification : To prevent overhead and excessive nesting of condition statements, this pointer has been     */
/*                       tested valid with many test cases, so there is no problem with the current implementation.   */
/*       Verification  : However, part of the code is verified manually and it is not having any impact.              */
/**********************************************************************************************************************/
/* Message (2: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: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 (3:3206)    : The parameter '%s' is not used in this function.                                             */
/* Rule                : CERTCCM MSC07, MSC13, MISRA C:2012 Rule-2.7                                                  */
/* JV-01 Justification : This is done as per implementation requirement                                               */
/*       Verification  : However, part of the code is verified manually and it is not having any impact.              */
/**********************************************************************************************************************/
/* Message (2:0316)    : Cast from a pointer to void to a pointer to object type.                                     */
/* Rule                : MISRA C:2012 Rule-11.5                                                                       */
/* JV-01 Justification : Typecasting from void* is necessary to hide internal types from the header files which are   */
/*                       exposed to user.                                                                             */
/*       Verification  : However, part of the code is verified manually and it is not having any impact.              */
/**********************************************************************************************************************/
/* Message (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 (4:2985)    : This operation is redundant. The value of the result is always that of the left-hand operand.*/
/* Rule                : CERTCCM MSC07, MSC13, MISRA C:2012 Rule-2.2                                                  */
/* JV-01 Justification : The content of LusReqSize will be changed if the user enables the EthSwt option, so the value*/
/*                       of this result is not always that of the left-hand operand.                                  */
/*       Verification  : However, part of the code is verified manually and it is not having any impact.              */
/**********************************************************************************************************************/
/* Message (2:2834)    : Possible: Division by zero.                                                                  */
/* Rule                : CERTCCM INT33                                                                                */
/* JV-01 Justification : Value generated by generation tool is always different from zero.                            */
/*       Verification  : It's not impact to driver source code implementation                                         */
/**********************************************************************************************************************/
/* Message (2:2934)    : Possible: Computing an invalid pointer value.                                                */
/* Rule                : CERTCCM ARR30, ARR37, ARR38, EXP08                                                           */
/* JV-01 Justification : To prevent overhead and excessive nesting of condition statements, this pointer has been     */
/*                       tested valid with many test cases, so there is no problem with the current implementation.   */
/*       Verification  : However, part of the code is verified manually and it is not having any impact.              */
/**********************************************************************************************************************/
/* Message (2:0306)    : Cast between a pointer to object and an integral type.                                       */
/* Rule                : CERTCCM INT36, MISRA C:2012 Rule-11.4                                                        */
/* JV-01 Justification : Typecasting is done as per the register size or hardware specific structure.                 */
/*       Verification  : However, part of the code is verified manually and it is not having any impact.              */
/**********************************************************************************************************************/
/* Message (2:0314)    : Cast from a pointer to object type to a pointer to void.                                     */
/* Rule                : MISRA C:2012 Dir-1.1                                                                         */
/* JV-01 Justification : This is necessary to set pointer value to DMA register.                                      */
/*       Verification  : However, part of the code is verified manually and it is not having any impact.              */
/**********************************************************************************************************************/
/* Message (2:3678)    : The object referenced by '%1s' is not modified through it, so '%1s' could be declared with   */
/*                       type '%2s'.                                                                                  */
/* Rule                : MISRA C:2012 Rule-8.13                                                                       */
/* JV-01 Justification : The 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 (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:0488)    : Performing pointer arithmetic.                                                               */
/* Rule                : CERTCCM EXP08, MISRA C:2012 Rule-18.4                                                        */
/* JV-01 Justification : This implementation is required for heap memory allocation algorithm                         */
/*       Verification  : However, part of the code is verified manually and it is not having any impact.              */
/**********************************************************************************************************************/
/* Message (1:1503)    : The function '%1s' is defined but is not used within this project.                           */
/* Rule                : CERTCCM MSC07, MISRA C:2012 Rule-2.1                                                         */
/* JV-01 Justification : This is accepted, due to the module's API is exported for user's usage.                      */
/*       Verification  : However, part of the code is verified manually and it is not having any impact.              */
/**********************************************************************************************************************/
/* Message (4:4391)    : A composite expression of 'essentially unsigned' type (unsigned char) is being cast to a     */
/*                       wider unsigned type 'unsigned short'.                                                        */
/* Rule                : MISRA C:2012 Rule-10.8                                                                       */
/* JV-01 Justification : This casting is necessary and is confirmed to be no problem.                                 */
/*       Verification  : However, part of the code is verified manually and it is not having any impact.              */
/**********************************************************************************************************************/
/***********************************************************************************************************************
**                                                    Global Data                                                     **
***********************************************************************************************************************/
#define ETH_START_SEC_VAR_NO_INIT_8
#include "Eth_MemMap.h"

#define ETH_STOP_SEC_VAR_NO_INIT_8
#include "Eth_MemMap.h"

#define ETH_START_SEC_VAR_NO_INIT_16
#include "Eth_MemMap.h"

#define ETH_STOP_SEC_VAR_NO_INIT_16
#include "Eth_MemMap.h"

#define ETH_START_SEC_VAR_NO_INIT_32
#include "Eth_MemMap.h"

VAR(Eth_RxFrameType, ETH_VAR_NO_INIT) Eth_GaaRxFrame[ETH_TOTAL_CTRL_CONFIG];

#if (ETH_USING_MACRO == ETH_MACRO_ETNE)
VAR(uint32, ETH_VAR_NO_INIT) Eth_GulTsDescTail;
#endif

#define ETH_STOP_SEC_VAR_NO_INIT_32
#include "Eth_MemMap.h"

#define ETH_START_SEC_VAR_NO_INIT_PTR
#include "Eth_MemMap.h"

P2VAR(void, ETH_VAR_FAST_NO_INIT, ETH_VAR_FAST_NO_INIT) Eth_GaaHeap[ETH_TOTAL_CTRL_CONFIG];

/* Global variable to store pointer to Configuration */
P2CONST(Eth_CtrlConfigType, ETH_CONST, ETH_CONFIG_CONST) volatile Eth_GpCtrlConfigPtr;
P2CONST(Eth_EthConfigType, ETH_CONST, ETH_CONFIG_CONST) volatile Eth_GpEthConfigPtr;


#define ETH_STOP_SEC_VAR_NO_INIT_PTR
#include "Eth_MemMap.h"

#define ETH_START_SEC_VAR_NO_INIT_UNSPECIFIED
#include "Eth_MemMap.h"

/* Multicast address filter list */
VAR(Eth_MacAddressType, ETH_VAR_NO_INIT) Eth_GaaAddressFilters[ETH_TOTAL_CTRL_CONFIG][ETH_MAX_FILTERS];

/* Status of controller(s) */
VAR(Eth_ControllerStatusType, ETH_VAR_NO_INIT) Eth_GaaCtrlStat[ETH_TOTAL_CTRL_CONFIG];

#define ETH_STOP_SEC_VAR_NO_INIT_UNSPECIFIED
#include "Eth_MemMap.h"

#define ETH_START_SEC_VAR_INIT_BOOLEAN
#include "Eth_MemMap.h"

#define ETH_STOP_SEC_VAR_INIT_BOOLEAN
#include "Eth_MemMap.h"

#define ETH_START_SEC_VAR_INIT_8
#include "Eth_MemMap.h"

#define ETH_STOP_SEC_VAR_INIT_8
#include "Eth_MemMap.h"

#define ETH_START_SEC_VAR_INIT_16
#include "Eth_MemMap.h"

#define ETH_STOP_SEC_VAR_INIT_16
#include "Eth_MemMap.h"

#define ETH_START_SEC_VAR_INIT_32
#include "Eth_MemMap.h"

#define ETH_STOP_SEC_VAR_INIT_32
#include "Eth_MemMap.h"


#define ETH_START_SEC_VAR_INIT_PTR
#include "Eth_MemMap.h"

#define ETH_STOP_SEC_VAR_INIT_PTR
#include "Eth_MemMap.h"

#define ETH_START_SEC_VAR_INIT_UNSPECIFIED
#include "Eth_MemMap.h"

/* Global variable to store Controller State*/
VAR(Eth_StateType, ETH_VAR_INIT) Eth_GenDriverState = ETH_STATE_UNINIT;                                                 /* PRQA S 1531 # JV-01 */

#define ETH_STOP_SEC_VAR_INIT_UNSPECIFIED
#include "Eth_MemMap.h"

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

/***********************************************************************************************************************
** Function Name         : Eth_InitializeBuffer
**
** Service ID            : N/A
**
** Description           : Initialize the Tx buffer ring
**
** Sync/Async            : Synchronous
**
** Reentrancy            : Non Reentrant
**
** Input Parameters      : LulCtrlIdx     : controller index
**
** InOut Parameters      : None
**
** Output Parameters     : None
**
** Return parameter      : None
**
** Preconditions         : None
**
** Global Variables Used : Eth_GaaTxBufferTotal,
**                         Eth_GaaTxBufferMgrTable, Eth_GaaCtrlStat,
**                         Eth_GaaRxFrame
**
** Function(s) invoked   : None
**
** Registers Used        : None
**
** Reference ID          : ETH_DUD_ACT_301,
** Reference ID          : ETH_DUD_ACT_301_GBL001, ETH_DUD_ACT_301_GBL002
** Reference ID          : ETH_DUD_ACT_301_GBL003, ETH_DUD_ACT_301_GBL004
** Reference ID          : ETH_DUD_ACT_301_GBL005, ETH_DUD_ACT_301_GBL006
** Reference ID          : ETH_DUD_ACT_301_GBL007
***********************************************************************************************************************/
FUNC(void, ETH_PRIVATE_CODE) Eth_InitializeBuffer(CONST(uint32, AUTOMATIC) LulCtrlIdx)                                  /* PRQA S 1532 # JV-01 */
{
  uint32 LulCnt;
  P2VAR(Eth_TxBufferType, AUTOMATIC, ETH_APPL_DATA) LpTxBuffer;                                                         /* PRQA S 3432 # JV-01 */

  /* Initialize resource information */
  Eth_GaaCtrlStat[LulCtrlIdx].ulTxBufTail = 0UL;                                                                        /* PRQA S 2844 # JV-01 */
  Eth_GaaRxFrame[LulCtrlIdx].ulFrameAddr = 0UL;                                                                         /* PRQA S 2844 # JV-01 */
  Eth_GaaRxFrame[LulCtrlIdx].ulEthTypeAddr = 0UL;                                                                       /* PRQA S 2844 # JV-01 */
  Eth_GaaRxFrame[LulCtrlIdx].ulFrameLength = 0UL;                                                                       /* PRQA S 2844 # JV-01 */
  Eth_GaaRxFrame[LulCtrlIdx].ulTsns = 0UL;                                                                              /* PRQA S 2844 # JV-01 */
  Eth_GaaRxFrame[LulCtrlIdx].ulTss = 0UL;                                                                               /* PRQA S 2844 # JV-01 */

  /* Initialize Tx buffer index list */
  for (LulCnt = 0UL; LulCnt < Eth_GaaTxBufferTotal[LulCtrlIdx]; LulCnt++)                                               /* PRQA S 2844 # JV-01 */
  {
    LpTxBuffer = (P2VAR(Eth_TxBufferType, AUTOMATIC, ETH_APPL_DATA))&Eth_GaaTxBufferMgrTable[LulCtrlIdx][LulCnt];       /* PRQA S 3432, 2844, 2824 # JV-01, JV-01, JV-01 */
    LpTxBuffer->pBufferHdr = NULL_PTR;                                                                                  /* PRQA S 2814 # JV-01 */
    LpTxBuffer->blTxOngoing = ETH_FALSE;
  }
}

/***********************************************************************************************************************
** Function Name         : Eth_PreprocessBuffer
**
** Service ID            : N/A
**
** Description           : Write source address to all Tx Buffers in advance
**                         because source address is never changed while
**                         a controller mode is ACTIVE.
**
** Sync/Async            : Synchronous
**
** Reentrancy            : Non Reentrant
**
** Input Parameters      : LulCtrlIdx     : controller index
**
** InOut Parameters      : None
**
** Output Parameters     : None
**
** Return parameter      : None
**
** Preconditions         : None
**
** Global Variables Used : None
**
** Function(s) invoked   : None
**
** Registers Used        : None
***********************************************************************************************************************/
FUNC(void, ETH_PRIVATE_CODE) Eth_PreprocessBuffer(CONST(uint32, AUTOMATIC) LulCtrlIdx)                                  /* PRQA S 1532, 3206 # JV-01, JV-01 */
{
  /* No action required because this function is retained for ETNC compatibility. */
}

/***********************************************************************************************************************
** Function Name         : Eth_GetTxBuffer
**
** Service ID            : N/A
**
** Description           : Get a buffer from the Tx buffer ring
**
** Sync/Async            : Synchronous
**
** Reentrancy            : Reentrant
**
** Input Parameters      : LulCtrlIdx     : controller index
**
** InOut Parameters      : None
**
** Output Parameters     : None
**
** Return parameter      : A index of acquired buffer
**
** Preconditions         : None
**
** Global Variables Used : Eth_GaaTxBufferMgrTable, Eth_GaaTxBufferTotal,
**                         Eth_GaaCtrlStat, Eth_GaaHeap, Eth_GpCtrlConfigPtr
**
** Function(s) invoked   : None
**
** Registers Used        : None
**
** Reference ID          : ETH_DUD_ACT_303
** Reference ID          : ETH_DUD_ACT_303_CRT001, ETH_DUD_ACT_303_CRT002
** Reference ID          : ETH_DUD_ACT_303_GBL001, ETH_DUD_ACT_303_GBL002,
** Reference ID          : ETH_DUD_ACT_303_GBL003
***********************************************************************************************************************/
FUNC(BufReq_ReturnType , ETH_PRIVATE_CODE) Eth_GetTxBuffer(                                                             /* PRQA S 1532 # JV-01 */
  CONST(uint32, AUTOMATIC) LulCtrlIdx,
  CONST(uint8, AUTOMATIC) LucPriority,
  CONSTP2VAR(Eth_BufIdxType, AUTOMATIC, ETH_APPL_DATA) LpBufIdxPtr,                                                     /* PRQA S 3432 # JV-01 */
  CONSTP2VAR(uint8*, AUTOMATIC, ETH_APPL_DATA) LpBufPtr,                                                                /* PRQA S 3432 # JV-01 */
  CONSTP2VAR(uint16, AUTOMATIC, ETH_APPL_DATA) LenBytePtr)                                                              /* PRQA S 3432 # JV-01 */
{
  P2CONST(Eth_ETNDEConfigType, AUTOMATIC, ETH_APPL_DATA) LpHwUnitConfig;
  BufReq_ReturnType LenReturnValue;
  Eth_BufHandlerType* LpTxBufferNode;
  uint32 LulRingIdx;
  uint32 LulTxBufferMax;
  uint16 LusTxPayloadMax;
  uint16 LusReqSize;
  #if (ETH_ETHSWITCH_MANAGEMENT_SUPPORT == STD_ON)
  P2VAR(uint8, AUTOMATIC, ETH_APPL_DATA) LpDataPtr;                                                                     /* PRQA S 3432 # JV-01 */
  Std_ReturnType LucReturnValue;
  #endif

  LpHwUnitConfig =
    (P2CONST(Eth_ETNDEConfigType, AUTOMATIC, ETH_APPL_DATA))Eth_GpCtrlConfigPtr[LulCtrlIdx].pHwUnitConfig;              /* PRQA S 0316 # JV-01 */
  LulTxBufferMax = LpHwUnitConfig->stQueueConfig.pTxQueueConfig[LucPriority].ulQueueBufs;                               /* PRQA S 2814, 2824 # JV-01, JV-01 */
  LusTxPayloadMax =
    (uint16)(LpHwUnitConfig->stQueueConfig.pTxQueueConfig[LucPriority].ulMaxFrameSize - ETH_HEADER_SIZE);               /* PRQA S 3383 # JV-01 */

  /* If the requested size is smaller than the minimum size, expand it to the minimum size */
  if ((uint16)ETH_MIN_PAYLOAD_SIZE > *LenBytePtr)                                                                       /* PRQA S 2814 # JV-01 */
  {
    *LenBytePtr = (uint16)ETH_MIN_PAYLOAD_SIZE;
  } /* else: No action required */

  LusReqSize = *LenBytePtr;
  #if (ETH_ETHSWITCH_MANAGEMENT_SUPPORT == STD_ON)
  /* Added Switch Management Information */
  EthSwt_EthTxAdaptBufferLength(&LusReqSize);
  #endif

  if (0UL == LulTxBufferMax)
  {
    LenReturnValue = BUFREQ_E_NOT_OK;
  }
  else if (LusReqSize > LusTxPayloadMax)
  {
    /* If the requested size is larger than the buffer, return error */
    *LenBytePtr = LusTxPayloadMax - (LusReqSize - *LenBytePtr);                                                         /* PRQA S 2985 # JV-01 */
    LenReturnValue = BUFREQ_E_OVFL;
  }
  else
  {
    /* Enter the critical section protection */
    ETH_ENTER_CRITICAL_SECTION(ETH_RAM_DATA_PROTECTION);

    /* Check the number of the Tx buffers allocated */
    if (Eth_GaaCtrlStat[LulCtrlIdx].stHwStat.pTxAllocCnt[LucPriority] < LulTxBufferMax)                                 /* PRQA S 2844, 2824 # JV-01, JV-01 */
    {
      /* Get tx buffer index */
      LulRingIdx = Eth_GaaCtrlStat[LulCtrlIdx].ulTxBufTail;
      /* This process never goes into an infinite loop */
      while (NULL_PTR != Eth_GaaTxBufferMgrTable[LulCtrlIdx][LulRingIdx].pBufferHdr)                                    /* PRQA S 2844, 2824 # JV-01, JV-01 */
      {
        /* Next buffer index */
        LulRingIdx = (LulRingIdx + 1UL) % Eth_GaaTxBufferTotal[LulCtrlIdx];                                             /* PRQA S 3383, 2834, 2844 # JV-01, JV-01, JV-01 */
      }

      /* Get the Tx buffer management node and Tx buffer */
      LpTxBufferNode = (Eth_BufHandlerType *)Eth_Util_RamAlloc(&Eth_GaaHeap[LulCtrlIdx],                                /* PRQA S 0316, 2934 # JV-01, JV-01 */
        (uint32)(LusReqSize + ETH_HEADER_SIZE + sizeof(Eth_BufHandlerType)));                                           /* PRQA S 3383 # JV-01 */
      if (NULL_PTR != LpTxBufferNode)
      {
        /* Set next buffer index */
        Eth_GaaCtrlStat[LulCtrlIdx].ulTxBufTail = (LulRingIdx + 1UL) % Eth_GaaTxBufferTotal[LulCtrlIdx];                /* PRQA S 2844, 3383, 2834 # JV-01, JV-01, JV-01 */

        Eth_GaaTxBufferMgrTable[LulCtrlIdx][LulRingIdx].pBufferHdr = LpTxBufferNode;
        Eth_GaaTxBufferMgrTable[LulCtrlIdx][LulRingIdx].blTxOngoing = ETH_FALSE;

        LpTxBufferNode->ulbufIdx = LulRingIdx;
        LpTxBufferNode->ulbufAddr = (uint32)LpTxBufferNode + (uint32)sizeof(Eth_BufHandlerType);                        /* PRQA S 0306, 3383 # JV-01, JV-01 */
        LpTxBufferNode->ulTxLength  = 0UL;
        LpTxBufferNode->ucPriority  = LucPriority;
        LpTxBufferNode->blbenableTS = ETH_FALSE;
        LpTxBufferNode->blTxConfirm = ETH_FALSE;
        #if (ETH_GLOBAL_TIME_SUPPORT == STD_ON)
        LpTxBufferNode->enTimeQual = ETH_INVALID;
        LpTxBufferNode->stTimeStamp.nanoseconds = (uint32)0UL;
        LpTxBufferNode->stTimeStamp.seconds     = (uint32)0UL;
        LpTxBufferNode->stTimeStamp.secondsHi   = (uint16)0U;
        #endif

        *LpBufIdxPtr = (Eth_BufIdxType)LpTxBufferNode->ulbufIdx;                                                        /* PRQA S 2814 # JV-01 */
        *LpBufPtr = (uint8 *)(LpTxBufferNode->ulbufAddr + (uint32)ETH_HEADER_SIZE);                                     /* PRQA S 2814, 0306, 3383 # JV-01, JV-01, JV-01 */
        LpTxBufferNode->ulEthTypeAddr = LpTxBufferNode->ulbufAddr + ETH_SRC_DST_ADDRESS_SIZE;                           /* PRQA S 3383 # JV-01 */

        #if (ETH_ETHSWITCH_MANAGEMENT_SUPPORT == STD_ON)
        LpDataPtr = (uint8 *)LpTxBufferNode->ulEthTypeAddr;                                                             /* PRQA S 0306 # JV-01 */
        /* Added Switch Management Information */
        LusReqSize = *LenBytePtr;
        /* Since the maximum value of controller index is 1, casting to uint8 does no problem. */
        LucReturnValue = EthSwt_EthTxPrepareFrame((uint8)LulCtrlIdx, *LpBufIdxPtr, &LpDataPtr, &LusReqSize);
        if (E_OK == LucReturnValue)
        {
          LpTxBufferNode->ulEthTypeAddr = (uint32)LpDataPtr;                                                            /* PRQA S 0306 # JV-01 */
          *LpBufPtr = (uint8 *)((uint32)LpDataPtr + ETH_ETHERTYPE_SIZE);                                                /* PRQA S 0306, 3383 # JV-01, JV-01 */
        } /* else: No action required. If it is not a switch frame, use it as a normal frame */
        #endif

        LenReturnValue = BUFREQ_OK;

        /* Increment Tx buffer counter */
        Eth_GaaCtrlStat[LulCtrlIdx].stHwStat.pTxAllocCnt[LucPriority]++;                                                /* PRQA S 2824, 2844 # JV-01, JV-01 */
      }
      else
      {
        LenReturnValue = BUFREQ_E_BUSY;
      }
    }
    else
    {
      LenReturnValue = BUFREQ_E_BUSY;
    }
    /* Exit the critical section protection */
    ETH_EXIT_CRITICAL_SECTION(ETH_RAM_DATA_PROTECTION);
  }

  return LenReturnValue;
}

/***********************************************************************************************************************
** Function Name         : Eth_ReleaseTxBuffer
**
** Service ID            : N/A
**
** Description           : Release a Tx buffer and store it to the tail of the
**                         Tx buffer ring
**
** Sync/Async            : Synchronous
**
** Reentrancy            : Reentrant
**
** Input Parameters      : LulCtrlIdx     : controller index
**                         LulBufIdx      : index of a tx buffer
**
** InOut Parameters      : None
**
** Output Parameters     : None
**
** Return parameter      : None
**
** Preconditions         : None
**
** Global Variables Used : Eth_GaaHeap, Eth_GaaTxBufferMgrTable, Eth_GaaCtrlStat
**
** Function(s) invoked   : Eth_Util_RamFree
**
** Registers Used        : None
**
** Reference ID          : ETH_DUD_ACT_304,
** Reference ID          : ETH_DUD_ACT_304_GBL001, ETH_DUD_ACT_304_GBL002
** Reference ID          : ETH_DUD_ACT_304_GBL003, ETH_DUD_ACT_304_GBL004
***********************************************************************************************************************/
FUNC(void, ETH_PRIVATE_CODE) Eth_ReleaseTxBuffer(                                                                       /* PRQA S 1532 # JV-01 */
  CONST(uint32, AUTOMATIC) LulCtrlIdx, CONST(uint32, AUTOMATIC) LulBufIdx)
{
  CONST(uint32, AUTOMATIC) LulPriority = Eth_GaaTxBufferMgrTable[LulCtrlIdx][LulBufIdx].pBufferHdr->ucPriority;         /* PRQA S 2844, 2824, 2814 # JV-01, JV-01, JV-01 */

  /* Release tx buffer handler */
  Eth_Util_RamFree(&Eth_GaaHeap[LulCtrlIdx], (void *)Eth_GaaTxBufferMgrTable[LulCtrlIdx][LulBufIdx].pBufferHdr);        /* PRQA S 2934, 0314 # JV-01, JV-01 */
  Eth_GaaTxBufferMgrTable[LulCtrlIdx][LulBufIdx].pBufferHdr = NULL_PTR;
  Eth_GaaCtrlStat[LulCtrlIdx].stHwStat.pTxAllocCnt[LulPriority]--;                                                      /* PRQA S 2844, 2824, 3383 # JV-01, JV-01, JV-01 */
}

/***********************************************************************************************************************
** Function Name         : Eth_PreprocessFrame
**
** Service ID            : N/A
**
** Description           : This function sets the destination MAC address
**                         and Ethernet type for the Tx buffer.
**
** Sync/Async            : Synchronous
**
** Reentrancy            : Non-Reentrant
**
** Input Parameters      : LulCtrlIdx     : controller index
**                         LulBufIdx      : index to the buffer
**                         LulFrameType   : ether type
**                         LpPhysAddrPtr  : destination mac address
**                         LpPayloadLen   : payload length
**
** InOut Parameters      : None
**
** Output Parameters     : None
**
** Return parameter      : None
**
** Preconditions         : None
**
** Global Variables Used : Eth_GaaCtrlStat
**
** Function(s) invoked   : EthSwt_EthTxProcessFrame,
**                         ETH_ENTER_CRITICAL_SECTION, ETH_EXIT_CRITICAL_SECTION
**
** Registers Used        : None
**
** Reference ID          : ETH_DUD_ACT_305,
** Reference ID          : ETH_DUD_ACT_305_CRT001, ETH_DUD_ACT_305_CRT002
***********************************************************************************************************************/
FUNC(void, ETH_PRIVATE_CODE) Eth_PreprocessFrame(                                                                       /* PRQA S 1532 # JV-01 */
  CONST(uint32, AUTOMATIC) LulCtrlIdx,
  CONST(uint32, AUTOMATIC) LulBufIdx,
  CONST(uint32, AUTOMATIC) LulFrameType,
  CONSTP2CONST(uint8, AUTOMATIC, ETH_APPL_DATA) LpPhysAddrPtr,
  CONSTP2VAR(uint16, AUTOMATIC, ETH_APPL_DATA) LpPayloadLen)                                                            /* PRQA S 3432, 3206 # JV-01, JV-01 */
{
  P2VAR(Eth_DataType, AUTOMATIC, ETH_APPL_DATA) LpBufPtr;                                                               /* PRQA S 3432 # JV-01 */
  P2VAR(Eth_BufHandlerType, AUTOMATIC, ETH_APPL_DATA) LpBufHandlerPtr;                                                  /* PRQA S 3432, 3678 # JV-01, JV-01 */
  #if (ETH_ETHSWITCH_MANAGEMENT_SUPPORT == STD_ON)
  P2VAR(uint8, AUTOMATIC, ETH_APPL_DATA) LpDataPtr;                                                                     /* PRQA S 3432 # JV-01 */
  uint16 LusTxLength;
  Std_ReturnType LucReturnValue;
  #endif

  ETH_ENTER_CRITICAL_SECTION(ETH_RAM_DATA_PROTECTION);

  /* Get Tx buffer address */
  LpBufHandlerPtr = Eth_GaaTxBufferMgrTable[LulCtrlIdx][LulBufIdx].pBufferHdr;                                          /* PRQA S 2844, 2824 # JV-01, JV-01 */

  ETH_EXIT_CRITICAL_SECTION(ETH_RAM_DATA_PROTECTION);

  LpBufPtr = (Eth_DataType *)LpBufHandlerPtr->ulbufAddr;                                                                /* PRQA S 0306, 2814 # JV-01, JV-01 */

  #if (ETH_ETHSWITCH_MANAGEMENT_SUPPORT == STD_ON)
  LpDataPtr = (P2VAR(uint8, AUTOMATIC, ETH_APPL_DATA))(LpBufHandlerPtr->ulbufAddr + ETH_SRC_DST_ADDRESS_SIZE);          /* PRQA S 0306, 3432, 3383 # JV-01, JV-01, JV-01 */
  /* Since the maximum value of buffer size is 1518, casting to uint16 does no problem. */
  LusTxLength = *LpPayloadLen;                                                                                          /* PRQA S 2814 # JV-01 */
  /* decreased by the management information length */
  /* Since the maximum value of controller index is 1, casting to uint8 does no problem. */
  LucReturnValue = EthSwt_EthTxProcessFrame((uint8)LulCtrlIdx, LpBufHandlerPtr->ulbufIdx, &LpDataPtr, &LusTxLength);
  if (E_OK == LucReturnValue)
  {
    /* Adjusted for switch processing */
    LpBufPtr = (Eth_DataType *)(LpBufHandlerPtr->ulEthTypeAddr -                                                        /* PRQA S 0306, 3383 # JV-01, JV-01 */
                                (ETH_SRC_DST_ADDRESS_SIZE + (uint32)(LusTxLength - *LpPayloadLen)));                    /* PRQA S 4391, 3383 # JV-01, JV-01 */
    LpBufHandlerPtr->ulbufAddr = (uint32)LpBufPtr;                                                                      /* PRQA S 0306 # JV-01 */
    *LpPayloadLen = LusTxLength;
  } /* else: No action required. If EthSwt_SetMgmtInfo is not called, normal operation */
  #endif

  /* Copy destination address */
  ETH_COPY_MAC_ADDRESS((CONST(uint8, AUTOMATIC) *)LpPhysAddrPtr, (uint8 *)LpBufPtr);                                    /* PRQA S 3469, 2824 # JV-01, JV-01 */
  LpBufPtr = LpBufPtr + ETH_MACADDR_SIZE;                                                                               /* PRQA S 0488 # JV-01 */

  ETH_UNPACK_ADDRESS_TO_8(Eth_GaaCtrlStat[LulCtrlIdx].stMacAddr, LpBufPtr);                                             /* PRQA S 3469, 2844, 2824 # JV-01, JV-01, JV-01 */

  /* Casted to uint8 to extract the required 1 byte. */
  LpBufPtr = (Eth_DataType *)LpBufHandlerPtr->ulEthTypeAddr;                                                            /* PRQA S 0306 # JV-01 */
  *LpBufPtr = (Eth_DataType)((uint8)(LulFrameType >> ETH_BYTE_BITS));                                                   /* PRQA S 2814 # JV-01 */
  LpBufPtr++;                                                                                                           /* PRQA S 2824 # JV-01 */
  /* Casted to uint8 to extract the required 1 byte. */
  *LpBufPtr = (Eth_DataType)((uint8)LulFrameType);                                                                      /* PRQA S 2814 # JV-01 */
}

/***********************************************************************************************************************
** Function Name         : Eth_CheckProvideBuffer
**
** Service ID            : N/A
**
** Description           : This function checks whether the memory
**                         at the specified buffer index has been allocated.
**
** Sync/Async            : Synchronous
**
** Reentrancy            : Non-Reentrant
**
** Input Parameters      : LulCtrlIdx     : controller index
**                         LulBufIdx      : index to the buffer
**
** InOut Parameters      : None
**
** Output Parameters     : None
**
** Return parameter      : None
**
** Preconditions         : None
**
** Global Variables Used : Eth_GaaTxBufferMgrTable
**
** Function(s) invoked   : None
**
** Registers Used        : None
**
** Reference ID          : ETH_DUD_ACT_306
***********************************************************************************************************************/
FUNC(Std_ReturnType, ETH_PRIVATE_CODE) Eth_CheckProvideBuffer(                                                          /* PRQA S 1532 # JV-01 */
  CONST(uint32, AUTOMATIC) LulCtrlIdx, CONST(uint32, AUTOMATIC) LulBufIdx)
{
  Std_ReturnType LucReturnValue;

  /* Find tx buffer handler */
  if ((NULL_PTR != Eth_GaaTxBufferMgrTable[LulCtrlIdx][LulBufIdx].pBufferHdr) &&                                        /* PRQA S 2844, 2824 # JV-01, JV-01 */
      (ETH_FALSE == Eth_GaaTxBufferMgrTable[LulCtrlIdx][LulBufIdx].blTxOngoing))
  {
    LucReturnValue = E_OK;
  }
  else
  {
    LucReturnValue = E_NOT_OK;
  }

  return LucReturnValue;
}

/***********************************************************************************************************************
** Function Name         : Eth_FindTxBufferHandler
**
** Service ID            : NA
**
** Description           : This get the tx buffer handler associated with
**                         the specified buffer index.
**
** Sync/Async            : Synchronous
**
** Reentrancy            : Non-Reentrant
**
** Input Parameters      : LulCtrlIdx - Index of controller
**                         LulBufIdx  - Index of tx buffer
**
** InOut Parameters      : None
**
** Output Parameters     : None
**
** Return parameter      : None
**
** Preconditions         : None
**
** Global Variable(s)    : Eth_GaaTxBufferMgrTable
**
** Function(s) invoked   : None
**
** Registers Used        : None
**
** Reference ID          : ETH_DUD_ACT_333
***********************************************************************************************************************/
FUNC(Eth_BufHandlerType *, ETH_PRIVATE_CODE) Eth_FindTxBufferHandler(                                                   /* PRQA S 1532 # JV-01 */
  CONST(uint32, AUTOMATIC) LulCtrlIdx, CONST(uint32, AUTOMATIC) LulBufIdx)
{
  return Eth_GaaTxBufferMgrTable[LulCtrlIdx][LulBufIdx].pBufferHdr;                                                     /* PRQA S 2844, 2824 # JV-01, JV-01 */
}
#define ETH_STOP_SEC_PRIVATE_CODE
#include "Eth_MemMap.h"

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