comparison packages/io/eth/current/doc/ethdrv.sgml @ 208:e0c0827131d1 ecos

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