WD 80x3 Under AIX
All this stuff is tucked away in /nifl. 
Makefile README bin instal man wdnet

README  IBM PS/2 WD8003Ex/A Ethernet Adapter Support

Introduction and Configuration
   This README describes how to configure your WD8003Ex/A Hardware and Software Options. The software provides support for one or two IBM WD8003Ex/A Ethernet Adapters running under AIX PS/2.  This README isrelevent for both Standalone and Heterogeneous installations, and supercedes the P211000 release notes.

Before installing the WD8003E board in your system, it may be necessary to manually set the Transceiver Type using the two jumpers on the WD8003E board. If you intend to use an external transceiver, select the AUI option.  If you intend to use the onboard transceiver, select the BNC option. If no WD8003E adapter is currently installed in the system, follow the instructions for 
installing an adapter in the appropriate IBM PS/2 Quick Reference Guide.

To configure the system to recognize the adapter, copy the option diskette which came with the adapter to a backup copy of the Reference Diskette which came with the system.  For instructions on how to copy an option diskette, see the appropriate IBM PS/2 Quick Reference Guide.  After the option information has been copied to the backup copy of the Reference Diskette, the system may be configured.

The WD8003E adapter has several configuration options such as Enable/Disable Adapter, I/O Address Range, Interrupt Level, Packet Buffer RAM Address Range. All are set using the reference diskette.  When running the reference diskette, the default values may generally be used.  Only if conflicts occur is it necessary to use values other than the default values.

Now boot the system under AIX PS/2.  The AIX PS/2 TCP/IP LPP must be installed before the AIX PS/2 WD8003Ex/A software.  This LPP provides the network applications such as ftp, telnet, rlogin, and others which are used to communicate over an Ethernet or Token Ring network.  You may check to see if the TCP/IP LPP is installed (and at what level) on your system by using the following command: "grep tcpip /etc/lpp/ghf".  See the AIX PS/2 TCP/IP User's Guide for instructions on how to install AIX PS/2 TCP/IP.

Superuser (root) authority is required to install the WD8003Ex/A software under AIX.  Once superuser authority is established, change directories to /usr/nifl/wd and enter the command "make install".  This will install the appropriate code into the kernel, modify some system files and rebuild the kernel.

Before rebooting with the new kernel, you may want to configure your machines local startup script.  When the system boots, the "/etc/rc.tcpip" script searches for a file called "/<LOCAL>/rc.tcpip.local" which is located in the "/<LOCAL>" directory of the system which has the WD8003Ex/A installed.  While it is usually advisable to configure your system from the "/etc/rc.tcpip" file, for unique configurations, /<LOCAL>/rc.tcpip.local comes in handy. For
example if you have 12 PS/2's on a cluster and ten use WD ethernet boards, while two use UB's, /etc/rc.tcpip should "ifconfig wd0 IPaddr", and the /<LOCAL>/rc.tcpip.local should "ifconfig net0 IPaddr".  It is better to have only two local files to maintain as opposed to ten.

To correctly configure rc.tcpip.local, make sure to remove any extra lines for "net0", "en0", etc.  For each adapter, there should be one line to configure each device.  Use "ifconfig wd? IPaddr", where "?" can be either "0" or "1", and "IPaddr" is the symbolic name (often the systemname) found in the /etc/hosts file.  It is always advisable to check /etc/hosts for correctness when adding new sites to a cluster.

   After the startup scripts are set up, boot the system and make sure there are no errors. The WD8003Ex/A network device should be available immediately after rebooting the system.  If your machine fails to reboot and "ping" other sites, reread this procedure or refer to the "AIX TCPIP USERS GUIDE".

INSTALLATION/TROUBLESHOOTING HINTS:

   o Always check the *simple* things first, like:

 a. Did I check the release notes up to the current PTF level? (ha-ha, very funny)
 b. Am I using a (tested) good ethernet cable?
 c. Is the cable plugged in?
 d. Is the TCP/IP LPP installed?
 e. Am I using the correct transceiver type?
 f. Are there more than 2 WD network cards installed in the backplane?  The WD driver supports a maximum of two cards.

   o When the following message is displayed, you may not be using the fixed version of if_ena.o, or it may not named correctly:
       
 ar -rv /usr/sys/386/386lib.a /usr/nifl/wd/bin/if_ena.o
 ** error code 1

   o If newkernel -install fails, the /local or /tmp filesystems may not have enough space.  Truncate any excess log files in /<LOCAL>/adm/{messages.old,pacct}, etc.  *NEVER* remove a log file.  Simply "cat /dev/null > filename".  You should issue a "kill -1 PID" to the syslogd process after truncating a file like /local/adm/messages.  Run "make install" again.
 

   o "make install" may have run to completion with no errors and rebuilt the kernel correctly.  If, after rebooting the machine, "ifconfig wc0" shows no sign of wd0, you probably did not boot off of the new kernel.  Make sure that /<LOCAL>/unix.std is the latest (check the date) kernel with newly installed wd support, and reboot the machine with the good kernel.  If this doesn't fix the problem, as a last resort, you may wish to copy a working kernel from another machine of the same type, patch it, and restore it by typing following steps:

     a.  cd /local
     b.  cp /<site with good kernel>/unix.std unix.std
     c.  /usr/sys/bin/ldminit -c - -l unix.std
     d.  loc_site:#:2 (where # is the site number of the machine)
     e.  utsname+32:"SITENAME": (where SITENAME is local name).
     f.  cluster_id:0xHHHHHHHH:4: ( Remember to swap bytes on PS/2's )
   o Example, an IP address of 200.130.20.1 would be patched as "cluster_id:0x0114c882:4:"
     g.  Press ctl-d
     h.  Reboot the machine
 

   o Even after successfully installing the WD8003E/A driver and rebooting the machine, you may still not be on the network although you have configured "wd0", and netstat -r shows correct routes.  This could mean that the machine has not been configured to use the WD8003Ex/A adapter with the correct transceiver type.  To correct this problem complete the following steps:

     a.  Halt the machine.
     b.  Remove the WD ethernet board from the chassis.
     c.  Choose the correct jumper configuration.
     d.  Reinstall the board and make sure it is secure.
     e.  Reboot ( you may need to rerun the reference diskette).

 NOTE:  Some boards may use the reference diskette to set the transceiver type.  If there are no jumpers on the WD ethernet board, set the transceiver type by booting with the reference diskette and choosing the "Set Configuration" option.

Removal
   The IBM WD8003Ex/A support may be removed from the system by logging in as root and running the devices command.  Once in the devices menu, select the "delete" option, select the "lan" category, and then select "wd0" or "wd1". When you exit the devices command, it will rebuild the kernel and the next time the AIX system is booted it will not have IBM WD8003Ex/A support in the kernel.  Alternatively, copy a previous kernel that has the default UB or 3COM ethernet driver support into /local/unix.std, patch if necessary, and reboot.



If_ena.n

WD8003E Ethernet/IEEE 802.3 Interface SYNOPSIS

   The wd device implements a LAN interface driver for the WD8003E/A family of LAN adaptors. The interface is supported for use with the AIX TCP/IP network package. The driver implements both the Ethernet and IEEE 802.3 modes of operation with the default being the Ethernet mode.

  The wd driver follows the normal AIX conventions for a LAN interface driver. It may be installed by using the devices command and adding wd8003e in the LAN section.

  The wd driver may only be installed once via the devices command no matter the number of adaptors installed. The driver automatically detects the number and types of adaptors installed and configures itself accordingly. The adaptor found in the lowest numbered slot is named wd0. If more than one adaptor is found, they are sequentially numbered in increasing slot order.
 
   The device does not have a special file associated with it and has no special ioctl commands for use by the user. Each autoconfigured adaptor may seen via the "netstat -i" command.
 
  The adaptor is made accessible to the TCP/IP protocols via the /etc/ifconfig command using the adaptor name/unit to identify which adaptor.



IF_ENA Driver Description

Introduction
  The if_ena driver provides support for the Western Digital WD80X3 and IBMENA families of LAN interfaces. The driver conforms to IBM AIX PS/2 device driver requirements for such a driver and follows the interfaces defined in the AIX Operating System For Personal System/2 Technical Reference Volume 2, Appendix C.

The basic driver form is based on drivers for the 4.3BSD version of UNIX. As a result, there are few surprises to be found in the driver.

This document describes the driver functions and data structures. Data structures which are a generic part of AIX will not be described in detail since they are documented elsewhere. The last section of this document gives a brief overview of the flow of control through the driver.

Driver Functions
   There are fourteen functions used in the if_ena driver. Of these functions, most are mandated by the AIX LAN driver interface and the rest are auxilliary functions used only by the driver.
These functions are:
wdinit,
wdattach,
wdintr,
wdreset,
wdoutput,
wdstart,
wdinput,
wdioctl,
wd_insert_slot,
wdinitboard,
wdgetboardtype,
wdtype,
wdbufflen,
wdwatchdog.

wdinit(dev)
    This function is a standard AIX driver initialization routine. The input parameter, dev, is defined for init routines and is used in LAN interface drivers only for the major device number which is used by the AIX devexist function.

The init function starts by querying AIX for all boards found for each adaptor ID defined in the array wd_adaptids. As each board is found, it is inserted into the slotmap array with an insertion sort on the slot number.  After the board's presence has been recorded, a count of the number of
boards found is incremented.

If no boards are found, the init function exits.

If boards were found the device is installed with SM DEV_INSTALL.

The boards are then examined starting at the lowest slot number found and working to the highest slot number found. This results in sequential unit numbers being assigned with zero for the board in the lowest numbered slot, increasing by one for each additional board found in slot order.

As each board is examined, the board type and configuration information is obtained and stored in a struct wdsoftc structure in the array wd_ifs, the driver interrupt handler is then inserted as a handler for the IRQ level the board is configured for, the shared memory segment is mapped into kernel address space, and the wdattach function is called with the unit number corresponding to the board.

When the init function exits, the driver is ready to be configured and the hardware initialized.

wdattach(unit)
This function uses its parameter, unit, as an index into the wd_ifs array and then initializes the struct ifnet structure defined by the wd_if member of the wdsoftc structure.

It is here that the name and unit number of the device become associated with the ifnet structure.  This is the name used by 2ifconfig and displayed by netstat -i

wdintr(vec)
This function is the center of most driver activity.  It is the device interrupt handler.  As such, it conforms to AIX device interrupt handler requirements and supports multiple devices on the same and different IRQ levels.

When the interrupt handler is called, it searches all of its device data structures for all devices which match the IRQ level specified by the vec parameter.  For each device found, the interrupt handler first disables the device interrupts and then checks to see if this device did, in fact, interrupt.  If the device didn't interrupt, the handler restores the interrupt status to its original value and continues the search.  This allows the IRQ to be shared with other drivers.

If the device did interrupt, a number of conditions are checked for and the events indicated in the status word are processed. The events handled are:

Receive Ring Overrun
In the case of a 8390 chip, special actions must be taken to let it recover.

Packet Received
  The receive buffer is scanned for all received packets.  For each one found, the \f5wdinput\fP function is called to retreive it. Then the packet is examined for its type and processed accordingly.

If the type is a value less than SM ETHERNETMTU, it is interpreted as an IEEE 802.2 LLC (Logical Link Control) packet.  In the current version of the driver, only SNAP packets (802.1 Sub-Network Access Protocol) are actually interpreted. The XID (eXchange ID) and TEST packets of the LLC protocol are responded to if received.

If the type is greater than SM ETHERNETMTU, it is interpreted as an Ethernet packet.

In both data link protocol modes, 802.2 and Ethernet, only the IP (Internet Protocol) and ARP (Address Resolution Protocol) are retained and queued to the appropriate input queue.  ARP packets are processed directly by calling arpinput and IP is placed on the ipintrq and a network, software interrupt is scheduled.

Transmit Complete Interrupt
  When this event is received, the currently active transmit buffer is freed and wdstart is called to start another packet transmitting if possible. Statistics counters in the ifnet structure are updated appropriately for all events.

wdreset(ifp)
This function is called by wdioctl when the IFF_UP flag is turned off by the ifconfig command. The ifp parameter is used to find the specific hardware to be reset.

wdoutput(ifp, m0, dst)
  This function is used to format a packet to be transmitted into the appropriate Ethernet or IEEE format and then queue it to the hardware specific queue. If the hardware isn't busy, it is started by calling the wdstart function. The ifp parameter is used to find the hardware specific queue in the ifnet structure. The m0 parameter is an mbuf pointer pointing to the data to be transmitted. The dst parameter is a poitner to an address structure which will, in the case of an SM AF_INET address, be converted to an Ethernet/IEEE 802.3 physical address via the AIX arp_resolve function.  This final address is used to build the header to the packet. The data is appended to the header and queued for transmit.

wdstart(ifp)
This function checks for the availability of a transmit buffer. If a buffer is available, the packet is copied to the buffer. If the hardware is not busy with a previous transmit, the buffer transmit will be started.  If there isn't an available buffer, the function just returns

wdinput(ifp, wdif)
This function is called by the interrupt handler when a packet is available to be received.  It is called once for each packet the interrupt handler finds in the receive buffer ring.  The entire packet is copied into an mbuf, or chain of mbufs.  The head of the resultant mbuf chain is returned as the result of the function.

wdioctl(ifp, cmd, data)
This functions is used to implement several ioctl calls specific to LAN interfaces.

SIOCSIFADDR
Set the interface address to the specified value.  Currently only the SM AF_INET address family is supported.

SIOCSIFFLAGS
Set the flags for the interface.  If the board is changing SM IFF_UP state, the board is initiallized by calling wdinitboard when changing to SM IFF_UP
and reset by wdreset when SM IFF_UP is cleared.

If the SM IF_IEEE flag is set, the if_mtu member of the ifnet structure for the device is changed from SM ETHERNETMTU to SM ETHERMTU to account for the size of the IEEE 802.2 header.

wd_insert_slot(map, nwd, slot)
This function is an internal utility which performs an insertion sort to add the slot parameter to the list of slots which have appropriate boards. The purpose is to be able to have the logical unit numbers of the interfaces correspond to the slot order of the boards. This is to compensate for the AIX devexist function searching for boards by POS ID values.  This driver supports multiple POS IDs.

The map parameter is the unsigned character array of slots and the nwd parameter is the size of the array.

wdinitboard(unit)
This function initializes the hardware to a working state. The unit parameter identifies which board to initialize.

The board is first reset to a powerup state and the buffer RAM is configured to the required physical address and enabled for use. The remaining setup consists of:

Check if a 16-bit board requiring additional setup.
If the board uses an interface chip, then the Configuration Control Register (CCR) is initialized.
The access, receive and transmit modes are setup.
The bus transfer mode is setup.  It is always word mode.
The xmit buffer availability is configured.  The driver uses double buffering if there is more than 8K of RAM in order to improve performance.
The xsmit and rcv buffer spaces are configured along with the memory size.
The desired interrupts are configured.
The physical address of the board is programmed into the controller chip.
The receiver is configured and started running.

wdgetboardtype(port, wdif)
This function probes the board identified by the IO port parameter and the wdif parameter. Various tests are done to determine what features are present. Features checked for include:

Hardware revision level
Interface chip presence
If a 690 chip is used instead of an 8390
The board media type
If a 594 interface chip is being used
The RAM size

wdtype(type)
This function uses the type parameter to look up the string identifying the board type.

wdbufflen(m0)
This function is a local utility routine that determines the number of bytes in an mbuf chain.

wdwatchdog(wdif)
This function is a special case to handle the 690 chip problem where it can lock up under heavy load.  This watchdog timer function is scheduled to go off HZ/2 clock ticks after the transmit is started. If the transmit completes correctly, the timer is cancelled.

Driver Data Structures
There are a few data structures specific to the driver.  The rest are standard AIX data structures. The important driver specific data structures are:

unsigned int wd_adaptids[]
This array contains a list of all supported POS IDs.  It is used to drive the search for boards via the devexist function in wdinit.

When new boards that have different IDs become available, this array should be added to struct wdsoftc *wd_ifs.

This pointer will be initialized to point to a data area which is large enough to have one wdsoftc structure per board found in the system.

The wdsoftc structure contains a number of structure members which hold the data necessary to control each board.  It also contains one member which is the ARP table which in turn contains the standard AIX ifnet structure for the board.  The rest of the structure members are used to control the board and keep track of which transmit buffers are in use.

The structure is defined as follows:

struct wdsoftc {
   struct arpcom wd_ac;         /* ARP table for this device */
#define wd_if   wd_ac.ac_if
#define wd_physaddr wd_ac.ac_lanaddr
   unsigned int wd_vec;         /* IRQ level */
   unsigned int wd_ioport;      /* I/O port */
   unsigned int wd_memsize;     /* size of memory segment */
   caddr_t      wd_base;        /* base address (not virtual) */
   caddr_t      wd_mp;          /* mapped address of memory segment */
   unsigned long wd_type;       /* derived hardware feature type */
   unsigned short wd_id;        /* board adaptor ID */
   unsigned short wd_rev;       /* board revision */
   struct callout *wd_watchdog; /* watchdog callout pointer */
   unsigned short wd_bufflen[2];/* length of transmit data in buffer */
   unsigned char wd_buffers;    /* number of transmit buffers */
   unsigned char wd_buffavail;  /* buffers available */
   unsigned char wd_buffinuse;  /* transmit buffers in use (mask) */
   unsigned char wd_xmitbusy;   /* tranmitter is busy */
   unsigned char wd_lastbuff;   /* last buffer used */
   unsigned char wd_nxtpkt;     /* next packet in the receive ring */
};

struct ifnet

   This structure is contained within the wdsoftc structure described above.  It is contained within the wd_ac member of the wdsoftc structure.  The ifnet structure is in turn linked into a list of devices by the wdattach function in order for the interface to be found by the protocols which might use the interface.

The ifnet structure is the primary mechanism for associating the device specific driver with protocol drivers.  All output gets queued through this structure while waiting on the hardware to become ready. Since this is a standard AIX data structure, it won't be described further.

Flow of Control
The driver control flows through three basic paths : intialization, output, and input. As stated above, the ifnet structure is the common tie between protocols and the device driver.

Initialization Path
   Initialization starts at system boot time and is completed when the interface is configured. Essentially, is called at boot time which uses some standard AIX utilities and then determines how many boards and of which types are present in the system. At configuration time, wdioctl is called which will then call wdinitboard to configure and activate the specific hardware.

Output Path
   The users of the interface are protocol stacks.  When a protocol wants to send data, it calls the wdoutput function which does appropriate manipulation of the data, queues it and then tries to send it if the hardware is available.  If it isn't available at that time, wdoutput returns.  In this case, another attempt will be made when the transmitter hardware interrupts on transmit complete and wdstart is called to try sending the queued data.

Input Path
  This path is activated on a receive interrupt. The wdintr function is called to handle the interrupt.  This can result in wdinput being called to retrieve the packet.  If the packet is one the system is interested in, either arpinput will be called or it will be inserted into the protocol receive queue and a software interrupt for that protocol will be scheduled.
 


9595 Main Page