source: rtems-docs/networking/networking_driver.rst @ 489740f

4.115
Last change on this file since 489740f was 489740f, checked in by Chris Johns <chrisj@…>, on 05/20/16 at 02:47:09

Set SPDX License Identifier in each source file.

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