1 |
1026 |
ivang |
@c
|
2 |
|
|
@c Written by Eric Norum
|
3 |
|
|
@c
|
4 |
|
|
@c COPYRIGHT (c) 1988-2002.
|
5 |
|
|
@c On-Line Applications Research Corporation (OAR).
|
6 |
|
|
@c All rights reserved.
|
7 |
|
|
@c
|
8 |
|
|
@c driver.t,v 1.11 2002/01/17 21:47:45 joel Exp
|
9 |
|
|
@c
|
10 |
|
|
|
11 |
|
|
@chapter Networking Driver
|
12 |
|
|
|
13 |
|
|
@section Introduction
|
14 |
|
|
|
15 |
|
|
This chapter is intended to provide an introduction to the
|
16 |
|
|
procedure for writing RTEMS network device drivers.
|
17 |
|
|
The example code is taken from the `Generic 68360' network device
|
18 |
|
|
driver. The source code for this driver is located in the
|
19 |
|
|
@code{c/src/lib/libbsp/m68k/gen68360/network} directory in the RTEMS
|
20 |
|
|
source code distribution. Having a copy of this driver at
|
21 |
|
|
hand when reading the following notes will help significantly.
|
22 |
|
|
|
23 |
|
|
@section Learn about the network device
|
24 |
|
|
|
25 |
|
|
Before starting to write the network driver become completely
|
26 |
|
|
familiar with the programmer's view of the device.
|
27 |
|
|
The following points list some of the details of the
|
28 |
|
|
device that must be understood before a driver can be written.
|
29 |
|
|
|
30 |
|
|
@itemize @bullet
|
31 |
|
|
|
32 |
|
|
@item Does the device use DMA to transfer packets to and from
|
33 |
|
|
memory or does the processor have to
|
34 |
|
|
copy packets to and from memory on the device?
|
35 |
|
|
|
36 |
|
|
@item If the device uses DMA, is it capable of forming a single
|
37 |
|
|
outgoing packet from multiple fragments scattered in separate
|
38 |
|
|
memory buffers?
|
39 |
|
|
|
40 |
|
|
@item If the device uses DMA, is it capable of chaining multiple
|
41 |
|
|
outgoing packets, or does each outgoing packet require
|
42 |
|
|
intervention by the driver?
|
43 |
|
|
|
44 |
|
|
@item Does the device automatically pad short frames to the minimum
|
45 |
|
|
64 bytes or does the driver have to supply the padding?
|
46 |
|
|
|
47 |
|
|
@item Does the device automatically retry a transmission on detection
|
48 |
|
|
of a collision?
|
49 |
|
|
|
50 |
|
|
@item If the device uses DMA, is it capable of buffering multiple
|
51 |
|
|
packets to memory, or does the receiver have to be restarted
|
52 |
|
|
after the arrival of each packet?
|
53 |
|
|
|
54 |
|
|
@item How are packets that are too short, too long, or received with
|
55 |
|
|
CRC errors handled? Does the device automatically continue
|
56 |
|
|
reception or does the driver have to intervene?
|
57 |
|
|
|
58 |
|
|
@item How is the device Ethernet address set? How is the device
|
59 |
|
|
programmed to accept or reject broadcast and multicast packets?
|
60 |
|
|
|
61 |
|
|
@item What interrupts does the device generate? Does it generate an
|
62 |
|
|
interrupt for each incoming packet, or only for packets received
|
63 |
|
|
without error? Does it generate an interrupt for each packet
|
64 |
|
|
transmitted, or only when the transmit queue is empty? What
|
65 |
|
|
happens when a transmit error is detected?
|
66 |
|
|
|
67 |
|
|
@end itemize
|
68 |
|
|
|
69 |
|
|
In addition, some controllers have specific questions regarding
|
70 |
|
|
board specific configuration. For example, the SONIC Ethernet
|
71 |
|
|
controller has a very configurable data bus interface. It can
|
72 |
|
|
even be configured for sixteen and thirty-two bit data buses. This
|
73 |
|
|
type of information should be obtained from the board vendor.
|
74 |
|
|
|
75 |
|
|
@section Understand the network scheduling conventions
|
76 |
|
|
|
77 |
|
|
When writing code for the driver transmit and receive tasks,
|
78 |
|
|
take care to follow the network scheduling conventions. All tasks
|
79 |
|
|
which are associated with networking share various
|
80 |
|
|
data structures and resources. To ensure the consistency
|
81 |
|
|
of these structures the tasks
|
82 |
|
|
execute only when they hold the network semaphore (@code{rtems_bsdnet_semaphore}).
|
83 |
|
|
The transmit and receive tasks must abide by this protocol. Be very
|
84 |
|
|
careful to avoid `deadly embraces' with the other network tasks.
|
85 |
|
|
A number of routines are provided to make it easier for the network
|
86 |
|
|
driver code to conform to the network task scheduling conventions.
|
87 |
|
|
|
88 |
|
|
@itemize @bullet
|
89 |
|
|
|
90 |
|
|
@item @code{void rtems_bsdnet_semaphore_release(void)}
|
91 |
|
|
|
92 |
|
|
This function releases the network semaphore.
|
93 |
|
|
The network driver tasks must call this function immediately before
|
94 |
|
|
making any blocking RTEMS request.
|
95 |
|
|
|
96 |
|
|
@item @code{void rtems_bsdnet_semaphore_obtain(void)}
|
97 |
|
|
|
98 |
|
|
This function obtains the network semaphore.
|
99 |
|
|
If a network driver task has released the network semaphore to allow other
|
100 |
|
|
network-related tasks to run while the task blocks, then this function must
|
101 |
|
|
be called to reobtain the semaphore immediately after the return from the
|
102 |
|
|
blocking RTEMS request.
|
103 |
|
|
|
104 |
|
|
@item @code{rtems_bsdnet_event_receive(rtems_event_set, rtems_option, rtems_interval, rtems_event_set *)}
|
105 |
|
|
The network driver task should call this function when it wishes to wait
|
106 |
|
|
for an event. This function releases the network semaphore,
|
107 |
|
|
calls @code{rtems_event_receive} to wait for the specified event
|
108 |
|
|
or events and reobtains the semaphore.
|
109 |
|
|
The value returned is the value returned by the @code{rtems_event_receive}.
|
110 |
|
|
|
111 |
|
|
@end itemize
|
112 |
|
|
|
113 |
|
|
@section Network Driver Makefile
|
114 |
|
|
|
115 |
|
|
Network drivers are considered part of the BSD network package and as such
|
116 |
|
|
are to be compiled with the appropriate flags. This can be accomplished by
|
117 |
|
|
adding @code{-D__INSIDE_RTEMS_BSD_TCPIP_STACK__} to the @code{command line}.
|
118 |
|
|
If the driver is inside the RTEMS source tree or is built using the
|
119 |
|
|
RTEMS application Makefiles, then adding the following line accomplishes
|
120 |
|
|
this:
|
121 |
|
|
|
122 |
|
|
@example
|
123 |
|
|
DEFINES += -D__INSIDE_RTEMS_BSD_TCPIP_STACK__
|
124 |
|
|
@end example
|
125 |
|
|
|
126 |
|
|
This is equivalent to the following list of definitions. Early versions
|
127 |
|
|
of the RTEMS BSD network stack required that all of these be defined.
|
128 |
|
|
|
129 |
|
|
@example
|
130 |
|
|
-D_COMPILING_BSD_KERNEL_ -DKERNEL -DINET -DNFS \
|
131 |
|
|
-DDIAGNOSTIC -DBOOTP_COMPAT
|
132 |
|
|
@end example
|
133 |
|
|
|
134 |
|
|
Defining these macros tells the network header files that the driver
|
135 |
|
|
is to be compiled with extended visibility into the network stack. This
|
136 |
|
|
is in sharp contrast to applications that simply use the network stack.
|
137 |
|
|
Applications do not require this level of visibility and should stick
|
138 |
|
|
to the portable application level API.
|
139 |
|
|
|
140 |
|
|
As a direct result of being logically internal to the network stack,
|
141 |
|
|
network drivers use the BSD memory allocation routines This means,
|
142 |
|
|
for example, that malloc takes three arguments. See the SONIC
|
143 |
|
|
device driver (@code{c/src/lib/libchip/network/sonic.c}) for an example
|
144 |
|
|
of this. Because of this, network drivers should not include
|
145 |
|
|
@code{}. Doing so will result in conflicting definitions
|
146 |
|
|
of @code{malloc()}.
|
147 |
|
|
|
148 |
|
|
@b{Application level} code including network servers such as the FTP
|
149 |
|
|
daemon are @b{not} part of the BSD kernel network code and should not be
|
150 |
|
|
compiled with the BSD network flags. They should include
|
151 |
|
|
@code{} and not define the network stack visibility
|
152 |
|
|
macros.
|
153 |
|
|
|
154 |
|
|
@section Write the Driver Attach Function
|
155 |
|
|
|
156 |
|
|
The driver attach function is responsible for configuring the driver
|
157 |
|
|
and making the connection between the network stack
|
158 |
|
|
and the driver.
|
159 |
|
|
|
160 |
|
|
Driver attach functions take a pointer to an
|
161 |
|
|
@code{rtems_bsdnet_ifconfig} structure as their only argument.
|
162 |
|
|
and set the driver parameters based on the
|
163 |
|
|
values in this structure. If an entry in the configuration
|
164 |
|
|
structure is zero the attach function chooses an
|
165 |
|
|
appropriate default value for that parameter.
|
166 |
|
|
|
167 |
|
|
|
168 |
|
|
The driver should then set up several fields in the ifnet structure
|
169 |
|
|
in the device-dependent data structure supplied and maintained by the driver:
|
170 |
|
|
|
171 |
|
|
@table @code
|
172 |
|
|
@item ifp->if_softc
|
173 |
|
|
Pointer to the device-dependent data. The first entry
|
174 |
|
|
in the device-dependent data structure must be an @code{arpcom}
|
175 |
|
|
structure.
|
176 |
|
|
|
177 |
|
|
@item ifp->if_name
|
178 |
|
|
The name of the device. The network stack uses this string
|
179 |
|
|
and the device number for device name lookups. The device name should
|
180 |
|
|
be obtained from the @code{name} entry in the configuration structure.
|
181 |
|
|
|
182 |
|
|
@item ifp->if_unit
|
183 |
|
|
The device number. The network stack uses this number and the
|
184 |
|
|
device name for device name lookups. For example, if
|
185 |
|
|
@code{ifp->if_name} is @samp{scc} and @code{ifp->if_unit} is @samp{1},
|
186 |
|
|
the full device name would be @samp{scc1}. The unit number should be
|
187 |
|
|
obtained from the `name' entry in the configuration structure.
|
188 |
|
|
|
189 |
|
|
@item ifp->if_mtu
|
190 |
|
|
The maximum transmission unit for the device. For Ethernet
|
191 |
|
|
devices this value should almost always be 1500.
|
192 |
|
|
|
193 |
|
|
@item ifp->if_flags
|
194 |
|
|
The device flags. Ethernet devices should set the flags
|
195 |
|
|
to @code{IFF_BROADCAST|IFF_SIMPLEX}, indicating that the
|
196 |
|
|
device can broadcast packets to multiple destinations
|
197 |
|
|
and does not receive and transmit at the same time.
|
198 |
|
|
|
199 |
|
|
@item ifp->if_snd.ifq_maxlen
|
200 |
|
|
The maximum length of the queue of packets waiting to be
|
201 |
|
|
sent to the driver. This is normally set to @code{ifqmaxlen}.
|
202 |
|
|
|
203 |
|
|
@item ifp->if_init
|
204 |
|
|
The address of the driver initialization function.
|
205 |
|
|
|
206 |
|
|
@item ifp->if_start
|
207 |
|
|
The address of the driver start function.
|
208 |
|
|
|
209 |
|
|
@item ifp->if_ioctl
|
210 |
|
|
The address of the driver ioctl function.
|
211 |
|
|
|
212 |
|
|
@item ifp->if_output
|
213 |
|
|
The address of the output function. Ethernet devices
|
214 |
|
|
should set this to @code{ether_output}.
|
215 |
|
|
@end table
|
216 |
|
|
|
217 |
|
|
RTEMS provides a function to parse the driver name in the
|
218 |
|
|
configuration structure into a device name and unit number.
|
219 |
|
|
|
220 |
|
|
@example
|
221 |
|
|
int rtems_bsdnet_parse_driver_name (
|
222 |
|
|
const struct rtems_bsdnet_ifconfig *config,
|
223 |
|
|
char **namep
|
224 |
|
|
);
|
225 |
|
|
@end example
|
226 |
|
|
|
227 |
|
|
The function takes two arguments; a pointer to the configuration
|
228 |
|
|
structure and a pointer to a pointer to a character. The function
|
229 |
|
|
parses the configuration name entry, allocates memory for the driver
|
230 |
|
|
name, places the driver name in this memory, sets the second argument
|
231 |
|
|
to point to the name and returns the unit number.
|
232 |
|
|
On error, a message is printed and -1 is returned.
|
233 |
|
|
|
234 |
|
|
Once the attach function has set up the above entries it must link the
|
235 |
|
|
driver data structure onto the list of devices by
|
236 |
|
|
calling @code{if_attach}. Ethernet devices should then
|
237 |
|
|
call @code{ether_ifattach}. Both functions take a pointer to the
|
238 |
|
|
device's @code{ifnet} structure as their only argument.
|
239 |
|
|
|
240 |
|
|
The attach function should return a non-zero value to indicate that
|
241 |
|
|
the driver has been successfully configured and attached.
|
242 |
|
|
|
243 |
|
|
@section Write the Driver Start Function.
|
244 |
|
|
This function is called each time the network stack wants to start the
|
245 |
|
|
transmitter. This occures whenever the network stack adds a packet
|
246 |
|
|
to a device's send queue and the @code{IFF_OACTIVE} bit in the
|
247 |
|
|
device's @code{if_flags} is not set.
|
248 |
|
|
|
249 |
|
|
For many devices this function need only set the @code{IFF_OACTIVE} bit in the
|
250 |
|
|
@code{if_flags} and send an event to the transmit task
|
251 |
|
|
indicating that a packet is in the driver transmit queue.
|
252 |
|
|
|
253 |
|
|
|
254 |
|
|
@section Write the Driver Initialization Function.
|
255 |
|
|
|
256 |
|
|
This function should initialize the device, attach to interrupt handler,
|
257 |
|
|
and start the driver transmit and receive tasks. The function
|
258 |
|
|
|
259 |
|
|
@example
|
260 |
|
|
rtems_id
|
261 |
|
|
rtems_bsdnet_newproc (char *name,
|
262 |
|
|
int stacksize,
|
263 |
|
|
void(*entry)(void *),
|
264 |
|
|
void *arg);
|
265 |
|
|
@end example
|
266 |
|
|
|
267 |
|
|
should be used to start the driver tasks.
|
268 |
|
|
|
269 |
|
|
Note that the network stack may call the driver initialization function more
|
270 |
|
|
than once.
|
271 |
|
|
Make sure multiple versions of the receive and transmit tasks are not accidentally
|
272 |
|
|
started.
|
273 |
|
|
|
274 |
|
|
|
275 |
|
|
|
276 |
|
|
@section Write the Driver Transmit Task
|
277 |
|
|
|
278 |
|
|
This task is reponsible for removing packets from the driver send queue and sending them to the device. The task should block waiting for an event from the
|
279 |
|
|
driver start function indicating that packets are waiting to be transmitted.
|
280 |
|
|
When the transmit task has drained the driver send queue the task should clear
|
281 |
|
|
the @code{IFF_OACTIVE} bit in @code{if_flags} and block until another outgoing
|
282 |
|
|
packet is queued.
|
283 |
|
|
|
284 |
|
|
|
285 |
|
|
@section Write the Driver Receive Task
|
286 |
|
|
This task should block until a packet arrives from the device. If the
|
287 |
|
|
device is an Ethernet interface the function @code{ether_input} should be called
|
288 |
|
|
to forward the packet to the network stack. The arguments to @code{ether_input}
|
289 |
|
|
are a pointer to the interface data structure, a pointer to the ethernet
|
290 |
|
|
header and a pointer to an mbuf containing the packet itself.
|
291 |
|
|
|
292 |
|
|
|
293 |
|
|
|
294 |
|
|
|
295 |
|
|
@section Write the Driver Interrupt Handler
|
296 |
|
|
A typical interrupt handler will do nothing more than the hardware
|
297 |
|
|
manipulation required to acknowledge the interrupt and send an RTEMS event
|
298 |
|
|
to wake up the driver receive or transmit task waiting for the event.
|
299 |
|
|
Network interface interrupt handlers must not make any calls to other
|
300 |
|
|
network routines.
|
301 |
|
|
|
302 |
|
|
|
303 |
|
|
|
304 |
|
|
@section Write the Driver IOCTL Function
|
305 |
|
|
This function handles ioctl requests directed at the device. The ioctl
|
306 |
|
|
commands which must be handled are:
|
307 |
|
|
|
308 |
|
|
@table @code
|
309 |
|
|
@item SIOCGIFADDR
|
310 |
|
|
@item SIOCSIFADDR
|
311 |
|
|
If the device is an Ethernet interface these
|
312 |
|
|
commands should be passed on to @code{ether_ioctl}.
|
313 |
|
|
|
314 |
|
|
@item SIOCSIFFLAGS
|
315 |
|
|
This command should be used to start or stop the device,
|
316 |
|
|
depending on the state of the interface @code{IFF_UP} and
|
317 |
|
|
@code{IFF_RUNNING} bits in @code{if_flags}:
|
318 |
|
|
@table @code
|
319 |
|
|
@item IFF_RUNNING
|
320 |
|
|
Stop the device.
|
321 |
|
|
|
322 |
|
|
@item IFF_UP
|
323 |
|
|
Start the device.
|
324 |
|
|
|
325 |
|
|
@item IFF_UP|IFF_RUNNING
|
326 |
|
|
Stop then start the device.
|
327 |
|
|
|
328 |
|
|
@item 0
|
329 |
|
|
Do nothing.
|
330 |
|
|
|
331 |
|
|
@end table
|
332 |
|
|
@end table
|
333 |
|
|
|
334 |
|
|
|
335 |
|
|
|
336 |
|
|
@section Write the Driver Statistic-Printing Function
|
337 |
|
|
This function should print the values of any statistic/diagnostic
|
338 |
|
|
counters the network driver may use. The driver ioctl function should call
|
339 |
|
|
the statistic-printing function when the ioctl command is
|
340 |
|
|
@code{SIO_RTEMS_SHOW_STATS}.
|
341 |
|
|
|
342 |
|
|
|