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.

Regarding developing xaui Ethernet driver for K2L or K2K Evm's

Hello TI,

we are working on K2L and K2K SOC's, there is a need from our customer to use XAUI.

since we are running TI RTOS on ARM corepac we are trying to port XAUI driver from Linux kernel space to TI RTOS as TI has not provided any 10G Ethernet example based on SYS/BIOS

from PDK package --->pdk_k2l_4_0_1--> we got example for 1G Ethernet-->D:\ti\pdk_k2l_4_0_1\packages\MyExampleProjects_old\PA_emacExample_K2LArmBiosExampleProject.

*  Example to illustrate the usage of EMAC CPSW3G switch using CPPI, QMSS
 *     low level drivers and CSL.
 *
 *     This example application does the following:
 *         (1) Initializes:
 *                 (a) Queue Manager (QM) Subsystem
 *                 (b) Packet Accelerator (PA) CPPI DMA
 *                 (c) Ethernet Subsystem (Ethernet switch + SGMII + MDIO) - (Note: Applicable only for NO_BOOT mode)
 *                 (d) PA Subsystem + PDSP - (Note: PDSP is initialized only during NO_BOOT mode)
 *
 *         (2) Sets up the CPPI descriptors and Queues required for sending and
 *             receiving data using Ethernet.
 *                 (a) Uses Host descriptors
 *                 (b) Uses High Priority Accumulation interrupts

Now we want to know if we can modify above sample example for 10G Ethernet?

we are thinking in place of step( c)--> (c) Ethernet Subsystem (Ethernet switch + SGMII + MDIO) --> instead of initializing Ethernet Subsystem for 1G , we can initialize it for 10G or XGE , is our understanding Correct???

 

we want to know what are all the necessary modifications needed for above sample 1G emac example to be made as 10G ...

kindly update us ASAP.

 

Thanks

Manjunath

  • Hello TI ,

    Kindly provide an update on this?

    can TI provide 10G etherenet example?

    Thanks
    Manjunath
  • We do not have 10G example on TI-RTOS(BIOS). Thank you.
  • I looked at K2L SOC datasheet, the block diagram doesn't show 10-GbE. Can you confirm you are working on K2L for this? For K2H/K, the SOC does supports 10-GbE.

    The Linux driver for 10-GbE is there, I am not sure what's your purpose to develop driver in RTOS, you can't easily test it unless you have network stack in RTOS as well. For SGMII, it uses NETCP/PA, with the RTOS, one can send/receive some packets with the test example, to use it for a network, you still need the package like NDK.  

    The Processor SDK package doesn't have any driver for 10-GbE, and you can't simply modify the SGMII/EMAC/PA example for that, this is the wrong path, two IP are different.

    The closest code example is in packages\ti\diag\serdes_diag, it has code example how to set-up 10-GbE Serdes level, but not to MAC layer.

    Regards, Eric

  • Hello Eric,

    Thanks for your update.

    we are working on both K2L and K2K boards for xaui we will be using K2k Boards

    please see our requirement as below
    1) We want to use XAUI as a physical Interface/port.. We will make the raw data packet and send over XAUI. We dont use TCP IP stack to send or receive Packet. In our product, Outside K2K SoC, it is another HW IP which receives XAUI raw packets and sends back raw XAUI packets.


    So, just trying to make a XAUI driver, where we can read write our raw packets to/fro XAUI port.

    Please suggest what would be the best way to go ahead..

    similar to SGMII example , we just want to send/receive Raw packets through XAUI port, if we are trying to write xaui driver for TI-RTOs with the help of CSL code.

    just for your information we have the below sample code written.
     
     

    /*
    * ======== Header Files ========
    */
    #include <stdlib.h>
    
    #include <xdc/std.h>
    #include <xdc/cfg/global.h>
    #include <xdc/runtime/System.h>
    
    #include <ti/sysbios/BIOS.h>
    #include <ti/sysbios/hal/Core.h>
    #include <ti/sysbios/hal/Timer.h>
    #include <ti/sysbios/knl/Swi.h>
    #include <ti/sysbios/knl/Clock.h>
    #include <ti/sysbios/knl/Task.h>
    #include <ti/sysbios/utils/Load.h>
    #include <ti/sysbios/knl/Semaphore.h>
    #include <xdc/runtime/Timestamp.h>
    #include <ti/csl/Csl_psc.h>
    #include <ti/csl/csl_pscAux.h>
    #include<ti/csl/src/ip/serdes_sb/v0/Csl_serdes2.h>
    #include<ti/csl/src/ip/serdes_sb/v0/Csl_serdes2_10ge.h>
    
    #define XGE_CFG_BASE_ADDR 0x2F00000
    #define SUB_CTRL (XGE_CFG_BASE_ADDR + 0xC)
    #define SOFT_RESET_PORT1 (XGE_CFG_BASE_ADDR + 0x0104)
    #define SGMII_CONTROL_PORT1 (XGE_CFG_BASE_ADDR + 0x0110)
    #define SOFT_RESET_PORT2 (XGE_CFG_BASE_ADDR + 0x0204)
    #define SGMII_CONTROL_PORT2 (XGE_CFG_BASE_ADDR + 0x0210)
    #define PCSR_CTRL_PORT_1 (XGE_CFG_BASE_ADDR + 0x600 + 0x24)
    #define PCSR_CTRL_PORT_2 (XGE_CFG_BASE_ADDR + 0x680 + 0x24)
    #define CPSW_TX_START_WDS (XGE_CFG_BASE_ADDR + 0x1020)
    #define CPSW_CTRL_REG (XGE_CFG_BASE_ADDR + 0x01004)
    #define CPSW_STAT_PORT_EN_REG (XGE_CFG_BASE_ADDR + 0x0100C)
    #define CPSW_FLOW_CTRL_REG (XGE_CFG_BASE_ADDR + 0x01024)
    #define MAC1_CTRL_REG (XGE_CFG_BASE_ADDR + 0x01404)
    #define MAC2_CTRL_REG (XGE_CFG_BASE_ADDR + 0x01444)
    #define ALE_CONTROL_REG (XGE_CFG_BASE_ADDR + 0x01708)
    #define ALE_PORTCTL0_REG (XGE_CFG_BASE_ADDR + 0x01740)
    #define ALE_PORTCTL1_REG (XGE_CFG_BASE_ADDR + 0x01744)
    #define ALE_PORTCTL2_REG (XGE_CFG_BASE_ADDR + 0x01748)
    #define ALE_TBLCTL_REG (XGE_CFG_BASE_ADDR + 0x01720)
    #define ALE_ENTRY0_REG (XGE_CFG_BASE_ADDR + 0x0173C)
    #define ALE_ENTRY1_REG (XGE_CFG_BASE_ADDR + 0x01740)
    #define ALE_ENTRY2_REG (XGE_CFG_BASE_ADDR + 0x01744)
    
    #define DEVICE_REG32_W(x,y) *(volatile unsigned int *)(x)=(y)
    #define DEVICE_REG32_R(x) (*(volatile unsigned int *)(x))
    #define CSL_PSC_LPSC_XGE 50
    #define CSL_PSC_PD_XGE 29
    #define CSL_XGE_SERDES_CFG_REGS (0x0231E000)
    #define XGE_SW_SIZE 0x00001000
    #define XGE_CTRL_OFFSET 0x0c
    
    
    
    
    Uint32 Xgbe_powerup(){
    CSL_PSC_disablePowerDomain(CSL_PSC_PD_XGE);
    
    CSL_PSC_enablePowerDomain (CSL_PSC_PD_XGE);
    
    /* Enable the clocks too for SRIO */
    CSL_PSC_setModuleNextState (CSL_PSC_LPSC_XGE, PSC_MODSTATE_ENABLE);
    
    /* Start the state transition */
    CSL_PSC_startStateTransition (CSL_PSC_PD_XGE);
    
    /* Wait until the state transition process is completed. */
    while (!CSL_PSC_isStateTransitionDone (CSL_PSC_LPSC_XGE));
    
    /* Return SRIO PSC status */
    if ((CSL_PSC_getPowerDomainState(CSL_PSC_PD_XGE) == PSC_PDSTATE_ON) &&
    (CSL_PSC_getModuleState (CSL_PSC_LPSC_XGE) == PSC_MODSTATE_ENABLE))
    {
    /* SRIO ON. Ready for use */
    return 0;
    }
    else
    {
    /* SRIO Power on failed. Return error */
    return -1;
    }
    
    }
    
    
    
    static inline void CSL_10GeSerdesLaneEnable(uint32_t base_addr,uint32_t lane_num,
    CSL_SERDES_REF_CLOCK ref_clock,
    CSL_SERDES_LINK_RATE rate
    )
    {
    
    
    /* Set Lane Control Rate */
    CSL_FINSR(*(volatile uint32_t *)(base_addr + 0x1fe0 + 4*lane_num),28,26, 0x4);
    CSL_FINSR(*(volatile uint32_t *)(base_addr + 0x1fe0 + 4*lane_num),12,10, 0x4);
    
    /* set bus-width */
    CSL_FINSR(*(volatile uint32_t *)(base_addr + 0x1fe0 + 4*lane_num),23,21, 0x7);
    CSL_FINSR(*(volatile uint32_t *)(base_addr + 0x1fe0 + 4*lane_num), 5, 3, 0x7);
    
    /* enable PCS overlay and lane select 10GKR */
    CSL_FINSR(*(volatile uint32_t *)(base_addr + 0x1fe0 + 4*lane_num),16,16, 0x1);
    CSL_FINSR(*(volatile uint32_t *)(base_addr + 0x1fe0 + 4*lane_num),19,19, 0x1);
    
    /* enable lanes */
    CSL_FINSR(*(volatile uint32_t *)(base_addr +0x1fc0 + 0x20 + (lane_num*4)),31,29,(uint32_t)0x07);
    CSL_FINSR(*(volatile uint32_t *)(base_addr +0x1fc0 + 0x20 + (lane_num*4)),15,13,0x07);
    
    
    }
    static inline void CSL_10GeSerdesPllEnable(uint32_t base_addr,CSL_SERDES_LINK_RATE rate)
    {
    CSL_FINSR(*(volatile uint32_t *)(base_addr + 0x1ff4), 27, 25, 0x7 );
    CSL_FINSR(*(volatile uint32_t *)(base_addr + 0x1ff4),31,29, (uint32_t)0x7);
    
    }
    
    static inline CSL_SERDES_STATUS CSL_10GeSerdesGetpllStatus
    (
    uint32_t base_addr,
    csl_serdes_phy_type phy_type
    )
    {
    CSL_SERDES_STATUS retval;
    retval = (CSL_SERDES_STATUS)CSL_FEXTR(*(volatile uint32_t *)(base_addr + 0x1ff4), 28, 28);
    return retval;
    }
    void XGbeSerdesSetup(){
    
    
    CSL_SERDES_REF_CLOCK refClock;
    CSL_SERDES_LINK_RATE linkRate;
    Uint32 baseAddr;
    CSL_SERDES_RESULT csl_retval;
    Uint32 i;
    CSL_SERDES_LANE_CTRL_RATE lane_rate;
    CSL_SERDES_STATUS pllstat;
    CSL_SERDES_LANE_ENABLE_STATUS lane_retval;
    
    int val;
    Uint32 lane_num;
    
    csl_retval = CSL_10GeSerdesInit(CSL_XGE_SERDES_CFG_REGS, CSL_SERDES_REF_CLOCK_156p25M, CSL_SERDES_LINK_RATE_10p3125G);
    
    if (csl_retval != 0)
    {
    printf ("Invalid XGE Serdes Init Params: %d\n", csl_retval);
    }
    
    for( lane_num = 0; lane_num<2; lane_num++)
    CSL_10GeSerdesLaneConfig(CSL_XGE_SERDES_CFG_REGS, CSL_SERDES_REF_CLOCK_156p25M, CSL_SERDES_LINK_RATE_10p3125G, lane_num);
    
    CSL_10GeSerdesComEnable(CSL_XGE_SERDES_CFG_REGS, CSL_SERDES_LINK_RATE_10p3125G);
    
    for( lane_num = 0; lane_num<2; lane_num++){
    CSL_10GeSerdesLaneEnable(CSL_XGE_SERDES_CFG_REGS, lane_num, CSL_SERDES_LINK_RATE_10p3125G, CSL_SERDES_LOOPBACK_DISABLED);
    
    }
    
    CSL_10GeSerdesPllEnable(CSL_XGE_SERDES_CFG_REGS, CSL_SERDES_LINK_RATE_10p3125G);
    
    do
    {
    pllstat = CSL_10GeSerdesGetpllStatus(CSL_XGE_SERDES_CFG_REGS, 0);
    }while(pllstat == CSL_SERDES_STATUS_PLL_NOT_LOCKED);
    
    }
    void PCSR_init(){
    DEVICE_REG32_W(PCSR_CTRL_PORT_1, 0x2);
    DEVICE_REG32_W(PCSR_CTRL_PORT_2, 0x2);
    }
    void k2serdes_enable_xgmii_port(){
    
    DEVICE_REG32_W(XGE_CFG_BASE_ADDR+XGE_SW_SIZE+XGE_CTRL_OFFSET,0x03);
    
    }
    
    
    void CPSW_init(){
    
    DEVICE_REG32_W(CPSW_CTRL_REG, 0x04);
    DEVICE_REG32_W(CPSW_TX_START_WDS, 0x08);
    DEVICE_REG32_W(CPSW_STAT_PORT_EN_REG, 0x7);
    DEVICE_REG32_W(CPSW_FLOW_CTRL_REG, 0x7);
    }
    void ALE_init(){
    
    DEVICE_REG32_W(ALE_CONTROL_REG, 0x80000002);
    DEVICE_REG32_W(ALE_PORTCTL0_REG, 0x03);
    DEVICE_REG32_W(ALE_PORTCTL1_REG, 0x03);
    DEVICE_REG32_W(ALE_PORTCTL2_REG, 0x03);
    /*DEVICE_REG32_W(ALE_TBLCTL_REG, 0x80000003);
    DEVICE_REG32_W(ALE_ENTRY0_REG, 0x44332211);
    DEVICE_REG32_W(ALE_ENTRY1_REG, 0x10006655);
    DEVICE_REG32_W(ALE_ENTRY2_REG, 0xC0);*/
    }
    void MAC_init(){
    
    DEVICE_REG32_W(MAC1_CTRL_REG, 0x2119);
    DEVICE_REG32_W(MAC2_CTRL_REG, 0x2119);
    }
    
    
    void Xgbe_init()
    {
    Xgbe_powerup();
    XGbeSerdesSetup();
    k2serdes_enable_xgmii_port();
    CPSW_init();
    PCSR_init();
    MAC_init();
    }
    
    
    
    Int main(Int argc, char* argv[])
    {
    
    Xgbe_init();
    BIOS_start();
    return (0);
    }
    



    Regards
    Manjunath

  • Hello Eric/TI,

    any update on this?

    Regards

    Manjunath

  • Hi Manjunath,

    The response may be delayed due to holiday in USA(Memorial Day). Thank you for your patience.
  • Manjunath,

    The code seems missed PKTDMA portion. We don't have XGE RTOS driver to Tx/Rx raw packets, so you may need some trial. Another example is the Keystone II Linux kernel http://git.ti.com/gitweb/?p=keystone-linux/linux.git;a=tree;f=drivers/net/ethernet/ti;h=53a3c18548c4a095e66958b41654cb702a77645d;hb=e5f8f30700366eabcad7a403a49689c358476bfa, it supports XGE. The code are written in a different format. Serdes initialization portion are based on CSL code, you may look at other functions how to intialize the sgmii, pcsr, mac, pktdma, etc....

    Regards, Eric

  • Hello Eric,

    Thanks for the info.

    Now we are trying to port Xaui drivers from Linux kernel space to TI-RTOS.

    we have some other version of Linux kernel in which there are 3 files related to xaui drivers keystone_xgemdio.c ,keystone_xgecpsr.c & keystone_xgess.c

    from file keystone_xgess.c  in function cpswx_probe() --> xge_serdes_init() is called  to initialize serdes .

    Now there is another file  keystone_xgemdio.c in function  keystone_mdiox_probe() ---->xge_serdes_init_156p25Mhz();  is again called?

    why there is a call to initialize serdes twice once in "CPSW driver"  and again in "MDIO driver"  ?

    could you please clarify our doubt?

    Regards

    Manjunath

  • Hello TI,

    Kindly update us

    Regards

    Manjunath

  • Manjunath,

    I am not sure if you are working with our latest XGE driver or using some older ones. From my search of the code, I didn't see that xge_serdes_init() was called. So xge_serdes_init_156p25Mhz() is only called once. If there is doubt of the call sequence, please use the latest code, you may also add some printk in the Linux kernel, rebuild it and to see what was called when Linux boot up.

    Regards, Eric