path: root/doc/networking/driver.t
diff options
authorJoel Sherrill <>1998-08-19 20:29:35 +0000
committerJoel Sherrill <>1998-08-19 20:29:35 +0000
commitab0c6890bf4ab674877448a1a60e1e4ceeb38a3c (patch)
tree92130f4d4b24ec876d0a2231bf1f71538012d23b /doc/networking/driver.t
parent26b5c77fb1f484730bc016c5402c3bf6e070de46 (diff)
Diffstat (limited to '')
1 files changed, 281 insertions, 0 deletions
diff --git a/doc/networking/driver.t b/doc/networking/driver.t
new file mode 100644
index 0000000000..43589aa694
--- /dev/null
+++ b/doc/networking/driver.t
@@ -0,0 +1,281 @@
+@c Written by Eric Norum
+@c COPYRIGHT (c) 1988-1998.
+@c On-Line Applications Research Corporation (OAR).
+@c All rights reserved.
+@c $Id$
+@chapter Writing RTEMS Network Device Drivers
+@section Introduction
+This chapter is intended to provide an introduction to the
+procedure for writing RTEMS network device drivers.
+The example code is taken from the `Generic 68360' network device
+driver. The source code for this driver is located in the
+@code{c/src/lib/libbsp/m68k/gen68360/network} directory in the RTEMS
+source code distribution. You should have a copy of this driver at
+hand when reading the following notes.
+@section Learn about the network device
+Before starting to write the network driver you need to be completely
+familiar with the programmer's view of the device.
+The following points list some of the details of the
+device that must be understood before a driver can be written.
+@itemize @bullet
+@item Does the device use DMA to transfer packets to and from
+memory or does the processor have to
+copy packets to and from memory on the device?
+@item If the device uses DMA, is it capable of forming a single
+outtoing packet from multiple fragments scattered in separate
+memory buffers?
+@item If the device uses DMA, is it capable of chaining multiple
+outgoing packets, or does each outgoing packet require
+intervention by the driver?
+@item Does the device automatically pad short frames to the minimum
+64 bytes or does the driver have to supply the padding?
+@item Does the device automatically retry a transmission on detection
+of a collision?
+@item If the device uses DMA, is it capable of buffering multiple
+packets to memory, or does the receiver have to be restarted
+after the arrival of each packet?
+@item How are packets that are too short, too long, or received with
+CRC errors handled? Does the device automatically continue
+reception or does the driver have to intervene?
+@item How is the device Ethernet address set? How is the device
+programmed to accept or reject broadcast and multicast packets?
+@item What interrupts does the device generate? Does it generate an
+interrupt for each incoming packet, or only for packets received
+without error? Does it generate an interrupt for each packet
+transmitted, or only when the transmit queue is empty? What
+happens when a transmit error is detected?
+@end itemize
+In addition, some controllers have specific questions regarding
+board specific configuration. For example, the SONIC Ethernet
+controller has a very configurable data bus interface. It can
+even be configured for sixteen and thirty-two bit data buses. This
+type of information should be obtained from the board vendor.
+@section Understand the network scheduling conventions
+When writing code for your driver transmit and receive tasks you must
+take care to follow the network scheduling conventions. All tasks
+which are associated with networking share various
+data structures and resources. To ensure the consistency
+of these structures the tasks
+execute only when they hold the network semaphore (@code{rtems_bsdnet_semaphore}).
+Your transmit and receive tasks must abide by this protocol which means you must
+be careful to avoid `deadly embraces' with the other network tasks.
+A number of routines are provided to make it easier for your code
+to conform to the network task scheduling conventions.
+@itemize @bullet
+@item @code{void rtems_bsdnet_semaphore_release(void)}
+This function releases the network semaphore.
+Your task must call this function immediately before
+making any blocking RTEMS request.
+@item @code{void rtems_bsdnet_semaphore_obtain(void)}
+This function obtains the network semaphore.
+If your task has released the network semaphore to allow other
+network-related tasks to run while your task blocks you must call this
+function to reobtain the semaphore immediately after the return from the
+blocking RTEMS request.
+@item @code{rtems_bsdnet_event_receive(rtems_event_set, rtems_option, rtems_interval, rtems_event_set *)}
+Your task should call this function when it wishes to wait for an event.
+This function releases the network semaphore,
+calls @code{rtems_event_receive} to wait for the specified event
+or events and reobtains the semaphore.
+The value returned is the value returned by the @code{rtems_event_receive}.
+@end itemize
+@section Write your driver attach function
+The driver attach function is responsible for configuring the driver
+and making the connection between the network stack
+and the driver.
+Driver attach functions take a pointer to an
+@code{rtems_bsdnet_ifconfig} structure as their only argument.
+and set the driver parameters based on the
+values in this structure. If an entry in the configuration
+structure is zero the attach function chooses an
+appropriate default value for that parameter.
+The driver should then set up several fields in the ifnet structure
+in the device-dependent data structure supplied and maintained by the driver:
+@table @code
+@item ifp->if_softc
+Pointer to the device-dependent data. The first entry
+in the device-dependent data structure must be an @code{arpcom}
+@item ifp->if_name
+The name of the device. The network stack uses this string
+and the device number for device name lookups.
+@item ifp->if_unit
+The device number. The network stack uses this number and the
+device name for device name lookups. For example, if
+@code{ifp->if_name} is @samp{scc}, and @code{ifp->if_unit} is @samp{1},
+the full device name would be @samp{scc1}.
+@item ifp->if_mtu
+The maximum transmission unit for the device. For Ethernet
+devices this value should almost always be 1500.
+@item ifp->if_flags
+The device flags. Ethernet devices should set the flags
+to @code{IFF_BROADCAST|IFF_SIMPLEX}, indicating that the
+device can broadcast packets to multiple destinations
+and does not receive and transmit at the same time.
+@item ifp->if_snd.ifq_maxlen
+The maximum length of the queue of packets waiting to be
+sent to the driver. This is normally set to @code{ifqmaxlen}.
+@item ifp->if_init
+The address of the driver initialization function.
+@item ifp->if_start
+The address of the driver start function.
+@item ifp->if_ioctl
+The address of the driver ioctl function.
+@item ifp->if_output
+The address of the output function. Ethernet devices
+should set this to @code{ether_output}.
+@end table
+Once the attach function has set up the above entries it must link the
+driver data structure onto the list of devices by
+calling @code{if_attach}. Ethernet devices should then
+call @code{ether_ifattach}. Both functions take a pointer to the
+device's @code{ifnet} structure as their only argument.
+The attach function should return a non-zero value to indicate that
+the driver has been successfully configured and attached.
+@section Write your driver start function.
+This function is called each time the network stack wants to start the
+transmitter. This occures whenever the network stack adds a packet
+to a device's send queue and the @code{IFF_OACTIVE} bit in the
+device's @code{if_flags} is not set.
+For many devices this function need only set the @code{IFF_OACTIVE} bit in the
+@code{if_flags} and send an event to the transmit task
+indicating that a packet is in the driver transmit queue.
+@section Write your driver initialization function.
+This function should initialize the device, attach to interrupt handler,
+and start the driver transmit and receive tasks. The function
+rtems_bsdnet_newproc (char *name,
+ int stacksize,
+ void(*entry)(void *),
+ void *arg);
+@end example
+should be used to start the driver tasks.
+Note that the network stack may call the driver initialization function more
+than once.
+Make sure you don't start multiple versions of the receive and transmit tasks.
+@section Write your driver transmit task.
+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
+driver start function indicating that packets are waiting to be transmitted.
+When the transmit task has drained the driver send queue the task should clear
+the @code{IFF_OACTIVE} bit in @code{if_flags} and block until another outgoing
+packet is queued.
+@section Write your driver receive task.
+This task should block until a packet arrives from the device. If the
+device is an Ethernet interface the function @code{ether_input} should be called
+to forward the packet to the network stack. The arguments to @code{ether_input}
+are a pointer to the interface data structure, a pointer to the ethernet
+header and a pointer to an mbuf containing the packet itself.
+@section Write your driver interrupt handler.
+A typical interrupt handler will do nothing more than the hardware
+manipulation required to acknowledge the interrupt and send an RTEMS event
+to wake up the driver receive or transmit task waiting for the event.
+Network interface interrupt handlers must not make any calls to other
+network routines.
+@section Write your driver ioctl function.
+This function handles ioctl requests directed at the device. The ioctl
+commands which must be handled are:
+@table @code
+If the device is an Ethernet interface these
+commands should be passed on to @code{ether_ioctl}.
+This command should be used to start or stop the device,
+depending on the state of the interface @code{IFF_UP} and
+@code{IFF_RUNNING} bits in @code{if_flags}:
+@table @code
+Stop the device.
+@item IFF_UP
+Start the device.
+Stop then start the device.
+@item 0
+Do nothing.
+@end table
+@end table
+@section Write your driver statistic-printing function
+This function should print the values of any statistic/diagnostic
+counters your driver may use. The driver ioctl function should call
+the statistic-printing function when the ioctl command is