URL
https://opencores.org/ocsvn/openrisc/openrisc/trunk
Subversion Repositories openrisc
[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [doc/] [html/] [ref/] [io-eth-call-graph.html] - Rev 613
Go to most recent revision | Compare with Previous | Blame | View Log
<!-- Copyright (C) 2003 Red Hat, Inc. --> <!-- This material may be distributed only subject to the terms --> <!-- and conditions set forth in the Open Publication License, v1.0 --> <!-- or later (the latest version is presently available at --> <!-- http://www.opencontent.org/openpub/). --> <!-- Distribution of the work or derivative of the work in any --> <!-- standard (paper) book form is prohibited unless prior --> <!-- permission is obtained from the copyright holder. --> <HTML ><HEAD ><TITLE >Calling graph for Transmission and Reception</TITLE ><meta name="MSSmartTagsPreventParsing" content="TRUE"> <META NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.76b+ "><LINK REL="HOME" TITLE="eCos Reference Manual" HREF="ecos-ref.html"><LINK REL="UP" TITLE="Generic Ethernet Device Driver" HREF="io-eth-drv-generic1.html"><LINK REL="PREVIOUS" TITLE="Upper Layer Functions" HREF="io-eth-drv-upper-api.html"><LINK REL="NEXT" TITLE="SNMP" HREF="net-snmp.html"></HEAD ><BODY CLASS="SECT1" BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" VLINK="#840084" ALINK="#0000FF" ><DIV CLASS="NAVHEADER" ><TABLE SUMMARY="Header navigation table" WIDTH="100%" BORDER="0" CELLPADDING="0" CELLSPACING="0" ><TR ><TH COLSPAN="3" ALIGN="center" >eCos Reference Manual</TH ></TR ><TR ><TD WIDTH="10%" ALIGN="left" VALIGN="bottom" ><A HREF="io-eth-drv-upper-api.html" ACCESSKEY="P" >Prev</A ></TD ><TD WIDTH="80%" ALIGN="center" VALIGN="bottom" >Chapter 46. Generic Ethernet Device Driver</TD ><TD WIDTH="10%" ALIGN="right" VALIGN="bottom" ><A HREF="net-snmp.html" ACCESSKEY="N" >Next</A ></TD ></TR ></TABLE ><HR ALIGN="LEFT" WIDTH="100%"></DIV ><DIV CLASS="SECT1" ><H1 CLASS="SECT1" ><A NAME="IO-ETH-CALL-GRAPH">Calling graph for Transmission and Reception</H1 ><P >It may be worth clarifying further the flow of control in the transmit and receive cases, where the hardware driver does use interrupts and so DSRs to tell the “foreground” when something asynchronous has occurred.</P ><DIV CLASS="SECT2" ><H2 CLASS="SECT2" ><A NAME="IO-ETH-CALL-GRAPH-TX">Transmission</H2 ><P ></P ><OL TYPE="1" ><LI ><P >Some foreground task such as the application, SNMP “daemon”, DHCP management thread or whatever, calls into network stack to send a packet, or the stack decides to send a packet in response to incoming traffic such as a “ping” or <SPAN CLASS="ACRONYM" >ARP</SPAN > request.</P ></LI ><LI ><P >The driver calls the <TT CLASS="FUNCTION" ><TT CLASS="REPLACEABLE" ><I >HRDWR</I ></TT >_can_send()</TT > function in the hardware driver.</P ></LI ><LI ><P ><TT CLASS="FUNCTION" ><TT CLASS="REPLACEABLE" ><I >HRDWR</I ></TT >_can_send()</TT > returns the number of available "slots" in which it can store a pending transmit packet. If it cannot send at this time, the packet is queued outside the hardware driver for later; in this case, the hardware is already busy transmitting, so expect an interrupt as described below for completion of the packet currently outgoing.</P ></LI ><LI ><P >If it can send right now, <TT CLASS="REPLACEABLE" ><I >HRDWR</I ></TT >_send() is called. <TT CLASS="FUNCTION" ><TT CLASS="REPLACEABLE" ><I >HRDWR</I ></TT >_send()</TT > copies the data into special hardware buffers, or instructs the hardware to “send that.” It also remembers the key that is associated with this tx request.</P ></LI ><LI ><P >These calls return … time passes …</P ></LI ><LI ><P >Asynchronously, the hardware makes an interrupt to say “transmit is done.” The ISR quietens the interrupt source in the hardware and requests that the associated DSR be run.</P ></LI ><LI ><P >The DSR calls (or <SPAN CLASS="emphasis" ><I CLASS="EMPHASIS" >is</I ></SPAN >) the <TT CLASS="FUNCTION" >eth_drv_dsr()</TT > function in the generic driver.</P ></LI ><LI ><P ><TT CLASS="FUNCTION" >eth_drv_dsr()</TT > in the generic driver awakens the “Network Delivery Thread” which calls the deliver function <TT CLASS="REPLACEABLE" ><I >HRDWR</I ></TT >_deliver() in the driver.</P ></LI ><LI ><P >The deliver function realizes that a transmit request has completed, and calls the callback tx-done function <TT CLASS="FUNCTION" >(sc->funs->eth_drv->tx_done)()</TT > with the same key that it remembered for this tx.</P ></LI ><LI ><P >The callback tx-done function uses the key to find the resources associated with this transmit request; thus the stack knows that the transmit has completed and its resources can be freed.</P ></LI ><LI ><P >The callback tx-done function also enquires whether <TT CLASS="REPLACEABLE" ><I >HRDWR</I ></TT >_can_send() now says “yes, we can send” and if so, dequeues a further transmit request which may have been queued as described above. If so, then <TT CLASS="REPLACEABLE" ><I >HRDWR</I ></TT >_send() copies the data into the hardware buffers, or instructs the hardware to "send that" and remembers the new key, as above. These calls then all return to the “Network Delivery Thread” which then sleeps, awaiting the next asynchronous event.</P ></LI ><LI ><P >All done …</P ></LI ></OL ></DIV ><DIV CLASS="SECT2" ><H2 CLASS="SECT2" ><A NAME="IO-ETH-CALL-GRAPH-RX">Receive</H2 ><P ></P ><OL TYPE="1" ><LI ><P >Asynchronously, the hardware makes an interrupt to say “there is ready data in a receive buffer.” The ISR quietens the interrupt source in the hardware and requests that the associated DSR be run.</P ></LI ><LI ><P >The DSR calls (or <SPAN CLASS="emphasis" ><I CLASS="EMPHASIS" >is</I ></SPAN >) the <TT CLASS="FUNCTION" >eth_drv_dsr()</TT > function in the generic driver.</P ></LI ><LI ><P ><TT CLASS="FUNCTION" >eth_drv_dsr()</TT > in the generic driver awakens the “Network Delivery Thread” which calls the deliver function <TT CLASS="REPLACEABLE" ><I >HRDWR</I ></TT >_deliver() in the driver.</P ></LI ><LI ><P >The deliver function realizes that there is data ready and calls the callback receive function <TT CLASS="FUNCTION" >(sc->funs->eth_drv->recv)()</TT > to tell it how many bytes to prepare for.</P ></LI ><LI ><P >The callback receive function allocates memory within the stack (eg. <SPAN CLASS="TYPE" >MBUFs</SPAN > in BSD/Unix style stacks) and prepares a set of scatter-gather buffers that can accommodate the packet.</P ></LI ><LI ><P >It then calls back into the hardware driver routine <TT CLASS="REPLACEABLE" ><I >HRDWR</I ></TT >_recv(). <TT CLASS="REPLACEABLE" ><I >HRDWR</I ></TT >_recv() must copy the data from the hardware's buffers into the scatter-gather buffers provided, and return.</P ></LI ><LI ><P >The network stack now has the data in-hand, and does with it what it will. This might include recursive calls to transmit a response packet. When this all is done, these calls return, and the “Network Delivery Thread” sleeps once more, awaiting the next asynchronous event.</P ></LI ></OL ></DIV ></DIV ><DIV CLASS="NAVFOOTER" ><HR ALIGN="LEFT" WIDTH="100%"><TABLE SUMMARY="Footer navigation table" WIDTH="100%" BORDER="0" CELLPADDING="0" CELLSPACING="0" ><TR ><TD WIDTH="33%" ALIGN="left" VALIGN="top" ><A HREF="io-eth-drv-upper-api.html" ACCESSKEY="P" >Prev</A ></TD ><TD WIDTH="34%" ALIGN="center" VALIGN="top" ><A HREF="ecos-ref.html" ACCESSKEY="H" >Home</A ></TD ><TD WIDTH="33%" ALIGN="right" VALIGN="top" ><A HREF="net-snmp.html" ACCESSKEY="N" >Next</A ></TD ></TR ><TR ><TD WIDTH="33%" ALIGN="left" VALIGN="top" >Upper Layer Functions</TD ><TD WIDTH="34%" ALIGN="center" VALIGN="top" ><A HREF="io-eth-drv-generic1.html" ACCESSKEY="U" >Up</A ></TD ><TD WIDTH="33%" ALIGN="right" VALIGN="top" >SNMP</TD ></TR ></TABLE ></DIV ></BODY ></HTML >
Go to most recent revision | Compare with Previous | Blame | View Log