Reading the ethernet device directly

Discussion to talk about software related topics only.
Post Reply
hendrixj
Posts: 33
Joined: Thu Oct 23, 2008 11:39 am

Reading the ethernet device directly

Post by hendrixj »

I need to read the ethernet device directly (not through the IP stack). Does anyone know how to do that?
Thanks
rnixon
Posts: 833
Joined: Thu Apr 24, 2008 3:59 pm

Re: Reading the ethernet device directly

Post by rnixon »

At what level?
What is the end goal you are trying to accomplish?
hendrixj
Posts: 33
Joined: Thu Oct 23, 2008 11:39 am

Re: Reading the ethernet device directly

Post by hendrixj »

I'd like to build a small IP packet that fits entirely in one ethernet frame, and transfer that ethernet frame as a block of bytes to the ethernet device.
Ridgeglider
Posts: 513
Joined: Sat Apr 26, 2008 7:14 am

Re: Reading the ethernet device directly

Post by Ridgeglider »

It's easy to map a struct into and/or out of a UDP packet and therefore to skip all the details of the frame. Would that work? Why do you care about frames?
hendrixj
Posts: 33
Joined: Thu Oct 23, 2008 11:39 am

Re: Reading the ethernet device directly

Post by hendrixj »

I have an embedded software project to do in which I must "speak IP" over ethernet without the benefit of an IP stack.
User avatar
Chris Ruff
Posts: 222
Joined: Thu Apr 24, 2008 4:09 pm
Location: topsail island, nc
Contact:

Re: Reading the ethernet device directly

Post by Chris Ruff »

ok. i'll byte...

Why?
Does timing require this?
Are you doing this on a tiny processor?
Is your customer requiring this?
Is this a 'must hack this' project?

Since the entire world of TCP/IP, UDP, uC/OS and everything else is there in NB, why the bare metal thing?

Chris
Real Programmers don't comment their code. If it was hard to write, it should be hard to understand
hendrixj
Posts: 33
Joined: Thu Oct 23, 2008 11:39 am

Re: Reading the ethernet device directly

Post by hendrixj »

I simply have to.

Ether_ProcessTask() (in ethernet.cpp for MOD2370) maybe running in it's own thread to read the device.
Perhaps this call ("pool_buffer *pb = ( pool_buffer * ) OSFifoPend( &FecFifo, wait );") is getting the ethernet data from the driver.
User avatar
lgitlitz
Posts: 331
Joined: Wed Apr 23, 2008 11:43 am
Location: San Diego, CA
Contact:

Re: Reading the ethernet device directly

Post by lgitlitz »

Hi,

If your packets are going to contain an IP header and checksum then you should add your code to recognize your packets in "void IPTask( void *p )" in ip.cpp. This is where we parse the IP packets to either ICMP, UDP, TCP or we throw them away.

If they are not going to have a standard IP header and checksum then you probably want to dig into the Ethernet.cpp file in the function "void DoRX( PoolPtr pp, WORD ocount )". In this function we do initial check if the packet is a valid "IP" packet with a good check sum or a valid "ARP" packet.

In the end you will want another task running similar to our TCP task. You should then have either the Ethernet or IP task relaying the packet to that task. If you simply add a new case in the switch statements in the functions I pointed out then you can have the normal network stack working with the ability to receive your special packets.

- Larry
hendrixj
Posts: 33
Joined: Thu Oct 23, 2008 11:39 am

Re: Reading the ethernet device directly

Post by hendrixj »

Here are the steps I ended up using to gain access to the Ethernet device directly:

Defined myProcessArp: void myProcessArp(PoolPtr p, PEFRAME ethernetFramePtr )
Call "FreeBuffer( p );" as final line.

Defined myProcessPacket: void myProcessPacket( PoolPtr p, PEFRAME ethernetFramePtr, WORD checksum )
Call "FreeBuffer( p );" as final line.

To set up, DO NOT invoke "InitializeStack()". Instead:
InitBuffers(); // buffers.h
InitializeNetwork( &myProcessPacket, &myProcessArp ); // netinterface.h
InterfaceBlock *pifb = GetInterFaceBlock(); // netinterface.h
if ( pifb != NULL )
{
pifb->netIP = 0xC0A8015A; // 192.168.1.90
pifb->netIpMask = 0xFFFFFF00; // 255.255.255.0
pifb->netIpGate = 0x0000; // 0.0.0.0
pifb->netDNS = 0x0000; // 0.0.0.0
}

Once you do this, ARP requests show up in the myProcessArp and IP messages show up in myProcessPacket. Both show up as Ethernet frames.

You can send an Ethernet frame out interface 1, via:
TransmitBuffer( &outbuff, 1);
where outbuff is of type pool_buffer.
You don't have to calculated the crc32 for the outgoing frame.

Pretty slick.
User avatar
lgitlitz
Posts: 331
Joined: Wed Apr 23, 2008 11:43 am
Location: San Diego, CA
Contact:

Re: Reading the ethernet device directly

Post by lgitlitz »

Nicely done. To get a bit of performance boost you might want to use the check sum functions in IP.cpp:
WORD GetSum( PWORD addr, WORD count );
WORD GetSum20( PDWORD addr );
WORD GetSumHdr( PsudeoHeader &hdr, PWORD addr, WORD count );
These functions were written in Coldfire assembly and tested to get high performance.

Also, since you are no longer using the TCP or IP tasks you can remove their task stacks from SRAM. This can be done by commenting out FAST_IP_STACK and FAST_TCP_STACK in constants.h and then recompiling teh system files. The buffer system will automatically use the extra free space for additional buffers in the fast SRAM.

-Larry
Post Reply