NDK: Dropped Raw Ethernet frames with SOCK_RAWETH socket

My c6748 application appears to be dropping received frames from a SOCK_RAWETH socket.

When I send 10 frames to the c6748 in a row, it only gets around to processing the first 2.

On the other hand, when I insert a pause (5 ms) between each frame being sent, all 10 frames are received.

Could this problem be related to internal socket buffers being filled?

I tried setting a higher value for SO_RCVBUF to no avail.

Pseudocode from my application is shown below:

Loop:

call recvnc()

copy received packet into temporary variable

call recvncfree()

process the packet as stored in the temporary variable

Thanks

Corey

29 Replies

  • Corey,

    Which version of the NDK and BIOS are you using?

    What is the CPU load of the target?

    Why are you using recvnc, if you are just going to copy the packet. It seems like you should just be using the standard recv.

    Todd

  • In reply to ToddMullanix:

    NDK version: 2.20.03.24

    BIOS version:  5.41.07.24

    The CPU is virtually idle while this loop is executing.

    I am aware that recvnc() combined with a copy is more-or-less equivalent to recv().

    The reason I am doing this is that I am under the impression that Raw sockets do not support recv(). Is this true?

    To make sure we are clear, my socket is created with the following code line:

    hRawSocket = socket(AF_RAWETH, SOCK_RAWETH, 0x801);

    In any case, why would this all lead to packets being dropped? I assume there is an underlying buffering system (i.e. "socket buffer") that will stow away received packets until the next time you call recvnc().

    Thanks

    Corey

  • In reply to Corey Kasten:

    Sorry. I missed the SOCK_RAWETH in the original post.

    What does the raw stats look like? Put "raweths" in your watch window. Hopefully this will shed some light.

    Todd

  • In reply to ToddMullanix:

    OK got the stats.

    Procedure A: Boot the DSP and send it 5 packets in a row. The receive stats are:

    RcvTotal 2
    RcvDrops 0

    Note: My application also processed 2 out of the 5 packets.

    Procedure B. Boot the DSP and remotely bring down and up, again, ehe link (in linux, use ifconfig down/up).  The receive stats are:

    RcvTotal 5

    RcvDrops 5

    This suggests:

    1. The driver does not have any idea that in Procedure A, above, it lost 3 packets.
    2. The RcvDrops field counts packets received by the ethernet driver but explicitly ignored (i.e. dropped), and RcvTotal counts all packets known to the driver, whether dropped or not.

    Why does the driver miss these packets? Perhaps the driver has only two buffers being ping-pong'd for DMA.  Can someone take a look at the Ethernet driver and determine the length of the buffer chain set up in the buffer descriptors?

    Thanks

    Corey




  • In reply to Corey Kasten:

    Corey,

    The "raweths" statistics are maintained in the NDK stack. 

    Have you plugged a statistics function into the driver? Look in the csl_emac.c file for a description.

    ecfg.pfcbStatistics            = &StatisticsUpdate;

    There is a dummy one in the ethdriver.c called StatisticsUpdate.The statistics are in the

    EMAC_Statistics Stats;

    field.

    You can call the EMAC_getStatistics() directly also, but the stats are cleared after every Rx and Tx in the driver.

    I'll find a evm6748  and reproduce the problem here.

    Todd

  • In reply to ToddMullanix:

    I have not plugged a statistics function into the driver as indicated by the fact that grep'ing my project files for "pfcbStatistics" returns only the line you mentioned:

    ecfg.pfcbStatistics         = &StatisticsUpdate;

    That function is defined as:

    static void StatisticsUpdate( Handle hApplication )
    {
        if( (Uint32)hApplication != 0x12345678 )
        {
            return;
        }
    }


    Looking at the numbers recorded in my previous post for "RcvTotal" and "RcvDrops", it is apparent that the statistics are NOT cleared after every Rx and Tx. Are you sure we are looking at the same version of NDK. Remember, my version is: 2.20.03.24.

    I appreciate that you will be trying to reproduce the problem with the c6748.  When trying to reproduce the problem, it is important that the remote send multiple packets in one atomic operation so that there will be know pause between the transmission of packets, since (as mentioned in my first post) the problem does NOT occur when a small pause occurs between the transmission of packets.  Hence, it appears that the problem is a timing-driven one. Let me know if you are having trouble reproducing the problem and I will try to help.

    Thanks

    Corey

  • In reply to Corey Kasten:

    Corey,

    The pfcbStatistics field is in the driver code, not the NDK. Which NSP are you using (NSP supply the driver, NDK is the generic stack)?

    In the NSP I'm looking at, 1.10.00.03, the pfcbStatistics function is called after each transmit and receive with the following comment

    Uint32 EMAC_TxServiceCheck(Handle hEMAC)
    {
      ...
            /* Read the stats and reset to zero         */

            /* This is necessary to clear the interrupt */
            emacUpdateStats(pd);

            /* Tell the application */
            (*localDev.Config.pfcbStatistics)(pd->hApplication);

    Todd

  • In reply to ToddMullanix:

    I am using NSP 1_00_00_09, but it looks like we have modified code in the "ethdriver.c". I am not sure why it is modified (by the previous developer of the project) but I suspect it was done to allow promiscuous mode or possibly to allow a custom protocol field in the MAC header.

    Here is the diff from the original version of "ethdriver.c" (from 1.00.00.09) to my version:

    36c36
    < #define     PKT_MAX                     64
    ---
    > #define     PKT_MAX                     190
    405c405
    <
    ---
    > volatile Int32 pktSize = 0;
    422a423
    >                 pktSize = sizeof(hPkt);
    439c440,441
    <                                  EMAC_CONFIG_MODEFLG_RMII;
    ---
    >                                  EMAC_CONFIG_MODEFLG_RMII |
    >                                  EMAC_CONFIG_MODEFLG_PASSALL;


    Should this modification have a bad effect?

    Is there any other information you need in order to help on this issue?

    Thanks

    Corey

  • In reply to Corey Kasten:

    Thanks. Nothing jumps out. Do you have a simple PC or Linux app that sends the data? Can you attach it (along with the source)? I want to limit the variables when I test it out here (I found a board).

    Todd

  • In reply to ToddMullanix:

    Attached is the source for sending raw packets to the DSP.  Unzip the the archive and do:

    # cd ethtest

    # make clean

    # make

    To send packets, e.g. 5 packets and assuming eth1, do:

    ./eth-send   eth1    5

    There are a couple things to keep in mind that could prevent this from working with your c6748 receiving code.

    1. The code assumes the receiving device is in promiscuous mode, i.e. will accept packets with a non-matching destination MAC address.

    If this seems to be the problem, run instead, "eth-send-mac", as follows, and substitute the MAC address that the c6748 is set as:

    # ./eth-send-mac eth1 1 01:23:45:67:89:AB

    2. The code fills in a custom protocol field in the MAC header.  If this is the problem, look at line 21 of ethlib.c:

    #define CUSTOM_PROTOCOL 0x0801

    You should modify this to be a protocol that the c6748's raw ethernet stack will accept.

    For example, 0x0800 will identify the packet as an ordinary IP packet.

    Recompile and try again.

    Let me know if this works.

    Thanks

    Corey