// +FHDR------------------------------------------------------------
//                 Copyright (c) 2022 SmartLogic.
//                       ALL RIGHTS RESERVED
// -----------------------------------------------------------------
// Filename      : phy_init.c
// Author        : xianfeng.du
// Created On    : 2022-12-27
// Last Modified :
// -----------------------------------------------------------------
// Description:
// ecs_rfm_spu0 msg_transfer_cfg
//
// -FHDR------------------------------------------------------------

#include "typedef.h"
#include "ucp_printf.h"
#include "ucp_utility.h"
#include "ucp_tick.h"
#include "msg_transfer_queue.h"
#include "app_interface.h"

#define RFM_TEST_MSG_SIZE   (8)
#define RFM_MSG_TYPE        (0)
#define CELL_SETUP_TYPE_SIMULATION (0x5a6b7c8d)
#define ORX_MSG_TYPE_SIMULATION (0xaabb7788)

static uint32_t g_u32_rfm_alloc_err = 0; //(15) 0xB7E0143C
static uint32_t g_u32_rfm_send_err  = 0; //(16) 0xB7E01440
static uint32_t g_u32_rfm_recv_num  = 0; //(17) 0xB7E01444
static uint32_t g_u32_rfm_send_ok   = 0; //(18) 0xB7E01448

uint32_t rx_callback_data(const char* buf,uint32_t payloadSize)
{
    /* RFM0接收消息后发给APE0 */
    uint32_t core_id = get_core_id();
    int32_t  ret = 0;
    char *addr = NULL;
    uint32_t u32_clock_tick   = 0;

    rdmcycle(&u32_clock_tick);
    do_write((buf+16), u32_clock_tick); //RFM receive tick
    g_u32_rfm_recv_num++;

    addr = osp_alloc_msg(RFM_TEST_MSG_SIZE);
    if (NULL == addr)
    {
        debug_write(DBG_DDR_COMMON_IDX(core_id, 15), ++g_u32_rfm_alloc_err);
        return payloadSize;
    }

    do_write(addr, (uint32_t)buf);
    do_write((addr+4), UCP4008_TRAFFIC_NR_eMBB_DATA);

    rdmcycle(&u32_clock_tick);
    do_write((buf+20), u32_clock_tick); //RFM forward tick

    ret = osp_send_msg((uint32_t)(addr),
                        RFM_TEST_MSG_SIZE,
                        RFM_MSG_TYPE,
                        9,      // src que id
                        0,      // dst que id
                        40,     // src task id
                        40);    // dst task id

    if (0 != ret)
    {
        debug_write(DBG_DDR_COMMON_IDX(core_id, 16), ++g_u32_rfm_send_err);
        return payloadSize;
    }
    g_u32_rfm_send_ok++;

    debug_write(DBG_DDR_COMMON_IDX(core_id, 17), g_u32_rfm_recv_num);
    debug_write(DBG_DDR_COMMON_IDX(core_id, 18), g_u32_rfm_send_ok);
    return payloadSize;
}

static uint32_t g_u32_rfm_alloc1_err = 0; //(19) 0xB7E0144C
static uint32_t g_u32_rfm_send1_err  = 0; //(20) 0xB7E01450
static uint32_t g_u32_rfm_send2_err  = 0; //(20) 0xB7E01450
static uint32_t g_u32_rfm_recv1_num  = 0; //(21) 0xB7E01454
static uint32_t g_u32_rfm_send1_ok   = 0; //(22) 0xB7E01458
static uint32_t g_u32_rfm_send2_ok   = 0; //(22) 0xB7E01458

int32_t cell_setup_msg_forward(char* buf, uint32_t payloadSize)
{
    /* RFM0接收消息后发给RFM1 */
    uint32_t core_id = get_core_id();
    int32_t  ret = 0;
    char *addr = NULL;

    uint32_t msg_type = do_read(buf);

    if ((CELL_SETUP_TYPE_SIMULATION != msg_type) && (ORX_MSG_TYPE_SIMULATION != msg_type)) {
        return 1;
    }
    uint32_t u32_clock_tick = 0;
    rdmcycle(&u32_clock_tick);
    do_write((buf+8), u32_clock_tick); //RFM forward tick

    addr = osp_alloc_msg(RFM_TEST_MSG_SIZE);
    if (NULL == addr)
    {
        return 2;
    }
    do_write(addr, buf);

    /*send cell setup message*/
    ret = osp_send_msg((uint32_t)addr,
                        RFM_TEST_MSG_SIZE,
                        RFM_MSG_TYPE,
                        9,       // src que id
                        11,      // dst que id
                        41,      // src task id
                        41);     // dst task id

    if (0 != ret)
    {
        debug_write(DBG_DDR_COMMON_IDX(core_id, 23), ++g_u32_rfm_send2_err);
        return 3;
    }
    g_u32_rfm_send2_ok++;
    debug_write(DBG_DDR_COMMON_IDX(core_id, 24), g_u32_rfm_send2_ok);
    return 0;
}

uint32_t rx_callback_ctrl(const char* buf,uint32_t payloadSize)
{
    int32_t  ret = cell_setup_msg_forward((char*)buf, payloadSize);
    if (0 == ret) {
        return payloadSize;
    }

    /* RFM0接收消息后发给APE1 */
    uint32_t core_id = get_core_id();
    char *addr = NULL;
    uint32_t u32_clock_tick   = 0;

    rdmcycle(&u32_clock_tick);
    do_write((buf+16), u32_clock_tick); //RFM receive tick
    g_u32_rfm_recv1_num++;

    addr = osp_alloc_msg(RFM_TEST_MSG_SIZE);
    if (NULL == addr)
    {
        debug_write(DBG_DDR_COMMON_IDX(core_id, 19), ++g_u32_rfm_alloc1_err);
        return payloadSize;
    }

    do_write(addr, (uint32_t)buf);
    do_write((addr+4), UCP4008_TRAFFIC_NR_eMBB_CTRL);

    rdmcycle(&u32_clock_tick);
    do_write((buf+20), u32_clock_tick); //RFM forward tick

    ret = osp_send_msg((uint32_t)(addr),
                        RFM_TEST_MSG_SIZE,
                        RFM_MSG_TYPE,
                        9,      // src que id
                        1,      // dst que id
                        40,     // src task id
                        40);    // dst task id

    if (0 != ret)
    {
        debug_write(DBG_DDR_COMMON_IDX(core_id, 20), ++g_u32_rfm_send1_err);
        return payloadSize;
    }
    g_u32_rfm_send1_ok++;

    debug_write(DBG_DDR_COMMON_IDX(core_id, 21), g_u32_rfm_recv1_num);
    debug_write(DBG_DDR_COMMON_IDX(core_id, 22), g_u32_rfm_send1_ok);

    return payloadSize;
}

uint32_t rx_callback_oam(const char* buf,uint32_t payloadSize)
{
    return payloadSize;
}

static uint32_t g_u32_rfm_1_alloc_err = 0; //(23) 0xB7E0145C
static uint32_t g_u32_rfm_1_send_err  = 0; //(24) 0xB7E01460
static uint32_t g_u32_rfm_1_recv_num  = 0; //(25) 0xB7E01464
static uint32_t g_u32_rfm_1_send_ok   = 0; //(26) 0xB7E01468

uint32_t rx1_callback_data(const char* buf,uint32_t payloadSize)
{
    /* RFM0接收消息后发给APE0 */
    uint32_t core_id = get_core_id();
    int32_t  ret = 0;
    char *addr = NULL;
    uint32_t u32_clock_tick   = 0;

    rdmcycle(&u32_clock_tick);
    do_write((buf+16), u32_clock_tick); //RFM receive tick
    g_u32_rfm_1_recv_num++;

    addr = osp_alloc_msg(RFM_TEST_MSG_SIZE);
    if (NULL == addr)
    {
        debug_write(DBG_DDR_COMMON_IDX(core_id, 23), ++g_u32_rfm_1_alloc_err);
        return payloadSize;
    }

    do_write(addr, (uint32_t)buf);
    do_write((addr+4), UCP4008_TRAFFIC_NR_eMBB_DATA);

    rdmcycle(&u32_clock_tick);
    do_write((buf+20), u32_clock_tick); //RFM forward tick

    ret = osp_send_msg((uint32_t)(addr),
                        RFM_TEST_MSG_SIZE,
                        RFM_MSG_TYPE,
                        9,      // src que id
                        2,      // dst que id
                        40,     // src task id
                        40);    // dst task id

    if (0 != ret)
    {
        debug_write(DBG_DDR_COMMON_IDX(core_id, 24), ++g_u32_rfm_1_send_err);
        return payloadSize;
    }
    g_u32_rfm_1_send_ok++;

    debug_write(DBG_DDR_COMMON_IDX(core_id, 25), g_u32_rfm_1_recv_num);
    debug_write(DBG_DDR_COMMON_IDX(core_id, 26), g_u32_rfm_1_send_ok);
    return payloadSize;
}

static uint32_t g_u32_rfm_1_alloc1_err = 0; //(27) 0xB7E0146C
static uint32_t g_u32_rfm_1_send1_err  = 0; //(28) 0xB7E01470
static uint32_t g_u32_rfm_1_recv1_num  = 0; //(29) 0xB7E01474
static uint32_t g_u32_rfm_1_send1_ok   = 0; //(30) 0xB7E01478

uint32_t rx1_callback_ctrl(const char* buf,uint32_t payloadSize)
{
    int32_t  ret = cell_setup_msg_forward((char*)buf, payloadSize);
    if (0 == ret) {
        return payloadSize;
    }

    /* RFM0接收消息后发给APE1 */
    uint32_t core_id = get_core_id();
    char *addr = NULL;
    uint32_t u32_clock_tick   = 0;

    rdmcycle(&u32_clock_tick);
    do_write((buf+16), u32_clock_tick); //RFM receive tick
    g_u32_rfm_1_recv1_num++;

    addr = osp_alloc_msg(RFM_TEST_MSG_SIZE);
    if (NULL == addr)
    {
        debug_write(DBG_DDR_COMMON_IDX(core_id, 27), ++g_u32_rfm_1_alloc1_err);
        return payloadSize;
    }

    do_write(addr, (uint32_t)buf);
    do_write((addr+4), UCP4008_TRAFFIC_NR_eMBB_CTRL);

    rdmcycle(&u32_clock_tick);
    do_write((buf+20), u32_clock_tick); //RFM forward tick

    ret = osp_send_msg((uint32_t)(addr),
                        RFM_TEST_MSG_SIZE,
                        RFM_MSG_TYPE,
                        9,      // src que id
                        3,      // dst que id
                        40,     // src task id
                        40);    // dst task id

    if (0 != ret)
    {
        debug_write(DBG_DDR_COMMON_IDX(core_id, 28), ++g_u32_rfm_1_send1_err);
        return payloadSize;
    }
    g_u32_rfm_1_send1_ok++;

    debug_write(DBG_DDR_COMMON_IDX(core_id, 29), g_u32_rfm_1_recv1_num);
    debug_write(DBG_DDR_COMMON_IDX(core_id, 30), g_u32_rfm_1_send1_ok);

    return payloadSize;
}

static uint32_t g_u32_rfm_2_alloc_err = 0; //(31) 0xB7E0147C
static uint32_t g_u32_rfm_2_send_err  = 0; //(32) 0xB7E01480
static uint32_t g_u32_rfm_2_recv_num  = 0; //(33) 0xB7E01484
static uint32_t g_u32_rfm_2_send_ok   = 0; //(34) 0xB7E01488

uint32_t rx2_callback_data(const char* buf,uint32_t payloadSize)
{
    /* RFM0接收消息后发给APE0 */
    uint32_t core_id = get_core_id();
    int32_t  ret = 0;
    char *addr = NULL;
    uint32_t u32_clock_tick   = 0;

    rdmcycle(&u32_clock_tick);
    do_write((buf+16), u32_clock_tick); //RFM receive tick
    g_u32_rfm_2_recv_num++;

    addr = osp_alloc_msg(RFM_TEST_MSG_SIZE);
    if (NULL == addr)
    {
        debug_write(DBG_DDR_COMMON_IDX(core_id, 31), ++g_u32_rfm_2_alloc_err);
        return payloadSize;
    }

    do_write(addr, (uint32_t)buf);
    do_write((addr+4), UCP4008_TRAFFIC_NR_eMBB_DATA);

    rdmcycle(&u32_clock_tick);
    do_write((buf+20), u32_clock_tick); //RFM forward tick

    ret = osp_send_msg((uint32_t)(addr),
                        RFM_TEST_MSG_SIZE,
                        RFM_MSG_TYPE,
                        9,      // src que id
                        4,      // dst que id
                        40,     // src task id
                        40);    // dst task id

    if (0 != ret)
    {
        debug_write(DBG_DDR_COMMON_IDX(core_id, 32), ++g_u32_rfm_2_send_err);
        return payloadSize;
    }
    g_u32_rfm_2_send_ok++;

    debug_write(DBG_DDR_COMMON_IDX(core_id, 33), g_u32_rfm_2_recv_num);
    debug_write(DBG_DDR_COMMON_IDX(core_id, 34), g_u32_rfm_2_send_ok);
    return payloadSize;
}

static uint32_t g_u32_rfm_2_alloc1_err = 0; //(35) 0xB7E0148C
static uint32_t g_u32_rfm_2_send1_err  = 0; //(36) 0xB7E01490
static uint32_t g_u32_rfm_2_recv1_num  = 0; //(37) 0xB7E01494
static uint32_t g_u32_rfm_2_send1_ok   = 0; //(38) 0xB7E01498

uint32_t rx2_callback_ctrl(const char* buf,uint32_t payloadSize)
{
    int32_t  ret = cell_setup_msg_forward((char*)buf, payloadSize);
    if (0 == ret) {
        return payloadSize;
    }

    /* RFM0接收消息后发给APE1 */
    uint32_t core_id = get_core_id();
    char *addr = NULL;
    uint32_t u32_clock_tick   = 0;

    rdmcycle(&u32_clock_tick);
    do_write((buf+16), u32_clock_tick); //RFM receive tick
    g_u32_rfm_2_recv1_num++;

    addr = osp_alloc_msg(RFM_TEST_MSG_SIZE);
    if (NULL == addr)
    {
        debug_write(DBG_DDR_COMMON_IDX(core_id, 35), ++g_u32_rfm_2_alloc1_err);
        return payloadSize;
    }

    do_write(addr, (uint32_t)buf);
    do_write((addr+4), UCP4008_TRAFFIC_NR_eMBB_CTRL);

    rdmcycle(&u32_clock_tick);
    do_write((buf+20), u32_clock_tick); //RFM forward tick

    ret = osp_send_msg((uint32_t)(addr),
                        RFM_TEST_MSG_SIZE,
                        RFM_MSG_TYPE,
                        9,      // src que id
                        5,      // dst que id
                        40,     // src task id
                        40);    // dst task id

    if (0 != ret)
    {
        debug_write(DBG_DDR_COMMON_IDX(core_id, 36), ++g_u32_rfm_2_send1_err);
        return payloadSize;
    }
    g_u32_rfm_2_send1_ok++;

    debug_write(DBG_DDR_COMMON_IDX(core_id, 37), g_u32_rfm_2_recv1_num);
    debug_write(DBG_DDR_COMMON_IDX(core_id, 38), g_u32_rfm_2_send1_ok);

    return payloadSize;
}

static uint32_t g_u32_rfm_3_alloc_err = 0; //(39) 0xB7E0149C
static uint32_t g_u32_rfm_3_send_err  = 0; //(40) 0xB7E014A0
static uint32_t g_u32_rfm_3_recv_num  = 0; //(41) 0xB7E014A4
static uint32_t g_u32_rfm_3_send_ok   = 0; //(42) 0xB7E014A8

uint32_t rx3_callback_data(const char* buf,uint32_t payloadSize)
{
    /* RFM0接收消息后发给APE0 */
    uint32_t core_id = get_core_id();
    int32_t  ret = 0;
    char *addr = NULL;
    uint32_t u32_clock_tick   = 0;

    rdmcycle(&u32_clock_tick);
    do_write((buf+16), u32_clock_tick); //RFM receive tick
    g_u32_rfm_3_recv_num++;

    addr = osp_alloc_msg(RFM_TEST_MSG_SIZE);
    if (NULL == addr)
    {
        debug_write(DBG_DDR_COMMON_IDX(core_id, 39), ++g_u32_rfm_3_alloc_err);
        return payloadSize;
    }

    do_write(addr, (uint32_t)buf);
    do_write((addr+4), UCP4008_TRAFFIC_NR_eMBB_DATA);

    rdmcycle(&u32_clock_tick);
    do_write((buf+20), u32_clock_tick); //RFM forward tick

    ret = osp_send_msg((uint32_t)(addr),
                        RFM_TEST_MSG_SIZE,
                        RFM_MSG_TYPE,
                        9,      // src que id
                        6,      // dst que id
                        40,     // src task id
                        40);    // dst task id

    if (0 != ret)
    {
        debug_write(DBG_DDR_COMMON_IDX(core_id, 40), ++g_u32_rfm_3_send_err);
        return payloadSize;
    }
    g_u32_rfm_3_send_ok++;

    debug_write(DBG_DDR_COMMON_IDX(core_id, 41), g_u32_rfm_3_recv_num);
    debug_write(DBG_DDR_COMMON_IDX(core_id, 42), g_u32_rfm_3_send_ok);
    return payloadSize;
}

static uint32_t g_u32_rfm_3_alloc1_err = 0; //(43) 0xB7E014AC
static uint32_t g_u32_rfm_3_send1_err  = 0; //(44) 0xB7E014B0
static uint32_t g_u32_rfm_3_recv1_num  = 0; //(45) 0xB7E014B4
static uint32_t g_u32_rfm_3_send1_ok   = 0; //(46) 0xB7E014B8

uint32_t rx3_callback_ctrl(const char* buf,uint32_t payloadSize)
{
    int32_t  ret = cell_setup_msg_forward((char*)buf, payloadSize);
    if (0 == ret) {
        return payloadSize;
    }

    /* RFM0接收消息后发给APE1 */
    uint32_t core_id = get_core_id();
    char *addr = NULL;
    uint32_t u32_clock_tick   = 0;

    rdmcycle(&u32_clock_tick);
    do_write((buf+16), u32_clock_tick); //RFM receive tick
    g_u32_rfm_3_recv1_num++;

    addr = osp_alloc_msg(RFM_TEST_MSG_SIZE);
    if (NULL == addr)
    {
        debug_write(DBG_DDR_COMMON_IDX(core_id, 43), ++g_u32_rfm_3_alloc1_err);
        return payloadSize;
    }

    do_write(addr, (uint32_t)buf);
    do_write((addr+4), UCP4008_TRAFFIC_NR_eMBB_CTRL);

    rdmcycle(&u32_clock_tick);
    do_write((buf+20), u32_clock_tick); //RFM forward tick

    ret = osp_send_msg((uint32_t)(addr),
                        RFM_TEST_MSG_SIZE,
                        RFM_MSG_TYPE,
                        9,      // src que id
                        7,      // dst que id
                        40,     // src task id
                        40);    // dst task id

    if (0 != ret)
    {
        debug_write(DBG_DDR_COMMON_IDX(core_id, 44), ++g_u32_rfm_3_send1_err);
        return payloadSize;
    }
    g_u32_rfm_3_send1_ok++;

    debug_write(DBG_DDR_COMMON_IDX(core_id, 45), g_u32_rfm_3_recv1_num);
    debug_write(DBG_DDR_COMMON_IDX(core_id, 46), g_u32_rfm_3_send1_ok);

    return payloadSize;
}

void phy_init(void)
{
    //uint8_t port_id = get_ucp_port_id();
    uint16_t inst_id = 0;
    uint16_t transfer_type = 0;
    uint16_t cu_flag = C_PLANE;
    int32_t handle_id = 0;
    //transfer_type_info_s transfer_type_info;

    for (inst_id=0; inst_id<MAX_INSTANCE_NUM; inst_id++)
    {
        transfer_type = OAM;
        handle_id = msg_transfer_callback_register(transfer_type,inst_id,cu_flag,rx_callback_oam);
        if (handle_id < 0) {
            UCP_PRINT_EMPTY("msg_transfer_cfg transfer_type:OAM, handle_id[0x%08x] error.",handle_id);
        }
    }

    /*********************************transfer_type = CU_SPLIT**********************************/
    transfer_type = CU_SPLIT;
    cu_flag = C_PLANE;
    handle_id = msg_transfer_callback_register(transfer_type, 0, cu_flag, rx_callback_ctrl);
    if (handle_id < 0) {
        UCP_PRINT_EMPTY("msg_transfer_cfg transfer_type:CU_SPLIT, handle_id[0x%08x] error.",handle_id);
    }

    cu_flag = U_PLANE;
    handle_id = msg_transfer_callback_register(transfer_type, 0, cu_flag, rx_callback_data);
    if (handle_id < 0) {
        UCP_PRINT_EMPTY("msg_transfer_cfg transfer_type:CU_SPLIT, handle_id[0x%08x] error.",handle_id);
    }

    transfer_type = CU_SPLIT;
    cu_flag = C_PLANE;
    handle_id = msg_transfer_callback_register(transfer_type, 1, cu_flag, rx1_callback_ctrl);
    if (handle_id < 0) {
        UCP_PRINT_EMPTY("msg_transfer_cfg transfer_type:CU_SPLIT, handle_id[0x%08x] error.",handle_id);
    }

    cu_flag = U_PLANE;
    handle_id = msg_transfer_callback_register(transfer_type, 1, cu_flag, rx1_callback_data);
    if (handle_id < 0) {
        UCP_PRINT_EMPTY("msg_transfer_cfg transfer_type:CU_SPLIT, handle_id[0x%08x] error.",handle_id);
    }

    transfer_type = CU_SPLIT;
    cu_flag = C_PLANE;
    handle_id = msg_transfer_callback_register(transfer_type, 2, cu_flag, rx2_callback_ctrl);
    if (handle_id < 0) {
        UCP_PRINT_EMPTY("msg_transfer_cfg transfer_type:CU_SPLIT, handle_id[0x%08x] error.",handle_id);
    }

    cu_flag = U_PLANE;
    handle_id = msg_transfer_callback_register(transfer_type, 2, cu_flag, rx2_callback_data);
    if (handle_id < 0) {
        UCP_PRINT_EMPTY("msg_transfer_cfg transfer_type:CU_SPLIT, handle_id[0x%08x] error.",handle_id);
    }

    transfer_type = CU_SPLIT;
    cu_flag = C_PLANE;
    handle_id = msg_transfer_callback_register(transfer_type, 3, cu_flag, rx3_callback_ctrl);
    if (handle_id < 0) {
        UCP_PRINT_EMPTY("msg_transfer_cfg transfer_type:CU_SPLIT, handle_id[0x%08x] error.",handle_id);
    }

    cu_flag = U_PLANE;
    handle_id = msg_transfer_callback_register(transfer_type, 3, cu_flag, rx3_callback_data);
    if (handle_id < 0) {
        UCP_PRINT_EMPTY("msg_transfer_cfg transfer_type:CU_SPLIT, handle_id[0x%08x] error.",handle_id);
    }

    return;
}

