/*
 *  Copyright (c) Texas Instruments Incorporated 2024
 *
 *  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 ti_enet_soc.c
 *
 *  \brief This file contains enet soc config related functionality.
 */


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


#include <stdint.h>
#include <stdarg.h>
#include <drivers/sciclient.h>
#include <drivers/hw_include/cslr_soc.h>
#include <drivers/qos/v0/qos.h>
#include <drivers/qos/v0/soc/am243x/qos_soc.h>
#include <hw_include/cslr_icss.h>
#include <priv/mod/cpsw_clks.h>
#include <enet.h>
#include <soc/k3/cpsw_soc.h>
#include <enet_cfg.h>
#include <priv/mod/mdio_priv.h>
#include <priv/core/enet_rm_priv.h>
#include <include/core/enet_utils.h>
#include <include/core/enet_osal.h>
#include <include/core/enet_soc.h>
#include <include/core/enet_per.h>
#include <include/per/icssg.h>
#include <priv/per/icssg_priv.h>
#include <soc/k3/icssg_soc.h>
#include <src/dma/udma/enet_udma_priv.h>
#include <enet_appsoc.h>

#define ICSSG_FW_PLACEMENT_SECTION __attribute__((section(".rodata")))

#include <networking/enet/core/src/per/firmware/icssg/dualmac/RX_PRU_SLICE0_bin.h>
#include <networking/enet/core/src/per/firmware/icssg/dualmac/RX_PRU_SLICE1_bin.h>
#include <networking/enet/core/src/per/firmware/icssg/dualmac/RTU0_SLICE0_bin.h>
#include <networking/enet/core/src/per/firmware/icssg/dualmac/RTU0_SLICE1_bin.h>
#include <networking/enet/core/src/per/firmware/icssg/dualmac/TX_PRU_SLICE0_bin.h>
#include <networking/enet/core/src/per/firmware/icssg/dualmac/TX_PRU_SLICE1_bin.h>

#include <networking/enet/core/src/per/firmware/icssg/switch/RX_PRU_SLICE0_bin.h>
#include <networking/enet/core/src/per/firmware/icssg/switch/RX_PRU_SLICE1_bin.h>
#include <networking/enet/core/src/per/firmware/icssg/switch/RTU0_SLICE0_bin.h>
#include <networking/enet/core/src/per/firmware/icssg/switch/RTU0_SLICE1_bin.h>
#include <networking/enet/core/src/per/firmware/icssg/switch/TX_PRU_SLICE0_bin.h>
#include <networking/enet/core/src/per/firmware/icssg/switch/TX_PRU_SLICE1_bin.h>




#include "ti_enet_config.h"
#include "ti_drivers_config.h"

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


/*DUAL MAC MODE*/
/*
 * ICSSG Port buffer pool memory:
 *  - Dual-MAC: Not needed
 */
//#define ICSSG_PORT_POOL_TOTAL_SIZE              (0U)
/*
 * ICSSG Host buffer pool memory:
 *  - Dual-MAC:
 *            Gigabit Support: No of pools based on QOS level and 8kB each
 *            100M Support:    No of pools based on QOS level and 4kB each
 */
#define ICSSG_DUALMAC_PORT_1_HOST_POOL_SIZE             ((ENET_SYSCFG_ENABLE_GIGABIT) ? ENET_UTILS_ALIGN((8 * 1024U),ICSSG_CACHELINE_ALIGNMENT) : ENET_UTILS_ALIGN((4 * 1024U),ICSSG_CACHELINE_ALIGNMENT))
#define ICSSG_DUALMAC_PORT_1_HOST_POOL_TOTAL_SIZE       (ICSSG_DUALMAC_PORT_1_HOST_BUFFER_POOL_NUM_CFG * ICSSG_DUALMAC_PORT_1_HOST_POOL_SIZE )
#define ICSSG1_HOST_POOL_0_TOTAL_SIZE               (ICSSG_DUALMAC_PORT_1_HOST_POOL_TOTAL_SIZE)
#define ICSSG_DUALMAC_PORT_2_HOST_POOL_SIZE             ((ENET_SYSCFG_ENABLE_GIGABIT) ? ENET_UTILS_ALIGN((8 * 1024U),ICSSG_CACHELINE_ALIGNMENT) : ENET_UTILS_ALIGN((4 * 1024U),ICSSG_CACHELINE_ALIGNMENT))
#define ICSSG_DUALMAC_PORT_2_HOST_POOL_TOTAL_SIZE       (ICSSG_DUALMAC_PORT_2_HOST_BUFFER_POOL_NUM_CFG * ICSSG_DUALMAC_PORT_2_HOST_POOL_SIZE )
#define ICSSG1_HOST_POOL_1_TOTAL_SIZE               (ICSSG_DUALMAC_PORT_2_HOST_POOL_TOTAL_SIZE)

/*
 * ICSSG Host egress queue memory:
 *  - Dual-MAC:
 *            Gigabit Support: 2 queues of (6kB + 2kB) each
 *            100M Support:    2 queues of (3kB + 2kB) each
 */
#define ICSSG_DUALMAC_HOST_QUEUE_SIZE            ((ENET_SYSCFG_ENABLE_GIGABIT) ? ENET_UTILS_ALIGN((8 * 1024U),ICSSG_CACHELINE_ALIGNMENT) : ENET_UTILS_ALIGN((5 * 1024U),ICSSG_CACHELINE_ALIGNMENT))
#define ICSSG_DUALMAC_HOST_QUEUE_TOTAL_SIZE      ((ICSSG_DUALMAC_HOST_EGRESS_QUEUE_NUM * ICSSG_DUALMAC_HOST_QUEUE_SIZE) + ENET_UTILS_ALIGN(ICSSG_HOST_EGRESS_BUFFER_PADDING,ICSSG_CACHELINE_ALIGNMENT))
#define ICSSG1_HOST_QUEUE_TOTAL_SIZE              (ICSSG_DUALMAC_HOST_QUEUE_TOTAL_SIZE)
#define ICSSG1_PRE_QUEUE_TOTAL_SIZE               ((ENET_SYSCFG_PREMPTION_ENABLE) ? (ICSSG_DUALMAC_HOST_QUEUE_TOTAL_SIZE) : 0)

#define ENET_PRU_INVALID CONFIG_PRUICSS_NUM_INSTANCES

/* --------------------------------- ICSS-G --------------------------------- */


/* ICSSG1 Port 0 memories */

static uint8_t gEnetSoc_icssg1HostPoolMem_0[ICSSG1_HOST_POOL_0_TOTAL_SIZE]
        __attribute__ ((aligned (ICSSG_CACHELINE_ALIGNMENT)));

static uint8_t gEnetSoc_icssg1HostQueueMem_0[ICSSG1_HOST_QUEUE_TOTAL_SIZE]
        __attribute__ ((aligned (ICSSG_CACHELINE_ALIGNMENT)));

static uint8_t gEnetSoc_icssg1ScratchMem_0[ICSSG_SCRATCH_BUFFER_SIZE]
        __attribute__ ((aligned (ICSSG_CACHELINE_ALIGNMENT)));





/* ICSSG1 Port 1 memories */



static uint8_t gEnetSoc_icssg1HostPoolMem_1[ICSSG1_HOST_POOL_1_TOTAL_SIZE]
        __attribute__ ((aligned (ICSSG_CACHELINE_ALIGNMENT)));

static uint8_t gEnetSoc_icssg1HostQueueMem_1[ICSSG1_HOST_QUEUE_TOTAL_SIZE]
        __attribute__ ((aligned (ICSSG_CACHELINE_ALIGNMENT)));

static uint8_t gEnetSoc_icssg1ScratchMem_1[ICSSG_SCRATCH_BUFFER_SIZE]
        __attribute__ ((aligned (ICSSG_CACHELINE_ALIGNMENT)));




static Icssg_FwPoolMem gEnetSoc_Icssg1_0_FwPoolMem[] =
{
    [0] =
    {
            .portBufferPoolMem   = NULL,
            .portBufferPoolSize  = 0U,
            .portBufferPoolNum   = 0U,

            .hostBufferPoolMem   = gEnetSoc_icssg1HostPoolMem_0,
            .hostBufferPoolSize  = ICSSG_DUALMAC_PORT_1_HOST_POOL_SIZE,
            .hostBufferPoolNum   = ICSSG_DUALMAC_PORT_1_HOST_BUFFER_POOL_NUM_CFG,

            .hostEgressQueueMem  = gEnetSoc_icssg1HostQueueMem_0,
            .hostEgressQueueSize = ICSSG_DUALMAC_HOST_QUEUE_SIZE,
            .hostEgressPreQueueMem  = NULL,
            .hostEgressPreQueueSize = ICSSG1_PRE_QUEUE_TOTAL_SIZE,
            .hostEgressQueueNum  = ICSSG_DUALMAC_HOST_EGRESS_QUEUE_NUM,

            .scratchBufferMem    = gEnetSoc_icssg1ScratchMem_0,
            .scratchBufferSize   = ICSSG_SCRATCH_BUFFER_SIZE,
    },
};






static Icssg_FwPoolMem gEnetSoc_Icssg1_1_FwPoolMem[] =
{
    [0] =
    {
            .portBufferPoolMem   = NULL,
            .portBufferPoolSize  = 0U,
            .portBufferPoolNum   = 0U,

            .hostBufferPoolMem   = gEnetSoc_icssg1HostPoolMem_1,
            .hostBufferPoolSize  = ICSSG_DUALMAC_PORT_2_HOST_POOL_SIZE,
            .hostBufferPoolNum   = ICSSG_DUALMAC_PORT_2_HOST_BUFFER_POOL_NUM_CFG,

            .hostEgressQueueMem  = gEnetSoc_icssg1HostQueueMem_1,
            .hostEgressQueueSize = ICSSG_DUALMAC_HOST_QUEUE_SIZE,
            .hostEgressPreQueueMem  = NULL,
            .hostEgressPreQueueSize = ICSSG1_PRE_QUEUE_TOTAL_SIZE,
            .hostEgressQueueNum  = ICSSG_DUALMAC_HOST_EGRESS_QUEUE_NUM,

            .scratchBufferMem    = gEnetSoc_icssg1ScratchMem_1,
            .scratchBufferSize   = ICSSG_SCRATCH_BUFFER_SIZE,
    },
};



/* QoS for ICSSG data movement accelerators: These widgets move the data between ICSS internal registers to MSRAM outside the ICSS module. 
 * In K3 SoC arch, the transactions goes through the CBASS interconnect. The CBASS interconnect provides MMRs to define the QoS.
 * EPRIORITY = 3 bits QoS field - 0x0 <Highest>, 0x7 <lowest>
 * TXPRU_XFRVBUS_RD - TXPRU uses read widget to read the packet content from the target memory during port egress.
 * RXPRU_XFRVBUS_WR - RXPRU uses write widget to write the packet content to the target memory during port ingress.
 * Default EPRIORITY is 0x7 (lowest).
 */
QOS_Config soc_qos_data[] = {
    /* ICSSG0_RXPRU_XFRVBUS_WR_NRT_RT - 1 endpoints, 2 channels */
    {
        .reg = ICSS_G_16FF_MAIN_0_PR1_EXT_VBUSM + 0x100 + 0x4 * 6,
        .val = EPRIORITY_1 | ORDERID_15,
    },
    {
        .reg = ICSS_G_16FF_MAIN_0_PR1_EXT_VBUSM + 0x100 + 0x4 * 7,
        .val = EPRIORITY_1 | ORDERID_15,
    },

    /* ICSSG0_TXPRU_XFRVBUS_RD_NRT - 1 endpoints, 2 channels */
    {
        .reg = ICSS_G_16FF_MAIN_0_PR1_EXT_VBUSM + 0x100 + 0x4 * 10,
        .val = ORDERID_15,
    },
    {
        .reg = ICSS_G_16FF_MAIN_0_PR1_EXT_VBUSM + 0x100 + 0x4 * 11,
        .val = ORDERID_15,
    },

    /* ICSSG1_RXPRU_XFRVBUS_WR_NRT_RT - 1 endpoints, 2 channels */
    {
        .reg = ICSS_G_16FF_MAIN_1_PR1_EXT_VBUSM + 0x100 + 0x4 * 6,
        .val = EPRIORITY_1 | ORDERID_15,
    },
    {
        .reg = ICSS_G_16FF_MAIN_1_PR1_EXT_VBUSM + 0x100 + 0x4 * 7,
        .val = EPRIORITY_1 | ORDERID_15,
    },

    /* ICSSG1_TXPRU_XFRVBUS_RD_NRT - 1 endpoints, 2 channels */
    {
        .reg = ICSS_G_16FF_MAIN_1_PR1_EXT_VBUSM + 0x100 + 0x4 * 10,
        .val = ORDERID_15,
    },
    {
        .reg = ICSS_G_16FF_MAIN_1_PR1_EXT_VBUSM + 0x100 + 0x4 * 11,
        .val = ORDERID_15,
    },


    /* Following registers set 1:1 mapping for orderID MAP1/MAP2
     * remap registers. orderID x is remapped to orderID x again
     * This is to ensure orderID from MAP register is unchanged
     */

    /* ICSS_G_16FF_MAIN_0_PR1_EXT_VBUSM - 0 groups */

    /* ICSS_G_16FF_MAIN_1_PR1_EXT_VBUSM - 0 groups */
};

/* PRU_ICSSG 0 */
Icssg_Pruss gEnetSoc_PruIcssg0 =
{
    .name        = ENET_PRU_INVALID,
    .instance    = ICSSG_PRUSS_ID_0,
    .initialized = false,
    .iep0InUse   = false,
};


/* PRU_ICSSG 1 */
Icssg_Pruss gEnetSoc_PruIcssg1 =
{
    .name        = CONFIG_PRU_ICSS1,
    .instance    = ICSSG_PRUSS_ID_1,
    .initialized = false,
    .iep0InUse   = false,
};

/* ICSSG1 Dual-MAC Port 1 (ENET_ICSSG_DUALMAC, 2) */
static Icssg_Obj gEnetSoc_icssg1DMacp1 =
{
    .enetPer =
    {
        .name         = "icssg1-1",
        .enetType     = ENET_ICSSG_DUALMAC,
        .instId       = 2U,
        .magic        = ENET_NO_MAGIC,
        .physAddr     = CSL_PRU_ICSSG1_DRAM0_SLV_RAM_BASE,
        .physAddr2    = 0U,
        .features     = ENET_FEAT_BASE,
        .errata       = ENET_ERRATA_NONE,
        .initCfg      = &Icssg_initCfg,
        .open         = &Icssg_open,
        .close        = &Icssg_close,
        .rejoin       = &Icssg_rejoin,
        .ioctl        = &Icssg_ioctl,
        .poll         = &Icssg_poll,
        .convertTs    = &Icssg_convertTs,
        .periodicTick = &Icssg_periodicTick,
        .registerEventCb   = &Icssg_registerEventCb,
        .unregisterEventCb = &Icssg_unregisterEventCb,
    },

    /* Shared between ICSSG1 Port 1 and Port 2 objects */
    .pruss = &gEnetSoc_PruIcssg1,

    /* Dual-MAC firmware for slice 0 */
    .fw =
    {
        {
            .pru       = RX_PRU_SLICE0_b00_DMac,
            .pruSize   = sizeof(RX_PRU_SLICE0_b00_DMac),
            .rtu       = RTU0_SLICE0_b00_DMac,
            .rtuSize   = sizeof(RTU0_SLICE0_b00_DMac),
            .txpru     = TX_PRU_SLICE0_b00_DMac,
            .txpruSize = sizeof(TX_PRU_SLICE0_b00_DMac)
        },
    },

    /* TimeSync module object */
    .timeSyncObj =
    {
        .enetMod =
        {
            .name       = "icssg1-1.timesync",
            .physAddr   = CSL_PRU_ICSSG1_DRAM0_SLV_RAM_BASE + CSL_ICSS_G_PR1_IEP0_SLV_REGS_BASE,
            .physAddr2  = CSL_PRU_ICSSG1_DRAM0_SLV_RAM_BASE + CSL_ICSS_G_RAM_SLV_RAM_REGS_BASE,
            .features   = ENET_FEAT_BASE,
            .errata     = ENET_ERRATA_NONE,
            .open       = &IcssgTimeSync_open,
            .rejoin     = &IcssgTimeSync_rejoin,
            .ioctl      = &IcssgTimeSync_ioctl,
            .close      = &IcssgTimeSync_close,
        },
    },

    /* MDIO module object */
    .mdioObj =
    {
        .enetMod =
        {
            .name       = "icssg1-1.mdio",
            .physAddr   = CSL_PRU_ICSSG1_PR1_MDIO_V1P7_MDIO_BASE,
            .features   = MDIO_FEATURE_CLAUSE45,
            .errata     = ENET_ERRATA_NONE,
            .open       = &Mdio_open,
            .rejoin     = &Mdio_rejoin,
            .ioctl      = &Mdio_ioctl,
            .close      = &Mdio_close,
        },
    },

    /* Stats module object */
    .statsObj =
    {
        .enetMod =
        {
            .name       = "icssg1-1.stats",
            .physAddr   = CSL_PRU_ICSSG1_DRAM0_SLV_RAM_BASE,
            .physAddr2  = 0,
            .features   = ENET_FEAT_BASE,
            .errata     = ENET_ERRATA_NONE,
            .open       = &IcssgStats_open,
            .rejoin     = &IcssgStats_rejoin,
            .ioctl      = &IcssgStats_ioctl,
            .close      = &IcssgStats_close,
        },
    },

    /* Tas module object */
    .tasObj =
    {
        {
            .enetMod =
            {
                .name       = "icssg1-1.tas",
                .physAddr   = CSL_PRU_ICSSG1_DRAM0_SLV_RAM_BASE,
                .physAddr2  = CSL_PRU_ICSSG1_DRAM0_SLV_RAM_BASE + CSL_ICSS_G_RAM_SLV_RAM_REGS_BASE,
                .features   = ENET_FEAT_BASE,
                .errata     = ENET_ERRATA_NONE,
                .open       = &IcssgTas_open,
                .rejoin     = &IcssgTas_rejoin,
                .ioctl      = &IcssgTas_ioctl,
                .close      = &IcssgTas_close,
            },
        },
    },

    /* RM module object */
    .rmObj =
    {
        .enetMod =
        {
            .name       = "icssg1-1.rm",
            .physAddr   = 0U,
            .features   = ENET_FEAT_BASE,
            .errata     = ENET_ERRATA_NONE,
            .open       = &EnetRm_open,
            .rejoin     = &EnetRm_rejoin,
            .ioctl      = &EnetRm_ioctl,
            .close      = &EnetRm_close,
        },
    },
};
/* ICSSG1 Dual-MAC Port 2 (ENET_ICSSG_DUALMAC, 3) */
static Icssg_Obj gEnetSoc_icssg1DMacp2 =
{
    .enetPer =
    {
        .name         = "icssg1-2",
        .enetType     = ENET_ICSSG_DUALMAC,
        .instId       = 3U,
        .magic        = ENET_NO_MAGIC,
        .physAddr     = CSL_PRU_ICSSG1_DRAM0_SLV_RAM_BASE,
        .physAddr2    = 0U,
        .features     = ENET_FEAT_BASE,
        .errata       = ENET_ERRATA_NONE,
        .initCfg      = &Icssg_initCfg,
        .open         = &Icssg_open,
        .close        = &Icssg_close,
        .rejoin       = &Icssg_rejoin,
        .ioctl        = &Icssg_ioctl,
        .poll         = &Icssg_poll,
        .convertTs    = &Icssg_convertTs,
        .periodicTick = &Icssg_periodicTick,
        .registerEventCb   = &Icssg_registerEventCb,
        .unregisterEventCb = &Icssg_unregisterEventCb,
    },

    /* Shared between ICSSG1 Port 1 and Port 2 objects */
    .pruss = &gEnetSoc_PruIcssg1,

    /* Dual-MAC firmware for slice 1 */
    .fw =
    {
        {
            .pru       = RX_PRU_SLICE1_b00_DMac,
            .pruSize   = sizeof(RX_PRU_SLICE1_b00_DMac),
            .rtu       = RTU0_SLICE1_b00_DMac,
            .rtuSize   = sizeof(RTU0_SLICE1_b00_DMac),
            .txpru     = TX_PRU_SLICE1_b00_DMac,
            .txpruSize = sizeof(TX_PRU_SLICE1_b00_DMac)
        },
    },

    /* TimeSync module object */
    .timeSyncObj =
    {
        .enetMod =
        {
            .name       = "icssg1-2.timesync",
            .physAddr   = CSL_PRU_ICSSG1_DRAM0_SLV_RAM_BASE + CSL_ICSS_G_PR1_IEP0_SLV_REGS_BASE,
            .physAddr2  = CSL_PRU_ICSSG1_DRAM0_SLV_RAM_BASE + CSL_ICSS_G_RAM_SLV_RAM_REGS_BASE,
            .features   = ENET_FEAT_BASE,
            .errata     = ENET_ERRATA_NONE,
            .open       = &IcssgTimeSync_open,
            .rejoin     = &IcssgTimeSync_rejoin,
            .ioctl      = &IcssgTimeSync_ioctl,
            .close      = &IcssgTimeSync_close,
        },
    },

    /* MDIO module object */
    .mdioObj =
    {
        .enetMod =
        {
            .name       = "icssg1-2.mdio",
            .physAddr   = CSL_PRU_ICSSG1_PR1_MDIO_V1P7_MDIO_BASE,
            .features   = MDIO_FEATURE_CLAUSE45,
            .errata     = ENET_ERRATA_NONE,
            .open       = &Mdio_open,
            .rejoin     = &Mdio_rejoin,
            .ioctl      = &Mdio_ioctl,
            .close      = &Mdio_close,
        },
    },

    /* Stats module object */
    .statsObj =
    {
        .enetMod =
        {
            .name       = "icssg1-2.stats",
            .physAddr   = CSL_PRU_ICSSG1_DRAM0_SLV_RAM_BASE,
            .physAddr2  = 0,
            .features   = ENET_FEAT_BASE,
            .errata     = ENET_ERRATA_NONE,
            .open       = &IcssgStats_open,
            .rejoin     = &IcssgStats_rejoin,
            .ioctl      = &IcssgStats_ioctl,
            .close      = &IcssgStats_close,
        },
    },

    /* Tas module object */
    .tasObj =
    {
        {
            .enetMod =
            {
                .name       = "icssg1-2.tas",
                .physAddr   = CSL_PRU_ICSSG1_DRAM1_SLV_RAM_BASE,
                .physAddr2  = CSL_PRU_ICSSG1_DRAM0_SLV_RAM_BASE + CSL_ICSS_G_RAM_SLV_RAM_REGS_BASE,
                .features   = ENET_FEAT_BASE,
                .errata     = ENET_ERRATA_NONE,
                .open       = &IcssgTas_open,
                .rejoin     = &IcssgTas_rejoin,
                .ioctl      = &IcssgTas_ioctl,
                .close      = &IcssgTas_close,
            },
        },
    },

    /* RM module object */
    .rmObj =
    {
        .enetMod =
        {
            .name       = "icssg1-2.rm",
            .physAddr   = 0U,
            .features   = ENET_FEAT_BASE,
            .errata     = ENET_ERRATA_NONE,
            .open       = &EnetRm_open,
            .rejoin     = &EnetRm_rejoin,
            .ioctl      = &EnetRm_ioctl,
            .close      = &EnetRm_close,
        },
    },
};
/* ---------------------------- Enet Peripherals ---------------------------- */
Enet_Obj gEnetSoc_perObj[] =
{
    /* CPSW_3G Enet driver/peripheral */
    {
        .enetPer = NULL,
    },

    /* ICSSG0 Dual-MAC Port 1 Enet driver/peripheral */
    {
        .enetPer = NULL,
    },

    {
        .enetPer = NULL,
    },

    {
        /* ICSSG1 Dual-MAC Port 1 Enet driver/peripheral */
        .enetPer = &gEnetSoc_icssg1DMacp1.enetPer,
    },

    {
        /* ICSSG1 Dual-MAC Port 2 Enet driver/peripheral */
        .enetPer = &gEnetSoc_icssg1DMacp2.enetPer,
    },

    {
        .enetPer = NULL,
    },

    {
        .enetPer = NULL,
    },

};

EnetUdma_DrvObj gEnetSoc_dmaObj[2U];


/* ICSSG1 Dual-MAC DMA SoC data: 4 TX channels and 9 RX flows per slice */
const IcssgSoc_Cfg gEnetSoc_icssg1DMacSocCfg[ICSSG_MAC_PORT_MAX] =
{
    {
        .dmscDevId        = TISCI_DEV_PRU_ICSSG1,
        .txChPeerThreadId = CSL_PSILCFG_DMSS_ICSS_G1_PSILD_THREAD_OFFSET,
        .rxChPeerThreadId = CSL_PSILCFG_DMSS_ICSS_G1_PSILS_THREAD_OFFSET,
        .txChCount        = ICSSG_DUALMAC_TX_CH_NUM,
        .rxFlowCount      = ICSSG_DUALMAC_RX_FLOW_NUM,
        .hwPushCnt        = 0U,
    },
    {
        .dmscDevId        = TISCI_DEV_PRU_ICSSG1,
        .txChPeerThreadId = CSL_PSILCFG_DMSS_ICSS_G1_PSILD_THREAD_OFFSET +
                            4U,
        .rxChPeerThreadId = CSL_PSILCFG_DMSS_ICSS_G1_PSILS_THREAD_OFFSET +
                            1U,
        .txChCount        = ICSSG_DUALMAC_TX_CH_NUM,
        .rxFlowCount      = ICSSG_DUALMAC_RX_FLOW_NUM,
        .hwPushCnt        = 0U,
    }
};

/* ICSSG1 Switch DMA SoC data: 4 TX channels and 9 RX flows */
const IcssgSoc_Cfg gEnetSoc_icssg1SwtSocCfg =
{
    .dmscDevId        = TISCI_DEV_PRU_ICSSG1,
    .txChPeerThreadId = CSL_PSILCFG_DMSS_ICSS_G1_PSILD_THREAD_OFFSET,
    .rxChPeerThreadId = CSL_PSILCFG_DMSS_ICSS_G1_PSILS_THREAD_OFFSET,
    .txChCount        = ICSSG_SWITCH_TX_CH_NUM,
    .rxFlowCount      = ICSSG_SWITCH_RX_FLOW_NUM,
    .hwPushCnt        = 0U,
};

/* ICSSG0 Dual-MAC DMA SoC data: 4 TX channels and 9 RX flows per slice */
const IcssgSoc_Cfg gEnetSoc_icssg0DMacSocCfg[ICSSG_MAC_PORT_MAX] =
{
    {
        .dmscDevId        = TISCI_DEV_PRU_ICSSG0,
        .txChPeerThreadId = CSL_PSILCFG_DMSS_ICSS_G0_PSILD_THREAD_OFFSET,
        .rxChPeerThreadId = CSL_PSILCFG_DMSS_ICSS_G0_PSILS_THREAD_OFFSET,
        .txChCount        = ICSSG_DUALMAC_TX_CH_NUM,
        .rxFlowCount      = ICSSG_DUALMAC_RX_FLOW_NUM,
        .hwPushCnt        = 0U,
    },
    {
        .dmscDevId        = TISCI_DEV_PRU_ICSSG0,
        .txChPeerThreadId = CSL_PSILCFG_DMSS_ICSS_G0_PSILD_THREAD_OFFSET +
                            4U,
        .rxChPeerThreadId = CSL_PSILCFG_DMSS_ICSS_G0_PSILS_THREAD_OFFSET +
                            1U,
        .txChCount        = ICSSG_DUALMAC_TX_CH_NUM,
        .rxFlowCount      = ICSSG_DUALMAC_RX_FLOW_NUM,
        .hwPushCnt        = 0U,
    },
};

/* ICSSG0 Switch DMA SoC data: 4 TX channels and 9 RX flows */
const IcssgSoc_Cfg gEnetSoc_icssg0SwtSocCfg =
{
    .dmscDevId        = TISCI_DEV_PRU_ICSSG0,
    .txChPeerThreadId = CSL_PSILCFG_DMSS_ICSS_G0_PSILD_THREAD_OFFSET,
    .rxChPeerThreadId = CSL_PSILCFG_DMSS_ICSS_G0_PSILS_THREAD_OFFSET,
    .txChCount        = ICSSG_SWITCH_TX_CH_NUM,
    .rxFlowCount      = ICSSG_SWITCH_RX_FLOW_NUM,
    .hwPushCnt        = 0U,
};

const  Icssg_FwPoolMem *Icssq_FwPoolMemInfo[2][4] =
{
    [0] = {
              [0] = NULL,
              [1] = NULL,
              [2] = &gEnetSoc_Icssg1_0_FwPoolMem[0],
              [3] = &gEnetSoc_Icssg1_1_FwPoolMem[0],
          },
    [1] = {
              [0] = NULL,
              [1] = NULL,
              [2] = NULL,
              [3] = NULL,
          },
};

/* ------------------------------- DMA objects ------------------------------ */

EnetUdma_DrvObjMemInfo gEnetSoc_dmaObjMemInfo =
{
    .numObjs = ENET_ARRAYSIZE(gEnetSoc_dmaObj),
    .drvObjMem = &gEnetSoc_dmaObj[0],
};


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

extern Icssg_Pruss gEnetSoc_PruIcssg0;
extern Icssg_Pruss gEnetSoc_PruIcssg1;
extern EnetUdma_DrvObjMemInfo gEnetSoc_dmaObjMemInfo;

int32_t EnetSoc_init(void)
{
    uint32_t qos_count = sizeof(soc_qos_data) / sizeof(soc_qos_data[0]);

    QOS_init(soc_qos_data, qos_count);
    memset(gEnetSoc_dmaObjMemInfo.drvObjMem, 0,
    gEnetSoc_dmaObjMemInfo.numObjs * sizeof(*(gEnetSoc_dmaObjMemInfo.drvObjMem)));

    gEnetSoc_PruIcssg0.lock = EnetOsal_createMutex();
    EnetSoc_assert((gEnetSoc_PruIcssg0.lock != NULL),
                 "Failed to create PRUICSSG0's mutex\n");

    gEnetSoc_PruIcssg1.lock = EnetOsal_createMutex();
    EnetSoc_assert((gEnetSoc_PruIcssg1.lock != NULL),
                  "Failed to create PRUICSSG1's mutex\n");

    return ENET_SOK;
}

void EnetSoc_deinit(void)
{
    gEnetSoc_PruIcssg1.initialized = false;
    EnetOsal_deleteMutex(gEnetSoc_PruIcssg1.lock);
    gEnetSoc_PruIcssg1.lock = NULL;

    gEnetSoc_PruIcssg0.initialized = false;
    EnetOsal_deleteMutex(gEnetSoc_PruIcssg0.lock);
    gEnetSoc_PruIcssg0.lock = NULL;
}

EnetDma_Handle EnetSoc_getDmaHandle(Enet_Type enetType,
                                    uint32_t instId)
{
    EnetDma_Handle hDma = NULL;

    switch (enetType)
    {
        case ENET_ICSSG_DUALMAC:
            switch (instId)
            {
                case 2:
                    hDma = &gEnetSoc_dmaObjMemInfo.drvObjMem[0U];
                    break;
                case 3:
                    hDma = &gEnetSoc_dmaObjMemInfo.drvObjMem[1U];
                    break;
                default:
                    EnetSoc_assert(false, "Invalid peripheral (eneType=%u instId=%u)\n", enetType, instId);
                    break;
            }
            break;

        default:
            break;
    }

    EnetSoc_assert(hDma != NULL, "Invalid peripheral (eneType=%u instId=%u)\n", enetType, instId);
    return hDma;

}

Enet_Handle EnetSoc_getEnetHandleByIdx(uint32_t idx)
{
    Enet_Handle hEnet = NULL;

    if (idx < ENET_ARRAYSIZE(gEnetSoc_perObj))
    {
        hEnet = &gEnetSoc_perObj[idx];
    }

    EnetSoc_assert((hEnet != NULL), "Unsupported  peripheral index (index=%u )\n", idx);
    return hEnet;
}

Enet_Handle EnetSoc_getEnetHandle(Enet_Type enetType,
                                  uint32_t instId)
{
    Enet_Handle hEnet = NULL;

    switch (enetType)
    {
        case ENET_CPSW_3G:
            if (instId == 0U)
            {
                hEnet = &gEnetSoc_perObj[0U];
            }
            break;

        case ENET_ICSSG_DUALMAC:
            switch (instId)
            {
                case 0:
                    hEnet = &gEnetSoc_perObj[1U];
                    break;
                case 1:
                    hEnet = &gEnetSoc_perObj[2U];
                    break;
                case 2:
                    hEnet = &gEnetSoc_perObj[3U];
                    break;
                case 3:
                    hEnet = &gEnetSoc_perObj[4U];
                    break;
                default:
                    EnetSoc_assert(false, "Invalid peripheral (eneType=%u instId=%u)\n", enetType, instId);
                    break;
            }
            break;

        case ENET_ICSSG_SWITCH:
            switch (instId)
            {
                case 0:
                    hEnet = &gEnetSoc_perObj[5U];
                    break;
                case 1:
                    hEnet = &gEnetSoc_perObj[6U];
                    break;
                case 2:
                    hEnet = &gEnetSoc_perObj[7U];
                    break;
                default:
                    EnetSoc_assert(false, "Invalid peripheral (eneType=%u instId=%u)\n", enetType, instId);
                    break;
            }
            break;

        default:
            {
                EnetSoc_assert(false, "Invalid peripheral (eneType=%u instId=%u)\n", enetType, instId);
            }
            break;
    }
    EnetSoc_assert((hEnet != NULL), "Invalid peripheral (eneType=%u instId=%u)\n", enetType, instId);
    return hEnet;
}

static bool  EnetSoc_isValidEnetType(Enet_Type enetType)
{
    bool validInstanceType = false;

    if ((enetType == ENET_ICSSG_DUALMAC)|| (enetType == ENET_ICSSG_SWITCH))
    {
        validInstanceType = true;
    }

    return validInstanceType;
}

uint32_t EnetSoc_getEnetNum(void)
{
    return ENET_ARRAYSIZE(gEnetSoc_perObj);
}

uint32_t EnetSoc_getMacPortMax(Enet_Type enetType,
                               uint32_t instId)
{
    uint32_t numPorts = 0U;

    if (enetType == ENET_ICSSG_DUALMAC)
    {
        numPorts = 1U;
    }
    else if (enetType == ENET_ICSSG_SWITCH)
    {
        numPorts = 2U;
    }
    else
    {
        EnetSoc_assert(false, "Invalid peripheral (eneType=%u instId=%u)\n", enetType, instId);
    }

    return numPorts;
}

uint32_t EnetSoc_isIpSupported(Enet_Type enetType,
                               uint32_t instId)
{
    bool supported = false;

    if (((enetType == ENET_ICSSG_DUALMAC) && (instId < 3U)) ||
             ((enetType == ENET_ICSSG_SWITCH) && (instId < 3U)))
    {
        supported = true;
    }

    EnetSoc_assert((EnetSoc_isValidEnetType(enetType) == true), "Invalid Enet & instId type %d, %d\n", enetType, instId);

    return supported;
}

uint32_t EnetSoc_getCoreId(void)
{
    uint32_t coreId = CSL_CORE_ID_R5FSS0_0;

    return coreId;
}

uint32_t EnetSoc_getClkFreq(Enet_Type enetType,
                            uint32_t instId,
                            uint32_t clkId)
{
    uint32_t freq = 0U;

    if (clkId == CPSW_CPPI_CLK)
    {
        if ((enetType == ENET_ICSSG_DUALMAC)|| (enetType == ENET_ICSSG_SWITCH))
        {
            //TODO: Freq is hard coded here.
            freq = 320000000LLU;
        }

        EnetSoc_assert((EnetSoc_isValidEnetType(enetType) == true), "Invalid Enet type %d\n", enetType);
    }
    else
    {
        EnetSoc_assert(false, "Invalid clk id %u\n", clkId);
    }

    return freq;
}

uint32_t EnetSoc_getIntrTriggerType(Enet_Type enetType,
                                    uint32_t instId,
                                    uint32_t intrId)
{
    return ENETOSAL_ARM_GIC_TRIG_TYPE_LEVEL;
}

/* Stupid hack to workaround FAE board issues */
//#define ENET_MAC_ADDR_HACK (TRUE)
int32_t EnetSoc_getEFusedMacAddrs(uint8_t macAddr[][ENET_MAC_ADDR_LEN],
                                  uint32_t *num)
{
#ifndef ENET_MAC_ADDR_HACK
    CSL_main_ctrl_mmr_cfg0Regs *mmrRegs;
    uint32_t val;

    if (*num >= 1U)
    {
        mmrRegs = (CSL_main_ctrl_mmr_cfg0Regs *)(uintptr_t)CSL_CTRL_MMR0_CFG0_BASE;

        val = CSL_REG32_RD(&mmrRegs->MAC_ID0);
        macAddr[0][5] = (uint8_t)((val & 0x000000FFU) >> 0U);
        macAddr[0][4] = (uint8_t)((val & 0x0000FF00U) >> 8U);
        macAddr[0][3] = (uint8_t)((val & 0x00FF0000U) >> 16U);
        macAddr[0][2] = (uint8_t)((val & 0xFF000000U) >> 24U);

        val = CSL_REG32_RD(&mmrRegs->MAC_ID1);
        macAddr[0][1] = (uint8_t)((val & 0x000000FFU) >> 0U);
        macAddr[0][0] = (uint8_t)((val & 0x0000FF00U) >> 8U);

        *num = 1U;
    }
#else
    macAddr[0][0] = 0xF4;
    macAddr[0][1] = 0x84;
    macAddr[0][2] = 0x4c;
    macAddr[0][3] = 0xf9;
    macAddr[0][4] = 0x4d;
    macAddr[0][5] = 0x29;
    *num = 1U;
#endif
    return ENET_SOK;
}

uint32_t EnetSoc_getMacPortCaps(Enet_Type enetType,
                                uint32_t instId,
                                Enet_MacPort macPort)
{
    uint32_t linkCaps = 0U;

    switch (enetType)
    {
        case ENET_ICSSG_DUALMAC:
        case ENET_ICSSG_SWITCH:
            if (macPort <= ENET_MAC_PORT_2)
            {
                linkCaps = (ENETPHY_LINK_CAP_HD10 | ENETPHY_LINK_CAP_FD10 |
                            ENETPHY_LINK_CAP_HD100 | ENETPHY_LINK_CAP_FD100 |
                            ENETPHY_LINK_CAP_FD1000);
            }
            break;

        default:
            EnetSoc_assert(false, "Invalid peripheral type: %u\n", enetType);
            break;

    }

    return linkCaps;
}

int32_t EnetSoc_getMacPortMii(Enet_Type enetType,
                              uint32_t instId,
                              Enet_MacPort macPort,
                              EnetMacPort_Interface *mii)
{
    return ENET_ENOTSUPPORTED;
}

int32_t EnetSoc_validateQsgmiiCfg(Enet_Type enetType,
                                  uint32_t instId)
{
    return ENET_ENOTSUPPORTED;
}

int32_t EnetSoc_mapPort2QsgmiiId(Enet_Type enetType,
                                 uint32_t instId,
                                 Enet_MacPort portNum,
                                 uint32_t *qsgmiiId)
{
    return ENET_ENOTSUPPORTED;
}

uint32_t EnetSoc_getRxFlowCount(Enet_Type enetType,
                                uint32_t instId)
{
    uint32_t rxFlowCount = 0U;
    if (enetType == ENET_ICSSG_DUALMAC)
    {
        switch (instId)
        {
            case 0:
                rxFlowCount = gEnetSoc_icssg0DMacSocCfg[0].rxFlowCount;
                break;
            case 1:
                rxFlowCount = gEnetSoc_icssg0DMacSocCfg[1].rxFlowCount;
                break;
            case 2:
                rxFlowCount = gEnetSoc_icssg1DMacSocCfg[0].rxFlowCount;
                break;
            case 3:
                rxFlowCount = gEnetSoc_icssg1DMacSocCfg[1].rxFlowCount;
                break;
            default:
                EnetSoc_assert(false, "Invalid peripheral (eneType=%u instId=%u)\n", enetType, instId);
                break;
        }
    }
    else if (enetType == ENET_ICSSG_SWITCH)
    {
        switch (instId)
        {
            case 0:
                rxFlowCount = gEnetSoc_icssg0SwtSocCfg.rxFlowCount;
                break;
            case 1:
                rxFlowCount = gEnetSoc_icssg1SwtSocCfg.rxFlowCount;
                break;
            default:
                EnetSoc_assert(false, "Invalid peripheral (eneType=%u instId=%u)\n", enetType, instId);
                break;
        }
    }

    EnetSoc_assert((EnetSoc_isValidEnetType(enetType) == true), "Invalid Enet type %d\n", enetType);

    return rxFlowCount;
}

uint32_t EnetSoc_getHwPushCount(Enet_Type enetType,
                                uint32_t instId)
{
    uint32_t hwPushCount = 0U;
    if (enetType == ENET_ICSSG_DUALMAC)
    {
        switch (instId)
        {
            case 0:
                hwPushCount = gEnetSoc_icssg0DMacSocCfg[0].hwPushCnt;
                break;
            case 1:
                hwPushCount = gEnetSoc_icssg0DMacSocCfg[1].hwPushCnt;
                break;
            case 2:
                hwPushCount = gEnetSoc_icssg1DMacSocCfg[0].hwPushCnt;
                break;
            case 3:
                hwPushCount = gEnetSoc_icssg1DMacSocCfg[1].hwPushCnt;
                break;
            default:
                EnetSoc_assert(false, "Invalid peripheral (eneType=%u instId=%u)\n", enetType, instId);
                break;
        }
    }
    else if (enetType == ENET_ICSSG_SWITCH)
    {
        switch (instId)
        {
            case 0:
                hwPushCount = gEnetSoc_icssg0SwtSocCfg.hwPushCnt;
                break;
            case 1:
                hwPushCount = gEnetSoc_icssg1SwtSocCfg.hwPushCnt;
                break;
            default:
                EnetSoc_assert(false, "Invalid peripheral (eneType=%u instId=%u)\n", enetType, instId);
                break;
        }
    }
    
    EnetSoc_assert((EnetSoc_isValidEnetType(enetType) == true), "Invalid Enet type %d\n", enetType);

    return hwPushCount;
}

uint32_t EnetSoc_getTxChPeerId(Enet_Type enetType,
                               uint32_t instId,
                               uint32_t chNum)
{
    uint32_t peerChNum = 0U;

    if (enetType == ENET_ICSSG_DUALMAC)
    {
        switch (instId)
        {
            case 0:
                peerChNum = gEnetSoc_icssg0DMacSocCfg[0].txChPeerThreadId;
                break;
            case 1:
                peerChNum = gEnetSoc_icssg0DMacSocCfg[1].txChPeerThreadId;
                break;
            case 2:
                peerChNum = gEnetSoc_icssg1DMacSocCfg[0].txChPeerThreadId;
                break;
            case 3:
                peerChNum = gEnetSoc_icssg1DMacSocCfg[1].txChPeerThreadId;
                break;
            default:
                EnetSoc_assert(false, "Invalid peripheral (eneType=%u instId=%u)\n", enetType, instId);
                break;
        }
    }
    else if (enetType == ENET_ICSSG_SWITCH)
    {
        switch (instId)
        {
            case 0:
                peerChNum = gEnetSoc_icssg0SwtSocCfg.txChPeerThreadId;
                break;
            case 1:
                peerChNum = gEnetSoc_icssg1SwtSocCfg.txChPeerThreadId;
                break;
            default:
                EnetSoc_assert(false, "Invalid peripheral (eneType=%u instId=%u)\n", enetType, instId);
                break;
        }
    }

    EnetSoc_assert((EnetSoc_isValidEnetType(enetType) == true), "Invalid Enet type %d\n", enetType);

    /* Get PSI-L destination thread offset for Tx channel */
    peerChNum = (peerChNum + chNum);

    return peerChNum;
}

uint32_t EnetSoc_getRxChPeerId(Enet_Type enetType,
                               uint32_t instId,
                               uint32_t chIdx)
{
    uint32_t peerChNum = 0U;

    if (enetType == ENET_ICSSG_DUALMAC)
    {
        switch (instId)
        {
            case 0:
                peerChNum = gEnetSoc_icssg0DMacSocCfg[0].rxChPeerThreadId;
                break;
            case 1:
                peerChNum = gEnetSoc_icssg0DMacSocCfg[1].rxChPeerThreadId;
                break;
            case 2:
                peerChNum = gEnetSoc_icssg1DMacSocCfg[0].rxChPeerThreadId;
                break;
            case 3:
                peerChNum = gEnetSoc_icssg1DMacSocCfg[1].rxChPeerThreadId;
                break;
            default:
                EnetSoc_assert(false, "Invalid peripheral (eneType=%u instId=%u)\n", enetType, instId);
                break;
        }
    }
    else if (enetType == ENET_ICSSG_SWITCH)
    {
        EnetSoc_assert(((chIdx == 0U) || (chIdx == 1U)), "Invalid channel index %u\n", chIdx);
        switch (instId)
        {
            case 0:
                peerChNum = gEnetSoc_icssg0SwtSocCfg.rxChPeerThreadId + chIdx;
                break;
            case 1:
                peerChNum = gEnetSoc_icssg1SwtSocCfg.rxChPeerThreadId + chIdx;
                break;
            default:
                EnetSoc_assert(false, "Invalid peripheral (eneType=%u instId=%u)\n", enetType, instId);
                break;
        }
    }
    EnetSoc_assert((EnetSoc_isValidEnetType(enetType) == true), "Invalid Enet type %d\n", enetType);

    return peerChNum;
}

uint32_t EnetSoc_getTxChCount(Enet_Type enetType,
                              uint32_t instId)
{
    uint32_t txChCount = 0U;
    if (enetType == ENET_ICSSG_DUALMAC)
    {
        switch (instId)
        {
            case 0:
                txChCount = gEnetSoc_icssg0DMacSocCfg[0].txChCount;
                break;
            case 1:
                txChCount = gEnetSoc_icssg0DMacSocCfg[1].txChCount;
                break;
            case 2:
                txChCount = gEnetSoc_icssg1DMacSocCfg[0].txChCount;
                break;
            case 3:
                txChCount = gEnetSoc_icssg1DMacSocCfg[1].txChCount;
                break;
            default:
                EnetSoc_assert(false, "Invalid peripheral (eneType=%u instId=%u)\n", enetType, instId);
                break;
        }
    }
    else if (enetType == ENET_ICSSG_SWITCH)
    {
        switch (instId)
        {
            case 0:
                txChCount = gEnetSoc_icssg0SwtSocCfg.txChCount;
                break;
            case 1:
                txChCount = gEnetSoc_icssg1SwtSocCfg.txChCount;
                break;
            default:
                EnetSoc_assert(false, "Invalid peripheral (eneType=%u instId=%u)\n", enetType, instId);
                break;
        }
    }
    EnetSoc_assert((EnetSoc_isValidEnetType(enetType) == true), "Invalid Enet type %d\n", enetType);

    return txChCount;
}

bool EnetSoc_isCoreAllowed(Enet_Type enetType,
                           uint32_t instId,
                           uint32_t coreId)
{
    return true;
}


/*!
 *  \brief ICSSG default configuration
 *         Note: If user wishes to change the Resource Partition the following
 *         things must be considered:
 *         1. Sum of numTxCh allocated to each core should not exceed 8.
 *         2. Sum of numRxFlows allocated to each core should not exceed 10 (not 64),
 *            as one Rx flow is reserved to the master core.
 *
 */
static EnetRm_ResPrms gEnetAppRmDefCfg_iccsgDMac =
{
    .coreResInfo =
    {
        [0] =
        {
            .coreId        = CSL_CORE_ID_R5FSS0_0,
            .numTxCh       = ENET_SYSCFG_TX_CHANNELS_NUM,    /* numTxCh */
            .numRxFlows    = ENET_SYSCFG_RX_FLOWS_NUM,    /* numRxFlows */
            .numMacAddress = 1U,
            .numHwPush     = 0U,
        },
    },
    .numCores = 1U,
};

static EnetRm_ResPrms gEnetAppRmDefCfg_iccsgSwt =
{
    .coreResInfo =
    {
        [0] =
        {
            .coreId        = CSL_CORE_ID_R5FSS0_0,
            .numTxCh       = ENET_SYSCFG_TX_CHANNELS_NUM,    /* numTxCh */
            .numRxFlows    = ENET_SYSCFG_RX_FLOWS_NUM,    /* numRxFlows */
            .numMacAddress = 4U,
            .numHwPush     = 0U,
        },
    },
    .numCores = 1U,
};

const EnetRm_ResPrms *EnetAppRm_getResPartInfo(Enet_Type enetType)
{
    const EnetRm_ResPrms *rmInitPrms = NULL;

    switch (enetType)
    {
        case ENET_ICSSG_DUALMAC:
        {
            rmInitPrms = &gEnetAppRmDefCfg_iccsgDMac;
            break;
        }

        case ENET_ICSSG_SWITCH:
        default:
        {
            rmInitPrms = &gEnetAppRmDefCfg_iccsgSwt;
            break;
        }
    }

    return(rmInitPrms);
}
/* Cores IOCTL Privileges */
static const EnetRm_IoctlPermissionTable gEnetAppIoctlPermission_iccsg =
{
    .defaultPermittedCoreMask = (ENET_BIT(CSL_CORE_ID_A53SS0_0) |
                                 ENET_BIT(CSL_CORE_ID_R5FSS0_0) |
                                 ENET_BIT(CSL_CORE_ID_R5FSS0_1)),
    .numEntries = 0,
};

const EnetRm_IoctlPermissionTable *EnetAppRm_getIoctlPermissionInfo(Enet_Type enetType)
{
    const EnetRm_IoctlPermissionTable *ioctlPerm = NULL;

    switch (enetType)
    {
        case ENET_ICSSG_DUALMAC:
        case ENET_ICSSG_SWITCH:
        {
            ioctlPerm = &gEnetAppIoctlPermission_iccsg;
            break;
        }
        default:
        {
            ioctlPerm = NULL;
            break;
        }
    }

    return(ioctlPerm);
}









