OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [packages/] [io/] [eth/] [v2_0/] [doc/] [ethdrv.sgml] - Blame information for rev 174

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 27 unneback
2
 
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
 
30
31
 
32
33
Ethernet Device Drivers
34
35
Generic Ethernet Device Driver
36
37
Generic Ethernet API
38
39
This file provides a simple description of how to write a low-level,
40
hardware dependent ethernet driver.
41
42
43
There is a high-level driver (which is only code — 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
eCos
50
supported
51
TCP/IP
52
stack,
53
RedBoot,
54
or any other, with no changes.
55
56
57
A driver instance is contained within a
58
struct eth_drv_sc:
59
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
103
104
If you have two instances of the same hardware, you only need one
105
struct eth_hwr_funs shared between them.
106
107
There is another structure which is used to communicate with the rest of
108
the stack:
109
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
123
Your driver does not create an instance of this
124
structure.  It is provided for driver code to use in the
125
eth_drv member of the function record.
126
Its usage is described below in 
127
128
One more function completes the API with which your driver communicates
129
with the rest of the stack:
130
131
extern void eth_drv_dsr(cyg_vector_t vector,
132
                        cyg_ucount32 count,
133
                        cyg_addrword_t data);
134
135
136
This function is designed so that it can be registered as the DSR for your
137
interrupt handler.  It will awaken the
138
“Network Delivery Thread”
139
to call your deliver routine.  See .
140
141
You create an instance of struct eth_drv_sc
142
using the
143
ETH_DRV_SC()
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
152
The “magic”
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
NETDEVTAB_ENTRY()
157
macro, which defines an initialization function
158
and the basic data structures for the low-level driver.
159
160
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
168
The device_instance
169
entry here would point to the struct eth_drv_sc
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 PPP
173
drivers, etc.  These will
174
use the NETDEVTAB_ENTRY()
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
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
182
#include <cyg/infra/cyg_type.h>
183
#include <cyg/hal/hal_arch.h>
184
#include <cyg/infra/diag.h>
185
#include <cyg/hal/drv_api.h>
186
#include <cyg/io/eth/netdev.h>
187
#include <cyg/io/eth/eth_drv.h>
188
 
189
ETH_DRV_SC(DRV_sc,
190
           0,             // No driver specific data needed
191
           "eth0",        // Name for this interface
192
           HRDWR_start,
193
           HRDWR_stop,
194
           HRDWR_control,
195
           HRDWR_can_send
196
           HRDWR_send,
197
           HRDWR_recv,
198
           HRDWR_deliver,
199
           HRDWR_poll,
200
           HRDWR_int_vector
201
);
202
 
203
NETDEVTAB_ENTRY(DRV_netdev,
204
                "DRV",
205
                DRV_HRDWR_init,
206
                &DRV_sc);
207
208
209
This, along with the referenced functions, completely define the driver.
210
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
ETH_DRV_SC()/NETDEVTAB_ENTRY()
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
219
        0, // No driver specific data
220
221
is currently.
222
223
224
225
Review of the functions
226
227
Now a brief review of the functions.  This discussion will use generic
228
names for the functions — your driver should use hardware-specific
229
names to maintain uniqueness against any other drivers.
230
231
232
Init function
233
234
235
static bool DRV_HDWR_init(struct cyg_netdevtab_entry *tab)
236
237
This function is called as part of system initialization.  Its primary
238
function is to decide if the hardware (as indicated via
239
tab->device_instance)
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
244
    struct eth_drv_sc *sc = (struct eth_drv_sc *)tab->device_instance;
245
    ....initialization code....
246
    // Initialize upper level driver
247
    (sc->funs->eth_drv->init)( sc, unsigned char *enaddr );
248
249
where enaddr
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
253
The ethernet station address
254
(ESA)
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
259
260
In many packages it is possible for the
261
ESA
262
to be set from RedBoot,
263
(perhaps from 'fconfig' data), hard-coded from
264
CDL, or from an EPROM.
265
A driver should choose a run-time specified
266
ESA
267
(e.g. from RedBoot)
268
preferentially, otherwise (in order) it should use a CDL specified
269
ESA
270
if one has been set, otherwise an EPROM set
271
ESA, or otherwise
272
fail. See the cl/cs8900a
273
ethernet driver for an example.
274
275
276
277
Start function
278
279
280
static void
281
HRDWR_start(struct eth_drv_sc *sc, unsigned char *enaddr, int flags)
282
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
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
ioctl() call in the application.
293
This may occur more than once, so this function needs to
294
be prepared for that case.
295
296
In future, the flags
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
301
302
303
Stop function
304
305
306
static void HRDWR_stop(struct eth_drv_sc *sc)
307
308
This function is the inverse of “start.”
309
It should shut down the hardware, disable the receiver, and keep it from
310
interacting with the physical network.
311
312
313
314
Control function
315
316
317
static int
318
HRDWR_control(
319
        struct eth_drv_sc *sc, unsigned long key,
320
        void *data, int len)
321
322
This function is used to perform low-level “control”
323
operations on the
324
interface.  These operations would typically be initiated via
325
ioctl() 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
330
The key parameter selects the operation, and the
331
data and len params point describe,
332
as required, some data for the operation in question.
333
334
Available Operations:
335
ETH_DRV_SET_MAC_ADDRESS
336
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
342
343
344
345
ETH_DRV_GET_IF_STATS_UD
346
ETH_DRV_GET_IF_STATS
347
348
These acquire a set of statistical counters from the interface, and write
349
the information into the memory pointed to by data.
350
The “UD” 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
354
The definition of the data structure is in
355
cyg/io/eth/eth_drv_stats.h.
356
357
This call is typically made by SNMP, see .
358
359
360
361
ETH_DRV_SET_MC_LIST
362
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 data.
366
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
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
376
377
378
379
ETH_DRV_SET_MC_ALL
380
381
This entry instructs the device to receive all multicast packets, and
382
delete any explicit filtering which had been set up.
383
384
385
386
387
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
392
393
394
Can-send function
395
396
397
static int HRDWR_can_send(struct eth_drv_sc *sc)
398
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
404
Return the number of packets which could be accepted at this time, zero
405
implies that the interface is saturated/busy.
406
407
408
409
Send function
410
411
412
struct eth_drv_sg {
413
    CYG_ADDRESS  buf;
414
    CYG_ADDRWORD len;
415
};
416
 
417
static void
418
HRDWR_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
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
428
All data in/out of the driver is specified via a
429
“scatter-gather”
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
struct eth_drv_sg defined above and pointed to by
433
sg_list.
434
435
Once the data has been successfully sent by the interface (or if an
436
error occurs), the driver should call
437
(sc->funs->eth_drv->tx_done)()
438
(see )
439
using the specified key.
440
Only then will the upper layers release the resources
441
for that packet and start another transmission.
442
443
In future, this function may be extended so that the data need not be
444
copied by having the function return a “disposition” code
445
(done, send pending, etc).  At this point, you should move the data to some
446
“safe” location before returning.
447
448
449
450
Deliver function
451
452
453
static void
454
HRDWR_deliver(struct eth_drv_sc *sc)
455
456
This function is called from the “Network Delivery Thread” in
457
order to let the device driver do the time-consuming work associated with
458
receiving a packet — usually copying the entire packet from the
459
hardware or a special memory location into the network stack's memory.
460
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
465
It will be called when the interrupt handler for the network device
466
has called
467
468
    eth_drv_dsr( vector, count, (cyg_addrword_t)sc );
469
470
to alert the system that “something requires attention.”
471
This eth_drv_dsr() call must occur from within the
472
interrupt handler's DSR (not the ISR) or actually be
473
the DSR, whenever it is determined that
474
the device needs attention from the foreground.  The third parameter
475
(data in the prototype of
476
eth_drv_dsr() must
477
be a valid struct eth_drv_sc pointer sc.
478
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
484
To deliver a newly-received packet into the network stack, the deliver
485
routine must call
486
487
(sc->funs->eth_drv->recv)(sc, len);
488
489
which will in turn call the receive function, which we talk about next.
490
See also  below.
491
492
493
494
Receive function
495
496
497
static void
498
HRDWR_recv(
499
        struct eth_drv_sc *sc,
500
        struct eth_drv_sg *sg_list, int sg_len)
501
502
This function is a call back, only invoked after the
503
upper-level function
504
505
(sc->funs->eth_drv->recv)(struct eth_drv_sc *sc, int total_len)
506
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 (sc->funs->eth_drv->recv)()
510
function then arranges network buffers
511
and structures for the data and then calls
512
HRDWR_recv() to actually
513
move the data from the interface.
514
515
A scatter-gather list (struct eth_drv_sg) is used once more,
516
just like in the send case.
517
518
519
520
Poll function
521
522
523
static void
524
HRDWR_poll(struct eth_drv_sc *sc)
525
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
531
It is perfectly correct and acceptable for the poll function to look like
532
this:
533
534
static void
535
HRDWR_poll(struct eth_drv_sc *sc)
536
{
537
   my_interrupt_ISR(sc);
538
   HRDWR_deliver(struct eth_drv_sc *sc);
539
}
540
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 “intelligence.”
545
546
547
548
Interrupt-vector function
549
550
551
static int
552
HRDWR_int_vector(struct eth_drv_sc *sc)
553
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 “CTRL-C” 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
562
563
564
565
Upper Layer Functions
566
567
Upper layer functions are called by drivers to deliver received packets
568
or transmission completion status back up into the network stack.
569
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
575
These functions require a pointer to a struct eth_drv_sc
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 “up” as appropriate.
579
580
581
Callback Init function
582
583
584
void (sc->funs->eth_drv->init)(
585
                struct eth_drv_sc *sc, unsigned char *enaddr)
586
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 ).
591
The hardware should be totally initialized
592
(not “started”)
593
when this function is called.
594
595
596
597
Callback Tx-Done function
598
599
600
void (sc->funs->eth_drv->tx_done)(
601
                struct eth_drv_sc *sc,
602
                unsigned long key, int status)
603
604
This function is called when a packet completes transmission on the
605
interface.  The key
606
value must be one of the keys provided to
607
HRDWR_send()
608
above.  The value status 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
612
It should be called from the deliver function
613
(see )
614
or poll function
615
(see ).
616
617
618
619
Callback Receive function
620
621
622
void (sc->funs->eth_drv->recv)(struct eth_drv_sc *sc, int len)
623
624
This function is called to indicate that a packet of length
625
len has
626
arrived at the interface.
627
The callback
628
HRDWR_recv() 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
632
It should be called from the deliver function
633
(see )
634
or poll function
635
(see ).
636
637
638
639
640
Calling graph for Transmission and Reception
641
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 “foreground” when something asynchronous has occurred.
645
646
647
Transmission
648
649
650
Some foreground task such as the application, SNMP “daemon”,
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 “ping” or ARP request.
654
655
656
The driver calls the
657
HRDWR_can_send()
658
function in the hardware driver.
659
660
661
HRDWR_can_send()
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
669
670
If it can send right now, HRDWR_send() is called.
671
HRDWR_send() copies the
672
data into special hardware buffers, or instructs the hardware to
673
“send that.” It also remembers the key that is associated with
674
this tx request.
675
676
677
These calls return … time passes …
678
679
680
Asynchronously, the hardware makes an interrupt to say
681
“transmit is done.”
682
The ISR quietens the interrupt source in the hardware and
683
requests that the associated DSR be run.
684
685
686
The DSR calls (or is) the
687
eth_drv_dsr() function in the generic driver.
688
689
690
eth_drv_dsr() in the generic driver awakens the
691
“Network Delivery Thread” which calls the deliver function
692
HRDWR_deliver() in the driver.
693
694
695
The deliver function realizes that a transmit request has completed,
696
and calls the callback tx-done function
697
(sc->funs->eth_drv->tx_done)()
698
with the same key that it remembered for this tx.
699
700
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
706
707
The callback tx-done function
708
also enquires whether HRDWR_can_send() now says
709
“yes, we can send”
710
and if so, dequeues a further transmit request
711
which may have been queued as described above.  If so, then
712
HRDWR_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 “Network Delivery Thread”
715
which then sleeps, awaiting the next asynchronous event.
716
717
718
All done …
719
720
721
722
723
Receive
724
725
726
Asynchronously, the hardware makes an interrupt to say
727
“there is ready data in a receive buffer.”
728
The ISR quietens the interrupt source in the hardware and
729
requests that the associated DSR be run.
730
731
732
The DSR calls (or is) the
733
eth_drv_dsr() function in the generic driver.
734
735
736
eth_drv_dsr() in the generic driver awakens the
737
“Network Delivery Thread” which calls the deliver function
738
HRDWR_deliver() in the driver.
739
740
741
The deliver function realizes that there is data ready and calls
742
the callback receive function
743
(sc->funs->eth_drv->recv)()
744
to tell it how many bytes to prepare for.
745
746
747
The callback receive function allocates memory within the stack
748
(eg. MBUFs in BSD/Unix style stacks) and prepares
749
a set of scatter-gather buffers that can
750
accommodate the packet.
751
752
753
It then calls back into the hardware driver routine
754
HRDWR_recv().
755
HRDWR_recv() must copy the data from the
756
hardware's buffers into the scatter-gather buffers provided, and return.
757
758
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
“Network Delivery Thread”
763
sleeps once more, awaiting the next asynchronous event.
764
765
766
767
768
769

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.