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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [packages/] [io/] [eth/] [current/] [doc/] [ethdrv.sgml] - Blame information for rev 786

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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