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.

Receiving Raw Ethernet Problem

I'm trying to run the client example on the 6678evm with raw ethernet. via the RJ45 connector.

I can send data successfully but do not receive any data...

(I'm sending the data from a FPGA or Unix program, using 0x300 protocol type. While I can capture the data on my PC the processor does not respond).

Any idea ?

Thanks,

Ami

  • Hi Ami,

    Is the incoming packet getting to the software on the 6678? For example, is the EMAC ISR running?

    Todd

  • How can I find that out ?

    I'm able to receive, with the client example, other packets like http. does this answer you question ?

    Thanks,

    Ami

    p.s. through the code, it seem like once we use raw ethernet, only protocols using the type field will be accepted unlike protocols using length field.

    Is that correct ?

  • Hi Ami,

    I just wanted to make sure the EMAC driver was working. If HTTP is working, the driver must be working.

    Why are you using 0x0300 for the EtherType? Here is a good discussion on this field: http://en.wikipedia.org/wiki/EtherType

    Can you look at the raweths variable in a Expressions/Watch Window? Here are the contents of this struct.

    typedef struct _rawethstat {
        /**
         * @brief   Total Raw Eth packets received by the Raw Eth
         *          Channel Mgmt Module.
         */
        UINT32      RcvTotal;       

        /**
         * @brief   Number of Raw Eth packets dropped by this module because
         *          of errors.
         */
        UINT32      RcvDrops;        

        /**
         * @brief   Total packets sent successfully by Raw Eth Module.
         */
        UINT32      SndTotal;       

        /**
         * @brief   Number of Sends failed due to memory allocation errors
         */
        UINT32      SndNoPacket;

    } RAWETHSTATS;

    Todd

  • Todd,

    Thanks for the reply.

    EthrType 0x300 was not my choice it's in the code example.

    I'm now trying to connect a FPGA to the DSP, so there is really no meaningful value to the EthrType.

    Just get it working..

    After a 500 loop of send and no response to receive here is the value of raweths:

    Thanks,

    Ami 

  • Can you confirm with 100% certainty that the remote side is sending a packet?

  • Yes. I tried to send data from a FPGA and from Unix PC.

    In both cases I can capture the data by connecting to my PC using Wireshark tool.

    Thanks,

    Ami

  • I'm looking in the 6678 EMAC driver to see what else to look at. Can you check the gRxCounter counter?

    It looks like the driver is checking to see if it a raw packet and calling PBMQ_enq on the raw rx queue. 

            if (protocol != ETHERTYPE_IP && protocol != ETHERTYPE_IPv6 && protocol != ETHERTYPE_VLAN
                && protocol != ETHERTYPE_PPPOECTL && protocol != ETHERTYPE_PPPOEDATA )
            {
                /* This is a raw packet, enqueue in Raw Rx Queue */
                PBMQ_enq( &ptr_pvt_data->pdi.PBMQ_rawrx, (PBM_Handle) hPkt);
            }
            else
            {   /* This is a normal IP packet. Enqueue in Rx Queue */
                PBMQ_enq( &ptr_pvt_data->pdi.PBMQ_rx, (PBM_Handle) hPkt );
            }

    These entries are popped off in the EmacPktService function which is called by the NDK thread. It all looks pretty straight-forward.

    What is the length of these packets? There is the following check in the NIMUReceivePacket (which is called in the EmacPktService function)

        if((ptr_pkt->ValidLen < ETH_MIN_PAYLOAD) || (ptr_pkt->ValidLen > ETH_MAX_PAYLOAD))
        {
            DbgPrintf(DBG_WARN,"NIMUReceivePacket: Bad Size; Payload is %d bytes", ptr_pkt->ValidLen);
            PBM_free(ptr_pkt);
            return -1;
        }

    Todd

  • Todd,

    Thanks for replying.

    The values of gRxCounter and gRxDropCounter are 0.

     

    ETH_MIN_PAYLOAD is set to 46 and ETH_MAX_PAYLOAD to  1514 (if _INCLUDE_JUMBOFRAME_SUPPORT is not defined). I have tried packets with different sizes but with no successes.

    For one that has no experience with NDK I'm not so sure everything looks so straight-forward. Not to mention that I've not done, (almost) any changes in code.

    To me the way all the directories and files are piled up in CCSv5 under 'include' without having an easy way to debug or even access through search, open declaration and etc, is a bit frustrating.

    By the way I realized that the _TMS320C6X is undefined in the project. Can this be related ?

    Thanks again,

    Ami

  • Hi Ami,

    The 6678 Ethernet driver requires some special configuration for raw (promiscuous) mode.  Please refer to the document linked to in the following thread:

    http://e2e.ti.com/support/embedded/bios/f/355/p/208123/741416.aspx

    Steve

  • Steve,

    Thank you for the response.

    Unfortunately this is the conclusion of the post you linked:

        " It is not mentioned in the MCSDK documents or source files for the C6678 GbE use,

          so I doubt that our drivers were written to support that mode. " 

    So lets try to move on.

    Unlike the above post in my application I have no interest in "promiscuous" / sniffing. I want to receive data from another device, (at this moment from a FPGA), using Ethernet but without having to implement all communication layers. In simple words 'raw ethernet'.

    I have no problem to define physical and data Link layers: MAC addresses (DA and SA) on both sides and Type/Length field. (Following the example, Type is now set to 0x300 but I've tried others too).

    I do not see any reason the device would not support this. To remind you I'm running the client example code without many changes. Looking through the code and the following documents it seems to be possible.

    http://www.ti.com/lit/ug/spru523h/spru523h.pdf

    http://www.ti.com/lit/ug/spru524h/spru524h.pdf

    I thought maybe I'm missing something in the setup which was not described in those documents.

    Thanks,

    Ami

  • Ami,

    I'm going to try to find the author of the driver and ask that they chime in on this thread and help you.

    ami adam said:
    Unlike the above post in my application I have no interest in "promiscuous" / sniffing. I want to receive data from another device, (at this moment from a FPGA), using Ethernet but without having to implement all communication layers. In simple words 'raw ethernet'.

    From what I understand, the hardware will drop raw frames by default. Putting the h/w into promiscuous mode allows all packets to come through.  So, you need to configure the hardware for promiscuous mode in order to prevent raw packets from being dropped in the data link layer.  This configuration is done in the driver as described in the document I linked in my previous post.

    ami adam said:
    I have no problem to define physical and data Link layers: MAC addresses (DA and SA) on both sides and Type/Length field. (Following the example, Type is now set to 0x300 but I've tried others too).

    In stack's NIMU layer (ti/ndk/stack/nimu/nimu.c), the 'Type' field of the Ethernet frame is checked against know values (for IP, ARP, IPv6) and then forwarded up the stack apporpriately (for raw processing in this case).  The default case tries to handle a raw packet.  This is handled by a switch statement:

        /* Dispatch the Packet to the appropriate protocol layer. */
        switch( Type )
        {
            case 0x800:
            {
                /* Received packet is an IP Packet. */
                IPRxPacket( ptr_pkt );
                break;
            }
            case 0x806:
            {
                /* Received packet is an ARP Packet. */
                LLIRxPacket( ptr_pkt );
                break;
            }
    #ifdef _INCLUDE_PPPOE_CODE
            case ETHERTYPE_PPPOE_CTRL:
            case ETHERTYPE_PPPOE_DATA:
            {
                /* Received packet is a PPP Packet (control or data) */
                pppoeInput( ptr_pkt );
                break;
            }
    #endif
    #ifdef _INCLUDE_IPv6_CODE
            case 0x86DD:
            {
                IPv6RxPacket (ptr_pkt);
                break;
            }
    #endif

            default:
            {
                /* Pass up the packet to Raw Ethernet Packet
                 * Handler Object.
                 */
                retVal = RawEthRxPacket (ptr_pkt);

                /* No Raw ethernet channel found matching the
                 * ethernet type in the packet/invalid packet.
                 * Free the packet.
                 */
                if (retVal != 0)
                {
                    /* Unrecognized packet; drop the packet */
                PBM_free( ptr_pkt );
                break;
                }
            }
        }

    ami adam said:
    (Following the example, Type is now set to 0x300 but I've tried others too)

    So, if another value for 'Type' is used and is not supported in the NIMU layer (i.e. not in the switch statement) then it will be dropped (and that's what would happen in the above code if you used a different 'Type' value).

    However, you won't even get to this point if the hardware is configured to drop raw packets at the data link layer.

    If you want to confirm this, you could check is to see if your packet is even reaching the NIMU layer.  Try placing a breakpoint at the call to RawEthRxPacket and see if you hit it.

    Steve

  • The NIMUReceivePacket function does not get called.

    Thanks again,

    Ami

    P.S. I can not replace breakpoints inside the above function. Only on the first line ?!

  • Thank God and thanks to your help I solved the problem.

    As Steve pointed out it seems like the driver drops the packages. But as I said in my case, I do not mind using the appropriate MAC DA and setting any Type field that's needed.

    I changed the Protocol Type that appears in the client code example from 0x300 to 0x888:

    sraw = socket (AF_RAWETH, SOCK_RAWETH, 0x888);

    Of course the packages where sent accordingly.

    (Another solution, less elegant to me.

    Transfer packages with known protocol e.g. 0x800.

    Add code in above function (nimo.c), So that in a given condition the Type field will be changed:

    / * e.g. Check if the packet is a from FPGA. * /     

    if (ptr_eth_header-> SrcMac [0] == ..)     

    {     

    Type = 0x300;     

    ptr_pkt-> EtherType = Type;     

     }

    / * Dispatch the Packet to the appropriate protocol layer. * /     

     switch (Type)     

    {         

    case 0x800:         

     {

    ..

     ).

    How amazing I get packages ..

    As Mitch posted:

    "NDK Raw Ethernet, not really raw?" (http://e2e.ti.com/support/embedded/bios/f/355/t/106536.aspx).

    However in terms of promiscuous mode on the C6678 device, this is the answer I received from in the C6000 Multicore DSP forum:

    http://e2e.ti.com/support/dsp/c6000_multi-core_dsps/f/639/p/237160/830827.aspx#830827

     

    Just to complete this subject. I want to know how can I, during running time, find out the MAC address of the device ?

    Thanks for everything,

    Ami

  • Hi Ami,

    By default, our NIMU driver should be in "promiscuous" mode - that is, the Packet Accelerator (PA) is configured to just forward any packet received to our queue buffers. It sounds like the packet is dropped before it even hit our NDK software stack.

    Can I ask you to double check the statistics from the GbE switch? We should see a steadily increasing amount of RXGOODFRAMES as you send packets to the board. I attached here a GEL file that prints out these statistic register values. Try pausing the application and running this script to see if there are any bad RX frames.

    -Ivan

    EDIT: It seems like you found your solution; sorry if I missed your previous message.

    8765.cpsw_stats_print.gel

  • Ivan,

    For my experience I want to follow your instructions, anyway.

    I did not use gel files in the past for output, so I apologize for these questions:

    1. Do I load this gel file in addition to the normal gel file?

    2. Where do I find the output ?

    Thanks,

    Ami

  • Ami,

    1. Yes

    2. On the CCS console, after you run the Print_All_Ethernet_Statistics script

    This gel file simply prints out the switch's statistics. I originally wanted to check if your packet was being dropped at the switch/PHY level for some reason. GEL scripts are helpful sometimes since you can modify and run them outside of your main application.

    Feel free to ask any more questions!

    -Ivan

  • Ami,

    Great news that you are getting the raw packets now!

    Just one thing to be careful about:

    ami adam said:

    (Another solution, less elegant to me.

    Transfer packages with known protocol e.g. 0x800.

    It sounds like you tried using this value for your raw packets.  0x800 is the type value for IPv4 so it's already reserved.  I think your other solution of using 0x888 is better, although you should double check that this number is not already reserved for the type field for another protocol.

    Steve

  • Ivan,

    Attached two output files.

    I sent three packets with appropriate MAC address and three without.

    One file was using 0x300 Type (in code and in packets) and the second with 0x888.

    3365.t0x300.txt

    8400.t0x888.txt 

    As you can see the files are identical.

    Ami

    P.S. Thanks for bring up the idea to debug with a gel file. This can be very helpful.

    How do you figure the registers addresses ?

  • Ami,

    I see the 6 packets on RXGOODFRAMES; that's a good sign. The results should be the same without any change in code, since this is just information on the switch level.

    For register addresses, refer to the datasheet. On page 22 of http://www.ti.com/lit/ds/symlink/tms320c6678.pdf, you can see that the Network Coprocessor registers are from 0x02000000 to 0x020FFFFF. On table 2-1 of the NetCP user's guide, http://www.ti.com/lit/ug/sprugz6/sprugz6.pdf, you find that the GbE Switch is offset 90000h. And finally, on table 3-28 of the GbE user's guide, http://www.ti.com/lit/ug/sprugv9b/sprugv9b.pdf, you can find the offset 300h and 400h for ethernet statistics.

    Let me know if this helps.

    -Ivan

  • Ivan,

    If there are 6 RXGOODFRAMES and NIMUReceivePacket function is not called then where does the 'switch level' appear ?

    Ami

  • Ami,

    When I say switch level, I meant that the GbE Switch in the 6678 EVM sees the packets. Instead of breakpointing at NIMUReceivePacket, I would try EmacRxPktISR. This is the function mapped to the accumulator interrupt.

    Simultaneously, I would go ahead and do a quick debug of the board without using NDK or NIMU at all. This could be done by modifying one of the PA example projects to be promiscuous.

    -Ivan

  • Ivan,

    I can't debug EmacRxPktISR function. Originally Todd had suggested to check the value of gRxCounter which happens to be 0.

    I'm not familiar enough with the PA examples and I could not find documentation.

    Searching through the forums I did find that :

    "The PA example does not program the PHY of the EVM nor does it program the SGMII's for PHY operation".

    http://e2e.ti.com/support/dsp/c6000_multi-core_dsps/f/639/t/216261.aspx

    So I gave up trying those examples..

    Do you think one of the PA examples fit my requirements more then the client example ? (I'm trying to receive lots of data with high frequency from a FPGA. Later I need to have also an interface from a PC).

    Or in other words what advantages / disadvantages is there using the NDK / NIMU ?

    Thanks,

    Ami

  • Ami,

    You should be able to breakpoint the EmacRxPktISR function. A likely reason that you're not able to is because you don't have debug symbols for the NIMU driver for your application. One of the tricks that I use is that I import the NIMU library and rebuild its debug configuration, and then rebuild the application using this library.

    It's true that the PA example do not touch the PHY or SGMII, but neither does NDK / NIMU. The PHY is handle through a default auto-negotiation, and the SGMII is configured by the GEL file (see configSGMIISerdes).

    Rather or not to use the NDK / NIMU comes down to what your applications are meant for. The NDK provides a good software stack and APIs for the web service, as seen in our HUA/Image Processing/Client examples. The NDK/NIMU also has a lot of ease-of-use functions, such as using sockets like you would on a PC application, or managing packet protocols. On the other hand, if you want the board to do purely packet processing, it might be simpler to start from just the PA examples.

    -Ivan