/*
 *  (c) Copyright 2006-2016 Freescale Semiconductor, Inc.
 *  Copyright 2017, 2019-2022 NXP
 *
 *  NXP Confidential. This software is owned or controlled by NXP and may only
 *  be used strictly in accordance with the applicable license terms. By
 *  expressly accepting such terms or by downloading, installing, activating
 *  and/or otherwise using the software, you are agreeing that you have read,
 *  and that you agree to comply with and are bound by, such license terms. If
 *  you do not agree to be bound by the applicable license terms, then you may
 *  not retain, install, activate or otherwise use the software.
 *
 *  This file contains sample code only. It is not part of the production code deliverables.
 */

#ifdef __cplusplus
extern "C"{
#endif

/*==================================================================================================
                                         INCLUDE FILES
 1) system and project includes
 2) needed interfaces from external units
 3) internal and external interfaces from this unit
==================================================================================================*/
#include "sample_app_ethswt_eth.h"

/*==================================================================================================
                                        LOCAL MACROS
==================================================================================================*/
#define TST_FRM_FILL_BYTE 0U
#define TST_FRM_LENGTH 28
#define TST_FRM_TYPE 0x0806U

#define ETH_43_PFE_START_SEC_VAR_INIT_8
#include "Eth_43_PFE_MemMap.h"

/* ARP packet */
uint8 tst_frm2_data[] =
{
    0x00U, 0x01U, /* HW type */
    0x08U, 0x00U, /* Protocol type */
    0x06U, /* HW size */
    0x04U, /* Protocol size */
    0x00U, 0x01U, /* Opcode: ARP request */
    0xd8U, 0xcbU, 0x8aU, 0xa3U, 0x7dU, 0xcfU, /* Sender MAC */
    0x00U, 0x00U, 0x00U, 0x00U, /* Sender IP */
    0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, /* Target MAC */
    0x00U, 0x00U, 0x00U, 0x00U, /* Target IP */
};

#define ETH_43_PFE_STOP_SEC_VAR_INIT_8
#include "Eth_43_PFE_MemMap.h"

/*==================================================================================================
                                      FILE VERSION CHECKS
==================================================================================================*/

/*==================================================================================================
                          LOCAL TYPEDEFS (STRUCTURES, UNIONS, ENUMS)
==================================================================================================*/

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

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

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

/*==================================================================================================
                                       GLOBAL VARIABLES
==================================================================================================*/
/* Used when running master and slave at the same time */
typedef struct
{
    uint32 rx_frm_cnt[ETH_43_PFE_NUM_CONTROLLER_CFG];
    uint32 tx_frm_cnt[ETH_43_PFE_NUM_CONTROLLER_CFG];
    uint8 mac_addr[ETH_43_PFE_NUM_CONTROLLER_CFG][6U];
    bool_t is_ready;
} device_info_t;

typedef struct
{
    device_info_t master;
    device_info_t slave;
    bool_t enable_write_mii;
    bool_t loopback_mode;
} shared_status_t;

#define ETH_43_PFE_START_SEC_VAR_INIT_32_NO_CACHEABLE
#include "Eth_43_PFE_MemMap.h"

volatile shared_status_t *p_shared_status = (volatile shared_status_t *) 0x345F4000U;

#define ETH_43_PFE_STOP_SEC_VAR_INIT_32_NO_CACHEABLE
#include "Eth_43_PFE_MemMap.h"

#define ETH_43_PFE_START_SEC_VAR_INIT_8
#include "Eth_43_PFE_MemMap.h"

/* usage scope: Tst_Pfe_SendDummyFrame */
static uint8        Priority = 0U;

#define ETH_43_PFE_STOP_SEC_VAR_INIT_8
#include "Eth_43_PFE_MemMap.h"

#define ETH_43_PFE_START_SEC_VAR_INIT_32
#include "Eth_43_PFE_MemMap.h"

extern uint32 pfeTxCtr[];
extern uint32 pfeTxErrorCtr[];

#define ETH_43_PFE_STOP_SEC_VAR_INIT_32
#include "Eth_43_PFE_MemMap.h"

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

/*==================================================================================================
                                       LOCAL FUNCTIONS
==================================================================================================*/

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

#define ETH_43_PFE_START_SEC_CODE
#include "Eth_43_PFE_MemMap.h"

Std_ReturnType Tst_Pfe_SendDummyFrame (uint8 srcCtrlIndex, uint8 *dstMacAddr)
{
    Std_ReturnType      tempRet     = E_NOT_OK;
    Eth_DataType        *bufPtr;
    Eth_BufIdxType      BufferIndex;
    uint16              LengthInBytes;
    uint16              Idx;
    BufReq_ReturnType   ProvideTxBufferResult;

    pfeTxCtr[srcCtrlIndex]++;

    LengthInBytes = TST_FRM_LENGTH;
    ProvideTxBufferResult = Eth_43_PFE_ProvideTxBuffer(srcCtrlIndex, Priority, &BufferIndex, &bufPtr, &LengthInBytes);

    if (BUFREQ_OK == ProvideTxBufferResult)
    {
        /* Write frame data */
        for (Idx = 0U; Idx < TST_FRM_LENGTH; Idx++)
        {
            bufPtr[Idx] = tst_frm2_data[Idx];
        }

        LengthInBytes = TST_FRM_LENGTH;
        tempRet = Eth_43_PFE_Transmit(srcCtrlIndex, BufferIndex, TST_FRM_TYPE, TRUE, LengthInBytes, dstMacAddr);

        if (E_OK != tempRet)
        {
            pfeTxErrorCtr[srcCtrlIndex]++;
        }
    }

    Priority = (Priority + 1) % ETH_43_PFE_MAX_TX_PRIO_NUM;

    return tempRet;
}

#ifdef LOOPBACK_TEST
uint32 Tst_Pfe_LoopbackTestFramesGood[ETH_43_PFE_NUM_CONTROLLER_CFG] = {0U};
uint32 Tst_Pfe_LoopbackTestFramesBad[ETH_43_PFE_NUM_CONTROLLER_CFG] = {0U};

/* Check if the frame matches transmitted dummy frame */
void Tst_Pfe_LoopbackTestCheckRxFrame( uint8 CtrlIdx, \
                                                        Eth_FrameType FrameType, \
                                                        bool_t IsBroadcast, \
                                                        uint8 * PhysAddrPtr, \
                                                        Eth_DataType *  DataPtr, \
                                                        uint16 LenByte
                                                      )
{
    (void)PhysAddrPtr;
    (void)LenByte;
    uint16 Idx;
    bool_t fail = FALSE;

    if(TST_FRM_TYPE != FrameType)
    {
        fail = TRUE;
    }
    if(FALSE == IsBroadcast)
    {
        fail = TRUE;
    }
    for(Idx = 0U; Idx < TST_FRM_LENGTH; Idx++)
    {
        if(TST_FRM_FILL_BYTE != DataPtr[Idx])
        {
            fail = TRUE;
        }
    }
    if(TRUE == fail)
    {
        Tst_Pfe_LoopbackTestFramesBad[CtrlIdx]++;
    }
    else
    {
        Tst_Pfe_LoopbackTestFramesGood[CtrlIdx]++;
    }
}
#endif /* LOOPBACK_TEST */

/*================================================================================================*/
/**
@brief      SampleAppEthInit - Initialize the Eth task
@details    After calling this function the task containing Eth driver should be initialized

@return     Returns the value of success
@retval     E_OK or E_NOT_OK

@pre None
@post None
*/
Std_ReturnType SampleAppEthInit(void)
{
    /* local variables here */
    Std_ReturnType  stdRet          = E_OK;
    uint8           pfeCtrlIndex    = 0U;
#ifdef USE_SJA1105P_DRIVER
    bool_t         configStatus    = (bool_t)FALSE;
#endif /* USE_SJA1105P_DRIVER */

    Eth_43_PFE_Init(NULL_PTR);

#ifdef USE_SJA1105P_DRIVER
    EthSwt_43_SJA1105P_Init(NULL_PTR);

    stdRet |= EthSwt_43_SJA1105P_SwitchInit(EthSwtConfig_0);
    stdRet |= EthSwt_43_SJA1105P_VerifyConfig(EthSwtConfig_0, &configStatus);
    if ((bool_t)FALSE == configStatus)
    {
        stdRet = E_NOT_OK;
    }
#endif /* USE_SJA1105P_DRIVER */

#if defined (PFE_CFG_PFE_MASTER)
#ifdef LOOPBACK_TEST
    /* The RX clock is not provided in loopback so configure the PHY to generate it */
    Eth_43_PFE_WriteMii(1U, 4U, 0U, 0x0140); /* Call Eth_WriteMii to disable autonegotiation, 1Gb/s */
#endif
#endif

    for (pfeCtrlIndex = 0U; pfeCtrlIndex < ETH_43_PFE_NUM_CONTROLLER_CFG; pfeCtrlIndex++)
    {
        stdRet |= Eth_43_PFE_SetControllerMode(pfeCtrlIndex, ETH_MODE_ACTIVE);
    }

    return(stdRet);
}

#define ETH_43_PFE_STOP_SEC_CODE
#include "Eth_43_PFE_MemMap.h"

/*================================================================================================*/
#ifdef __cplusplus
}
#endif

