This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TDA4VM: Connect two TDA4VM with SGMII MAC-MAC but link down

Part Number: TDA4VM


Our customer has tried to connect two TDA4VM with MAC-MAC SGMII mode. They have followed the instruction on our FAQ E2E: https://e2e.ti.com/support/processors-group/processors/f/processors-forum/936840/faq-dra829vxevm-is-it-possible-to-connect-two-dra829-evms-via-sgmii  . Their SDK is 7.2 and they use Serdes0 lane 1.

We have changed related dts and PDK. Attachments are what customer did, however when we read the link register it shows link down. And we cannot ping successfully.

Although in master’s log we can see link-up status, however when read the register directly it shows:

And the script is:

TDA4_SGMII.rar

From my point of view, there are two points need to be considered. One is whether Serdes0 is configured correctly, we checked this by read MMRSerdes and MMRENET CTRL register:

 

Both of them are configured to SGMII mode.

I also checked the changing of their PDK code, it seems fine.

Can you help share any ideas that we can apply to analyze this link down issue?

Their linux changes are: 

https://e2e.ti.com/cfs-file/__key/communityserver-discussions-components-files/791/serders0_5F00_line1.patch

And their RTOS changes are:

/******************************************************************************
 * Copyright (c) 2019 Texas Instruments Incorporated - http://www.ti.com
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *    Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 *    Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the
 *    distribution.
 *
 *    Neither the name of Texas Instruments Incorporated nor the names of
 *    its contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *****************************************************************************/
/**
 *  \file   board_cfg.c
 *
 *  \brief  EVM serdes configuration file
 *
 *  Configures the serdes module.
 *
 */

#include "board_serdes_cfg.h"

static Board_STATUS Board_CfgSgmii_serdes0_lan0(void)
{
    CSL_SerdesResult result;
    CSL_SerdesLaneEnableStatus laneRetVal = CSL_SERDES_LANE_ENABLE_NO_ERR;
    CSL_SerdesLaneEnableParams serdesLane0EnableParams  = {0};

    memset(&serdesLane0EnableParams, 0, sizeof(serdesLane0EnableParams));

    /* SGMII Config */
    serdesLane0EnableParams.serdesInstance    = (CSL_SerdesInstance)CSL_SIERRA_SERDES0;
    serdesLane0EnableParams.baseAddr          = CSL_SERDES_16G0_BASE;
    serdesLane0EnableParams.refClock          = CSL_SERDES_REF_CLOCK_100M;
    serdesLane0EnableParams.refClkSrc         = CSL_SERDES_REF_CLOCK_INT;
    serdesLane0EnableParams.linkRate          = CSL_SERDES_LINK_RATE_1p25G;
    serdesLane0EnableParams.numLanes          = 0x2;
    serdesLane0EnableParams.laneMask          = 0x3;
    serdesLane0EnableParams.SSC_mode          = CSL_SERDES_NO_SSC;
    serdesLane0EnableParams.phyType           = CSL_SERDES_PHY_TYPE_SGMII;
    serdesLane0EnableParams.operatingMode     = CSL_SERDES_FUNCTIONAL_MODE;
    serdesLane0EnableParams.phyInstanceNum    = SERDES_LANE_SELECT_CPSW;
    serdesLane0EnableParams.pcieGenType        = CSL_SERDES_PCIE_GEN3;

    serdesLane0EnableParams.laneCtrlRate[0]   = CSL_SERDES_LANE_FULL_RATE;
    serdesLane0EnableParams.loopbackMode[0]   = CSL_SERDES_LOOPBACK_DISABLED;

    serdesLane0EnableParams.laneCtrlRate[1]   = CSL_SERDES_LANE_FULL_RATE;
    serdesLane0EnableParams.loopbackMode[1]   = CSL_SERDES_LOOPBACK_DISABLED;

    CSL_serdesPorReset(serdesLane0EnableParams.baseAddr);

    /* Select the IP type, IP instance num, Serdes Lane Number */
    CSL_serdesIPSelect(CSL_CTRL_MMR0_CFG0_BASE,
                       serdesLane0EnableParams.phyType,
                       serdesLane0EnableParams.phyInstanceNum,
                       serdesLane0EnableParams.serdesInstance,
                       0U);


    result = CSL_serdesRefclkSel(CSL_CTRL_MMR0_CFG0_BASE,
                                 serdesLane0EnableParams.baseAddr,
                                 serdesLane0EnableParams.refClock,
                                 serdesLane0EnableParams.refClkSrc,
                                 serdesLane0EnableParams.serdesInstance,
                                 serdesLane0EnableParams.phyType);

    if (result != CSL_SERDES_NO_ERR)
    {
        return BOARD_FAIL;
    }
    /* Assert PHY reset and disable all lanes */
    CSL_serdesDisablePllAndLanes(serdesLane0EnableParams.baseAddr, serdesLane0EnableParams.numLanes,
                                 serdesLane0EnableParams.laneMask);

    /* Load the Serdes Config File */
    result = CSL_serdesEthernetInit(&serdesLane0EnableParams);
    /* Return error if input params are invalid */
    if (result != CSL_SERDES_NO_ERR)
    {
        return BOARD_FAIL;
    }

    /* Common Lane Enable API for lane enable, pll enable etc */
    laneRetVal = CSL_serdesLaneEnable(&serdesLane0EnableParams);
    if (laneRetVal != 0)
    {
        return BOARD_FAIL;
    }

    return BOARD_SOK;
}

static Board_STATUS Board_CfgSgmii_serdes0_lan1(void)
{
    CSL_SerdesResult result;
    CSL_SerdesLaneEnableStatus laneRetVal = CSL_SERDES_LANE_ENABLE_NO_ERR;
    CSL_SerdesLaneEnableParams serdesLane0EnableParams  = {0};

    memset(&serdesLane0EnableParams, 0, sizeof(serdesLane0EnableParams));

    /* SGMII Config */
    serdesLane0EnableParams.serdesInstance    = (CSL_SerdesInstance)CSL_SIERRA_SERDES0;
    serdesLane0EnableParams.baseAddr          = CSL_SERDES_16G0_BASE;
    serdesLane0EnableParams.refClock          = CSL_SERDES_REF_CLOCK_100M;
    serdesLane0EnableParams.refClkSrc         = CSL_SERDES_REF_CLOCK_INT;
    serdesLane0EnableParams.linkRate          = CSL_SERDES_LINK_RATE_1p25G;
    serdesLane0EnableParams.numLanes          = 0x2;
    serdesLane0EnableParams.laneMask          = 0x3;
    serdesLane0EnableParams.SSC_mode          = CSL_SERDES_NO_SSC;
    serdesLane0EnableParams.phyType           = CSL_SERDES_PHY_TYPE_SGMII;
    serdesLane0EnableParams.operatingMode     = CSL_SERDES_FUNCTIONAL_MODE;
    serdesLane0EnableParams.phyInstanceNum    = SERDES_LANE_SELECT_CPSW;
    serdesLane0EnableParams.pcieGenType        = CSL_SERDES_PCIE_GEN3;

    serdesLane0EnableParams.laneCtrlRate[0]   = CSL_SERDES_LANE_FULL_RATE;
    serdesLane0EnableParams.loopbackMode[0]   = CSL_SERDES_LOOPBACK_DISABLED;

    serdesLane0EnableParams.laneCtrlRate[1]   = CSL_SERDES_LANE_FULL_RATE;
    serdesLane0EnableParams.loopbackMode[1]   = CSL_SERDES_LOOPBACK_DISABLED;

    CSL_serdesPorReset(serdesLane0EnableParams.baseAddr);

    /* Select the IP type, IP instance num, Serdes Lane Number */
    CSL_serdesIPSelect(CSL_CTRL_MMR0_CFG0_BASE,
                       serdesLane0EnableParams.phyType,
                       serdesLane0EnableParams.phyInstanceNum,
                       serdesLane0EnableParams.serdesInstance,
                       1U);


    result = CSL_serdesRefclkSel(CSL_CTRL_MMR0_CFG0_BASE,
                                 serdesLane0EnableParams.baseAddr,
                                 serdesLane0EnableParams.refClock,
                                 serdesLane0EnableParams.refClkSrc,
                                 serdesLane0EnableParams.serdesInstance,
                                 serdesLane0EnableParams.phyType);

    if (result != CSL_SERDES_NO_ERR)
    {
        return BOARD_FAIL;
    }
    /* Assert PHY reset and disable all lanes */
    CSL_serdesDisablePllAndLanes(serdesLane0EnableParams.baseAddr, serdesLane0EnableParams.numLanes,
                                 serdesLane0EnableParams.laneMask);

    /* Load the Serdes Config File */
    result = CSL_serdesEthernetInit(&serdesLane0EnableParams);
    /* Return error if input params are invalid */
    if (result != CSL_SERDES_NO_ERR)
    {
        return BOARD_FAIL;
    }

    /* Common Lane Enable API for lane enable, pll enable etc */
    laneRetVal = CSL_serdesLaneEnable(&serdesLane0EnableParams);
    if (laneRetVal != 0)
    {
        return BOARD_FAIL;
    }

    return BOARD_SOK;
}

static Board_STATUS Board_CfgQsgmii(void)
{
    CSL_SerdesResult result;
    CSL_SerdesLaneEnableStatus laneRetVal = CSL_SERDES_LANE_ENABLE_NO_ERR;
    CSL_SerdesLaneEnableParams serdesLane0EnableParams  = {0};

    memset(&serdesLane0EnableParams, 0, sizeof(serdesLane0EnableParams));

    /* QSGMII Config */
    serdesLane0EnableParams.serdesInstance    = (CSL_SerdesInstance)SGMII_SERDES_INSTANCE;
    serdesLane0EnableParams.baseAddr          = CSL_SERDES_16G0_BASE;
    serdesLane0EnableParams.refClock          = CSL_SERDES_REF_CLOCK_100M;
    serdesLane0EnableParams.refClkSrc         = CSL_SERDES_REF_CLOCK_INT;
    serdesLane0EnableParams.linkRate          = CSL_SERDES_LINK_RATE_5G;
    serdesLane0EnableParams.numLanes          = 0x2;
    serdesLane0EnableParams.laneMask          = 0x3;
    serdesLane0EnableParams.SSC_mode          = CSL_SERDES_NO_SSC;
    serdesLane0EnableParams.phyType           = CSL_SERDES_PHY_TYPE_QSGMII;
    serdesLane0EnableParams.operatingMode     = CSL_SERDES_FUNCTIONAL_MODE;
    serdesLane0EnableParams.phyInstanceNum    = SERDES_LANE_SELECT_CPSW;
    serdesLane0EnableParams.pcieGenType        = CSL_SERDES_PCIE_GEN4;

    serdesLane0EnableParams.laneCtrlRate[0]   = CSL_SERDES_LANE_FULL_RATE;
    serdesLane0EnableParams.loopbackMode[0]   = CSL_SERDES_LOOPBACK_DISABLED;

    serdesLane0EnableParams.laneCtrlRate[1]   = CSL_SERDES_LANE_FULL_RATE;
    serdesLane0EnableParams.loopbackMode[1]   = CSL_SERDES_LOOPBACK_DISABLED;

    CSL_serdesPorReset(serdesLane0EnableParams.baseAddr);

    /* Select the IP type, IP instance num, Serdes Lane Number */
    CSL_serdesIPSelect(CSL_CTRL_MMR0_CFG0_BASE,
                       serdesLane0EnableParams.phyType,
                       serdesLane0EnableParams.phyInstanceNum,
                       serdesLane0EnableParams.serdesInstance,
                       SGMII_LANE_NUM);


    result = CSL_serdesRefclkSel(CSL_CTRL_MMR0_CFG0_BASE,
                                 serdesLane0EnableParams.baseAddr,
                                 serdesLane0EnableParams.refClock,
                                 serdesLane0EnableParams.refClkSrc,
                                 serdesLane0EnableParams.serdesInstance,
                                 serdesLane0EnableParams.phyType);

    if (result != CSL_SERDES_NO_ERR)
    {
        return BOARD_FAIL;
    }
    /* Assert PHY reset and disable all lanes */
    CSL_serdesDisablePllAndLanes(serdesLane0EnableParams.baseAddr, serdesLane0EnableParams.numLanes,
                                 serdesLane0EnableParams.laneMask);

    /* Load the Serdes Config File */
    result = CSL_serdesEthernetInit(&serdesLane0EnableParams);
    /* Return error if input params are invalid */
    if (result != CSL_SERDES_NO_ERR)
    {
        return BOARD_FAIL;
    }

    /* Common Lane Enable API for lane enable, pll enable etc */
    laneRetVal = CSL_serdesLaneEnable(&serdesLane0EnableParams);
    if (laneRetVal != 0)
    {
        return BOARD_FAIL;
    }

    return BOARD_SOK;
}

/**
 *  \brief serdes configurations
 *
 *  The function configures the serdes1 module for one lane pcie interface
 *
 *  \return   BOARD_SOK in case of success or appropriate error code
 *
 */
Board_STATUS Board_serdesCfgSgmii(void)
{
    Board_STATUS ret;

    /* SERDES0 Lan0 Initializations */
    ret = Board_CfgSgmii_serdes0_lan0();
    if (ret != BOARD_SOK)
    {
        return ret;
    }
    /* SERDES0 Lan1 Initializations */
    ret = Board_CfgSgmii_serdes0_lan1();
    if (ret != BOARD_SOK)
    {
        return ret;
    }


    return BOARD_SOK;
}

/**
 *  \brief serdes configurations
 *
 *  The function configures the serdes1 module for one lane pcie interface
 *
 *  \return   BOARD_SOK in case of success or appropriate error code
 *
 */
Board_STATUS Board_serdesCfgQsgmii(void)
{
    Board_STATUS ret;

    /* SERDES0 Initializations */
    ret = Board_CfgQsgmii();
    if (ret != BOARD_SOK)
    {
        return ret;
    }

    return BOARD_SOK;
}
/*
 *  Copyright (c) Texas Instruments Incorporated 2020
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *    Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 *    Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the
 *    distribution.
 *
 *    Neither the name of Texas Instruments Incorporated nor the names of
 *    its contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/*!
 * \file     enet_appboardutils_j721e_gesi.c
 *
 * \brief    This file contains the board specific utilities for J721E GESI brd.
 */

/* ========================================================================== */
/*                             Include Files                                  */
/* ========================================================================== */

#include <string.h>
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>

#include <ti/osal/osal.h>
#include <ti/drv/i2c/I2C.h>
#include <ti/drv/i2c/soc/I2C_soc.h>
#include <ti/csl/soc.h>
#include <ti/drv/enet/include/phy/dp83867.h>
#include <ti/board/board.h>
#if defined (SOC_J721E)
#include <ti/board/src/j721e_evm/include/board_pinmux.h>
#include <ti/board/src/j721e_evm/include/board_utils.h>
#include <ti/board/src/j721e_evm/include/board_control.h>
#include <ti/board/src/j721e_evm/include/board_ethernet_config.h>
#include <ti/board/src/j721e_evm/include/board_serdes_cfg.h>
#elif defined (SOC_J7200)
#include <ti/board/src/j7200_evm/include/board_pinmux.h>
#include <ti/board/src/j7200_evm/include/board_utils.h>
#include <ti/board/src/j7200_evm/include/board_control.h>
#include <ti/board/src/j7200_evm/include/board_ethernet_config.h>
#include <ti/board/src/j7200_evm/include/board_serdes_cfg.h>
#else
#error "Invalid SOC"
#endif
#include <ti/drv/enet/enet.h>

#include <ti/drv/enet/examples/utils/include/enet_apputils.h>
#include <ti/drv/enet/examples/utils/include/enet_appboardutils.h>
#include <ti/board/boot_info.h>


#undef TEST_ICSSG

/* ========================================================================== */
/*                           Macros & Typedefs                                */
/* ========================================================================== */

/* None */

/* ========================================================================== */
/*                         Structures and Enums                               */
/* ========================================================================== */

/* None */

/* ========================================================================== */
/*                 Internal Function Declarations                             */
/* ========================================================================== */

/* ========================================================================== */
/*                            Global Variables                                */
/* ========================================================================== */

/* None */

/* ========================================================================== */
/*                          Function Definitions                              */
/* ========================================================================== */

#if defined(BUILD_MCU2_0)
static void EnetBoard_enetExpCfg(void)
{
    Board_STATUS boardStatus;

    /* Release PHY reset. Note this is needed for both SGMII and QSGMII boards */
    boardStatus = Board_cpswEnetExpPhyReset(0U);
    EnetAppUtils_assert(BOARD_SOK == boardStatus);

    if (Board_detectBoard(BOARD_ID_ENET))
    {
        /* Release the COMA_MODE pin */
        boardStatus = Board_cpswEnetExpComaModeCfg(0U);
        EnetAppUtils_assert(BOARD_SOK == boardStatus);
    }
}
#endif

#if defined(BUILD_MCU2_0)

#if defined (SOC_J721E)
static void EnetBoard_configSierra0Clks(void)
{
    uint32_t moduleId, clkId, clkRateHz;

    /* Configure the required PLLs for SERDES0 */
    moduleId  = TISCI_DEV_SERDES_16G0;
    clkId     = TISCI_DEV_SERDES_16G0_CORE_REF1_CLK;
    clkRateHz = 100000000U;
    EnetAppUtils_clkRateSet(moduleId, clkId, clkRateHz);

    clkId     = TISCI_DEV_SERDES_16G0_CORE_REF_CLK;
    clkRateHz = 100000000U;
    EnetAppUtils_clkRateSet(moduleId, clkId, clkRateHz);
    EnetAppUtils_setDeviceState(moduleId, TISCI_MSG_VALUE_DEVICE_SW_STATE_ON, 0U);
}
#endif

#if defined (SOC_J721E)
static void EnetBoard_configSierra1Clks(void)
{
    uint32_t moduleId, clkId, clkRateHz;

    /* Configure the required PLLs for SERDES1 */
    moduleId  = TISCI_DEV_SERDES_16G1;
    clkId     = TISCI_DEV_SERDES_16G1_CORE_REF1_CLK;
    clkRateHz = 100000000U;
    EnetAppUtils_clkRateSet(moduleId, clkId, clkRateHz);

    clkId     = TISCI_DEV_SERDES_16G1_CORE_REF_CLK;
    clkRateHz = 100000000U;
    EnetAppUtils_clkRateSet(moduleId, clkId, clkRateHz);
    EnetAppUtils_setDeviceState(moduleId, TISCI_MSG_VALUE_DEVICE_SW_STATE_ON, 0U);
}
#endif

static void EnetBoard_configTorrentClks(void)
{
    uint32_t moduleId, clkId, clkRateHz;

    /* Configure the required PLLs for SERDES1 */
#if defined (SOC_J721E)
    moduleId  = TISCI_DEV_SERDES_10G0;
    clkId     = TISCI_DEV_SERDES_10G0_CORE_REF_CLK;
#elif defined (SOC_J7200)
    moduleId  = TISCI_DEV_SERDES_10G1;
    clkId     = TISCI_DEV_SERDES_10G1_CORE_REF_CLK;
#endif
    clkRateHz = 100000000U;
    EnetAppUtils_clkRateSet(moduleId, clkId, clkRateHz);
    EnetAppUtils_setDeviceState(moduleId, TISCI_MSG_VALUE_DEVICE_SW_STATE_ON, 0U);
}

#if defined (SOC_J721E)
static void EnetBoard_disableSierra0Clks(void)
{
    uint32_t moduleId;

    /* Set module set to HW AUTO */
    moduleId = TISCI_DEV_SERDES_16G0;
    EnetAppUtils_setDeviceState(moduleId, TISCI_MSG_VALUE_DEVICE_SW_STATE_AUTO_OFF, 0U);
}
#endif

#if defined (SOC_J721E)
static void EnetBoard_disableSierra1Clks(void)
{
    uint32_t moduleId;

    /* Set module set to HW AUTO */
    moduleId  = TISCI_DEV_SERDES_16G1;
    EnetAppUtils_setDeviceState(moduleId, TISCI_MSG_VALUE_DEVICE_SW_STATE_AUTO_OFF, 0U);
}
#endif

static void EnetBoard_disableTorrentClks(void)
{
    uint32_t moduleId;

    /* Set module set to HW AUTO */
#if defined (SOC_J721E)
    moduleId  = TISCI_DEV_SERDES_10G0;
#elif defined (SOC_J7200)
    moduleId  = TISCI_DEV_SERDES_10G1;
#endif
    EnetAppUtils_setDeviceState(moduleId, TISCI_MSG_VALUE_DEVICE_SW_STATE_AUTO_OFF, 0U);
}
#endif

static void EnetBoard_boardInit(Board_initCfg *boardCfg)
{
    Board_STATUS status;
    Board_PinmuxConfig_t pinmuxCfg;

    /* Configure CPSW9G PADs for Ports on the GESI board */
    Board_pinmuxGetCfg(&pinmuxCfg);
#if defined(ENET_ENABLE_ICSSG) && defined(TEST_ICSSG)
    pinmuxCfg.gesiExp = BOARD_PINMUX_GESI_ICSSG;
#else
    pinmuxCfg.gesiExp = BOARD_PINMUX_GESI_CPSW;
#endif
    Board_pinmuxSetCfg(&pinmuxCfg);

#if defined(BUILD_MCU2_0)
    Board_initParams_t initParams;

    Board_getInitParams(&initParams);
    /* mcu2_0 UART instances:
     *  - J721E EVM: UART2
     *  - J7200 EVM: UART3 */
    initParams.uartInst      = ENET_UTILS_MCU2_0_UART_INSTANCE;
    initParams.uartSocDomain = BOARD_SOC_DOMAIN_MAIN;
    /* Use non-exclusive mode in board lib when accessing the module for clock enable
     * to let Linux also access the module */
    initParams.pscMode = BOARD_PSC_DEVICE_MODE_NONEXCLUSIVE;
    Board_setInitParams(&initParams);
#endif

    status = Board_init(*boardCfg);
    EnetAppUtils_assert(status == BOARD_SOK);

    /* Avoid I2C conflicts between EthFw and u-boot */
#if !defined(ENETAPPUTILS_BYPASS_I2C)
    if (Board_detectBoard(BOARD_ID_GESI))
    {
#if defined(BUILD_MCU2_0)
        EnetAppUtils_print("GESI board detected1\n");
        EnetAppUtils_print("BUILD_MCU2_0\n");
#endif
    }

    if (Board_detectBoard(BOARD_ID_ENET))
    {
        EnetAppUtils_print("QSGMII board detected\n");
    }
#endif
}

extern pinmuxBoardCfg_t g_uart6pinmuxdata[];
void uart_init()
{
    uint32_t i, moduleCnt, appFlags;
    uint32_t clkModuleId[] = { TISCI_DEV_UART6, };

    appFlags = 0U;
    moduleCnt = ENET_ARRAYSIZE(clkModuleId);
    for (i = 0; i < moduleCnt; i++)
    {
        EnetAppUtils_setDeviceState(clkModuleId[i],
                                    TISCI_MSG_VALUE_DEVICE_HW_STATE_ON,
                                    appFlags);
    }
    Board_pinmuxUpdate(g_uart6pinmuxdata,
                       BOARD_SOC_DOMAIN_MAIN);
}
/* Hack to run EthFw with Linux
 * We do only limited pinmux configuration and also don't configure RMII and MDIO board muxes
 * as it causes conflict with Linux in using Main domain I2C0. If we need any of configuration on I2c
 * we should ask Linux to do that. Currently we wouldn't use RMII port in EthFw and we don't need MDIO
 * board mux as default is CPSW9G
 */
void EnetBoard_initEthFw(void)
{
    Board_initCfg boardCfg = 0U;
    Board_STATUS status;
    uint32_t i, moduleCnt, appFlags;
    uint32_t clkModuleId[] = { TISCI_DEV_DDR0,
                               TISCI_DEV_TIMER12,
                               TISCI_DEV_TIMER13,
                               TISCI_DEV_UART6,
                             };

    appFlags = 0U;
    uart_init();
    moduleCnt = ENET_ARRAYSIZE(clkModuleId);
    for (i = 0; i < moduleCnt; i++)
    {
        EnetAppUtils_setDeviceState(clkModuleId[i],
                                    TISCI_MSG_VALUE_DEVICE_SW_STATE_ON,
                                    appFlags);
    }

    status = EnetBoard_configEthFwPinmux();
    EnetAppUtils_assert(status == BOARD_SOK);

    /* Setting up UART3 in J7200 requires I2C accesses, so need to be bypassed for mcu2_0 */
#if defined(ENETAPPUTILS_UART_ALLOWED)
    boardCfg |= BOARD_INIT_UART_STDIO;
#endif

#if defined (SOC_J721E)
    boardCfg |= BOARD_INIT_ENETCTRL_CPSW9G;
#elif defined (SOC_J7200)
    boardCfg |= BOARD_INIT_ENETCTRL_CPSW5G;
#endif

    EnetBoard_boardInit(&boardCfg);

#if defined(ENETAPPUTILS_UART_ALLOWED) && defined (SOC_J7200) && defined(BUILD_MCU2_0)
    /* Set SOM's MUX2 for UART3 route */
    status = Board_control(BOARD_CTRL_CMD_SET_SOM_UART_MUX, NULL);
    EnetAppUtils_assert(status == BOARD_SOK);
#endif

#if !defined(ENETAPPUTILS_BYPASS_I2C) && defined(BUILD_MCU2_0)
    /* Configure SGMII/QSGMII expansion board
     * Note - We call below without any check as these functions can be called
     * without daughter board also. They just change the output state of IO
     * expander pins on CP board which goes to daughter board.
     * No negative impact when they are configured without DB. */
    EnetBoard_enetExpCfg();
#endif

#if !defined(ENETAPPUTILS_BYPASS_QSGMII) && defined(BUILD_MCU2_0)
#if defined (SOC_J721E)
    /* On J721E EVM, port 1 (SERDES0, lane 1) is brought for SGMII */
    EnetBoard_configSierra0Clks();
#elif defined (SOC_J7200)
    /* On J721E EVM, port 1 (SERDES0, lane 1) is brought for SGMII */
    EnetBoard_configTorrentClks();
#endif

    if (Board_detectBoard(BOARD_ID_ENET))
    {
        status = Board_serdesCfgQsgmii();
        EnetAppUtils_assert(status == BOARD_SOK);
    }
#endif
}

void EnetBoard_init(void)
{
    Board_initCfg boardCfg;
#if defined(BUILD_MCU2_0)
    Board_STATUS status;
#endif
#if defined(BUILD_MCU2_0)
    int32_t enetCard;
#endif

#if defined(ENET_ENABLE_ICSSG) && defined(TEST_ICSSG)
    boardCfg = BOARD_INIT_PINMUX_CONFIG |
               BOARD_INIT_MODULE_CLOCK |
               BOARD_INIT_ENETCTRL_ICSS |
               BOARD_INIT_UART_STDIO;
#else
    boardCfg = BOARD_INIT_PINMUX_CONFIG |
               BOARD_INIT_MODULE_CLOCK |
               BOARD_INIT_ENETCTRL_CPSW2G |
               BOARD_INIT_UART_STDIO;

#if defined (SOC_J721E)
    boardCfg |= BOARD_INIT_ENETCTRL_CPSW9G;
#elif defined (SOC_J7200)
    boardCfg |= BOARD_INIT_ENETCTRL_CPSW5G;
#endif
#endif

    EnetBoard_boardInit(&boardCfg);

#if defined(BUILD_MCU2_0)
#if defined (SOC_J7200)
    /* Set SOM's MUX2 for UART3 route */
    status = Board_control(BOARD_CTRL_CMD_SET_SOM_UART_MUX, NULL);
    EnetAppUtils_assert(status == BOARD_SOK);
#endif

#ifdef TEST_ICSSG
    /* Enable ICSSG MDIO mux */
    status = Board_control(BOARD_CTRL_CMD_SET_ICSSG_MDIO_MUX, NULL);
    EnetAppUtils_assert(status == BOARD_SOK);
#else
    /* Enable CPSW9G MDIO mux */
    status = Board_control(BOARD_CTRL_CMD_SET_GESI_CPSW_MDIO_MUX, NULL);
    EnetAppUtils_assert(status == BOARD_SOK);
#endif

#if defined (SOC_J721E)
    /* Set IO Expander to use RMII on GESI board */
    status = Board_control(BOARD_CTRL_CMD_SET_RMII_DATA_MUX, NULL);
    EnetAppUtils_assert(status == BOARD_SOK);

    /* On J721E EVM, port 1 (SERDES0, lane 1) is brought for SGMII */
    EnetBoard_configSierra0Clks();

    /* We don't need to enable SERDES1/2 clocks for CPSW tests on EVM. Below is test code
     * so customers have ready to use functions.
     */
    EnetBoard_configSierra1Clks();
#endif

    EnetBoard_configTorrentClks();

    /* Configure SGMII/QSGMII expansion board
     * Note - We call below without any check as these functions can be called
     * without daughter board also. They just change the output state of IO
     * expander pins on CP board which goes to daughter board.
     * No negative impact when they are configured without DB. */
    EnetBoard_enetExpCfg();

    enetCard = Board_detectEnetCard();
    if (enetCard == BOARD_ENET_QSGMII)
    {
        status = Board_serdesCfgQsgmii();
        EnetAppUtils_assert(status == BOARD_SOK);
    }
    else if (enetCard == BOARD_ENET_SGMII)
    {
        status = Board_serdesCfgSgmii();
        EnetAppUtils_assert(status == BOARD_SOK);
    }
#endif //BUILD_MCU2_0
}

void EnetBoard_deInit(void)
{
    Board_STATUS boardInitStatus;
    Board_initCfg boardCfg;

#if defined(BUILD_MCU2_0)
#if defined (SOC_J721E)
    EnetBoard_disableSierra0Clks();
    EnetBoard_disableSierra1Clks();
#endif
    EnetBoard_disableTorrentClks();
#endif

    boardCfg = BOARD_INIT_PINMUX_CONFIG |
               BOARD_INIT_MODULE_CLOCK |
               BOARD_INIT_ENETCTRL_CPSW2G |
               BOARD_INIT_ENETCTRL_CPSW9G |
               BOARD_INIT_UART_STDIO;

    boardInitStatus = Board_deinit(boardCfg);
    EnetAppUtils_assert(boardInitStatus == BOARD_SOK);
}

uint32_t EnetBoard_getPhyAddr(Enet_Type enetType,
                              Enet_MacPort portNum)
{
    uint32_t phyAddr = ENETPHY_INVALID_PHYADDR;
    uint32_t board_id = 0;
    int32_t ret = -1;

#if defined(BUILD_MCU2_0)
    EnetAppUtils_print("%s: line%d... enet is %dm port is %d\n", __func__, __LINE__, enetType, portNum);
#endif

    switch (enetType)
    {
        case ENET_CPSW_2G:
            EnetAppUtils_assert(portNum == ENET_MAC_PORT_1);
#if 0
            phyAddr = 0x00U;
#else
            phyAddr = ENETPHY_INVALID_PHYADDR;
#endif
            break;

        case ENET_CPSW_5G:
            switch (portNum)
            {
                case ENET_MAC_PORT_1:
                    /* QSGMII port */
                    phyAddr = 16U;
                    break;

                case ENET_MAC_PORT_2:
                    /* Use RGMII port in GESI board when QSGMII is disabled */
#if defined(ENETAPPUTILS_BYPASS_QSGMII)
                    /* RGMII port */
                    phyAddr = 0U;
#else
                    /* QSGMII port */
                    phyAddr = 17U;
#endif
                    break;

                case ENET_MAC_PORT_3:
                    /* QSGMII port */
                    phyAddr = 18U;
                    break;

                case ENET_MAC_PORT_4:
                    /* QSGMII port */
                    phyAddr = 19U;
                    break;

                default:
                    EnetAppUtils_assert(false);
                    break;
            }

            break;

        case ENET_CPSW_9G:
            switch (portNum)
            {
                case ENET_MAC_PORT_1:
                {
                    ret = get_acu_board_id(&board_id);
                    if (0 != ret) {
                        appLogPrintf("get_acu_board_id failed\n");
                        return ENETPHY_INVALID_PHYADDR;
                    }

                    appLogPrintf("%s: board_id is= %d\n",__FUNCTION__, board_id);

	                if ((board_id == ACU_HW_ID_SIXI_BYD_EVT_MASTER) || (board_id == ACU_HW_ID_SIXI_BYD_DVT_MASTER))
                    {
                        phyAddr = 1U;
	                }
	                else if ((board_id == ACU_HW_ID_SIXI_BYD_EVT_SLAVE) || (board_id == ACU_HW_ID_SIXI_BYD_DVT_SLAVE))
	                {
                        phyAddr = 2U;
	                }	  
                    /* RGMII port */
                    
                    break;
                }


                case ENET_MAC_PORT_3:
                    /* RGMII port */
                    phyAddr = 0U;
                    break;

                case ENET_MAC_PORT_4:
                    /* RGMII port */
                    phyAddr = 3U;
                    break;

                case ENET_MAC_PORT_8:
                    /* RGMII port */
                    phyAddr = 15U;
                    break;

                case ENET_MAC_PORT_2:
                    /* QSGMII port */
                    phyAddr = ENETPHY_INVALID_PHYADDR;
                    break;

                case ENET_MAC_PORT_5:
                    /* QSGMII port */
                    phyAddr = 0U;
                    break;

                case ENET_MAC_PORT_6:
                    /* QSGMII port */
                    phyAddr = ENETPHY_INVALID_PHYADDR;
                    break;

                case ENET_MAC_PORT_7:
                    /* QSGMII port */
                    phyAddr = 19U;
                    break;

                default:
                    EnetAppUtils_assert(false);
                    break;
            }

            break;

        default:
            EnetAppUtils_assert(false);
            break;
    }

    return phyAddr;
}

uint32_t EnetBoard_getSgmiiPhyAddr(void)
{
    /* Both Q/SGMII DB and GESI board use MAC port 2, so we can't use generic EnetBoard_getPhyAddr
     * function */
    return 0U;
    //return 10U;
}

uint32_t EnetBoard_getRmiiPhyAddr(void)
{
    /* Both QSGMII DB and GESI board use MAC port 7, so we can't use generic EnetBoard_getPhyAddr
     * function */
    return 23U;
}

static void MV_88Q2112_phy_enable()
{
    uint32_t pin_data = 0;
    uint32_t regVal = 0;

    //mv882122   set dir
    regVal = CSL_REG32_RD(CSL_GPIO0_BASE + 0x60U);
    regVal &= (~(1U << 5U));
    CSL_REG32_WR(CSL_GPIO0_BASE + 0x60U, regVal);

    //set high 
    regVal = CSL_REG32_RD(CSL_GPIO0_BASE + 0x68U);
    regVal |= ((1U << 5U));
    CSL_REG32_WR(CSL_GPIO0_BASE + 0x68U, regVal);
}

void EnetBoard_setPhyConfigSgmii(Enet_MacPort portNum,
                                 CpswMacPort_Cfg *macCfg,
                                 EnetMacPort_Interface *interface,
                                 EnetPhy_Cfg *phyCfg)
{
    Board_STATUS boardStatus;
    Enet_Type enetType = ENET_CPSW_9G;
    uint32_t instId;
    uint32_t board_id = 0;
    int32_t ret = -1;

    /* Override the ENET control set by board lib */
#if defined (SOC_J721E)
    EnetAppUtils_assert(portNum == ENET_MAC_PORT_1 || portNum == ENET_MAC_PORT_2);
    enetType = ENET_CPSW_9G;
    instId   = 0U;
#elif defined (SOC_J7200)
    EnetAppUtils_assert(portNum == ENET_MAC_PORT_1);
    enetType = ENET_CPSW_5G;
    instId   = 0U;
#endif

    /* Override the ENET control set by board lib */
    EnetBoard_setEnetControl(enetType, instId, portNum, SGMII);

    boardStatus = Board_serdesCfgSgmii();
    EnetAppUtils_assert(boardStatus == BOARD_SOK);

    EnetPhy_initCfg(phyCfg);
    phyCfg->phyAddr = ENETPHY_INVALID_PHYADDR;

    /* RGMII interface type */
    interface->layerType    = ENET_MAC_LAYER_GMII;
    interface->sublayerType = ENET_MAC_SUBLAYER_SERIAL;
    interface->variantType  = ENET_MAC_VARIANT_NONE;
    
    phyCfg->phyAddr = EnetBoard_getPhyAddr(enetType, portNum);
    /*byd Port2 MAC to MAC*/
    if(portNum == ENET_MAC_PORT_1){
        macCfg->sgmiiMode = ENET_MAC_SGMIIMODE_SGMII_WITH_PHY; 

    }else if (portNum == ENET_MAC_PORT_2)  
    {
        ret = get_acu_board_id(&board_id);
        if (0 != ret) {
            appLogPrintf("get_acu_board_id failed\n");
	        return;
        }
        appLogPrintf("%s: board_id is= %d\n",__FUNCTION__, board_id);
	    if ((board_id == ACU_HW_ID_SIXI_BYD_EVT_MASTER) || (board_id == ACU_HW_ID_SIXI_BYD_DVT_MASTER))
        {
            macCfg->sgmiiMode = ENET_MAC_SGMIIMODE_SGMII_AUTONEG_MASTER;
	    }
	    else if ((board_id == ACU_HW_ID_SIXI_BYD_EVT_SLAVE) || (board_id == ACU_HW_ID_SIXI_BYD_DVT_SLAVE))
	    {
            macCfg->sgmiiMode = ENET_MAC_SGMIIMODE_SGMII_AUTONEG_SLAVE;
	    }
        ENETTRACE_ERR("%s %d, EnetBoard_setPhyConfigSgmii portNum %d as %d\r\n", __FILE__, __LINE__, portNum, macCfg->sgmiiMode);	  
    }
}

void EnetBoard_setPhyConfigQsgmii(Enet_Type enetType,
                                  Enet_MacPort portNum,
                                  CpswMacPort_Cfg *macCfg,
                                  EnetMacPort_Interface *interface,
                                  EnetPhy_Cfg *phyCfg)
{
    bool isAlpha = false;
    Enet_MacPort qsgmiiMain;

    /*
     * Disable QSGMII on alpha revision EVMs due to ADASVISION-3869 cpsw - mdio
     * instability for QSGMII PHYs on alpha EVM. Issue is resolved in the Beta
     * HW revision.
     */
    isAlpha = Board_isAlpha(BOARD_ID_CP);

    if (isAlpha)
    {
        EnetAppUtils_print("QSGMII DB not supported on alpha revision of EVM\n");
        EnetAppUtils_assert(false);
    }

#if defined (SOC_J721E)
    /* QSGMII PHYs are routed as follows in QUAD PORT ETH EXP board:
     *  MAC port 1 = QSGMII MAIN
     *  MAC port 4 = QSGMII SUB
     *  MAC port 5 = QSGMII SUB
     *  MAC port 6 = QSGMII SUB
     */
    EnetAppUtils_assert((portNum == ENET_MAC_PORT_2) ||
                        (portNum == ENET_MAC_PORT_5) ||
                        (portNum == ENET_MAC_PORT_6) ||
                        (portNum == ENET_MAC_PORT_7));

    qsgmiiMain = ENET_MAC_PORT_2;
#elif defined (SOC_J7200)
    EnetAppUtils_assert((portNum == ENET_MAC_PORT_1) ||
                        (portNum == ENET_MAC_PORT_2) ||
                        (portNum == ENET_MAC_PORT_3) ||
                        (portNum == ENET_MAC_PORT_4));

    qsgmiiMain = ENET_MAC_PORT_1;
#endif

    EnetPhy_initCfg(phyCfg);
    phyCfg->phyAddr = EnetBoard_getPhyAddr(enetType, portNum);

    /* QSGMII ports */
    /* In QSGMII config each port is independent port just going over one link so
     * we need set up each port just like SGMII ports - autoneg, mac control etc.*/
    interface->layerType    = ENET_MAC_LAYER_GMII;
    interface->variantType  = ENET_MAC_VARIANT_NONE;
    macCfg->sgmiiMode = ENET_MAC_SGMIIMODE_SGMII_WITH_PHY;

    if (portNum == qsgmiiMain)
    {
        interface->sublayerType = ENET_MAC_SUBLAYER_QUAD_SERIAL_MAIN;
    }
    else
    {
        interface->sublayerType = ENET_MAC_SUBLAYER_QUAD_SERIAL_SUB;
    }
}

void EnetBoard_setPhyConfigRmii(Enet_MacPort portNum,
                                CpswMacPort_Cfg *macCfg,
                                EnetMacPort_Interface *interface,
                                EnetPhy_Cfg *phyCfg)
{
    EnetAppUtils_assert(portNum == ENET_MAC_PORT_8);

    /* Override the ENET control set by board lib */
    EnetBoard_setEnetControl(ENET_CPSW_9G, 0U/* instId */, portNum, RMII);

    EnetPhy_initCfg(phyCfg);
    phyCfg->phyAddr = ENETPHY_INVALID_PHYADDR;
    phyCfg->skipExtendedCfg = false;

    /* Mac port 7 on GESI board is RMII port */
    interface->layerType    = ENET_MAC_LAYER_MII;
    interface->sublayerType = ENET_MAC_SUBLAYER_REDUCED;
    interface->variantType  = ENET_MAC_VARIANT_NONE;
}

void EnetBoard_setPhyConfigRgmii(Enet_Type enetType,
                                 Enet_MacPort portNum,
                                 CpswMacPort_Cfg *macCfg,
                                 EnetMacPort_Interface *interface,
                                 EnetPhy_Cfg *phyCfg)
{
    Dp83867_Cfg extendedCfg;
    Board_STATUS boardStatus;

#if defined (SOC_J721E)
    /* RGMII PHYs can be used on the following MAC ports as per board library pinmux:
     *   GESI board: 0, 1, 2, 3
     *  SGMII board: 2, 3, 6, 7
     * QSGMII board: 0, 2, 3, 7
     */
    EnetAppUtils_assert((portNum == ENET_MAC_PORT_1) ||
                        (portNum == ENET_MAC_PORT_2) ||
                        (portNum == ENET_MAC_PORT_3) ||
                        (portNum == ENET_MAC_PORT_4) ||
                        (portNum == ENET_MAC_PORT_5) ||
                        (portNum == ENET_MAC_PORT_6) ||
                        (portNum == ENET_MAC_PORT_7) ||
                        (portNum == ENET_MAC_PORT_8));
#elif defined (SOC_J7200)
    if (enetType == ENET_CPSW_2G)
    {
        EnetAppUtils_assert(portNum == ENET_MAC_PORT_1);
    }
    else if (enetType == ENET_CPSW_5G)
    {
        EnetAppUtils_assert(portNum == ENET_MAC_PORT_2);
        /* Override the ENET control set by board lib */
        EnetBoard_setEnetControl(enetType, 0U/* instId */, portNum, RGMII);
    }
#endif

    /* Override the ENET control set by board lib */
    boardStatus = Board_cpsw9gEthConfig(portNum, RGMII);
    EnetAppUtils_assert(boardStatus == BOARD_SOK);
    EnetPhy_initCfg(phyCfg);

#if defined(SOC_J7200)
    phyCfg->phyAddr = 0U;
#else
    phyCfg->phyAddr = EnetBoard_getPhyAddr(enetType, portNum);
#endif

    /* DP83867 specific configuration */
    Dp83867_initCfg(&extendedCfg);
    extendedCfg.txFifoDepth          = 4U;
    extendedCfg.txClkShiftEn     = true;
    extendedCfg.rxClkShiftEn     = true;
    extendedCfg.impedanceInMilliOhms = 35000; /* 35 ohms */
    extendedCfg.gpio0Mode            = DP83867_GPIO0_LED3;
    extendedCfg.ledMode[1]           = DP83867_LED_LINKED_100BTX;
    extendedCfg.ledMode[2]           = DP83867_LED_RXTXACT;
    extendedCfg.ledMode[3]           = DP83867_LED_LINKED_1000BT;

    if ((enetType == ENET_CPSW_9G) || (enetType == ENET_CPSW_5G))
    {
        extendedCfg.txDelayInPs      = 2750U; /* 2.75 ns */
        extendedCfg.rxDelayInPs      = 2500U; /* 2.50 ns */
    }

    EnetPhy_setExtendedCfg(phyCfg,
                           &extendedCfg,
                           sizeof(extendedCfg));

    /* RGMII interface type */
    interface->layerType    = ENET_MAC_LAYER_GMII;
    interface->sublayerType = ENET_MAC_SUBLAYER_REDUCED;
    interface->variantType  = ENET_MAC_VARIANT_FORCED;
}

void EnetBoard_setPhyConfig(Enet_Type enetType,
                            Enet_MacPort portNum,
                            CpswMacPort_Cfg *macCfg,
                            EnetMacPort_Interface *interface,
                            EnetPhy_Cfg *phyCfg)
{
    ENETTRACE_INFO("WLY TEST >>>> EnetBoard_setPhyConfig start. %d\r\n", enetType);
    switch (enetType)
    {
        case ENET_CPSW_2G:
            EnetAppUtils_assert(portNum == ENET_MAC_PORT_1);

            EnetBoard_setPhyConfigRgmii(enetType,
                                        portNum,
                                        macCfg,
                                        interface,
                                        phyCfg);
            break;

        case ENET_CPSW_5G:
            /* Use RGMII port in GESI board when QSGMII is disabled */
#if defined(ENETAPPUTILS_BYPASS_QSGMII)
            if (ENET_MAC_PORT_2 == portNum)
            {
                EnetBoard_setPhyConfigRgmii(enetType,
                                            portNum,
                                            macCfg,
                                            interface,
                                            phyCfg);
            }
#else
            EnetBoard_setPhyConfigQsgmii(enetType,
                                         portNum,
                                         macCfg,
                                         interface,
                                         phyCfg);
#endif
            break;

        case ENET_CPSW_9G:
            if ((ENET_MAC_PORT_1 == portNum))
            {
                ENETTRACE_ERR("%s %d, EnetBoard_setPhyConfigSgmii portNum %d\r\n", __FILE__, __LINE__, portNum);
                MV_88Q2112_phy_enable();
                EnetBoard_setPhyConfigSgmii(portNum,
                                            macCfg,
                                            interface,
                                            phyCfg);

#if defined(BUILD_MCU2_0)
                EnetAppUtils_print("EnetBoard_setPhyConfigSgmii Port:%d\n", portNum);
#endif
            }
            else if ((ENET_MAC_PORT_2 == portNum))
            {
                ENETTRACE_ERR("%s %d, EnetBoard_setPhyConfigSgmii portNum %d\r\n", __FILE__, __LINE__, portNum);
                EnetBoard_setPhyConfigSgmii(portNum,
                                            macCfg,
                                            interface,
                                            phyCfg);

#if defined(BUILD_MCU2_0)
                EnetAppUtils_print("EnetBoard_setPhyConfigSgmii Port:%d\n", portNum);
#endif
            }
            else if ((ENET_MAC_PORT_6 == portNum)) 
            {
                ENETTRACE_ERR("%s %d, EnetAppUtils_setNoPhyCfgRgmii portNum %d\r\n", __FILE__, __LINE__, portNum);
                Board_cpsw9gEthConfig(portNum, RGMII);
                EnetAppUtils_setNoPhyCfgRgmii(interface,
                                              phyCfg);

#if defined(BUILD_MCU2_0)
                EnetAppUtils_print("EnetAppUtils_setNoPhyCfgRgmii Port:%d interface->variantType is %d\n", portNum,
                                   interface->variantType);
#endif
            }
            else
            {
                ENETTRACE_ERR("%s %d, EnetBoard_setPhyConfigRgmii portNum %d\r\n", __FILE__, __LINE__, portNum);
                EnetBoard_setPhyConfigRgmii(enetType,
                                            portNum,
                                            macCfg,
                                            interface,
                                            phyCfg);
#if defined(BUILD_MCU2_0)
                EnetAppUtils_print("EnetBoard_setPhyConfigRgmii Port:%d\n", portNum);
#endif
            }
            break;
        default:
            EnetAppUtils_assert(false);
    }

}

void EnetBoard_setLpbkCfg(bool phyLpbk,
                          Enet_MacPort portNum,
                          const EnetMacPort_Interface *interface,
                          CpswMacPort_Cfg *macCfg,
                          EnetPhy_Cfg *phyCfg,
                          EnetMacPort_LinkCfg *linkCfg)
{
    /* Set speed according to the interface type */
    if (interface->layerType == ENET_MAC_LAYER_MII)
    {
        linkCfg->speed = ENET_SPEED_100MBIT;
    }
    else
    {
        linkCfg->speed = ENET_SPEED_1GBIT;
    }

    linkCfg->duplexity = ENET_DUPLEX_FULL;

    /* MAC and PHY loopbacks are mutually exclusive */
    phyCfg->loopbackEn = phyLpbk;
    macCfg->loopbackEn = !phyLpbk;
}

void EnetBoard_getMacAddrList(uint8_t macAddr[][ENET_MAC_ADDR_LEN],
                              uint32_t maxMacEntries,
                              uint32_t *pAvailMacEntries)
{
#if 0
    uint8_t macAddrBuf[ENET_RM_NUM_MACADDR_MAX * BOARD_MAC_ADDR_BYTES];
    Board_STATUS boardStatus;
    uint32_t macAddrCnt, tempCnt;
    uint32_t allocMacEntries = 0;
    uint32_t i, j;

    EnetAppUtils_assert(pAvailMacEntries != NULL);

    if (Board_detectBoard(BOARD_ID_GESI))
    {
        /* Read number of MAC addresses in GESI board */
        boardStatus = Board_readMacAddrCount(BOARD_ID_GESI, &macAddrCnt);
        EnetAppUtils_assert(boardStatus == BOARD_SOK);
        EnetAppUtils_assert(macAddrCnt <= ENET_RM_NUM_MACADDR_MAX);

        /* Read MAC addresses */
        boardStatus = Board_readMacAddr(BOARD_ID_GESI,
                                        macAddrBuf,
                                        sizeof(macAddrBuf),
                                        &tempCnt);
        EnetAppUtils_assert(boardStatus == BOARD_SOK);
        EnetAppUtils_assert(tempCnt == macAddrCnt);

        /* Save only those required to meet the max number of MAC entries */
        macAddrCnt = EnetUtils_min(macAddrCnt, maxMacEntries);
        for (i = 0U; i < macAddrCnt; i++)
        {
            ENET_UTILS_COMPILETIME_ASSERT(ENET_MAC_ADDR_LEN == BOARD_MAC_ADDR_BYTES);
            memcpy(macAddr[i], &macAddrBuf[i * BOARD_MAC_ADDR_BYTES], ENET_MAC_ADDR_LEN);
        }

        allocMacEntries = macAddrCnt;
    }

    if (Board_detectBoard(BOARD_ID_ENET))
    {
        /* Read number of MAC addresses in QUAD Eth board */
        boardStatus = Board_readMacAddrCount(BOARD_ID_ENET, &macAddrCnt);
        EnetAppUtils_assert(boardStatus == BOARD_SOK);
        EnetAppUtils_assert(macAddrCnt <= ENET_RM_NUM_MACADDR_MAX);

        /* Read MAC addresses */
        boardStatus = Board_readMacAddr(BOARD_ID_ENET,
                                        macAddrBuf,
                                        sizeof(macAddrBuf),
                                        &tempCnt);
        EnetAppUtils_assert(boardStatus == BOARD_SOK);
        EnetAppUtils_assert(tempCnt == macAddrCnt);

        /* Save only those required to meet the max number of MAC entries */
        macAddrCnt = EnetUtils_min(macAddrCnt, maxMacEntries - allocMacEntries);
        for (i = 0U, j = allocMacEntries; i < macAddrCnt; i++, j++)
        {
            ENET_UTILS_COMPILETIME_ASSERT(ENET_MAC_ADDR_LEN == BOARD_MAC_ADDR_BYTES);
            memcpy(macAddr[j], &macAddrBuf[i * BOARD_MAC_ADDR_BYTES], ENET_MAC_ADDR_LEN);
        }

        allocMacEntries += macAddrCnt;
    }

    *pAvailMacEntries = allocMacEntries;

    if (allocMacEntries == 0U)
    {
        EnetAppUtils_print("EnetBoard_getMacAddrList Failed - GESI/ENET board not present\n");
        EnetAppUtils_assert(false);
    }
#else
    /*
     * Workaround for EthFw/u-boot I2C conflicts:
     * EthFw reads MAC addresses from GESI and QUAD_ETH boards during EthFw
     * initialization which are stored in EEPROM memories and are read via
     * I2C.  These I2C accesses tend to occur around the same u-boot is also
     * performing I2C accesses, causing transactions to timeout or other
     * similar symptoms.
     *
     * I2C sharing is a known limitation but no current solution exists at
     * this time.  As a temporary workaround, EthFw will use fixed MAC
     * addresses in Linux builds. For RTOS build, MAC addresses will still
     * be read from EEPROM as such I2C contention isn't an problem.
     */

    uint32_t board_id = 0;
    int32_t ret = -1;
    uint32_t macAddrCnt = 0;
    uint8_t MasterMacAddrBuf[][ENET_MAC_ADDR_LEN] =
    {
        { 0x70U, 0xFFU, 0x76U, 0x1DU, 0x92U, 0xC1U },
        { 0x70U, 0xFFU, 0x76U, 0x1DU, 0x92U, 0xC2U },
        { 0x70U, 0xFFU, 0x76U, 0x1DU, 0x92U, 0xC3U },
        { 0x70U, 0xFFU, 0x76U, 0x1DU, 0x92U, 0xC4U },
        { 0x70U, 0xFFU, 0x76U, 0x1DU, 0x92U, 0xC5U },
        { 0x70U, 0xFFU, 0x76U, 0x1DU, 0x92U, 0xC6U },
        { 0x70U, 0xFFU, 0x76U, 0x1DU, 0x92U, 0xC7U },
        { 0x70U, 0xFFU, 0x76U, 0x1DU, 0X8BU, 0xC6U },
        { 0x70U, 0xFFU, 0x76U, 0x1DU, 0X8BU, 0xC7U },
    }; 

    uint8_t SlaveMacAddrBuf[][ENET_MAC_ADDR_LEN] =
    {
        { 0x70U, 0xFFU, 0x76U, 0x1DU, 0x92U, 0xB1U },
        { 0x70U, 0xFFU, 0x76U, 0x1DU, 0x92U, 0xB2U },
        { 0x70U, 0xFFU, 0x76U, 0x1DU, 0x92U, 0xB3U },
        { 0x70U, 0xFFU, 0x76U, 0x1DU, 0x92U, 0xB4U },
        { 0x70U, 0xFFU, 0x76U, 0x1DU, 0x92U, 0xB5U },
        { 0x70U, 0xFFU, 0x76U, 0x1DU, 0X8BU, 0xB4U },
        { 0x70U, 0xFFU, 0x76U, 0x1DU, 0X8BU, 0xB5U },
        { 0x70U, 0xFFU, 0x76U, 0x1DU, 0X8BU, 0xB6U },
        { 0x70U, 0xFFU, 0x76U, 0x1DU, 0X8BU, 0xB7U },
    };

    ret = get_acu_board_id(&board_id);
    if (0 != ret) {
        appLogPrintf("get_acu_board_id failed\n");
	    return;
    }

    appLogPrintf("%s: board_id is= %d\n",__FUNCTION__, board_id);

	if ((board_id == ACU_HW_ID_SIXI_BYD_EVT_MASTER) || (board_id == ACU_HW_ID_SIXI_BYD_DVT_MASTER))
    {
        macAddrCnt = ENET_ARRAYSIZE(MasterMacAddrBuf);
        /* Save only those required to meet the max number of MAC entries */
        *pAvailMacEntries = EnetUtils_min(macAddrCnt, maxMacEntries);
        memcpy(&macAddr[0U][0U], &MasterMacAddrBuf[0U][0U], *pAvailMacEntries * ENET_MAC_ADDR_LEN);
	}
	else
	{
        macAddrCnt = ENET_ARRAYSIZE(SlaveMacAddrBuf);
        /* Save only those required to meet the max number of MAC entries */
        *pAvailMacEntries = EnetUtils_min(macAddrCnt, maxMacEntries);
        memcpy(&macAddr[0U][0U], &SlaveMacAddrBuf[0U][0U], *pAvailMacEntries * ENET_MAC_ADDR_LEN);
	}	

#endif
}

void EnetBoard_setEnetControl(Enet_Type enetType,
                              uint32_t instId,
                              Enet_MacPort portNum,
                              uint32_t modeSel)
{
    int32_t status = BOARD_FAIL;

    switch (enetType)
    {
        case ENET_CPSW_2G:
            status = Board_cpsw2gMacModeConfig(modeSel);
            break;
#if defined (SOC_J7200)
        case ENET_CPSW_5G:
            status = Board_cpsw5gEthConfig(portNum, modeSel);
            break;
#endif
#if defined (SOC_J721E)
        case ENET_CPSW_9G:
            status = Board_cpsw9gEthConfig(portNum, modeSel);
            break;
#endif
        default:
            break;
    }

    EnetAppUtils_assert(status == BOARD_SOK);
}
/******************************************************************************
 * Copyright (c) 2019 Texas Instruments Incorporated - http://www.ti.com
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *    Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 *    Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the
 *    distribution.
 *
 *    Neither the name of Texas Instruments Incorporated nor the names of
 *    its contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *****************************************************************************/

/**
 *   \file  board_ethernet_config.c
 *
 *   \brief
 *      This file contains the boards specific Ethernet PHY configurations.
 *
 */

#include "board_ethernet_config.h"
#include "board_internal.h"
#include <ti/csl/soc.h>
#include <ti/csl/cslr_mdio.h>


Board_pruicssMdioInfo  Board_gPruicssMdioInfo[BOARD_ICSS_EMAC_PORT_MAX] =
{
    {CSL_PRU_ICSSG0_PR1_MDIO_V1P7_MDIO_BASE, BOARD_ICSS0_EMAC_PHY0_ADDR},
    {CSL_PRU_ICSSG0_PR1_MDIO_V1P7_MDIO_BASE, BOARD_ICSS0_EMAC_PHY1_ADDR},
    {CSL_PRU_ICSSG1_PR1_MDIO_V1P7_MDIO_BASE, BOARD_ICSS1_EMAC_PHY0_ADDR},
    {CSL_PRU_ICSSG1_PR1_MDIO_V1P7_MDIO_BASE, BOARD_ICSS1_EMAC_PHY1_ADDR},
};

Board_pruicssMdioInfo  Board_cpswMdioInfo[BOARD_CPSW9G_EMAC_PORT_MAX] =
{
    {(CSL_CPSW0_NUSS_BASE + BOARD_CPSW_MDIO_REG_OFFSET), BOARD_ICSS0_EMAC_PHY0_ADDR},
    {(CSL_CPSW0_NUSS_BASE + BOARD_CPSW_MDIO_REG_OFFSET), BOARD_ICSS0_EMAC_PHY1_ADDR},
    {(CSL_CPSW0_NUSS_BASE + BOARD_CPSW_MDIO_REG_OFFSET), BOARD_ICSS1_EMAC_PHY0_ADDR},
    {(CSL_CPSW0_NUSS_BASE + BOARD_CPSW_MDIO_REG_OFFSET), BOARD_ICSS1_EMAC_PHY1_ADDR},
};
/**
 * \brief  Function to initialize MDIO
 *
 * \param   baseAddr [IN]   MDIO base address
 *
 * \return  uint32_t
            TRUE     Read is successful.
 *          FALSE    Read is not acknowledged properly.
 */
static void Board_mdioInit(uint32_t baseAddr)
{
    HW_WR_REG32((baseAddr + BOARD_MDIO_CTRL_REG_OFFSET),
                (CSL_FMKT(MDIO_CONTROL_REG_ENABLE, YES) |
                 CSL_FMK(MDIO_CONTROL_REG_CLKDIV,
                         BOARD_MDIO_CLK_DIV_CFG)));
}

/**
 * \brief  PHY register write function
 *
 * This function is used to writes a PHY register using MDIO.
 *
 * \param   baseAddr [IN]   MDIO base address
 *          phyAddr  [IN]   PHY Address
 *          regAddr  [IN]   Register offset to be written
 *          data     [IN]   Value to be written
 *
 */
static void Board_ethPhyRegWrite(uint32_t baseAddr, uint32_t phyAddr,
                                 uint32_t regAddr, uint16_t data)
{
    uint32_t regVal = 0U;

    /* Wait till transaction completion if any */
    while (HW_RD_FIELD32(baseAddr + CSL_MDIO_USER_GROUP_USER_ACCESS_REG(0U),
                         CSL_MDIO_USER_GROUP_USER_ACCESS_REG_GO) == 1)
    {}

    HW_SET_FIELD(regVal, CSL_MDIO_USER_GROUP_USER_ACCESS_REG_GO, 1);
    HW_SET_FIELD(regVal, CSL_MDIO_USER_GROUP_USER_ACCESS_REG_WRITE, 1);
    HW_SET_FIELD(regVal, CSL_MDIO_USER_GROUP_USER_ACCESS_REG_PHYADR, phyAddr);
    HW_SET_FIELD(regVal, CSL_MDIO_USER_GROUP_USER_ACCESS_REG_REGADR, regAddr);
    HW_SET_FIELD(regVal, CSL_MDIO_USER_GROUP_USER_ACCESS_REG_DATA, data);
    HW_WR_REG32(baseAddr + CSL_MDIO_USER_GROUP_USER_ACCESS_REG(0U), regVal);

    /* wait for command completion */
    while (HW_RD_FIELD32(baseAddr + CSL_MDIO_USER_GROUP_USER_ACCESS_REG(0U),
                         CSL_MDIO_USER_GROUP_USER_ACCESS_REG_GO) == 1)
    {}
}

/**
 * \brief  PHY register read function
 *
 * This function is used to Read a PHY register using MDIO.
 *
 * \param   baseAddr [IN]   MDIO base address
 *          phyAddr  [IN]   PHY Address
 *          regAddr  [IN]   Register offset to be written
 *          regData  [OUT]  Pointer where the read value shall be written
 *
 * \return  uint32_t
            TRUE     Read is successful.
 *          FALSE    Read is not acknowledged properly.
 */
static uint32_t BoardDiag_ethPhyRegRead(uint32_t baseAddr, uint32_t phyAddr,
                                        uint32_t regAddr, uint16_t *regData)
{
    uint32_t regVal = 0U;
    uint32_t retVal = 0U;

    /* Wait till transaction completion if any */
    while (HW_RD_FIELD32(baseAddr + CSL_MDIO_USER_GROUP_USER_ACCESS_REG(0U),
                         CSL_MDIO_USER_GROUP_USER_ACCESS_REG_GO) == 1)
    {}
    HW_SET_FIELD(regVal, CSL_MDIO_USER_GROUP_USER_ACCESS_REG_GO, 1);
    HW_SET_FIELD(regVal, CSL_MDIO_USER_GROUP_USER_ACCESS_REG_WRITE, 0);
    HW_SET_FIELD(regVal, CSL_MDIO_USER_GROUP_USER_ACCESS_REG_PHYADR, phyAddr);
    HW_SET_FIELD(regVal, CSL_MDIO_USER_GROUP_USER_ACCESS_REG_REGADR, regAddr);
    HW_WR_REG32(baseAddr + CSL_MDIO_USER_GROUP_USER_ACCESS_REG(0U), regVal);

    /* wait for command completion */
    while (HW_RD_FIELD32(baseAddr + CSL_MDIO_USER_GROUP_USER_ACCESS_REG(0U),
                         CSL_MDIO_USER_GROUP_USER_ACCESS_REG_GO) == 1)
    {}

    /* Store the data if the read is acknowledged */
    if (HW_RD_FIELD32(baseAddr + CSL_MDIO_USER_GROUP_USER_ACCESS_REG(0U),
                      CSL_MDIO_USER_GROUP_USER_ACCESS_REG_ACK) == 1)
    {
        *regData = (uint16_t)(HW_RD_FIELD32(baseAddr + \
                                            CSL_MDIO_USER_GROUP_USER_ACCESS_REG(0U),
                                            CSL_MDIO_USER_GROUP_USER_ACCESS_REG_DATA));
        retVal = (uint32_t)TRUE;
    }
    else
    {
        retVal = (uint32_t)FALSE;
    }

    return (retVal);
}

/**
 * \brief  Function to write extended address registers of Ethernet PHY
 *
 * \param   baseAddr [IN]    MDIO base address
 *          phyAddr  [IN]    Ethernet PHY address
 *          regNum   [IN]    PHY Register address
 *          pData    [OUT]   Values read from register
 *
 */
static void Board_ethPhyExtendedRegRead(uint32_t baseAddr,
                                        uint32_t phyAddr,
                                        uint32_t regNum,
                                        uint16_t *pData)
{
    Board_ethPhyRegWrite(baseAddr, phyAddr,
                         BOARD_ETHPHY_REGCR_REG_ADDR,
                         BOARD_ETHPHY_REGCR_ADDR_EN);
    Board_ethPhyRegWrite(baseAddr, phyAddr,
                         BOARD_ETHPHY_ADDAR_REG_ADDR, regNum);
    Board_ethPhyRegWrite(baseAddr, phyAddr,
                         BOARD_ETHPHY_REGCR_REG_ADDR,
                         BOARD_ETHPHY_REGCR_DATA_EN);
    BoardDiag_ethPhyRegRead(baseAddr, phyAddr,
                            BOARD_ETHPHY_ADDAR_REG_ADDR, pData);
}

/**
 * \brief  Function to write extended address registers of Ethernet PHY
 *
 * \param   baseAddr [IN]    MDIO base address
 * \param   phyAddr  [IN]    Ethernet PHY address
 * \param   regNum   [IN]    PHY Register address
 * \param   regVal   [IN]    Register value to be written
 *
 * \return  none
 */
static void Board_ethPhyExtendedRegWrite(uint32_t baseAddr,
        uint32_t phyAddr,
        uint32_t regNum,
        uint16_t regVal)
{
    Board_ethPhyRegWrite(baseAddr, phyAddr,
                         BOARD_ETHPHY_REGCR_REG_ADDR,
                         BOARD_ETHPHY_REGCR_ADDR_EN);
    Board_ethPhyRegWrite(baseAddr, phyAddr,
                         BOARD_ETHPHY_ADDAR_REG_ADDR, regNum);
    Board_ethPhyRegWrite(baseAddr, phyAddr,
                         BOARD_ETHPHY_REGCR_REG_ADDR,
                         BOARD_ETHPHY_REGCR_DATA_EN);
    Board_ethPhyRegWrite(baseAddr, phyAddr,
                         BOARD_ETHPHY_ADDAR_REG_ADDR, regVal);
}

/**
 * \brief  Disables ICSSG MAC internal delay
 *
 * \return  none
 */
static void Board_disableIcssEmacDelay(void)
{
    HW_WR_REG32((CSL_CTRL_MMR0_CFG0_BASE + CSL_MAIN_CTRL_MMR_CFG0_ICSSG0_CTRL0), BOARD_EMAC_DELAY_CFG);
    HW_WR_REG32((CSL_CTRL_MMR0_CFG0_BASE + CSL_MAIN_CTRL_MMR_CFG0_ICSSG0_CTRL1), BOARD_EMAC_DELAY_CFG);
    HW_WR_REG32((CSL_CTRL_MMR0_CFG0_BASE + CSL_MAIN_CTRL_MMR_CFG0_ICSSG1_CTRL0), BOARD_EMAC_DELAY_CFG);
    HW_WR_REG32((CSL_CTRL_MMR0_CFG0_BASE + CSL_MAIN_CTRL_MMR_CFG0_ICSSG1_CTRL1), BOARD_EMAC_DELAY_CFG);
}

/**
 * \brief  Enable/Disable PHY reset for ENET EXP boards PHY
 *
 * \return  BOARD_SOK in case of success or appropriate error code
 */
Board_STATUS Board_cpswEnetExpPhyReset(bool enableFlag)
{
    return BOARD_SOK;

#if 0
    Board_IoExpCfg_t ioExpCfg;
    Board_STATUS status = BOARD_SOK;

    ioExpCfg.i2cInst     = BOARD_I2C_IOEXP_DEVICE2_INSTANCE;
    ioExpCfg.socDomain   = BOARD_SOC_DOMAIN_MAIN;
    ioExpCfg.slaveAddr   = BOARD_I2C_IOEXP_DEVICE2_ADDR;
    ioExpCfg.enableIntr  = false;
    ioExpCfg.ioExpType   = THREE_PORT_IOEXP;
    ioExpCfg.portNum     = PORTNUM_2;
    ioExpCfg.pinNum      = PIN_NUM_1;

    if (1U == enableFlag)
    {
        /* EXP_ENET_RSTz - set to 0 for PHY reset */
        ioExpCfg.signalLevel = GPIO_SIGNAL_LEVEL_LOW;
    }
    else
    {
        /* EXP_ENET_RSTz - set to 1 to take PHY out of reset (normal operation)*/
        ioExpCfg.signalLevel = GPIO_SIGNAL_LEVEL_HIGH;
    }

    status = Board_control(BOARD_CTRL_CMD_SET_IO_EXP_PIN_OUT, &ioExpCfg);

    return status;
#endif //if 0
}

/**
 * \brief  Enable/Disable COMA_MODE for ENET EXP boards PHY
 *
 * \return  BOARD_SOK in case of success or appropriate error code
 */
Board_STATUS Board_cpswEnetExpComaModeCfg(bool enableFlag)
{
    Board_IoExpCfg_t ioExpCfg;
    Board_STATUS status = BOARD_SOK;

    if (Board_detectBoard(BOARD_ID_ENET) == TRUE)
    {
        ioExpCfg.i2cInst     = BOARD_I2C_IOEXP_DEVICE2_INSTANCE;
        ioExpCfg.socDomain   = BOARD_SOC_DOMAIN_MAIN;
        ioExpCfg.slaveAddr   = BOARD_I2C_IOEXP_DEVICE2_ADDR;
        ioExpCfg.enableIntr  = false;
        ioExpCfg.ioExpType   = THREE_PORT_IOEXP;
        ioExpCfg.portNum     = PORTNUM_2;
        ioExpCfg.pinNum      = PIN_NUM_0;

        if (1U == enableFlag)
        {
            /* ENET_EXP_PWRDN - set to 1 for device power down */
            ioExpCfg.signalLevel = GPIO_SIGNAL_LEVEL_HIGH;
        }
        else
        {
            /* ENET_EXP_PWRDN - set to 0 for normal operation */
            ioExpCfg.signalLevel = GPIO_SIGNAL_LEVEL_LOW;
        }

        status = Board_control(BOARD_CTRL_CMD_SET_IO_EXP_PIN_OUT, &ioExpCfg);
    }

    return status;
}

/**
 * \brief  Board specific configurations for SGMII Ethernet PHYs
 *
 * This function takes care of configuring the internal delays for SGMII
 * Ethernet PHYs
 *
 * \return  BOARD_SOK in case of success or appropriate error code
 */
Board_STATUS Board_sgmiiEthPhyConfig(void)
{
    return BOARD_SOK;
}

/**
 * \brief  Board specific configurations for CPSW9G Ethernet PHYs
 *
 * This function takes care of configuring the internal delays for CPSW9G
 * Ethernet PHYs
 *
 * \return  BOARD_SOK in case of success or appropriate error code
 */
Board_STATUS Board_cpsw9gEthPhyConfig(void)
{
    Board_STATUS status;
    uint32_t baseAddr;
    uint8_t  phyAddr;
    uint32_t index;
    uint16_t regData = 0;
    bool isAlpha = 0;

    /*
     * MDIO stability issue due to ENET card is resolved in Beta HW revision.
     * Disabling ENET card is needed only for Alpha CP boards.
     */
    isAlpha = Board_isAlpha(BOARD_ID_CP);

    if (isAlpha == TRUE)
    {
        /* CPSW9G MDIO access is unstable when ENET card is connected.
           Keeping the ENET PHY in reset as a temporary workaround */
        status = Board_cpswEnetExpComaModeCfg(1U);
        status = Board_cpswEnetExpPhyReset(1U);
        if (status != BOARD_SOK)
        {
            return status;
        }
    }

    for (index = 0; index < BOARD_CPSW9G_EMAC_PORT_MAX; index++)
    {
        baseAddr = Board_cpswMdioInfo[index].mdioBaseAddrs;
        phyAddr  = Board_cpswMdioInfo[index].phyAddrs;

        Board_mdioInit(baseAddr);

        /* Enable PHY speed LED functionality */
        Board_ethPhyExtendedRegRead(baseAddr, phyAddr,
                                    BOARD_ETHPHY_GPIO_MUX_CTRL2_REG_ADDR,
                                    &regData);
        regData  = (regData & ~(BOARD_ETHPHY_GPIO_MUX_CTRL2_REG_MASK)) |
                   BOARD_ETHPHY_GPIO_MUX_CTRL2_REG_CFG;
        Board_ethPhyExtendedRegWrite(baseAddr, phyAddr,
                                     BOARD_ETHPHY_GPIO_MUX_CTRL2_REG_ADDR,
                                     regData);

        regData = 0;
        BoardDiag_ethPhyRegRead(baseAddr, phyAddr,
                                BOARD_ETHPHY_LEDCR1_REG_ADDR, &regData);
        regData  = (regData & ~(BOARD_ETHPHY_LEDCR1_REG_MASK)) |
                   BOARD_ETHPHY_LEDCR1_REG_CFG;
        Board_ethPhyRegWrite(baseAddr, phyAddr,
                             BOARD_ETHPHY_LEDCR1_REG_ADDR, regData);

        /* When the Phy is strapped to enable Fast Link Drop (FLD) feature,
         * the detect threshold value becomes 0x2 in bit 2:0 instead of 0x1
         * in the  FLD_THRESH (0x2e) register  as in non strapped case.
         * This causes the phy link to be unstable.
         * As a workaround, write a value of 0x1 in this bit field if
         * bit 10 of STRAP_STS2 (0x6f) register is set (enable FLD).
         */
        regData = 0;
        Board_ethPhyExtendedRegRead(baseAddr, phyAddr,
                                    BOARD_ETHPHY_STRAP_STS2_REG_ADDR,
                                    &regData);
        if (regData & BOARD_ETHPHY_STRAP_FLD_MASK)
        {
            regData = 0;
            Board_ethPhyExtendedRegRead(baseAddr, phyAddr,
                                        BOARD_ETHPHY_FLD_THRESH_REG_ADDR,
                                        &regData);
            if (regData == BOARD_ETHPHY_STRAP_FLD_THS_CHECK_FLAG)
            {
                regData &= ~0x7;
                Board_ethPhyExtendedRegWrite(baseAddr, phyAddr,
                                             BOARD_ETHPHY_FLD_THRESH_REG_ADDR,
                                             (regData | 0x1));
            }
        }

        /*Setting IO impedance to 35ohms  */
        Board_ethPhyExtendedRegWrite(baseAddr, phyAddr,
                                     BOARD_ETHPHY_GPIO_MUX_CFG_REG_ADDR,
                                     BOARD_ETHPHY_IO_IMPEDANCE);

        /* Enable the PHY delay configurations */
        Board_ethPhyExtendedRegWrite(baseAddr, phyAddr, BOARD_ETHPHY_RGMIICTL_REG_ADDR,
                                     BOARD_ETHPHY_DELAY_CTRL);

        /* Setting delay */
        Board_ethPhyExtendedRegWrite(baseAddr, phyAddr,
                                     BOARD_ETHPHY_RGMIIDCTL_REG_ADDR,
                                     BOARD_ETHPHY_CPSW9G_DELAY);
    }

    return BOARD_SOK;
}

/**
 * \brief  Board specific configurations for CPSW2G Ethernet PHY
 *
 * This function takes care of configuring the internal delays for MCU gigabit
 * Ethernet PHY
 *
 * \return  BOARD_SOK in case of success or appropriate error code
 */
Board_STATUS Board_cpsw2gEthPhyConfig(void)
{
    uint32_t baseAddr;
    uint16_t regData = 0;

    baseAddr = (CSL_MCU_CPSW0_NUSS_BASE + 0x0F00);

    Board_mdioInit(baseAddr);

    /* Enable PHY speed LED functionality */
    Board_ethPhyExtendedRegRead(baseAddr, BOARD_MCU_EMAC_PHY_ADDR,
                                BOARD_ETHPHY_GPIO_MUX_CTRL2_REG_ADDR,
                                &regData);
    regData  = (regData & ~(BOARD_ETHPHY_GPIO_MUX_CTRL2_REG_MASK)) |
               BOARD_ETHPHY_GPIO_MUX_CTRL2_REG_CFG;
    Board_ethPhyExtendedRegWrite(baseAddr, BOARD_MCU_EMAC_PHY_ADDR,
                                 BOARD_ETHPHY_GPIO_MUX_CTRL2_REG_ADDR,
                                 regData);

    regData = 0;
    BoardDiag_ethPhyRegRead(baseAddr, BOARD_MCU_EMAC_PHY_ADDR,
                            BOARD_ETHPHY_LEDCR1_REG_ADDR, &regData);
    regData  = (regData & ~(BOARD_ETHPHY_LEDCR1_REG_MASK)) |
               BOARD_ETHPHY_LEDCR1_REG_CFG;
    Board_ethPhyRegWrite(baseAddr, BOARD_MCU_EMAC_PHY_ADDR,
                         BOARD_ETHPHY_LEDCR1_REG_ADDR, regData);

    /* When the Phy is strapped to enable Fast Link Drop (FLD) feature,
     * the detect threshold value becomes 0x2 in bit 2:0 instead of 0x1
     * in the  FLD_THRESH (0x2e) register  as in non strapped case.
     * This causes the phy link to be unstable.
     * As a workaround, write a value of 0x1 in this bit field if
     * bit 10 of STRAP_STS2 (0x6f) register is set (enable FLD).
     */
    regData = 0;
    Board_ethPhyExtendedRegRead(baseAddr, BOARD_MCU_EMAC_PHY_ADDR,
                                BOARD_ETHPHY_STRAP_STS2_REG_ADDR,
                                &regData);
    if (regData & BOARD_ETHPHY_STRAP_FLD_MASK)
    {
        regData = 0;
        Board_ethPhyExtendedRegRead(baseAddr, BOARD_MCU_EMAC_PHY_ADDR,
                                    BOARD_ETHPHY_FLD_THRESH_REG_ADDR,
                                    &regData);
        if (regData == BOARD_ETHPHY_STRAP_FLD_THS_CHECK_FLAG)
        {
            regData &= ~0x7;
            Board_ethPhyExtendedRegWrite(baseAddr, BOARD_MCU_EMAC_PHY_ADDR,
                                         BOARD_ETHPHY_FLD_THRESH_REG_ADDR,
                                         (regData | 0x1));
        }
    }

    /* Enabling the TX and RX delay */
    Board_ethPhyExtendedRegRead(baseAddr, BOARD_MCU_EMAC_PHY_ADDR,
                                BOARD_ETHPHY_RGMIICTL_REG_ADDR, &regData);
    regData = regData | 0x3;
    Board_ethPhyExtendedRegWrite(baseAddr, BOARD_MCU_EMAC_PHY_ADDR,
                                 BOARD_ETHPHY_RGMIICTL_REG_ADDR, regData);

    /* Setting delay */
    Board_ethPhyExtendedRegWrite(baseAddr, BOARD_MCU_EMAC_PHY_ADDR,
                                 BOARD_ETHPHY_RGMIIDCTL_REG_ADDR,
                                 BOARD_ETHPHY_CPSW2G_DELAY);

    return BOARD_SOK;

}

/**
 * \brief  Board specific configurations for ICSS EMAC Ethernet PHYs
 *
 * This function takes care of configuring the internal delays for ICSS
 * Ethernet PHY
 *
 * \return  BOARD_SOK in case of success or appropriate error code
 */
Board_STATUS Board_icssEthPhyConfig(void)
{
    uint32_t baseAddr;
    uint8_t  phyAddr;
    uint32_t index;
    uint16_t regData = 0;
    Board_STATUS status = BOARD_SOK;

    status = Board_control(BOARD_CTRL_CMD_SET_ICSSG_MDIO_MUX, NULL);
    if (status == BOARD_SOK)
    {
        for (index = 0; index < BOARD_ICSS_EMAC_PORT_MAX; index++)
        {
            baseAddr = Board_gPruicssMdioInfo[index].mdioBaseAddrs;
            phyAddr  = Board_gPruicssMdioInfo[index].phyAddrs;

            Board_mdioInit(baseAddr);

            /* Enable the PHY delay configurations */
            Board_ethPhyExtendedRegWrite(baseAddr, phyAddr,
                                         BOARD_ETHPHY_RGMIICTL_REG_ADDR,
                                         BOARD_ETHPHY_DELAY_CTRL);

            /* Setting delay */
            Board_ethPhyExtendedRegWrite(baseAddr, phyAddr,
                                         BOARD_ETHPHY_RGMIIDCTL_REG_ADDR,
                                         BOARD_ETHPHY_ICSSG_DELAY);

            /*Setting IO impedance to 35ohms  */
            Board_ethPhyExtendedRegWrite(baseAddr, phyAddr,
                                         BOARD_ETHPHY_GPIO_MUX_CFG_REG_ADDR,
                                         BOARD_ETHPHY_IO_IMPEDANCE);

            /* Enable PHY speed LED functionality */
            Board_ethPhyExtendedRegRead(baseAddr, phyAddr,
                                        BOARD_ETHPHY_GPIO_MUX_CTRL2_REG_ADDR,
                                        &regData);
            regData  = (regData & ~(BOARD_ETHPHY_GPIO_MUX_CTRL2_REG_MASK)) | 0x6;
            Board_ethPhyExtendedRegWrite(baseAddr, phyAddr,
                                         BOARD_ETHPHY_GPIO_MUX_CTRL2_REG_ADDR,
                                         regData);

            regData = 0;
            BoardDiag_ethPhyRegRead(baseAddr, phyAddr,
                                    BOARD_ETHPHY_LEDCR1_REG_ADDR, &regData);
            regData  = (regData & ~(BOARD_ETHPHY_LEDCR1_REG_MASK)) |
                       BOARD_ETHPHY_LEDCR1_REG_CFG;
            Board_ethPhyRegWrite(baseAddr, phyAddr,
                                 BOARD_ETHPHY_LEDCR1_REG_ADDR, regData);

            /* When the Phy is strapped to enable Fast Link Drop (FLD) feature,
             * the detect threshold value becomes 0x2 in bit 2:0 instead of 0x1
             * in the  FLD_THRESH (0x2e) register  as in non strapped case.
             * This causes the phy link to be unstable.
             * As a workaround, write a value of 0x1 in this bit field if
             * bit 10 of STRAP_STS2 (0x6f) register is set (enable FLD).
             */
            regData = 0;
            Board_ethPhyExtendedRegRead(baseAddr, phyAddr,
                                        BOARD_ETHPHY_STRAP_STS2_REG_ADDR,
                                        &regData);
            if (regData & BOARD_ETHPHY_STRAP_FLD_MASK)
            {
                regData = 0;
                Board_ethPhyExtendedRegRead(baseAddr, phyAddr,
                                            BOARD_ETHPHY_FLD_THRESH_REG_ADDR,
                                            &regData);
                if (regData == BOARD_ETHPHY_STRAP_FLD_THS_CHECK_FLAG)
                {
                    regData &= ~0x7;
                    Board_ethPhyExtendedRegWrite(baseAddr, phyAddr,
                                                 BOARD_ETHPHY_FLD_THRESH_REG_ADDR,
                                                 (regData | 0x1));
                }
            }
        }
    }

    return status;
}

/**
 * \brief  Configures the CPSW9G Subsytem for RGMII and RMII mode
 *
 * \param  portNum [IN]    EMAC port number
 * \param  mode    [IN]    Mode selection for the specified port number
 *                         000 - GMII
 *                         001 - RMII
 *                         010 - RGMII
 *                         011 - SGMII
 *                         100 - QSGMII
 *
 * \return  BOARD_SOK in case of success or appropriate error code
 */
Board_STATUS Board_cpsw9gEthConfig(uint32_t portNum, uint8_t mode)
{
    uint32_t status;
    uintptr_t modeSel;
    uint32_t regData;

    Board_unlockMMR();

    modeSel = CSL_CTRL_MMR0_CFG0_BASE + CSL_MAIN_CTRL_MMR_CFG0_ENET1_CTRL + (portNum * 0x04);
    regData = CSL_REG32_RD(modeSel);
    regData = mode;
    if (RGMII == mode)
    {
        if(5 != portNum)
        {
            /* ENET_MAC_PORT_6 configed as rgmii then connected to mcu domain, we must enable Internal transmit delay "0" */
            regData |= (RGMII_ID_DISABLE_MASK);
        }
    }
    CSL_REG32_WR(modeSel, regData);
    status = CSL_REG32_RD(modeSel);
    if (status != regData)
    {
        return BOARD_FAIL;
    }

    return BOARD_SOK;
}

/**
 * \brief  Board specific configurations for ICSSG RGMII Ethernet
 *
 * This function takes care of configuring the internal delays for
 * ICSSG RGMII Ethernet PHY
 *
 * \return  BOARD_SOK in case of success or appropriate error code
 */
static Board_STATUS Board_icssEthConfig(uint32_t portNum, uint8_t mode)
{
    Board_disableIcssEmacDelay();
    return BOARD_SOK;
}

/**
 * \brief  Configures the CPSW2G Subsytem for RGMII mode
 *
 * \param  mode    [IN]    Mode selection for the specified port number
 *                         00 - GMII
 *                         01 - RMII
 *                         10 - RGMII
 *                         11 - SGMII
 *
 * \return  BOARD_SOK in case of success or appropriate error code
 */
Board_STATUS Board_cpsw2gMacModeConfig(uint8_t mode)
{
    uint32_t status;
    uintptr_t ethModeCtrl;
    uint32_t regData;

    ethModeCtrl = CSL_MCU_CTRL_MMR0_CFG0_BASE + CSL_MCU_CTRL_MMR_CFG0_MCU_ENET_CTRL;
    regData = CSL_REG32_RD(ethModeCtrl);
    regData = mode;
    if (RGMII == mode)
    {
        regData |= (RGMII_ID_DISABLE_MASK);
    }

    CSL_REG32_WR(ethModeCtrl, regData);
    status = CSL_REG32_RD(ethModeCtrl);
    if (status != regData)
    {
        return BOARD_FAIL;
    }

    return BOARD_SOK;
}

/**
 * \brief  Board specific configurations for CPSW2G Ethernet ports
 *
 * This function used to configures CPSW2G Ethernet controllers with the respective modes
 *
 * \return  BOARD_SOK in case of success or appropriate error code
 */
Board_STATUS Board_ethConfigCpsw2g(void)
{
    Board_STATUS status = BOARD_SOK;

    Board_unlockMMR();

    /* Configures the MCU Ethernet */
    status = Board_cpsw2gMacModeConfig(RGMII);
    if (status != BOARD_SOK)
    {
        return BOARD_FAIL;
    }

    return BOARD_SOK;
}

/**
 * \brief  Board specific configurations for CPSW9G Ethernet ports
 *
 * This function used to configures CPSW9G Ethernet controllers with the respective modes
 *
 * \return  BOARD_SOK in case of success or appropriate error code
 */
Board_STATUS Board_ethConfigCpsw9g(void)
{
    Board_STATUS status = BOARD_SOK;
    uint8_t portNum;

    /* On J721E EVM to use all 8 ports simultaneously, we use below configuration
       RGMII Ports - 1,3,4,8. QSGMII ports - 2 (main),5,6,7 (sub)*/
    /* On Baidu Double tda4 board, we use below configuration
       RGMII Ports - 6 . SGMII ports - 0 */

    /* Configures the CPSW9G RGMII ports */
    for (portNum = 0; portNum < BOARD_CPSW9G_PORT_MAX; portNum++)
    {
        if ((0U == portNum) || (1U == portNum))
        {
            status = Board_cpsw9gEthConfig(portNum, SGMII);
        }
        else
        {
            status = Board_cpsw9gEthConfig(portNum, RGMII);
        }

        if (status != BOARD_SOK)
        {
            return BOARD_FAIL;
        }
    }

    return BOARD_SOK;
}

/**
 * \brief  Board specific configurations for ICSS Ethernet ports
 *
 * This function used to configures ICSS Ethernet controllers with the respective modes
 *
 * \return  BOARD_SOK in case of success or appropriate error code
 */
Board_STATUS Board_ethConfigIcss(void)
{
    Board_STATUS status = BOARD_SOK;
    uint8_t portNum;

    Board_unlockMMR();

    /* Configures ICSSG Ethernet */
    for (portNum = 0; portNum < BOARD_ICSS_EMAC_PORT_MAX; portNum++)
    {
        status = Board_icssEthConfig(portNum, RGMII);
        if (status != BOARD_SOK)
        {
            return BOARD_FAIL;
        }
    }

    return BOARD_SOK;
}

The logs seems fine:

master_remote.log     slave_remote.log

 We have tried to change SGMII MODE from Master and slave to force link,but still does not work:

BR

Sikai

  • Dear Experts,

         We have solved the link issue. The problem is customer did not clean the kernel dts, and after he rebuild it with disabled pcie, it can link now.

         However, during this process we have found another question:

         

           As the code says, we should do a loop judgement to check the link status. While if we delete this judgement then MCU2_0 will stuck. Is it normal?  If we do not want this judgement, how should we make change?

           Thanks.

    BR 

    Sikai