Compaq TRU64 AA-RNG2A-TE User Manual

Tru64 UNIX
Writing Network Device Drivers
Part Number: AA-RNG2A-TE
December 2000
Product Version: Device Driver Kit Version 2.0 Operating System and Version: Tru64 UNIX Version 5.0A or higher
This manual contains information that systems engineers need to write network device drivers that operate on any bus.
© 2000 Compaq Computer Corporation Compaq and the Compaq logo Registered in U.S. Patent and Trademark Office. Tru64 is a trademark of
Compaq Information Technologies Group, L.P.inthe United States and other countries. UNIX and X/Open are trademarks of The Open Group in the United States and other countries. All other
product names mentioned herein may be trademarks of their respective companies. Confidential computer software. Valid license from Compaq required for possession, use, or copying.
Consistent with FAR 12.211 and 12.212, Commercial Computer Software, Computer Software Documentation, and Technical Data for Commercial Items are licensed to the U.S. Government under vendor’s standard commercial license.
Compaq shall not be liable for technical or editorial errors or omissions contained herein. The information in this document is provided “as is” without warranty of any kind and is subject to change without notice. The warranties for Compaq products are set forth in the express limited warranty statements accompanying such products. Nothing herein should be construed as constituting an additional warranty.
About This Manual
1 Network Device Driver Environment
1.1
1.2
1.2.1
1.2.2
1.2.3
1.2.4
1.3
1.4
1.5
1.6
1.7
1.8
1.9
1.10
1.11
Include Files Section for a Network Driver ....................... 1–3
Declarations Section for a Network Driver ....................... 1–4
External and Forward Declarations .......................... 1–5
Declaring softc and controller Data Structure Arrays ...... 1–6
Declaring and Initializing the driver Data Structure ...... 1–7
Defining Driver-Specific Macros ............................... 1–7
Configure Section for a Network Driver ........................... 1–10
Autoconfiguration Support Section for a Network Driver ...... 1–10
Initialization Section for a Network Driver ....................... 1–10
Start Section for a Network Driver ................................ 1–10
Watchdog Section for a Network Driver ........................... 1–11
Reset Section for a Network Driver ................................ 1–11
ioctl Section for a Network Driver .................................. 1–11
Interrupt Section for a Network Driver ........................... 1–11
Output Section for a Network Driver .............................. 1–11
Contents
2 Defining Device Register Offsets
2.1
2.2
2.3
2.4
2.5
2.6
2.7
Interrupt and Status Register Offset Definitions ................ 2–1
Command Port Register Offset Definitions ....................... 2–2
Window 0 Configuration Register Offset Definitions ............ 2–4
Window 3 Configuration Register Offset Definitions ............ 2–7
Window 1 Operational Register Offset Definitions .............. 2–9
Window 4 Diagnostic Register Offset Definitions ................ 2–11
EEPROM Data Structure Definition .............................. 2–13
3 Defining the softc Data Structure
3.1
3.2
3.3
3.4
3.5
Defining Common Information ..................................... 3–2
Enabling Support for Enhanced Hardware Management ...... 3–4
Defining Media State Information ................................. 3–4
Defining the Base Register .......................................... 3–6
Defining Multicast Table Information ............................. 3–6
Contents iii
3.6
3.7
3.8
3.9
3.10
3.11
3.12
3.13
3.14
3.15
3.16
Defining the Interrupt Handler ID .................................
Defining CSR Pointer Information .................................
Defining FIFO Maintenance Information ......................... 3–7
Defining Bus-Specific Information .................................
Defining the Broadcast Flag ........................................
Defining the Debug Flag .............................................
Defining Interrupt and Timeout Statistics ....................... 3–8
Defining Autosense Kernel Thread Context Information ...... 3–9
Defining the Polling Context Flag .................................. 3–9
Defining a Copy of the w3_eeprom Data Structure .............. 3–10
Declaring the Simple Lock Data Structure ....................... 3–10
4 Implementing the Configure Section
4.1
4.2
Declaring Configure-Related Variables and the
cfg_subsys_attr_t Data Structure .................................. 4–1
Setting Up the el_configure Routine ............................... 4–3
5 Implementing the Autoconfiguration Support Section (probe)
5.1
5.1.1
5.1.2
5.1.3
5.1.4
5.1.5
5.1.6
5.1.7
5.1.8
5.1.9
5.1.10
5.1.11
5.1.12
5.1.13
5.1.14
5.2
5.3
5.3.1
5.3.2
5.3.3
5.3.4
Implementing the el_probe Routine ............................... 5–1
Setting Up the el_probe Routine ............................... 5–2
Checking the Maximum Number of Devices That the
Driver Supports ..................................................
Performing Bus-Specific Tasks ................................. 5–4
Allocating Memory for the softc Data Structure ............ 5–6
Allocating the ether_driver Data Structure .................. 5–7
Initializing the Enhanced Hardware Management Data
Structure .......................................................... 5–8
Computing the CSR Addresses ................................ 5–8
Setting Bus-Specific Data Structure Members .............. 5–8
Handling First-Time Probe Operations ....................... 5–10
Handling Subsequent Probe Operations ..................... 5–12
Registering the Interrupt Handler ............................ 5–14
Saving the controller and softc Data Structure Pointers .. 5–16
Trying to Allocate Another controller Data Structure ...... 5–16
Registering the shutdown Routine ............................ 5–17
Implementing the el_shutdown Routine .......................... 5–17
Implementing the el_autosense_thread Routine ................. 5–17
Setting Up the el_autosense_thread Routine ................ 5–19
Blocking Until Awakened ....................................... 5–19
Testing for the Termination Flag .............................. 5–20
Starting Up Statistics ........................................... 5–20
3–6 3–6
3–7 3–8 3–8
5–4
iv Contents
5.3.5
5.3.6
5.3.7
5.3.8
5.3.9
5.3.10
5.3.11
5.3.12
5.3.13
5.3.14
5.3.15
5.3.16
5.3.17
Entering the Packet Transmit Loop ............
Saving Counters Prior to the Transmit Operation .......... 5–21
Allocating Memory for a Test Packet ...........
Using the Default from the ROM ..............................
Setting the Media in the Hardware ............
Building the Test Packet ........................................
Transmitting the Test Packet .................................. 5–22
Setting a Timer for the Current Kernel Thread ............. 5–23
Testing for Loss of Carrier ...................................... 5–23
Determining Whether Packets Were Transmitted
Successfully .......................................................
Printing Debug Information .................................... 5–24
Setting Up New Media .......................................... 5–24
Establishing the Media .......................................... 5–25
............... 5–20
............... 5–21
............... 5–22
6 Implementing the Autoconfiguration Support Section (attach)
6.1
6.2
6.3
6.4
6.5
6.6
6.7
6.8
6.9
6.10
6.11
6.12
Setting Up the el_attach Routine .................................. 6–1
Initializing the Media Address and Media Header Lengths ... 6–2
Setting Up the Media ................................................
Initializing Simple Lock Information .............................. 6–5
Printing a Success Message ......................................... 6–6
Specifying the Network Driver Interfaces ........................ 6–6
Setting the Baud Rate ...............................................
Attaching to the Packet Filter and the Network Layer ......... 6–8
Setting Network Attributes and Registering the Adapter ...... 6–9
Handling the Reinsert Operation .................................. 6–9
Enabling the Interrupt Handler .................................... 6–10
Starting the Polling Process ......................................... 6–10
5–21 5–22
5–24
6–3
6–8
7 Implementing the unattach Routine
7.1
7.2
7.3
7.4
7.5
7.6
7.7
7.8
7.9
Setting Up the el_unattach Routine ............................... 7–1
Verifying That the Interface Has Shut Down .................... 7–2
Obtaining the Simple Lock and Shutting Down the Device .... 7–2
Disabling the Interrupt Handler ................................... 7–3
Terminating the Autosense Kernel Thread ....................... 7–3
Unregistering the PCMCIA Event Callback Routine ........... 7–4
Stopping the Polling Process ........................................ 7–4
Unregistering the Shutdown Routine ............................. 7–4
Terminating the Simple Lock ....................................... 7–4
Contents v
7.10
7.11
Unregistering the Card from the Hardware Management
Database ...............................................................
Freeing Resources ....................................................
8 Implementing the Initialization Section
8.1
8.1.1
8.1.2
8.1.3
8.1.4
8.1.5
8.1.6
8.2
8.2.1
8.2.2
8.2.3
8.2.4
8.2.5
8.2.6
8.2.7
8.2.8
8.2.9
8.2.10
8.2.11
8.2.12
8.2.13
8.2.14
8.2.15
8.2.16
8.2.17
Implementing the el_init Routine .................................. 8–1
Setting Up the el_init Routine ................................. 8–1
Determining Whether the PCMCIA Card Is Present ....... 8–2
Setting the IPL and Obtaining the Simple Lock ............ 8–2
Calling the el_init_locked Routine ............................ 8–3
Releasing the Simple Lock and Resetting the IPL .......... 8–3
Returning the Status from the el_init_locked Routine ..... 8–3
Implementing the el_init_locked Routine ......................... 8–3
Resetting the Transmitter and Receiver ...................... 8–4
Clearing Interrupts ..............................................
Starting the Device ..............................................
Ensuring That the 10Base2 Transceiver Is Off .............. 8–5
Setting the LAN Media .......................................... 8–6
Setting a LAN Attribute ........................................ 8–7
Selecting Memory Mapping .................................... 8–7
Resetting the Transmitter and Receiver Again .............. 8–7
Setting the LAN Address ....................................... 8–8
Processing Special Flags ........................................ 8–8
Setting the Debug Flag .......................................... 8–9
Enabling TX and RX .............................................
Enabling Interrupts ............................................. 8–10
Setting the Operational Window .............................. 8–10
Marking the Device as Running ............................... 8–10
Starting the Autosense Kernel Thread ....................... 8–11
Starting the Transmit of Pending Packets ................... 8–11
7–5 7–5
8–4 8–5
8–9
9 Implementing the Start Section
9.1
9.1.1
9.1.2
9.1.3
9.2
9.2.1
9.2.2
vi Contents
Implementing the el_start Routine ................................ 9–1
Setting the IPL and Obtaining the Simple Lock ............ 9–1
Calling the el_start_locked Routine ........................... 9–2
Releasing the Simple Lock and Resetting the IPL .......... 9–2
Implementing the el_start_locked Routine ....................... 9–3
Discarding All Transmits After the User Removes the
PCMCIA Card .................................................... 9–3
Removing Packets from the Pending Queue and Preparing
the Transmit Buffer .............................................. 9–4
9.2.3
9.2.4
9.2.5
9.2.6
Transmitting the Buffer .........................................
Accounting for Outgoing Bytes .................................
Updating Counters, Freeing the Transmit Buffer, and
Marking the Output Process as Active ....................... 9–7
Indicating When to Start the Watchdog Routine ............
10 Implementing a Watchdog Section
10.1
10.2
10.3
Setting the IPL and Obtaining the Simple Lock ................. 10–1
Incrementing the Transmit Timeout Counter and Resetting
the Unit ................................................................
Releasing the Simple Lock and Resetting the IPL ............... 10–2
11 Implementing the Reset Section
11.1
11.2
Implementing the el_reset Routine ................................ 11–1
Implementing the el_reset_locked Routine ....................... 11–2
12 Implementing the ioctl Section
12.1
12.2
12.3
12.4
12.5
12.6
12.7
12.8
12.9
12.10
12.11
12.12
12.13
12.14
Setting Up the el_ioctl Routine ..................................... 12–2
Determining Whether the User Has Removed the PCMCIA
Card from the Slot ....................................................
Setting the IPL and Obtaining the Simple Lock ................. 12–3
Enabling Loopback Mode (SIOCENABLBACK ioctl
Command) .............................................................
Disabling Loopback Mode (SIOCDISABLBACK ioctl
Command) ............................................................. 12–4
Reading Current and Default MAC Addresses
(SIOCRPHYSADDR ioctl Command) .............................. 12–5
Setting the Local MAC Address (SIOCSPHYSADDR ioctl
Command) ............................................................. 12–5
Adding the Device to a Multicast Group (SIOCADDMULTI
ioctl Command) ....................................................... 12–6
Deleting the Device from a Multicast Group (SIOCDELMULTI
ioctl Command) ....................................................... 12–7
Accessing Network Counters (SIOCRDCTRS and
SIOCRDZCTRS ioctl Commands) .................................. 12–8
Bringing Up the Device (SIOCSIFADDR ioctl Command) ..... 12–9
Using Currently Set Flags (SIOCSIFFLAGS ioctl Command) 12–10
Setting the IP MTU (SIOCSIPMTU ioctl Command) ........... 12–10
Setting the Media Speed (SIOCSMACSPEED ioctl
Command) ............................................................. 12–10
9–6 9–7
9–8
10–2
12–3
12–4
Contents vii
12.15
12.16
12.17
Resetting the Device (SIOCIFRESET ioctl Command) ......... 12–11
Setting Device Characteristics (SIOCIFSETCHAR ioctl
Command) .............................................................
Releasing the Simple Lock and Resetting the IPL ............... 12–13
13 Implementing the Interrupt Section
13.1
13.1.1
13.1.2
13.1.3
13.1.4
13.1.5
13.1.6
13.1.7
13.1.8
13.2
13.2.1
13.2.2
13.2.3
13.2.4
13.2.5
13.3
13.3.1
13.3.2
13.3.3
13.3.4
13.3.5
13.4
Implementing the el_intr Routine .................................. 13–1
Setting the IPL and Obtaining the Simple Lock ............ 13–2
Rearming the Next Timeout .................................... 13–2
Reading the Interrupt Status .................................. 13–3
Processing Completed Receive and Transmit Operations . 13–3
Acknowledging the Interrupt .................................. 13–4
Transmitting Pending Frames ................................. 13–4
Releasing the Simple Lock and Resetting the IPL .......... 13–4
Indicating That the Interrupt WasServiced ................. 13–5
Implementing the el_rint Routine .................................. 13–5
Counting the Receive Interrupt and Reading the Receive
Status ..............................................................
Pulling the Packets from the FIFO Buffer ................... 13–6
Examining the First Part of the Packet ...................... 13–7
Copying the Received Packet into the mbuf ................. 13–8
Discarding a Packet .............................................
Implementing the el_tint Routine .................................. 13–10
Counting the Transmit Interrupt .............................. 13–10
Reading the TransmitStatus and Counting All Significant
Events ..............................................................
Managing Excessive Data Collisions .......................... 13–11
Writing to the Status Register to Obtain the Next Value .. 13–11
Queuing Other Transmits ...................................... 13–12
Implementing the el_error Routine ................................ 13–12
12–11
13–5
13–9
13–10
14 Network Device Driver Configuration
Index
Figures
1–1 2–1 2–2 2–3
viii Contents
Sections of a Network Device Driver ............................... 1–2
Window 0 Configuration Registers ................................. 2–5
Window 3 Configuration Registers ................................. 2–8
Window 1 Operational Registers ................................... 2–9
2–4 3–1 3–2
Tables
1–1 12–1 12–2
Window 4 Diagnostic Registers .....................................
Typical softc Data Structure ........................................
Mapping Alternate Names ..........................................
Driver-Specific Macros ...............................................
Network ioctl Commands ............................................
Network Interface Counter Types .................................. 12–9
2–11
3–2 3–4
1–9
12–1
Contents ix
This manual discusses how to write network device drivers for computer systems that run the Compaq Tru64UNIX operating system.
Audience
This manual is intended for systems engineers who:
Use standard library routines to develop programs in the C language
Know the Bourne shell or some other shell that is based on the UNIX
Understand basic Tru64 UNIX concepts such as kernel, shell, process,
Understand how to use the Tru64 UNIX programming tools, compilers,
Develop programs in an environment that involves dynamic memory
Understand the hardware device for which the driver is being written
Understand the basics of the CPU hardware architecture, including
About This Manual
operating system
configuration, and autoconfiguration
and debuggers
allocation, linked list data structures, and multitasking
interrupts, direct memory access (DMA) operations, and I/O
Before you write a network device driver, we recommend that you be familiar with the networking subsystem that the Tru64 UNIX operating system provides. This manual assumes that you are familiar with the following network interface types:
Ethernet
Fiber Distributed Data Interface (FDDI)
Token Ring
See the Tru64 UNIX Technical Overview for descriptions of the data link media.
This manual also assumes that you have some knowledge of the Tru64 UNIX network programming environment, particularly:
Data link provider interface
X/Open transport interface
Sockets
About This Manual xi
Socket and XTI programming examples
TCP specific programming information
Information for Token Ring driver developers
Data link interface
See the Tru64 UNIX Network Programmer’s Guide for descriptions of these topics.
Scope of this Manual
This manual builds on the concepts and topics that are presented in Writing Device Drivers, which is the core manual for developing device drivers on
Tru64 UNIX. It introduces topics that are specific to writing a device driver for a local area network (LAN) device and that are beyond the scope of the core manual.
In this manual, you can study a network driver called if_el. The if_el driver supports the driver interface requirements for a LAN device, specifically the 3Com 3C589C series PCMCIA adapter. The if_el driver was implemented according to the specifications detailed in Ethernet III
Parallel Tasking ISA, EISA, Micro Channel, and PCMCIA Adapter Drivers Technical Reference . This specification is published by 3Com Corporation,
and the manual part number is 09-0398-002B. You can access the if_el source code in the device driver examples directory
(if you have installed it on your system). Ethernet is the network interface type that is associated with the if_el driver. However, the explanations point out where differences exist between Ethernet and other network interfaces, including fiber distributed data interface (FDDI) and Token Ring.
The example network driver operates on multiple buses (specifically, the PCMCIA bus and the ISA bus). It uses the common ifnet interface to communicate with the upper layers of the Tru64 UNIX operating system. The example does not emphasize any specific types of network device drivers. However, mastering the concepts presented in this manual is useful preparation for writing network device drivers that operate on a variety of buses.
The manual does not discuss:
How to write STREAMS network device drivers
Topics associated with wide area networks (WANs)
How to write an asynchronous transfer mode (ATM) device driver
Details related to the network programming environment
xii About This Manual
New and Changed Features
This revision of the manual documents the following new features:
Enabling support for enhanced hardware management Enhanced hardware management (EHM) allows you to modify hardware
attributes, such as the type of LAN device, on either a local or a remote system. See
Section 3.2 for more information about how a network device
driver uses routines to define and export hardware attributes.
The unattach( ) routine The unattach( ) routine stops the network device and frees resources
prior to unloading the device driver or powering off the bus to which the device is attached. See Chapter 7 for more information.
Organization
This manual is organized as follows:
Chapter 1 Describes the sections that make up a
Chapter 2 Describes the device register offset
Chapter 3 Describes how to define a softc data
Chapter 4 Describes how to implement a
Chapter 5 Describes how to implement a probe
Chapter 6 Describes how to implement an attach
Chapter 7 Describes how to implement an
network driver and compares them to the sections that are associated with block and character drivers.
definitions for the if_el device drivers associated LAN device, the 3Com 3C5x9 series Ethernet adapter.
structure, usingthe if_el devicedrivers
el_softc structure as an example.
configure interface, using the if_el
device drivers el_configure( ) routine as an example.
interface and associated routines, using the if_el device drivers el_probe( ) routine as an example.
interface, using the if_el device drivers
el_attach( ) routine as an example.
unattach( ) routine to stop the device.
About This Manual xiii
Chapter 8 Describes how to implement an init
interface and associated routines, using the if_el device drivers el_init( ) routine as an example.
Chapter 9 Describes how to implement a start
interface and associated routines, using the if_el device drivers el_start( ) routine as an example.
Chapter 10 Describes how to implement a watchdog
Chapter 11 Describes how to implement a reset
Chapter 12 Describes how to implement an ioctl
Chapter 13
Chapter 14 Describes the sysconfigtab option
interface, using the if_el device drivers el_watch( ) routine as an example.
interface and associated routines, using the if_el device drivers el_reset( ) routine as an example.
interface, using the if_el device drivers el_ioctl( ) routine as an example.
Describes how to implement an interrupt handler, using the if_el device drivers el_intr interrupt handler as an example.
entries necessary for configuring network device drivers on different bus types.
Related Documentation
The following examples and documents supplement information in this manual.
Examples
The directory /usr/examples/ddk/src/network includes the example source files that are used throughout this manual: if_el.c, if_elreg.h, files, and sysconfigtab.
Manuals
The following documents provide important information that supplements the information in this manual:
Installation Instructions and Release Notes contains instructions on how to install the Device Driver Kit Version 2.0 product, including source code with examples and user manuals. It also describes changes to the product and documentation since the Device Driver Kit Release 1.0.
xiv About This Manual
Writing Device Drivers contains information that you need to develop device drivers on the Compaq Tru64 UNIX operating system.
Writing Kernel Modules describes topics for all kernel modules such as kernel threads and writing kernel modules in a symmetric multiprocessing (SMP) environment.
Writing PCI Bus Device Drivers describes PCI bus-specific topics, including PCI bus architecture and data structures that PCI bus device drivers use.
Writing VMEbus Device Drivers describes VMEbus-specific topics, including VMEbus architecture and routines that VMEbus device drivers use.
The Guide to Preparing Product Kits describes how to create kernel (device driver) product kits and layered product kits.
Kernel Debugging describes how to use the debuggers to find problems in kernel code. It also describes how to write a kdbx utility extension and how to create and analyze a crash dump file.
Programming Support Tools describes several commands and utilities in the Tru64UNIX system, including facilities for text manipulation, macro and program generation, and source file management.
The Programmers Guide describes the programming environment of the Tru64 UNIX operating system, with an emphasis on the C programming language.
dbx, kdbx, and kdebug
The Network Programmers Guide describes the Tru64 UNIX network programming environment and provides information on STREAMS programming.
System Administration describes how to configure, use, and maintain the Tru64 UNIX operating system.
Reference Pages
Tru64 UNIX reference pages (also called manpages) contain descriptions of the routines (Section 9r), data structures (Section 9s), loadable services routines (Section 9u), and global variables (Section 9v) that apply to device drivers.
Reader’s Comments
Compaq welcomes any comments and suggestions you have on this and other Tru64 UNIX manuals.
You can send your comments in the following ways:
Fax: 603-884-0120 Attn: UBPG Publications, ZKO3-3/Y32
About This Manual xv
Internet electronic mail: readers_comment@zk3.dec.com A Readers Comment form is located on your system in the following
location:
/usr/doc/readers_comment.txt
Please include the following information along with your comments:
The full title of the book and the order number. (The order number is printed on the title page of this book and on its back cover.)
The section numbers and page numbers of the information on which you are commenting.
The version of Tru64 UNIX that you are using.
If known, the type of processor that is running the Tru64 UNIX software.
The Tru64 UNIX Publications group cannot respond to system problems or technical support inquiries. Please address technical questions to your local system vendor or to the appropriate Compaq technical support office. Information provided with the software media explains how to send problem reports to Compaq.
Conventions
This manual uses the following conventions: .
.
.
...
file
buf
[]
xvi About This Manual
A vertical ellipsis indicates that a portion of an example that would normally be present is not shown.
In syntax definitions, a horizontal ellipsis indicates that the preceding item can be repeated one or more times.
Italic (slanted) type indicates variable values, placeholders, and function parameter names.
In function definitions and syntax definitions used in driver configuration, this typeface indicates names that you must type exactly as shown.
In formal parameter declarations in function definitions and in structure declarations, brackets indicate arrays. Brackets also specify ranges for device minor numbers and device special files in file fragments. However, for the syntax definitions
that are used in driver configuration, these brackets indicate items that are optional.
| Vertical bars separating items that appear in the
syntax definitions used in driver configuration indicate that you choose one item from among those listed.
About This Manual xvii
1
Network Device Driver Environment
A network device is responsible for both transmitting and receiving frames over the network media. Network devices have network device drivers associated with them. A network device driver attaches a network subsystem to a network interface, prepares the network interface for operation, and governs the transmission and reception of network frames over the network interface. Examples of network interface types include Ethernet, Fiber Distributed Data Interface (FDDI), and Token Ring.
Similar to the character and block device drivers that are discussed in Writing Device Drivers, a network device driver has the following sections:
An include files section (Section 1.1)
A declarations section (Section 1.2)
A configure section (Section 1.3)
An autoconfiguration support section (Section 1.4)
An ioctl section (Section 1.9)
An interrupt section (Section 1.10)
Similar to a character device driver, a network device driver can also have a reset section (Section 1.8).
Unlike a character or block device driver, a network device driver contains the following network driver-specific sections:
An initialization section (Section 1.5)
A start transmit section (Section 1.6)
A watchdog section (Section 1.7)
An output section (Section 1.11)
Figure 1–1 shows the sections that a typical network device driver can contain. Network device drivers are not required to have all of these sections, and more complex network drivers can have additional sections. However, all network drivers must have a configure section, and because network device drivers are associated with some device, they also must have a device register header file.
Network Device Driver Environment 1–1
Figure 1–1: Sections of a Network Device Driver
Network Device Driver
/* Include Files Section */
/* Declarations Section */
/* Configure Section */
/* Initialization Section */
/* Autoconfiguration Support Section */
/* Start Transmit Section */
/* Ioctl Section */
/* Interrupt Section */
/* Reset Section */
/* Watchdog Section */
Unlike for block and character drivers, you do not specify network driver entry points in the dsent data structure. This means that a network driver has no exposure into the file system and, therefore, has no entry in the /dev directory. Thus, network drivers do not have block and character driver-specific interfaces such as open, close, read, write, and strategy.
12 Network Device Driver Environment
ZK-0818U-AI
Instead of registering its entry points in a dsent data structure, a network driver registers its entry points with the upper layers of the Tru64 UNIX operating system in an ifnet data structure. For example, a network driver registers entry points for queueing data for transmission and for starting data transmission.
In addition to storing the entry points for a network drivers associated interfaces, the ifnet data structure stores parameter-related information such as the transmission medium and statistics to track the performance of the interface and network.
The ifnet data structure also contains a queue of data packets that the network driver sends to the network device. These packets are linked lists of mbuf data structures. Each such linked list represents one data packet. Depending on how a network driver fills in certain members of the ifnet data structure, the upper-level network code fragments the data to be sent out over a network. In the case of the Ethernet network interface, the upper-level code never hands off to the driver a single packet that exceeds 1514 bytes.
1.1 Include Files Section for a Network Driver
A network device driver includes header files that define data structures and constant values that the driver references. A network device driver includes some of the same files as a block or character device driver, such as errno.h. It can also include the header files that are specific to network device drivers. For example:
#include <net/net_globals.h> #include <sys/socket.h> #include <net/if.h> #include <net/if_types.h>
The following code shows the include files section for the if_el device driver:
#include <sys/param.h> #include <sys/systm.h> #include <sys/mbuf.h> #include <sys/buf.h> #include <sys/protosw.h> #include <sys/socket.h> #include <sys/vmmac.h> #include <vm/vm_kern.h> #include <sys/ioctl.h> #include <sys/errno.h> #include <sys/time.h> #include <sys/kernel.h> #include <sys/proc.h> #include <sys/sysconfig.h> #include <net/if.h> #include <net/netisr.h> #include <net/route.h> #include <netinet/in.h> #include <netinet/in_systm.h> #include <netinet/in_var.h>
1
2
Network Device Driver Environment 1–3
#include <netinet/ip.h> #include <netinet/ip_var.h> #include <netinet/if_ether.h> #include <net/ether_driver.h> #include <io/common/devdriver.h> #include <hal/cpuconf.h> #include <kern/thread.h> #include <kern/sched_prim.h> #include <kern/lock.h>
#include <io/dec/eisa/eisa.h> #include <io/dec/pcmcia/pcmcia.h> #include <io/dec/pcmcia/cardinfo.h>
#include <io/dec/netif/lan_common.h>
#include <io/dec/netif/if_elreg.h> 8
1 Includes the ioctl.h include file, which defines common ioctl com-
3
4
5
6
7
mands. The ioctl.h file is located in /usr/include/sys/ioctl.h.
2 Includes the sysconfig.h header file, which defines the constants that
all device drivers use during configuration. The sysconfig.h file is located in /usr/include/sys/sysconfig.h.
3 Includes the if_ether.h header file, which defines the ether_header
data structure. All network drivers typically include this file. If you are writing the network driver for FDDI media, you also include
the header file if_fddi.h. If you are writing the network driver for Token Ring media, you also include the header file if_trn.h.
4 Includes the devdriver.h header file, which defines common device
driver data structures and constants. The devdriver.h file is located in /usr/include/io/common/devdriver.h.
5 Includes the header file eisa.h, which is associated with the ISA bus.
If you are writing the driver to operate on multiple bus architectures, you must include the bus-specific header file. The if_el device driver is implemented to operate on two buses: the ISA and the PCMCIA.
6 Includes the header files pcmcia.h and cardinfo.h, which are
associated with the PCMCIA bus.
7 Includes the lan_common.h file, which contains definitions that all
local area network (LAN) device drivers need.
8 Includes the device register header file. The directory specification you
make here depends on where you put the device register header file.
1.2 Declarations Section for a Network Driver
The declarations section for a network device driver contains the following categories of information:
1–4 Network Device Driver Environment
External and forward declarations (Section 1.2.1)
Declaration of softc and controller data structure arrays
(Section 1.2.2)
Declaration of the driver data structure (Section 1.2.3)
Definitions of driver-specific macros (Section 1.2.4)
The following sections discuss each of these categories of declarations, using the if_el device driver as an example.
The declarations section also contains the definition of the softc data structure and declarations for configure-related variables and data structures. Chapter 3 discusses the definition of a network drivers softc data structure. Section 4.1 discusses the declarations that are related to configuration.
1.2.1 External and Forward Declarations
The following code shows the external and forward declarations for the
if_el device driver:
int el_configure(cfg_op_t, cfg_attr_t *, size_t, cfg_attr_t *, size_t); 1
static int el_probe (io_handle_t, struct controller *); 2 static int el_attach(struct controller *); static int el_unattach(struct bus *, struct controller *); static int el_init_locked(struct el_softc *, struct ifnet *, int); static int el_init(int); static void el_start_locked(struct el_softc *, struct ifnet *); static void el_start(struct ifnet *); static int el_watch(int); static void el_reset_locked(struct el_softc *, struct ifnet *, int); static void el_reset(int); static int el_ioctl(struct ifnet *, u_int, caddr_t); static int el_intr(int); static void el_rint(struct el_softc *, struct ifnet *); static void el_tint(struct el_softc *, struct ifnet *); static void el_error(struct el_softc *, struct ifnet *); static void el_shutdown(struct el_softc *); static void el_card_remove(int, struct el_softc *); static int el_isa_reset_all(io_handle_t, int *, struct controller *); static int el_isa_activate(io_handle_t, int *, struct controller *); static unsigned short el_isa_read_offset(io_handle_t, int); static void el_wait(struct el_softc *); static void el_autosense_thread(struct el_softc *); static int el_card_out(struct el_softc *); extern struct timeval time; extern task_t first_task; 4
3
1 Declares the function prototype definitions for all exported functions. 2 Declares the driver interfaces for the if_el device driver. 3 Declares the external timeval data structure called time. Various
ioctl commands use this data structure.
Network Device Driver Environment 1–5
4 Declares a pointer to the external task_t data structure called
first_task. The task_t data structure is an opaque data structure; that is, all of its associated members are referenced and manipulated by the Tru64 UNIX operating system and not by the user of kernel threads. Every kernel thread must be part of a task.
The if_el drivers el_probe interface uses this data structure when it creates a kernel thread.
1.2.2 Declaring softc and controller Data Structure Arrays
The following code shows the declarations for the el_softc and controller data structure arrays. The system uses these arrays to find out
which softc and controller data structures are associated with a specific 3Com 3C5x9 device. The drivers el_probe interface initializes these arrays if the probe operation is successful.
The arrays of el_softc and controller data structures need to be static for the if_el device driver. Be aware that static arrays fix the maximum number of devices that the user can configure on the system.
#define el_MAXDEV 7 1 static struct el_softc *el_softc[el_MAXDEV]={0}; 2 static struct controller *el_info[el_MAXDEV]={0}; 3
static int el_isa_tag = 0; 4 static int el_isa_reset = 0; 5 decl_simple_lock_info(static, el_lock_info); 6
1 Defines a constant called el_MAXDEV, which allocates data structures
that the if_el device driver needs. A maximum of seven instances of the 3C5x9 controller can be on the system. This means that el_MAXDEV is the maximum number of controllers that the if_el driver can support. This is a small number of instances of the driver, and the data structures themselves are not large, so it is acceptable to allocate for the maximum configuration.
2 Declares an array of pointers to el_softc data structures and calls it
el_softc. The el_MAXDEV constant specifies the size of this array.
3 Declares an array of pointers to controller data structures and calls
it el_info. The el_MAXDEV constant specifies the size of this array.
4 Declares a variable called el_isa_tag and initializes it to the value
0 (zero). The if_el drivers el_isa_activate interface uses this variable.
5 Declares a variable called el_isa_reset and initializes it to the value
0 (zero). The if_el drivers el_probe interface uses this variable.
6 Uses the decl_simple_lock_info( ) routine to declare a simple lock
data structure called el_lock_info.
1–6 Network Device Driver Environment
1.2.3 Declaring and Initializing the driver Data Structure
The following code shows how the if_el device driver declares and initializes the driver data structure with the names of its entry points:
static struct driver eldriver = { 1
el_probe, 0, el_attach, 0, 0, 0, 0, 0, "el", el_info, 0, 0, 0, 0, 0, el_unattach, 0
};
1 Declares and initializes the driver data structure called eldriver.
Because a network device driver does not have exposure to the file system, it does not provide open, close, read, write, and strategy interfaces. The members of the driver data structure that specify these entry points are initialized to 0 (zero).
The if_el driver initializes the following members to nonzero values:
probe, which specifies the drivers probe interface, el_probe
cattach, which specifies the drivers controller attach interface,
el_attach
ctlr_name, which specifies the controller name, el
ctlr_list, which specifies a pointer to the array of pointers to
controller data structures, el_info
ctlr_unattach, which specifies the drivers controller unattach interface, el_unattach
1.2.4 Defining Driver-Specific Macros
To help you write more portable device drivers, Tru64 UNIX provides the following kernel routines, which allow you to read from and write to a control status register (CSR) address without directly accessing its device registers. These macros call the read_io_port( ) or write_io_port( ) generic routines.
Network Device Driver Environment 1–7
READ_BUS_D8
READ_BUS_D16
READ_BUS_D32
READ_BUS_D64
WRITE_BUS_D8
WRITE_BUS_D16
WRITE_BUS_D32
WRITE_BUS_D64
Reads a byte (8 bits) from a device register. Reads a word (16 bits) from a device register. Reads a longword (32 bits) from a device register. Reads a quadword (64 bits) from a device register. Writes a byte (8 bits) to a device register. Writes a word (16 bits) to a device register. Writes a longword (32 bits) to a device register. Writes a quadword (64 bits) to a device register.
The following code shows how the if_el driver uses the READ_BUS_D16, READ_BUS_D32, WRITE_BUS_D16, and WRITE_BUS_D32 kernel routines to construct driver-specific macros to perform read and write operations on the 3Com 3C5x9 device:
#define READ_CCR(sc) READ_BUS_D16((sc)->reg4); mb(); 1 #define WRITE_CCR(sc, val) WRITE_BUS_D16((sc)->reg4, (val)); mb(); #define READ_ACR(sc) READ_BUS_D16((sc)->reg6); mb(); #define WRITE_ACR(sc, val) WRITE_BUS_D16((sc)->reg6, (val)); mb(); #define WRITE_RCR(sc, val) WRITE_BUS_D16((sc)->reg8, (val)); mb(); #define WRITE_ECR(sc, val) WRITE_BUS_D16((sc)->regA, (val)); mb(); #define READ_EDR(sc) READ_BUS_D16((sc)->regC); mb(); #define WRITE_CMD(sc, val) WRITE_BUS_D16((sc)->regE, (val)); \
#define READ_STS(sc) READ_BUS_D16((sc)->regE); mb(); #define WRITE_DATA(sc, val) WRITE_BUS_D32((sc)->data, (val)); mb(); #define READ_DATA(sc) READ_BUS_D32((sc)->data); mb(); #define READ_ND(sc) READ_BUS_D16((sc)->reg6); mb(); #define WRITE_ND(sc, val) WRITE_BUS_D16((sc)->reg6, (val)); mb(); #define READ_MD(sc) READ_BUS_D16((sc)->regA); mb(); #define WRITE_MD(sc, val) WRITE_BUS_D16((sc)->regA, (val)); mb(); #define READ_TXF(sc) READ_BUS_D16((sc)->regC); mb(); #define READ_RXF(sc) READ_BUS_D16((sc)->regA); mb(); #define WRITE_AD1(sc, val) WRITE_BUS_D16((sc)->reg0, (val)); mb(); #define WRITE_AD2(sc, val) WRITE_BUS_D16((sc)->reg2, (val)); mb(); #define WRITE_AD3(sc, val) WRITE_BUS_D16((sc)->reg4, (val)); mb(); #define READ_TXS(sc) READ_BUS_D16((sc)->regA); mb(); #define WRITE_TXS(sc, val) WRITE_BUS_D16((sc)->regA, (val)); mb(); #define READ_RXS(sc) READ_BUS_D16((sc)->reg8); mb(); #define READ_FDP(sc) READ_BUS_D16((sc)->reg4); mb();
mb(); el_wait((sc))
1 Constructs driver-specific macros to read from and write to the 3Com
3C5x9 devices CSRs. The first argument to these macros specifies an I/O handle that
references a device register or memory that is located in bus address space (either I/O space or memory space). You can perform standard C mathematical operations (addition and subtraction only) on the I/O handle. The READ_CCR, WRITE_CCR, and the other macros construct the first argument by referencing the I/O handle that is defined in the el_softc data structure.
1–8 Network Device Driver Environment
The second argument to the WRITE_CCR and the other write macros specifies the data to be written to the device register in bus address space. These write macros construct the second argument by referencing the val variable. For the if_el driver, this data is typically one of the device register offsets that is defined in the if_elreg.h file.
The read and write driver-specific macros call the mb( ) kernel routine to perform a memory barrier. The mb( ) kernel routine ensures that the read or write operation is issued before the CPU executes any subsequent code. See Section 7.5 of the Tru64 UNIX
Writing Device
Drivers manual for more information about the mb( ) routine and
when to use it. Table 1–1 provides information on the driver-specific macros.
Table 1–1: Driver-Specific Macros
Macro Description
READ_CCR and WRITE_CCR Read from and write to the 3Com 3C5x9 devices
configuration control register.
READ_ACR and WRITE_ACR Read from and write to the 3Com 3C5x9 devices
address control register.
WRITE_RCR
WRITE_ECR
READ_EDR
WRITE_CMD
READ_STS
READ_DATA and
WRITE_DATA
READ_ND and WRITE_ND Read from and write to the 3Com 3C5x9 devices
READ_MD and WRITE_MD Read from and write to the 3Com 3C5x9 devices media
READ_TXF and READ_RXF Read from the 3Com 3C5x9 devices transmit and
WRITE_AD1, WRITE_AD2, and WRITE_AD3
READ_TXS and WRITE_TXS Read from and write to the 3Com 3C5x9 devices
Write to the 3Com 3C5x9 devices resource configuration register.
Write to the 3Com 3C5x9 devices EEPROM command register.
Read from the 3Com 3C5x9 devices EEPROM data register.
Write to the 3Com 3C5x9 devices command port registers.
Read from the 3Com 3C5x9 devices I/O status register. Read from and write to the 3Com 3C5x9 devices
receive data and transmit data registers.
network diagnostic register.
type and status register.
receive FIFO registers. Set the LAN physical address for the 3Com 3C5x9
device.
transmit status register.
Network Device Driver Environment 1–9
Table 1–1: Driver-Specific Macros (cont.)
Macro Description
READ_RXS
READ_FDP
Read from the 3Com 3C5x9 devices receive status register.
Read from the 3Com 3C5x9 devices FIFO diagnostic port register.
1.3 Configure Section for a Network Driver
The configure section for a network device driver contains a configure interface. The cfgmgr framework calls the drivers configure interface at system startup to handle static configuration requests. The cfgmgr framework can also call the drivers configure interface to handle user-level requests to dynamically configure, unconfigure, query, and reconfigure a device driver at run time. If you implement the driver as a single binary module, the configure interface can handle both static and dynamic configuration.
1.4 Autoconfiguration Support Section for a Network Driver
The autoconfiguration support section for a network device driver contains the following entry points:
A probe interface, which determines if the network device exists and is functional on the system
An attach interface, which establishes communication with the device and initializes the drivers ifnet data structure.
You define the entry point for each of these interfaces in the driver data structure.
1.5 Initialization Section for a Network Driver
The initialization section for a network device driver prepares the network to transmit and receive data packets.
1.6 Start Section for a Network Driver
The start section for a network device driver contains a start interface, which transmits data packets on the network interface. You define the entry point for the start interface in the ifnet data structure. However, before this interface can be called, the network adapter must be enabled for data packet transmission and reception. You enable the network adapter by invoking the SIOCSIFADDR ioctl command.
1–10 Network Device Driver Environment
1.7 Watchdog Section for a Network Driver
The watchdog section for a network device driver contains a watchdog interface, which attempts to restart the adapter. The watchdog interface is optional in a network device driver. If the network device driver implements it, watchdog is called by a kernel thread if the drivers interrupt handler has not shut down the countdown timer within a certain number of seconds of queueing a data packet for transmission from the upper layer. This indicates that the adapter is no longer on line.
1.8 Reset Section for a Network Driver
The reset section for a network device driver contains a reset interface. The reset interface resets the LAN adapter. This interface is called to restart the device following a network failure. This interface resets all of the counters and local variables. It can also free up and reallocate all of the buffers that the network driver uses.
1.9 ioctl Section for a Network Driver
The ioctl section for network device drivers performs miscellaneous tasks that have nothing to do with data packet transmission and reception. Typically, these tasks relate to turning specific features of the hardware on or off.
The ioctl section contains an ioctl interface. You define this entry point in the ifnet data structure.
1.10 Interrupt Section for a Network Driver
The interrupt section for a network device driver contains an interrupt handler. The interrupt handler processes network device interrupts. You define the entry point for the interrupt handler by calling the handler interfaces. The interrupt handler is called each time that the network interface receives an interrupt. After identifying which type of interrupt was received transmit or receive the interrupt handler calls the appropriate routine to process the interrupt.
1.11 Output Section for a Network Driver
The output section for a network device driver formats a data packet for transmission on the network. The ether_output( ) routine formats data packets for Tru64 UNIX network drivers. Despite its name, ether_output( ) handles the frame formats for Ethernet, token ring, and FDDI. After it has properly formatted the data packet, ether_output( ) enqueues the packet on the drivers send queue and calls the drivers start
Network Device Driver Environment 1–11
interface to transmit the data. All network drivers must set the output member of the ifnet data structure to ether_output.
1–12 Network Device Driver Environment
Loading...
+ 129 hidden pages