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.

Problems sending EMAC (RGMII) packets to FPGA (C6472 DSP)

Hello,

I'm new to this platform and environment so I appreciate any help I can get.  I have tried using the Emac_core_restart_example as well as the loopback example provided by TI for this test. The 6472 is being used on a proprietary board. Basically, I'm trying to send packets using the EMAC which has been configured for RGMII. The DSP is connected to an FPGA, which has been set up in loopback mode, therefore, packets should route out to the FPGA, which should then loop them back.  Our FPGA has designated registers to keep track of the # of packets received as well as the total # of bytes.  After doing a reset of the DSP, I will see the BOOTP frame get registered on the FPGA with a size of 0x15a bytes - both the Rx and Tx registers increment indicated that the loopback mode is working properly.  ModeFlags have been modiefied for RGMII / GigE usage (see code). When I run the code, EMAC_sendPacket (&EMACObj, pPkt); returns success, however, I do not see any action on the FPGA count registers to show that packets are received.

Any clues on what can be happening here or how to debug further will be greatly appreciated.  I attached the main part of the code ...

   EMAC_Common_Config commonCfg;
    EMAC_Core_Config coreCfg;
    EMAC_AddrConfig *addrCfg;
    Uint32          i, size, j;
    Uint32          TxCount=0;
    Uint32          RxCount=0;
    EMAC_Pkt        *pPkt;

    coreNum = CSL_chipReadReg(CSL_CHIP_DNUM);

    /* Disable L1D Cache */
    CACHE_setL1dSize(CACHE_L1_0KCACHE);

    /*
     * Basic Initialization
     */                   
    printf("EMAC example for EMAC 0");
    /*
     * Initialize Common Configuration of EMAC
     */
    if(bReconfigEMAC)
    {
        /* Not using the MDIO configuration */
        commonCfg.UseMdio = 0;
        /* core 0 is master core in terms of EMAC */
        commonCfg.CoreNum = 0;
        /* packet size */
        commonCfg.PktMTU  = 1600;

        /* Setup the EMAC configuration */
        //commonCfg.ModeFlags      = EMAC_CONFIG_MODEFLG_MACLOOPBACK | EMAC_CONFIG_MODEFLG_FULLDUPLEX
        //                                     | EMAC_CONFIG_MODEFLG_GMIIEN;
       
        commonCfg.ModeFlags      = EMAC_CONFIG_MODEFLG_RGMIIEN | EMAC_CONFIG_MODEFLG_FULLDUPLEX
                                             | EMAC_CONFIG_MODEFLG_GIGABIT | EMAC_CONFIG_MODEFLAG_GIGFORCE;

                                             
        commonCfg.MdioModeFlags  = MDIO_MODEFLG_FD1000;
    }

    /*
     * Initialize Core Specific Configuration of EMAC
     */
    /* Total 3 MAC addresses allocated for the receive channel */
    coreCfg.NumOfMacAddrs = 3;
    /* selects CPPI RAM for Descriptor memory */
    coreCfg.DescBase = EMAC_DESC_BASE_CPPI;

    coreCfg.RxMaxPktPool              = 8;
    coreCfg.pfcbGetPacket             = &GetPacket;
    coreCfg.pfcbFreePacket            = &FreePacket;
    coreCfg.pfcbRxPacket              = &RxPacket;
    coreCfg.pfcbStatus                = &StatusUpdate;
    coreCfg.pfcbStatistics            = &StatisticsUpdate;

    switch(coreNum) {
        default:
        case 0:                   /* core 0 use channel 0 */
            coreCfg.ChannelInfo.TxChanEnable = 1;
            coreCfg.ChannelInfo.RxChanEnable = 1;
            break;
        case 1:                   /* core 1 use channel 1 */
            coreCfg.ChannelInfo.TxChanEnable = 2;
            coreCfg.ChannelInfo.RxChanEnable = 2;
            break;
        case 2:                   /* core 2 use channel 2 */
            coreCfg.ChannelInfo.TxChanEnable = 4;
            coreCfg.ChannelInfo.RxChanEnable = 4;
            break;
    }

    /*    Configures MAC addresses per channel
    *        Hardware gives support for 32 MAC addresses for 8 receive channels
    *        Here total 9 MAC addresses are assigned to 3 receive channels
    *        3 MAC addresses per channel
    *        MAC addresses and channels allocated are like mentioned below
    *            core no       channel assigned       MAC address
    *                core0         channel 0            00.01.02.03.04.05
    *                                                10.11.12.13.14.15
    *                                                20.21.22.23.24.25(address used for loopback test)
    *                                         
    *                core1         channel 1            30.31.32.33.34.35
    *                                                40.41.42.43.44.45
    *                                                50.51.52.53.54.55(address used for loopback test)
    *                                           
    *                core2         channel 2            60.61.62.63.64.65
    *                                                70.71.72.73.74.75
    *                                                80.81.82.83.84.85(address used for loopback test)
    *
    */
    coreCfg.MacAddr = (EMAC_AddrConfig **)
                        malloc(coreCfg.NumOfMacAddrs * sizeof(EMAC_AddrConfig *));

    for (j=0; j<coreCfg.NumOfMacAddrs; j++){
        coreCfg.MacAddr[j] = (EMAC_AddrConfig *)malloc(sizeof(EMAC_AddrConfig));
    }

    for(j=0; (Uint8)j<(coreCfg.NumOfMacAddrs); j++){
        addrCfg = coreCfg.MacAddr[j];
        addrCfg->ChannelNum = coreNum;       
        for (i=0; i<6; i++)
        {
            addrCfg->Addr[i] = j * 0x10 + i + coreNum * 0x30;
        }
    }

    /*
     * EMAC common initialization
     */
    /* Common Initialization which needs to be done only once */
    if(bReconfigEMAC)
    {
        /* Initialize our EMAC Dev structure.*/
        memset(&EMACObj, 0, sizeof(EMAC_Device));
        /* Enable EMAC in PSC control module */
           enableEMAC();
        /* Calling EMAC_commonInit for common initialization of EMAC */
        printf("Calling EMAC_commonInit()\n");
        i = EMAC_commonInit(CSL_EMAC_0, &commonCfg, &EMACObj);
        if(i)
        {
            printf("Returned error %08x\n",i);
            goto close_emac;
        }
        bReconfigEMAC = 0;
    }

    /*
     * EMAC core de-initialization
     */
    printf("Calling EMAC_coreDeInit()\n");
    i = EMAC_coreDeInit(&EMACObj);
    if(i)
    {
        printf("Returned error %08x\n",i);
        goto close_emac;
    }

    /*
     * Prepear packet data
     */
    /* Init packet data array */
    for( i=0; i<1600; i++ ) {
        packet_sourcedata[i] = i;
    }

    /* Specifiy destination and source address */
      addrCfg = coreCfg.MacAddr[2];

    for( i=0; i<6; i++ ) {
        packet_sourcedata[i] = addrCfg->Addr[i];
    }
   
    for( i=6; i<12; i++ ) {
        packet_sourcedata[i] = addrCfg->Addr[i-6];
    }

    /* Initialize our buffer pool */
    memset( &FreeQueue, 0, sizeof(APP_PKTQ) );
    memset( &RxQueue, 0, sizeof(APP_PKTQ) );
    for( i=0; i<PKT_MAX; i++ ) {
        /*
         * Init the buffer headers. Note that the buffer pointer
         * and buffer length are fixed and to not change
         */
        memset( &packet_header[i], 0, sizeof(EMAC_Pkt) );
        packet_header[i].pDataBuffer = packet_buffer[i];
        packet_header[i].BufferLen   = 1600;
        App_pqPush( &FreeQueue, &packet_header[i] );
    }

    /*
     * EMAC core initialization
     */
    printf("Calling EMAC_coreInit()\n");
    i = EMAC_coreInit(&EMACObj, (Handle)0x12345678, &coreCfg);
    if(i)
    {
        printf("Returned error %08x\n",i);
        goto close_emac;
    }

    /*
     * Set the receive filter
     */
    /* Use our re-entrancy gate to call EMAC functions */
    printf("Calling EMAC_setReceiveFilter()\n");
    OUREMAC_enter();
    i = EMAC_setReceiveFilter( &EMACObj, EMAC_RXFILTER_DIRECT, 0 );
    OUREMAC_exit();
    if(i)
    {
        printf("Returned error %08x\n",i);
        goto close_emac;
    }

    /* Do timer initialization */
    DoTimerInitialization();

    /* Do interrupt setup - use MAC 0 */
    DoInterruptsInitialization( CSL_EMAC_0 );

    /*
     * Wait for the device to link
     *
     * The device can not send or receive packets until its
     * linked.
     *
     */
    printf("Waiting for link...\n");
    LocalTicks = 0;
    if(EMACObj.Config.UseMdio){
        while( !LinkStatus && LocalTicks < 10000);
   }

    /* Need to print this here, as it's not possible from the callback function */
    EMAC_getStatus( &EMACObj, &status);

    LinkStatus = status.MdioLinkStatus;
    if( LinkStatus <= 5 )
        printf("Link Status  : %s on PHY number %d\n",
               LinkStr[LinkStatus],status.PhyDev);

    printf("Packets Held : %d-RX  %d-TX\n",
           status.RxPktHeld, status.TxPktHeld);
    if( status.FatalError )
        printf("Fatal Error  : %d\n",status.FatalError);

    if( !LinkStatus )
        printf("\nWARNING: No device LINK.\n");

    /* Start packet transfer */
    printf("\nStarting packet transfer...\n");

    LocalTicks = 0;
    while( 1 ) {
        /* See if we should send a packet */
        if(TxCount<(RxCount+8) ) {
            /*
             * Send a packet
             */
            /* First get a packet buffer from our private queue */
            pPkt = App_pqPop( &FreeQueue );
            if( pPkt ) {
                size = 1200;
                memcpy( pPkt->pDataBuffer, packet_sourcedata, size);

                /* Send the packet */
                pPkt->Flags      = EMAC_PKT_FLAGS_SOP | EMAC_PKT_FLAGS_EOP;
                pPkt->ValidLen   = size;
                pPkt->DataOffset = 0;

                switch(coreNum) {
                    default:
                    case 0:pPkt->PktChannel = 0; break; /* core 0 use channel 0 */
                    case 1:pPkt->PktChannel = 1; break; /* core 1 use channel 1 */
                    case 2:pPkt->PktChannel = 2; break; /* core 2 use channel 2 */
                }

                pPkt->PktLength  = size;
                pPkt->PktFrags   = 1;

                /*
                 * IMPORTANT: If our data packet were in EXTERNAL memory,
                 * we would have to clean it from the CACHE before submitting
                 * it to the EMAC module!!!
                 *
                 * We should probably do the clean operation right here.
                 */

                /* Use our re-entrancy gate to call EMAC functions */
                OUREMAC_enter();
                i = EMAC_sendPacket(&EMACObj, pPkt);
                OUREMAC_exit();
                if(i) {
                    printf("EMAC_sendPacket() returned error %08x\n",i);
                    break;
                }
                /* Bump the TX count */
                TxCount++;
            }
        }

        /*
         * See if we received a packet
         */
        if( pPkt = App_pqPop( &RxQueue ) ) {
            /* Validate this packet */
            if( !verify_packet( pPkt, 1200) ) {
                printf("ERROR: Verify failure on packet %d\n",RxCount);
                break;
            }

            /* Free the packet */
            App_pqPush( &FreeQueue, pPkt );

            /* Bump the RX count */
            RxCount++;
        }

        if(TxCount%8==0)
            printf("Sent %d packets, received %d packets\n",
                    TxCount, RxCount);
    }