]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - packages/io/eth/v2_0/doc/ethdrv.sgml
Initial revision
[karo-tx-redboot.git] / packages / io / eth / v2_0 / doc / ethdrv.sgml
1 <!-- {{{ Banner                         -->
2
3 <!-- =============================================================== -->
4 <!--                                                                 -->
5 <!--     ethdrv.sgml                                                 -->
6 <!--                                                                 -->
7 <!--     eCos generic ethernet driver documentation                  -->
8 <!--                                                                 -->
9 <!-- =============================================================== -->
10 <!-- ####COPYRIGHTBEGIN####                                          -->
11 <!--                                                                 -->
12 <!-- =============================================================== -->
13 <!-- Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.  -->
14 <!-- This material may be distributed only subject to the terms      -->
15 <!-- and conditions set forth in the Open Publication License, v1.0  -->
16 <!-- or later (the latest version is presently available at          -->
17 <!-- http://www.opencontent.org/openpub/)                            -->
18 <!-- Distribution of the work or derivative of the work in any       -->
19 <!-- standard (paper) book form is prohibited unless prior           -->
20 <!-- permission obtained from the copyright holder                   -->
21 <!-- =============================================================== -->
22 <!--                                                                 -->      
23 <!-- ####COPYRIGHTEND####                                            -->
24 <!-- =============================================================== -->
25 <!-- #####DESCRIPTIONBEGIN####                                       -->
26 <!--                                                                 -->
27 <!-- ####DESCRIPTIONEND####                                          -->
28 <!-- =============================================================== -->
29
30 <!-- }}} -->
31
32 <part id="io-eth-drv-generic">
33 <title>Ethernet Device Drivers</title>
34 <chapter id="io-eth-drv-generic1">
35 <title>Generic Ethernet Device Driver</title>
36 <sect1 id="io-eth-drv-api">
37 <title>Generic Ethernet API</title>
38 <para>
39 This section provides a simple description of how to write a low-level,
40 hardware dependent ethernet driver.
41 </para>
42 <para>
43 There is a high-level driver (which is only code &mdash; with no state of
44 its own) that is part of the stack.  There will be one or more low-level
45 drivers tied to the actual network hardware.  Each of these drivers
46 contains one or more driver instances.  The intent is that the
47 low-level drivers know nothing of the details of the stack that will be
48 using them.  Thus, the same driver can be used by the
49 <productname>eCos</productname>
50 supported
51 <acronym>TCP/IP</acronym>
52 stack,
53 <productname>RedBoot</productname>,
54 or any other, with no changes.
55 </para>
56 <para>
57 A driver instance is contained within a
58 <type>struct eth_drv_sc</type>:
59 <programlisting>
60 struct eth_hwr_funs {
61     // Initialize hardware (including startup)
62     void (*start)(struct eth_drv_sc *sc,
63                   unsigned char *enaddr,
64                   int flags);
65     // Shut down hardware
66     void (*stop)(struct eth_drv_sc *sc);
67     // Device control (ioctl pass-thru)
68     int  (*control)(struct eth_drv_sc *sc,
69                     unsigned long key,
70                     void *data,
71                     int   data_length);
72     // Query - can a packet be sent?
73     int  (*can_send)(struct eth_drv_sc *sc);
74     // Send a packet of data
75     void (*send)(struct eth_drv_sc *sc,
76                  struct eth_drv_sg *sg_list,
77                  int sg_len,
78                  int total_len,
79                  unsigned long key);
80     // Receive [unload] a packet of data
81     void (*recv)(struct eth_drv_sc *sc,
82                  struct eth_drv_sg *sg_list,
83                  int sg_len);
84     // Deliver data to/from device from/to stack memory space
85     // (moves lots of memcpy()s out of DSRs into thread)
86     void (*deliver)(struct eth_drv_sc *sc);
87     // Poll for interrupts/device service
88     void (*poll)(struct eth_drv_sc *sc);
89     // Get interrupt information from hardware driver
90     int (*int_vector)(struct eth_drv_sc *sc);
91     // Logical driver interface
92     struct eth_drv_funs *eth_drv, *eth_drv_old;
93 };
94
95 struct eth_drv_sc {
96     struct eth_hwr_funs *funs;
97     void                *driver_private;
98     const char          *dev_name;
99     int                  state;
100     struct arpcom        sc_arpcom; /* ethernet common */
101 };
102 </programlisting>
103 </para><note><para>
104 If you have two instances of the same hardware, you only need one
105 <type>struct eth_hwr_funs</type> shared between them.
106 </para></note><para>
107 There is another structure which is used to communicate with the rest of
108 the stack:
109 <programlisting>
110 struct eth_drv_funs {
111     // Logical driver - initialization
112     void (*init)(struct eth_drv_sc *sc, 
113                  unsigned char *enaddr);
114     // Logical driver - incoming packet notifier
115     void (*recv)(struct eth_drv_sc *sc, 
116                  int total_len);
117     // Logical driver - outgoing packet notifier
118     void (*tx_done)(struct eth_drv_sc *sc, 
119                     CYG_ADDRESS key, 
120                     int status);
121 };
122 </programlisting>
123 Your driver does <emphasis>not</emphasis> create an instance of this
124 structure.  It is provided for driver code to use in the
125 <type>eth_drv</type> member of the function record.
126 Its usage is described below in <xref linkend=io-eth-drv-upper-api>
127 </para><para>
128 One more function completes the API with which your driver communicates
129 with the rest of the stack:
130 <programlisting>
131 extern void eth_drv_dsr(cyg_vector_t vector,
132                         cyg_ucount32 count,
133                         cyg_addrword_t data);
134 </programlisting>
135 </para><para>
136 This function is designed so that it can be registered as the DSR for your
137 interrupt handler.  It will awaken the
138 &ldquo;Network Delivery Thread&rdquo;
139 to call your deliver routine.  See <xref linkend=io-eth-drv-api-deliver>.
140 </para><para>
141 You create an instance of <type>struct eth_drv_sc</type>
142 using the
143 <function>ETH_DRV_SC()</function>
144 macro which
145 sets up the structure, including the prototypes for the functions, etc.
146 By doing things this way, if the internal design of the ethernet drivers
147 changes (e.g. we need to add a new low-level implementation function),
148 existing drivers will no longer compile until updated.  This is much
149 better than to have all of the definitions in the low-level drivers
150 themselves and have them be (quietly) broken if the interfaces change.
151 </para><para>
152 The &ldquo;magic&rdquo;
153 which gets the drivers started (and indeed, linked) is
154 similar to what is used for the I/O subsystem.
155 This is done using the
156 <function>NETDEVTAB_ENTRY()</function>
157 macro, which defines an initialization function
158 and the basic data structures for the low-level driver.
159 </para>
160 <para><programlisting>
161   typedef struct cyg_netdevtab_entry {
162       const char        *name;
163       bool             (*init)(struct cyg_netdevtab_entry *tab);
164       void              *device_instance;
165       unsigned long     status;
166   } cyg_netdevtab_entry_t;
167 </programlisting>
168 The <varname>device_instance</varname>
169 entry here would point to the <type>struct eth_drv_sc</type>
170 entry previously defined.  This allows the network driver
171 setup to work with any class of driver, not just ethernet drivers.  In
172 the future, there will surely be serial <acronym>PPP</acronym>
173 drivers, etc.  These will
174 use the <function>NETDEVTAB_ENTRY()</function>
175 setup to create the basic driver, but they will
176 most likely be built on top of other high-level device driver layers.
177 </para><para>
178 To instantiate itself, and connect it to the system,
179 a hardware driver will have a template
180 (boilerplate) which looks something like this:
181 <programlisting>
182 #include &lt;cyg/infra/cyg_type.h&gt;
183 #include &lt;cyg/hal/hal_arch.h&gt;
184 #include &lt;cyg/infra/diag.h&gt;
185 #include &lt;cyg/hal/drv_api.h&gt;
186 #include &lt;cyg/io/eth/netdev.h&gt;
187 #include &lt;cyg/io/eth/eth_drv.h&gt;
188
189 ETH_DRV_SC(<replaceable>DRV</replaceable>_sc,
190            0,             // No driver specific data needed
191            "eth0",        // Name for this interface
192            <replaceable>HRDWR</replaceable>_start,
193            <replaceable>HRDWR</replaceable>_stop,
194            <replaceable>HRDWR</replaceable>_control,
195            <replaceable>HRDWR</replaceable>_can_send
196            <replaceable>HRDWR</replaceable>_send,
197            <replaceable>HRDWR</replaceable>_recv,
198            <replaceable>HRDWR</replaceable>_deliver,
199            <replaceable>HRDWR</replaceable>_poll,
200            <replaceable>HRDWR</replaceable>_int_vector
201 );
202
203 NETDEVTAB_ENTRY(<replaceable>DRV</replaceable>_netdev, 
204                 "<replaceable>DRV</replaceable>", 
205                 <replaceable>DRV_HRDWR</replaceable>_init, 
206                 &amp;<replaceable>DRV</replaceable>_sc);
207 </programlisting>
208 </para><para>
209 This, along with the referenced functions, completely define the driver.
210 </para><note><para>
211 If one needed the same low-level driver to handle
212 multiple similar hardware interfaces, you would need multiple invocations
213 of the
214 <function>ETH_DRV_SC()</function>/<function>NETDEVTAB_ENTRY()</function>
215 macros.  You would add a pointer
216 to some instance specific data, e.g. containing base addresses, interrupt
217 numbers, etc, where the
218 <programlisting>
219         0, // No driver specific data
220 </programlisting>
221 is currently.
222 </para></note>
223 </sect1>
224 <sect1 id="io-eth-drv-api-funcs">
225 <title>Review of the functions</title>
226 <para>
227 Now a brief review of the functions.  This discussion will use generic
228 names for the functions &mdash; your driver should use hardware-specific
229 names to maintain uniqueness against any other drivers.
230 </para>
231 <sect2 id="io-eth-drv-api-init">
232 <title>Init function</title>
233 <para>
234 <programlisting>
235 static bool <replaceable>DRV_HDWR</replaceable>_init(struct cyg_netdevtab_entry *tab)
236 </programlisting>
237 This function is called as part of system initialization.  Its primary
238 function is to decide if the hardware (as indicated via
239 <type>tab-&gt;device_instance</type>)
240 is working and if the interface needs to be made
241 available in the system.  If this is the case, this function needs to
242 finish with a call to the ethernet driver function:
243 <programlisting>
244     struct eth_drv_sc *sc = (struct eth_drv_sc *)tab->device_instance;
245     <replaceable>....initialization code....</replaceable>
246     // Initialize upper level driver
247     (sc-&gt;funs-&gt;eth_drv-&gt;init)( sc, unsigned char *enaddr );
248 </programlisting>
249 where <parameter>enaddr</parameter>
250 is a pointer to the ethernet station address for this unit, to inform
251 the stack of this device's readiness and availability.
252 </para>
253 <note><para>The ethernet station address
254 (<acronym>ESA</acronym>)
255 is supposed to be a
256 world-unique, 48 bit address for this particular ethernet interface.
257 Typically it is provided by the board/hardware manufacturer in ROM.
258 </para>
259 <para>
260 In many packages it is possible for the
261 <acronym>ESA</acronym>
262 to be set from RedBoot,
263 (perhaps from 'fconfig' data), hard-coded from
264 <acronym>CDL</acronym>, or from an <acronym>EPROM</acronym>.
265 A driver should choose a run-time specified
266 <acronym>ESA</acronym>
267 (e.g. from RedBoot)
268 preferentially, otherwise (in order) it should use a <acronym>CDL</acronym> specified
269 <acronym>ESA</acronym>
270 if one has been set, otherwise an <acronym>EPROM</acronym> set
271 <acronym>ESA</acronym>, or otherwise
272 fail. See the <filename>cl/cs8900a</filename>
273 ethernet driver for an example.
274 </para></note>
275 </sect2>
276 <sect2 id="io-eth-drv-api-start">
277 <title>Start function</title>
278 <para>
279 <programlisting>
280 static void
281 <replaceable>HRDWR</replaceable>_start(struct eth_drv_sc *sc, unsigned char *enaddr, int flags)
282 </programlisting>
283 This function is called, perhaps much later than system initialization
284 time, when the system (an application) is ready for the interface to
285 become active.  The purpose of this function is to set up the hardware
286 interface to start accepting packets from the network and be able to
287 send packets out.  The receiver hardware should not be enabled prior to
288 this call.
289 </para><note><para>This function will be called whenever the
290 up/down state of the logical interface changes, e.g. when the IP address
291 changes, or when promiscuous mode is selected by means of an
292 <function>ioctl()</function> call in the application.
293 This may occur more than once, so this function needs to
294 be prepared for that case.
295 </para></note><note><para>
296 In future, the <parameter>flags</parameter>
297 field (currently unused) may be used to tell the
298 function how to start up, e.g. whether interrupts will be used,
299 alternate means of selecting promiscuous mode etc.
300 </para></note>
301 </sect2>
302 <sect2 id="io-eth-drv-api-stop">
303 <title>Stop function</title>
304 <para>
305 <programlisting>
306 static void <replaceable>HRDWR</replaceable>_stop(struct eth_drv_sc *sc)
307 </programlisting>
308 This function is the inverse of &ldquo;start.&rdquo;
309 It should shut down the hardware, disable the receiver, and keep it from
310 interacting with the physical network.
311 </para>
312 </sect2>
313 <sect2 id="io-eth-drv-api-control">
314 <title>Control function</title>
315 <para>
316 <programlisting>
317 static int
318 <replaceable>HRDWR</replaceable>_control(
319         struct eth_drv_sc *sc, unsigned long key,
320         void *data, int len)
321 </programlisting>
322 This function is used to perform low-level &ldquo;control&rdquo;
323 operations on the
324 interface.  These operations would typically be initiated via
325 <function>ioctl()</function> calls in the BSD
326 stack, and would be anything that might require the hardware setup to
327 change (i.e. cannot be performed totally by the
328 platform-independent layers).
329 </para><para>
330 The <parameter>key</parameter> parameter selects the operation, and the
331 <parameter>data</parameter> and <parameter>len</parameter> params point describe,
332 as required, some data for the operation in question.
333 </para>
334 <variablelist><title>Available Operations:</title>
335 <varlistentry><term>ETH_DRV_SET_MAC_ADDRESS</term>
336 <listitem><para>
337 This operation sets the ethernet station address (ESA or MAC) for the
338 device.  Normally this address is kept in non-volatile memory and is
339 unique in the world.  This function must at least set the interface to
340 use the new address.  It may also update the NVM as appropriate.
341 </para>
342 </listitem>
343 </varlistentry>
344 <varlistentry>
345 <term>ETH_DRV_GET_IF_STATS_UD</term>
346 <term>ETH_DRV_GET_IF_STATS</term>
347 <listitem><para>
348 These acquire a set of statistical counters from the interface, and write
349 the information into the memory pointed to by <parameter>data</parameter>.
350 The &ldquo;UD&rdquo; variant explicitly instructs the driver to acquire
351 up-to-date values.  This is a separate option because doing so may take
352 some time, depending on the hardware.
353 </para><para>
354 The definition of the data structure is in
355 <filename>cyg/io/eth/eth_drv_stats.h</filename>.
356 </para><para>
357 This call is typically made by SNMP, see <xref linkend=net-snmp-ecos-port>.
358 </para>
359 </listitem>
360 </varlistentry>
361 <varlistentry><term>ETH_DRV_SET_MC_LIST</term>
362 <listitem><para>
363 This entry instructs the device to set up multicast packet filtering
364 to receive only packets addressed to the multicast ESAs in the list pointed
365 to by <parameter>data</parameter>.
366 </para><para>
367 The format of the data is a 32-bit count of the ESAs in the list, followed
368 by packed bytes which are the ESAs themselves, thus:
369 <programlisting>
370 #define ETH_DRV_MAX_MC 8
371 struct eth_drv_mc_list {
372     int len;
373     unsigned char addrs[ETH_DRV_MAX_MC][ETHER_ADDR_LEN];
374 };
375 </programlisting>
376 </para>
377 </listitem>
378 </varlistentry>
379 <varlistentry><term>ETH_DRV_SET_MC_ALL</term>
380 <listitem><para>
381 This entry instructs the device to receive all multicast packets, and
382 delete any explicit filtering which had been set up.
383 </para>
384 </listitem>
385 </varlistentry>
386 </variablelist>
387 <para>
388 This function should return zero if the specified operation was
389 completed successfully.  It should return non-zero if the operation
390 could not be performed, for any reason.
391 </para>
392 </sect2>
393 <sect2 id="io-eth-drv-api-can-send">
394 <title>Can-send function</title>
395 <para>
396 <programlisting>
397 static int <replaceable>HRDWR</replaceable>_can_send(struct eth_drv_sc *sc)
398 </programlisting>
399 This function is called to determine if it is possible to start the
400 transmission of a packet on the interface.  Some interfaces will allow
401 multiple packets to be "queued" and this function allows for the highest
402 possible utilization of that mode.
403 </para><para>
404 Return the number of packets which could be accepted at this time, zero
405 implies that the interface is saturated/busy.
406 </para>
407 </sect2>
408 <sect2 id="io-eth-drv-api-send">
409 <title>Send function</title>
410 <para>
411 <programlisting>
412 struct eth_drv_sg {
413     CYG_ADDRESS  buf;
414     CYG_ADDRWORD len;
415 };
416
417 static void
418 <replaceable>HRDWR</replaceable>_send(
419         struct eth_drv_sc *sc,
420         struct eth_drv_sg *sg_list, int sg_len,
421         int total_len, unsigned long key)
422 </programlisting>
423 This function is used to send a packet of data to the network.  It is
424 the responsibility of this function to somehow hand the data over to the
425 hardware interface.  This will most likely require copying, but just the
426 address/length values could be used by smart hardware.
427 </para><note><para>
428 All data in/out of the driver is specified via a
429 &ldquo;scatter-gather&rdquo;
430 list.  This is just an array of address/length pairs which describe
431 sections of data to move (in the order given by the array), as in the
432 <type>struct eth_drv_sg</type> defined above and pointed to by
433 <parameter>sg_list</parameter>.
434 </para></note><para>
435 Once the data has been successfully sent by the interface (or if an
436 error occurs), the driver should call
437 <function>(sc->funs->eth_drv->tx_done)()</function>
438 (see <xref linkend=io-eth-drv-tx-done>)
439 using the specified <parameter>key</parameter>.
440 Only then will the upper layers release the resources
441 for that packet and start another transmission.
442 </para><note><para>
443 In future, this function may be extended so that the data need not be
444 copied by having the function return a &ldquo;disposition&rdquo; code
445 (done, send pending, etc).  At this point, you should move the data to some
446 &ldquo;safe&rdquo; location before returning.
447 </para></note>
448 </sect2>
449 <sect2 id="io-eth-drv-api-deliver">
450 <title>Deliver function</title>
451 <para>
452 <programlisting>
453 static void
454 <replaceable>HRDWR</replaceable>_deliver(struct eth_drv_sc *sc)
455 </programlisting>
456 This function is called from the &ldquo;Network Delivery Thread&rdquo; in
457 order to let the device driver do the time-consuming work associated with
458 receiving a packet &mdash; usually copying the entire packet from the
459 hardware or a special memory location into the network stack's memory.
460 </para><para>
461 After handling any outstanding incoming packets or pending transmission
462 status, it can unmask the device's interrupts, and free any relevant
463 resources so it can process further packets.
464 </para><para>
465 It will be called when the interrupt handler for the network device
466 has called
467 <programlisting>
468     eth_drv_dsr( vector, count, (cyg_addrword_t)sc );
469 </programlisting>
470 to alert the system that &ldquo;something requires attention.&rdquo;
471 This <function>eth_drv_dsr()</function> call must occur from within the
472 interrupt handler's DSR (not the ISR) or actually <emphasis>be</emphasis>
473 the DSR, whenever it is determined that
474 the device needs attention from the foreground.  The third parameter
475 (<parameter>data</parameter> in the prototype of
476 <function>eth_drv_dsr()</function> <emphasis>must</emphasis>
477 be a valid <type>struct eth_drv_sc</type> pointer <varname>sc</varname>.
478 </para><para>
479 The reason for this slightly convoluted train of events is to keep the DSR
480 (and ISR) execution time as short as possible, so that other activities of
481 higher priority than network servicing are not denied the CPU by network
482 traffic.
483 </para><para>
484 To deliver a newly-received packet into the network stack, the deliver
485 routine must call
486 <programlisting>
487 (sc->funs->eth_drv->recv)(sc, len);
488 </programlisting>
489 which will in turn call the receive function, which we talk about next.
490 See also <xref linkend=io-eth-drv-upper-recv> below.
491 </para>
492 </sect2>
493 <sect2 id="io-eth-drv-api-recv">
494 <title>Receive function</title>
495 <para>
496 <programlisting>
497 static void
498 <replaceable>HRDWR</replaceable>_recv(
499         struct eth_drv_sc *sc,
500         struct eth_drv_sg *sg_list, int sg_len)
501 </programlisting>
502 This function is a call back, only invoked after the
503 upper-level function
504 <programlisting>
505 (sc->funs->eth_drv->recv)(struct eth_drv_sc *sc, int total_len)
506 </programlisting>
507 has been called itself from your deliver function when it knows that a
508 packet of data is available on the
509 interface.  The <function>(sc->funs->eth_drv->recv)()</function>
510 function then arranges network buffers
511 and structures for the data and then calls
512 <function><replaceable>HRDWR</replaceable>_recv()</function> to actually
513 move the data from the interface.
514 </para><para>
515 A scatter-gather list (<type>struct eth_drv_sg</type>) is used once more,
516 just like in the send case.
517 </para>
518 </sect2>
519 <sect2 id="io-eth-drv-api-poll">
520 <title>Poll function</title>
521 <para>
522 <programlisting>
523 static void
524 <replaceable>HRDWR</replaceable>_poll(struct eth_drv_sc *sc)
525 </programlisting>
526 This function is used when in a non-interrupt driven system, e.g. when
527 interrupts are completely disabled. This allows the driver time to check
528 whether anything needs doing either for transmission, or to check if
529 anything has been received, or if any other processing needs doing.
530 </para><para>
531 It is perfectly correct and acceptable for the poll function to look like
532 this:
533 <programlisting>
534 static void
535 <replaceable>HRDWR</replaceable>_poll(struct eth_drv_sc *sc)
536 {
537    <replaceable>my_interrupt_ISR</replaceable>(sc);
538    <replaceable>HRDWR</replaceable>_deliver(struct eth_drv_sc *sc);
539 }
540 </programlisting>
541 provided that both the ISR and the deliver functions are idempotent and
542 harmless if called when there is no attention needed by the hardware.  Some
543 devices might not need a call to the ISR here if the deliver function
544 contains all the &ldquo;intelligence.&rdquo;
545 </para>
546 </sect2>
547 <sect2 id="io-eth-drv-api-int-vector">
548 <title>Interrupt-vector function</title>
549 <para>
550 <programlisting>
551 static int
552 <replaceable>HRDWR</replaceable>_int_vector(struct eth_drv_sc *sc)
553 </programlisting>
554 This function returns the interrupt vector number used for receive
555 interrupts.
556 This is so that the common GDB stubs can detect when to check
557 for incoming &ldquo;CTRL-C&rdquo; packets (used to asynchronously
558 halt the application) when debugging over ethernet.
559 The GDB stubs need to know which interrupt the ethernet device uses
560 so that they can mask or unmask that interrupt as required.
561 </para>
562 </sect2>
563 </sect1>
564 <sect1 id=io-eth-drv-upper-api>
565 <title>Upper Layer Functions</title>
566 <para>
567 Upper layer functions are called by drivers to deliver received packets
568 or transmission completion status back up into the network stack.
569 </para><para>
570 These functions are defined by the hardware independent upper layers of
571 the networking driver support.  They are present to hide the interfaces
572 to the actual networking stack so that the hardware drivers may
573 be used by different network stack implementations without change.
574 </para><para>
575 These functions require a pointer to a <type>struct eth_drv_sc</type>
576 which describes the interface at a logical level.  It is assumed that the
577 low level hardware driver will keep track of this pointer so
578 it may be passed &ldquo;up&rdquo; as appropriate.
579 </para>
580 <sect2 id="io-eth-drv-upper-init">
581 <title>Callback Init function</title>
582 <para>
583 <programlisting>
584 void (sc->funs->eth_drv->init)(
585                 struct eth_drv_sc *sc, unsigned char *enaddr)
586 </programlisting>
587 This function establishes the device at initialization time.
588 It should be called once per device instance only, from the
589 initialization function, if all is well
590 (see <xref linkend=io-eth-drv-api-init>).
591 The hardware should be totally initialized
592 (<emphasis>not</emphasis> &ldquo;started&rdquo;)
593 when this function is called.
594 </para>
595 </sect2>
596 <sect2 id="io-eth-drv-tx-done">
597 <title>Callback Tx-Done function</title>
598 <para>
599 <programlisting>
600 void (sc->funs->eth_drv->tx_done)(
601                 struct eth_drv_sc *sc,
602                 unsigned long key, int status)
603 </programlisting>
604 This function is called when a packet completes transmission on the
605 interface.  The <parameter>key</parameter>
606 value must be one of the keys provided to
607 <function><replaceable>HRDWR</replaceable>_send()</function>
608 above.  The value <parameter>status</parameter> should be non-zero
609 (details currently undefined) to indicate that an error occurred during the
610 transmission, and zero if all was well.
611 </para><para>
612 It should be called from the deliver function
613 (see <xref linkend=io-eth-drv-api-deliver>)
614 or poll function
615 (see <xref linkend=io-eth-drv-api-poll>).
616 </para>
617 </sect2>
618 <sect2 id="io-eth-drv-upper-recv">
619 <title>Callback Receive function</title>
620 <para>
621 <programlisting>
622 void (sc->funs->eth_drv->recv)(struct eth_drv_sc *sc, int len)
623 </programlisting>
624 This function is called to indicate that a packet of length
625 <parameter>len</parameter> has
626 arrived at the interface.
627 The callback
628 <function><replaceable>HRDWR</replaceable>_recv()</function> function
629 described above will be used to actually unload the data from the
630 interface into buffers used by the device independent layers.
631 </para><para>
632 It should be called from the deliver function
633 (see <xref linkend=io-eth-drv-api-deliver>)
634 or poll function
635 (see <xref linkend=io-eth-drv-api-poll>).
636 </para>
637 </sect2>
638 </sect1>
639 <sect1 id=io-eth-call-graph>
640 <title>Calling graph for Transmission and Reception</title>
641 <para>
642 It may be worth clarifying further the flow of control in the transmit and
643 receive cases, where the hardware driver does use interrupts and so DSRs to
644 tell the &ldquo;foreground&rdquo; when something asynchronous has occurred.
645 </para>
646 <sect2 id=io-eth-call-graph-tx>
647 <title>Transmission</title>
648 <orderedlist>
649 <listitem><para>
650 Some foreground task such as the application, SNMP &ldquo;daemon&rdquo;,
651 DHCP management thread or whatever, calls into network stack to send a
652 packet, or the stack decides to send a packet in response to incoming
653 traffic such as a &ldquo;ping&rdquo; or <acronym>ARP</acronym> request.
654 </para></listitem>
655 <listitem><para>
656 The driver calls the
657 <function><replaceable>HRDWR</replaceable>_can_send()</function>
658 function in the hardware driver.
659 </para></listitem>
660 <listitem><para>
661 <function><replaceable>HRDWR</replaceable>_can_send()</function>
662 returns the number of available "slots" in which it
663 can store a pending transmit packet.
664 If it cannot send at this time, the packet is queued outside the
665 hardware driver for later; in this case, the hardware is already busy
666 transmitting, so expect an interrupt as described below for completion
667 of the packet currently outgoing.
668 </para></listitem>
669 <listitem><para>
670 If it can send right now, <replaceable>HRDWR</replaceable>_send() is called.
671 <function><replaceable>HRDWR</replaceable>_send()</function> copies the
672 data into special hardware buffers, or instructs the hardware to
673 &ldquo;send that.&rdquo; It also remembers the key that is associated with
674 this tx request.
675 </para></listitem>
676 <listitem><para>
677 These calls return &hellip; time passes &hellip;
678 </para></listitem>
679 <listitem><para>
680 Asynchronously, the hardware makes an interrupt to say
681 &ldquo;transmit is done.&rdquo;
682 The ISR quietens the interrupt source in the hardware and
683 requests that the associated DSR be run.
684 </para></listitem>
685 <listitem><para>
686 The DSR calls (or <emphasis>is</emphasis>) the
687 <function>eth_drv_dsr()</function> function in the generic driver.
688 </para></listitem>
689 <listitem><para>
690 <function>eth_drv_dsr()</function> in the generic driver awakens the
691 &ldquo;Network Delivery Thread&rdquo; which calls the deliver function
692 <replaceable>HRDWR</replaceable>_deliver() in the driver.
693 </para></listitem>
694 <listitem><para>
695 The deliver function realizes that a transmit request has completed,
696 and calls the callback tx-done function
697 <function>(sc->funs->eth_drv->tx_done)()</function>
698 with the same key that it remembered for this tx.
699 </para></listitem>
700 <listitem><para>
701 The callback tx-done function
702 uses the key to find the resources associated with
703 this transmit request; thus the stack knows that the transmit has
704 completed and its resources can be freed.
705 </para></listitem>
706 <listitem><para>
707 The callback tx-done function
708 also enquires whether <replaceable>HRDWR</replaceable>_can_send() now says
709 &ldquo;yes, we can send&rdquo;
710 and if so, dequeues a further transmit request
711 which may have been queued as described above.  If so, then
712 <replaceable>HRDWR</replaceable>_send() copies the data into the hardware buffers, or
713 instructs the hardware to "send that" and remembers the new key, as above.
714 These calls then all return to the &ldquo;Network Delivery Thread&rdquo;
715 which then sleeps, awaiting the next asynchronous event.
716 </para></listitem>
717 <listitem><para>
718 All done &hellip;
719 </para></listitem>
720 </orderedlist>
721 </sect2>
722 <sect2 id=io-eth-call-graph-rx>
723 <title>Receive</title>
724 <orderedlist>
725 <listitem><para>
726 Asynchronously, the hardware makes an interrupt to say
727 &ldquo;there is ready data in a receive buffer.&rdquo;
728 The ISR quietens the interrupt source in the hardware and
729 requests that the associated DSR be run.
730 </para></listitem>
731 <listitem><para>
732 The DSR calls (or <emphasis>is</emphasis>) the
733 <function>eth_drv_dsr()</function> function in the generic driver.
734 </para></listitem>
735 <listitem><para>
736 <function>eth_drv_dsr()</function> in the generic driver awakens the
737 &ldquo;Network Delivery Thread&rdquo; which calls the deliver function
738 <replaceable>HRDWR</replaceable>_deliver() in the driver.
739 </para></listitem>
740 <listitem><para>
741 The deliver function realizes that there is data ready and calls
742 the callback receive function
743 <function>(sc->funs->eth_drv->recv)()</function>
744 to tell it how many bytes to prepare for.
745 </para></listitem>
746 <listitem><para>
747 The callback receive function allocates memory within the stack
748 (eg. <type>MBUFs</type> in BSD/Unix style stacks) and prepares
749 a set of scatter-gather buffers that can
750 accommodate the packet.
751 </para></listitem>
752 <listitem><para>
753 It then calls back into the hardware driver routine
754 <replaceable>HRDWR</replaceable>_recv().
755 <replaceable>HRDWR</replaceable>_recv() must copy the data from the
756 hardware's buffers into the scatter-gather buffers provided, and return.
757 </para></listitem>
758 <listitem><para>
759 The network stack now has the data in-hand, and does with it what it will.
760 This might include recursive calls to transmit a response packet.
761 When this all is done, these calls return, and the
762 &ldquo;Network Delivery Thread&rdquo;
763 sleeps once more, awaiting the next asynchronous event.
764 </para></listitem>
765 </orderedlist>
766 </sect2>
767 </sect1>
768 </chapter>
769 </part>