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.

PDK NIMU driver and C6678 prefetch buffer

Hello,

I had some performance problems while receiving data using a TCP socket (< 100kB/s). Some TCP error counters started rising during transmission (e.g. tcps.RcvBadSum, tcps.OOPack).

After some debugging I found out that the nimu driver doesn't care about the DSP's prefetch buffer. This sometimes results in invalid RX packet data.

There are two solutions:

1.: Use a 128 Byte gap in front of each packet buffer:

int32_t Setup_Rx (NETIF_DEVICE* ptr_net_device)
{
...
    pktLen = ptr_net_device->mtu + ETHHDR_SIZE + 4; /* ETh Header + 4 bytes of FCS */
    pktLen += 128;     // => 128 Byte gap in order to prevent prefetch buffer problems
...
Cppi_setData (Cppi_DescType_HOST, pCppiDesc, (uint8_t *)Convert_CoreLocal2GlobalAddr((uint32_t)pDataBuffer+128), pktLen);

2.: Invalidate the prefetch buffer before reading the packet:

EmacRxPktISR()
{
....
        if((uint32_t)(pHostDesc->buffPtr) & EMAC_EXTMEM )
        {
            CSL_XMC_invalidatePrefetchBuffer();
            CACHE_invL2((void *) pHostDesc->buffPtr, pHostDesc->buffLen, CACHE_WAIT);
        }

Maybe someone can use this information to update the nimu driver.

Ralf

  • In addition, I found some confusing code about cache operations at multiple locations in the NIMU driver (nimu_eth.c).

    For example:

    if ((uint32_t)(pHostDesc->buffPtr) & EMAC_EXTMEM )
    {
        CACHE_invL2((void *) pHostDesc->buffPtr, pHostDesc->buffLen, CACHE_WAIT);
    }
    if ((uint32_t)(pHostDesc->buffPtr) & EMAC_MSMCSRAM )
    {
        CACHE_invL1d((void *)pHostDesc->buffPtr, pHostDesc->buffLen, CACHE_WAIT);
    }

    If the buffer is located at address 0x8400000 for example, the CACHE_invL1d() in second if() statement will also execute. This doesn't cause any harm, but it's not necessary.

    Because L2 cache operations always also execute in L1d, I would suggest to replace both if() statements with this:

    if ((uint32_t)(pHostDesc->buffPtr) >= EMAC_MSMCSRAM )
    {
        CACHE_invL2((void *) pHostDesc->buffPtr, pHostDesc->buffLen, CACHE_WAIT);
    }

    Ralf

  • Ralf,

     Thanks for bringing it our notice. Agreed with the suggestions. The internal development is looking at the change request and will implement the optimal solution.

  • Ralf,

     In order to recreate this error, can you give the details of your setup. And also the software version, like MCSDK, PDK and NDK versions.

    Thanks

  • The problem appeared with our custom hardware using PDK 1.1.0.3 and NDK 2.21.1.38. I also made a change to the NIMU driver which seems to have an effect on this problem. I decreased the timer value for interrupt pacing from 40 to 5 in order to achieve better network performance:

    accCfg.timerLoadCount = 5;

    Please let me know if you need more information.

    Ralf

  • Thanks Ralf. Appreciate the helpful information. Were you using any specific network testing tool.

    Regards,

    Varada

  • Hi Varada,

    In my test I'm using Iperf on a PC which sends data to the DSP. It's similar to the NDK loopback test used in the MCSDK demo, but without sending the data back to the PC.

    Thanks,

    Ralf