/**********************************************************************************************************************
*  Copyright (C), 2022-2026, SMARTLOGIC TECHNOLOGY LTD.
*  File Name: ecpri_switch.s.c
*  Create Date: 23/08/18
*  Description: eCPRI SWITCH Module Source File
*  Change History: 
*      <author>      <time>      <version>   <desc>
*    1. ShangH      23/08/18        1.0       Build this module
**********************************************************************************************************************/


/* -------------------------------------------------- <INC FILE> --------------------------------------------------- */
#include "ecpri_switch.h"


/* --------------------------------------------------- <VAR DEF> --------------------------------------------------- */


/* -------------------------------------------------- <FUNC DEF> --------------------------------------------------- */
/**********************************************************************************************************************
*  Function: ecpri_pcs_init
*  Description: eCPRI PCS init
*  Input: 
*    <name>        <type>               <desc>
*     skb           sk_buff *            socket buffer
*     dev           net_device *         network device
*  Output: none
*  Return: operation result - success or failure.
*  Others: none
**********************************************************************************************************************/
void ecpri_pcs_init(uint32_t ecpri_speed_sel)
{
    if (ecpri_speed_sel == 10) //10G
    {
        do_write(&MC_PCS_CONTROL_1, BIT13+BIT6+(0<<2));//0 0 0 0 = 10Gbps
        do_write(&MC_PCS_CONTROL_2, 0);//0 0 0 0 = select 10GBASE-R PCS type
        do_write(&MC_CFG_TX, BIT1+BIT3);//rx_elastic_buffer_initial_fill 5
        do_write(&MC_CFG_RX, BIT1+BIT3);//rx_elastic_buffer_initial_fill 5
        do_write(&MC_GENERAL_TX, BIT0+BIT3+(32<<7));  //64b_xgmii_tx 32 SERDES WIDTH +RESET
        do_write(&MC_GENERAL_RX, BIT0+BIT3+(32<<7));  //64b_xgmii_tx 32 SERDES WIDTH +RESET
        do_write(&MC_GENERAL_TX, BIT3+(32<<7));  //64b_xgmii_tx 32 SERDES WIDTH
        do_write(&MC_GENERAL_RX, BIT3+(32<<7));  //64b_xgmii_tx 32 SERDES WIDTH
    }
    else if (ecpri_speed_sel == 25) //25G
    {
        do_write(&MC_PCS_CONTROL_1, BIT13+BIT6+(5<<2));//0 1 0 1 = 25Gbps
        do_write(&MC_PCS_CONTROL_2, 0);//0 0 0 0 = select 10GBASE-R PCS type
        do_write(&MC_CFG_TX, BIT1+BIT3);//rx_elastic_buffer_initial_fill 5
        do_write(&MC_CFG_RX, BIT1+BIT3);//rx_elastic_buffer_initial_fill 5
        do_write(&MC_GENERAL_TX, BIT0+BIT3+(32<<7));  //64b_xgmii_tx 32 SERDES WIDTH +RESET
        do_write(&MC_GENERAL_RX, BIT0+BIT3+(32<<7));  //64b_xgmii_tx 32 SERDES WIDTH +RESET
        do_write(&MC_GENERAL_TX, BIT3+(32<<7));  //64b_xgmii_tx 32 SERDES WIDTH
        do_write(&MC_GENERAL_RX, BIT3+(32<<7));  //64b_xgmii_tx 32 SERDES WIDTH
    }
}

/**********************************************************************************************************************
*  Function: ecpri_mac_init
*  Description: eCPRI MAC init
*  Input: 
*    <name>        <type>               <desc>
*     dev           net_device *         network device
*     data          uint8_t *            data received
*     len           uint32_t             data length
*  Output: none
*  Return: operation result - success or failure.
*  Others: none
**********************************************************************************************************************/
void ecpri_mac_init(uint32_t ecpri_speed_sel)
{
    //设置manticore收到的最大jumbo帧的大小
    do_write(&MC_MAXIMUM_FRAME_SIZE, 65535);
}

/**********************************************************************************************************************
*  Function: ecpri_switch_init
*  Description: eCPRI SWITCH init
*  Input: 
*    <name>        <type>               <desc>
*     dev           net_device *         network device
*     addr          void *               network address
*  Output: none
*  Return: operation result - success or failure.
*  Others: none
**********************************************************************************************************************/
void ecpri_switch_init(uint32_t ecpri_speed_sel)
{
    do_write(&MC_SWITCH_PORT0_CFG_VLAN, do_read_volatile(&MC_SWITCH_PORT0_CFG_VLAN) & (~(BIT12|BIT13|BIT14)));
    do_write(&MC_SWITCH_PORT1_CFG_VLAN, do_read_volatile(&MC_SWITCH_PORT1_CFG_VLAN) & (~(BIT12|BIT13|BIT14)));
    do_write(&MC_SWITCH_PORT2_CFG_VLAN, do_read_volatile(&MC_SWITCH_PORT2_CFG_VLAN) & (~(BIT12|BIT13|BIT14)));

    //do_write(&MC_SWITCH_PORT0_PORT_MAC_2, 0x0A);
    //do_write(&MC_SWITCH_PORT1_PORT_MAC_2, 0x0A);
    //do_write(&MC_SWITCH_PORT2_PORT_MAC_2, 0x0A);

    //do_write(&MC_SWITCH_PORT0_PORT_MAC_1, 0x09080706);
    //do_write(&MC_SWITCH_PORT1_PORT_MAC_1, 0x09080716);
    //do_write(&MC_SWITCH_PORT2_PORT_MAC_1, 0x09080726);

    //enable vid 2 port 1-3
    while ((do_read_volatile(&MC_SWITCH_OP_CTRL) & 0xf) != 0);
    do_write(&MC_SWITCH_PORT_MASK_1, 0xffffffff);
    do_write(&MC_SWITCH_PORT_MASK_2, 0xffffffff);
    do_write(&MC_SWITCH_VLAN_ID, 0x10);
    do_write(&MC_SWITCH_OP_CTRL, 0x110);

    while ((do_read_volatile(&MC_SWITCH_OP_CTRL) & 0xf) != 0);
    do_write(&MC_SWITCH_PORT_MASK_1, 0x4);
    do_write(&MC_SWITCH_PORT_MASK_2, 0x0);
    do_write(&MC_SWITCH_FDB_MAC_INSERT_1, 0x0a0908);
    do_write(&MC_SWITCH_FDB_MAC_INSERT_2, ((0x0726<<16)+0xf));
    do_write(&MC_SWITCH_OP_CTRL, 0x100);

    //RX方向指定插入MAC方式进行转发过滤
    while ((do_read_volatile(&MC_SWITCH_OP_CTRL) & 0xf) != 0);
    do_write(&MC_SWITCH_PORT_MASK_1, 0x2);
    do_write(&MC_SWITCH_PORT_MASK_2, 0x0);
    do_write(&MC_SWITCH_FDB_MAC_INSERT_1, 0x0a0908);
    do_write(&MC_SWITCH_FDB_MAC_INSERT_2, ((0x0716<<16)+0xf));
    do_write(&MC_SWITCH_OP_CTRL, 0x100);

    //while ((do_read_volatile(&MC_SWITCH_OP_CTRL) & 0xf) != 0);
    //do_write(&MC_SWITCH_PORT_MASK_1, 0x1);
    //do_write(&MC_SWITCH_PORT_MASK_2, 0x0);
    //do_write(&MC_SWITCH_FDB_MAC_INSERT_1, 0x0a0908);
    //do_write(&MC_SWITCH_FDB_MAC_INSERT_2, ((0x0706<<16)+0xf));
    //do_write(&MC_SWITCH_OP_CTRL, 0x100);

    do_write(&MC_SWITCH_CFG_MAE, 0XFFFF0002);

#if 1 //10G
    //do_write(&MC_SWITCH_FLOOD_MASK_1, 0xffffffff);
    do_write(&MC_SWITCH_FLOOD_MASK_1, 0xfffffff8); //0xfffffff1
#else
    do_write(&MC_SWITCH_FLOOD_MASK_1, 0xfffffff1);
#endif

    //TX方向指定TRAP方式进行转发（强制转发）
    do_write(&MC_SWITCH_PORT1_CFG_TRAP, 0x00000001);
}

/**********************************************************************************************************************
*  Function: ecpri_pcs_link_status_get
*  Description: eCPRI PCS link status get
*  Input: none
*  Output: none
*  Return: link status - true: link up; false: link down.
*  Others: none
**********************************************************************************************************************/
bool ecpri_pcs_link_status_get(void)
{
    bool link_status = false;

    /* check PCS receive link status is link up or not */
    if (0 != (do_read_volatile(&MC_PCS_STATUS_1) & BIT2))
    {
        link_status = true;
    }

    return link_status;
}



