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.

C6748 NDK lost RAW TX packet broadcast?

I'm running into a problem where I've verified that I'm passing a request for transmission of a raw packet to the NDK and although the function returns good status the packet never gets transmitted.

In short I'm implementing the EtherCAT Master protocol.  I've simplified things where I am just scanning a single slave (nothing else on private network) so the transmitted and received packets are almost identical except for MAC ID (64 byte packet size).  The Master is doing a broadcast.  Two separate threads are used, one to send, the other to receive.  fdShare() works fine and all works well but after several minutes and 100K of packet transactions I was getting a timeout on the receiver.  In checking further I can see that a broadcast was passed to the stack for transmission but never appeared on the wire.  The slave did not see it nor Wireshark.  Retry and it will send fine and continue on until the next timeout is encountered.

One thing EtherCAT does is have the slave respond very quickly since hardware is used to send the packet back to the Master, thus virtually as soon as the NDK sends a packet there are interrupts occuring for the response.  In my test each direction is only a single packet, running half duplex.

What is strange is there is no error reported for the lost raw packet with regards to the send() function call.  I have also used the RawEthTxPacket() call with the same result.

Environment:

LogicPD Development board, Sys/Bios 6.32.03.43, NDK 2.20.4.26, NDK Support Pkg 1.0.0.09, Compiler 7.30, XDCTools 3.22.02.27 & CCSV5

Anyone know of any prior history of similiar problems or thoughts before I start diving into the NDK source and driver code?

Thanks,

Kev

  • Some added info.  Made a copy of the RAWETHSTATS before transmission and after receive timeout awaiting response and it records the packet in the SndTotal although never was actually transmitted.  Basically SndTotal was incremented by one after the call to RawEthTxPacket(), thus data was passed to the stack.  Also verified packet data was valid.

  • Seems like I'm talking to myself on here but on the oft chance a TI person reviews I've just verified that the problem is a bug in the nsp_1_00_00_09 L138/C6748 EMAC driver.  Have not been able to fix it yet but am rebuilding the driver and adding diagnostic code.  In doing so the packet that was to be transmitted was placed in the descriptor list and was also dequeued.  The below modification to the driver copies the last dequeued packet from the descriptor list to a buffer which I look at when a timeout occurs waiting for a reply to the lost transmitted packet.  My missing packet is present but it never hit the wire.  A counter was also put at the Transmit Complete ISR (HwTxInt) function and an interrupt occured when the last packet was put in queue.  Now question is, where did it go and why would the EMAC skip the descriptor or is the driver dequeing too early?

     

    unsigned char _EMAC_LastPacketBuffer[2048];

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

    int

     

     

    int

     

     

    static

     

     

     

    Uint32 PktFlgLen;

     

     

    register Uint32 i;

     

     

    register Uint32 j = (Uint32)pdc->pDescRead;

     

     

    volatile Uint32 *pRegAddr;

     

     

    /* Get the status of the ACK descriptor */

    PktFlgLen = pDescAck->PktFlgLen;

     

     

     

    /* Calc the new "Read" descriptor */

     

     

    if (pDescAck == pdc->pDescLast)

    pdc->pDescRead = pdc->pDescFirst;

     

     

    else

    pdc->pDescRead = pDescAck+1;

     

    i = (

    Uint32)pdc->pDescRead;

     

     

     

    /* Turn i into a descriptor count */

     

     

    if( j < i )

    i = (i-j)/

    sizeof(EMAC_Desc);

     

     

    else

    i = pdc->DescMax - ((j-i)/

    sizeof(EMAC_Desc));

     

     

     

    if (pdc->DescCount == 0)

    i = 0;

     

     

    else

    pdc->DescCount -= i;

     

     

     

    /* Pop & Free Buffers 'till the last Descriptor */

     

     

    while (((int)(i--)) > 0) {

     

     

    /* Recover the buffer and free it */

    pPkt = pqPop(&pdc->DescQueue);

     

    if (pPkt)

    (*localDev.Config.pfcbFreePacket)(pdc->pd->hApplication,pPkt);

    }

     

     

     

    if (pPkt)

    {

     

    memcpy(_EMAC_LastPacketBuffer,pPkt->pDataBuffer,pPkt->PktLength);  // keep a copy of the last packet for debug

    _EMAC_lastBufferLen = pPkt->PktLength;

    }

     

     

    /* If the transmitter stopped and we have more descriptors, then restart */

     

     

    if ((PktFlgLen & EMAC_DSC_FLAG_EOQ) && pdc->DescCount)

    {

    pRegAddr = &EMAC_REGS->TX0HDP;

    *(pRegAddr + pdc->ChannelIndex) = (

    Uint32)pdc->pDescRead;

    }

     

     

     

    /* Try to post any waiting TX packets */

     

     

    if (pdc->WaitQueue.Count)

    void emacDequeueTx(EMAC_DescCh *pdc, EMAC_Desc *pDescAck)

    {

    EMAC_Pkt *pPkt;

     

    _EMAC_dequeueCounter = 0;
    _EMAC_lastBufferLen = 0;

    emacEnqueueTx(pdc);

    _EMAC_dequeueCounter++;

    }

     

  • Now that I know more than I care to about the EMAC operation, the driver is working fine. Just discovered it was the unmanaged switch dropping the packet. There is no broadcast storm control on the Netgear switch but it seems to drop a packet once in a while. Bypassed the switch and never skipped a beat...