This is the mail archive of the ecos-devel@sourceware.org mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: DMA capable Ethernet driver... (zero-copy)?


Nick Garnett wrote:

"Lars Povlsen" <lpovlsen@vitesse.com> writes:


> Hello!
>
> On working on a.k.a. Ethernet for eCos I was initially triggered by
> seeing a stack-allocated Ethernet header (redboot/stand-alone) to
> investigate other Ethernet drivers... I was sad to see only copying
> send() implementations until I saw the following comment in the eCos
> docs:
>
> "Note: In future, this function may be extended so that the data need
> not be copied by having the function return a "disposition" code (done,
> send pending, etc). At this point, you should move the data to some
> "safe" location before returning."
>
> Is this really the state of affairs? Copy no matter that the hardware
> may have all kinds of fancy scatter/gather frame DMA?


Direct DMA from the buffers should work since they should not be released until the driver calls the tx_done() function. A key is passed back and forth so that the calls can be properly matched. As an example the Intel 82544 driver does direct DMA transmission.

Thanks for the pointers - I'll have a look.


I have to admit that I'm not entirely sure what that note means, since
the functionality it describes is already mostly present in the
send()/tx_done() interface. Perhaps Gary, who probably wrote it
several years ago, could explain what he meant.

>
> I guess I may DMA the frame directly out - spinning on completion. Ouch!

No need to spin or even wait in the send() function. You just return
once the transmission has been started. Eventually an interrupt will
indicate completion, and cause the deliver function to be called, in
which you call tx_done().

See redboot/current/src/net/enet.c:

void
__enet_send(pktbuf_t *pkt, enet_addr_t *dest, int eth_type)
{
=>  eth_header_t eth_hdr;

   // Set up ethernet header
   memcpy(&eth_hdr.destination, dest, sizeof(enet_addr_t));
   memcpy(&eth_hdr.source, __local_enet_addr, sizeof(enet_addr_t));
   eth_hdr.type = htons(eth_type);

   eth_drv_write((char *)&eth_hdr, (char *)pkt->buf, pkt->pkt_bytes);
#ifdef ENET_STATS
   ++num_transmitted;
#endif
}

Unless the fragments (notably the first - the ethernet header) are squirelled away, it will be thrashed randomly by subsequent stack use.

So is this a bug?

Off course, other network stacks may have better characteristics, but at least redboot will exhibit random data thrashing if I use straight DMA. The occurrence will be dependent on how fast the DMA is started (other system/network) activity - which may be non-existing in the redboot - which could explain why this apparently is not a problem...?

---Lars

--
Nick Garnett                                 eCos Kernel Architect
http://www.ecoscentric.com            The eCos and RedBoot experts



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]