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