VxWorks Reference Manual : Libraries
ln97xEnd - END style AMD Am79C97X PCnet-PCI Ethernet driver
ln97xEndLoad( ) - initialize the driver and device
ln97xInitParse( ) - parse the initialization string
This module implements the Advanced Micro Devices Am79C971 Am79C972 and Am79C973 PCnet-PCI Ethernet 32 bit network interface driver.
The PCnet-PCI ethernet controller is inherently little endian because the chip is designed to operate on a PCI bus which is a little endian bus. The software interface to the driver is divided into three parts. The first part is the PCI configuration registers and their set up. This part is done at the BSP level in the various BSPs which use this driver. The second and third part are dealt in the driver. The second part of the interface comprises of the I/O control registers and their programming. The third part of the interface comprises of the descriptors and the buffers.
This driver is designed to be moderately generic, operating unmodified across the range of architectures and targets supported by VxWorks. To achieve this, the driver must be given several target-specific parameters, and some external support routines must be provided. These target-specific values and the external support routines are described below.
This driver supports multiple units per CPU. The driver can be configured to support big-endian or little-endian architectures. It contains error recovery code to handle known device errata related to DMA activity.
Big endian processors can be connected to the PCI bus through some controllers which take care of hardware byte swapping. In such cases all the registers which the chip DMA s to have to be swapped and written to, so that when the hardware swaps the accesses, the chip would see them correctly. The chip still has to be programmed to operated in little endian mode as it is on the PCI bus. If the cpu board hardware automatically swaps all the accesses to and from the PCI bus, then input and output byte stream need not be swapped.
This device is on-board. No jumpering diagram is necessary.
The only external interface is the ln97xEndLoad( ) routine, which expects the initString parameter as input. This parameter passes in a colon-delimited string of the format:
unit:devMemAddr:devIoAddr:pciMemBase:
:intLvl:memAdrs: memSize:memWidth:csr3b:offset:flags The ln97xEndLoad( ) function uses strtok( ) to parse the string.
- unit
- A convenient holdover from the former model. This parameter is used only in the string name for the driver.
- devMemAddr
- This parameter in the memory base address of the device registers in the memory map of the CPU. It indicates to the driver where to find the RDP register. The LANCE presents two registers to the external interface, the RDP (register data port) and RAP (register address port) registers. This driver assumes that these two registers occupy two unique addresses in a memory space that is directly accessible by the CPU executing this driver. The driver assumes that the RDP register is mapped at a lower address than the RAP register; the RDP register is therefore derived from the "base address." This parameter should be equal to NONE if memory map is not used.
- devIoAddr
- This parameter in the IO base address of the device registers in the IO map of some CPUs. It indicates to the driver where to find the RDP register. If both devIoAddr and devMemAddr are given then the device chooses devMemAddr which is a memory mapped register base address. This parameter should be equal to NONE if IO map is not used.
- pciMemBase
- This parameter is the base address of the CPU memory as seen from the PCI bus. This parameter is zero for most intel architectures.
- vecNum
- This parameter is the vector associated with the device interrupt. This driver configures the LANCE device to generate hardware interrupts for various events within the device; thus it contains an interrupt handler routine. The driver calls pciIntConnect( ) to connect its interrupt handler to the interrupt vector generated as a result of the LANCE interrupt.
- intLvl
- Some targets use additional interrupt controller devices to help organize and service the various interrupt sources. This driver avoids all board-specific knowledge of such devices. During the driver's initialization, the external routine sysLan97xIntEnable( ) is called to perform any board-specific operations required to allow the servicing of a LANCE interrupt. For a description of sysLan97xIntEnable( ), see "External Support Requirements" below.
- memAdrs
- This parameter gives the driver the memory address to carve out its buffers and data structures. If this parameter is specified to be NONE then the driver allocates cache coherent memory for buffers and descriptors from the system pool. The LANCE device is a DMA type of device and typically shares access to some region of memory with the CPU. This driver is designed for systems that directly share memory between the CPU and the LANCE. It assumes that this shared memory is directly available to it without any arbitration or timing concerns.
- memSize
- This parameter can be used to explicitly limit the amount of shared memory (bytes) this driver will use. The constant NONE can be used to indicate no specific size limitation. This parameter is used only if a specific memory region is provided to the driver.
- memWidth
- Some target hardware that restricts the shared memory region to a specific location also restricts the access width to this region by the CPU. On these targets, performing an access of an invalid width will cause a bus error.
This parameter can be used to specify the number of bytes of access width to be used by the driver during access to the shared memory. The constant NONE can be used to indicate no restrictions.
Current internal support for this mechanism is not robust; implementation may not work on all targets requiring these restrictions.
- csr3b
- The LANCE control register #3 determines the bus mode of the device, allowing the support of big-endian and little-endian architectures. This parameter, defined as "UINT32 lnCSR_3B", is the value that will be placed into LANCE control register #3. The default value supports Motorola-type buses. For information about changing this parameter, see the manual. Normally for devices on the PCI bus this should always be little endian. This value is zero normally
- offset
- This parameter specifies the offset from which the packet has to be loaded from the begining of the device buffer. Normally this parameter is zero except for architectures which access long words only on aligned addresses. For these architectures the value of this offset should be 2.
- flags
- This is parameter is used for future use, currently its value should be zero.
This driver requires several external support functions, defined as macros:
SYS_INT_CONNECT(pDrvCtrl, routine, arg) SYS_INT_DISCONNECT (pDrvCtrl, routine, arg) SYS_INT_ENABLE(pDrvCtrl) SYS_INT_DISABLE(pDrvCtrl) SYS_OUT_BYTE(pDrvCtrl, reg, data) SYS_IN_BYTE(pDrvCtrl, reg, data) SYS_OUT_WORD(pDrvCtrl, reg, data) SYS_IN_WORD(pDrvCtrl, reg, data) SYS_OUT_LONG(pDrvCtrl, reg, data) SYS_IN_LONG(pDrvCtrl, reg, data) SYS_ENET_ADDR_GET(pDrvCtrl, pAddress) sysLan97xIntEnable(pDrvCtrl->intLevel) sysLan97xIntDisable(pDrvCtrl->intLevel) sysLan97xEnetAddrGet(pDrvCtrl, enetAdrs)There are default values in the source code for these macros. They presume memory mapped accesses to the device registers and the pciIntConnect( ), and intEnable( ) BSP functions. The first argument to each is the device controller structure. Thus, each has access back to all the device-specific information. Having the pointer in the macro facilitates the addition of new features to this driver.The macros SYS_INT_CONNECT, SYS_INT_DISCONNECT, SYS_INT_ENABLE and SYS_INT_DISABLE allow the driver to be customized for BSPs that use special versions of these routines.
The macro SYS_INT_CONNECT is used to connect the interrupt handler to the appropriate vector. By default it is the routine pciIntConnect( ).
The macro SYS_INT_DISCONNECT is used to disconnect the interrupt handler prior to unloading the module. By default this is pciIntDisconnect( ).
The macro SYS_INT_ENABLE is used to enable the interrupt level for the end device. It is called once during initialization. It calls an external board level routine sysLan97xIntEnable( ).
The macro SYS_INT_DISABLE is used to disable the interrupt level for the end device. It is called during stop. It calls an external board level routine sysLan97xIntDisable( ).
The macro SYS_ENET_ADDR_GET is used get the ethernet hardware of the chip. This macro calls an external board level routine namely sysLan97xEnetAddrGet( ) to get the ethernet address.
When implemented, this driver requires the following system resources:
- one mutual exclusion semaphore
- one interrupt vector
- 13288 bytes in text for a I80486 target
- 64 bytes in the initialized data section (data)
- 0 bytes in the uninitialized data section (BSS)The driver allocates clusters of size 1520 bytes for receive frames and and transmit frames.
end.h endLib.h etherMultiLib.h ln97xEnd.h
ln97xEnd, muxLib, endLib, netBufLib Writing and Enhanced Network Driver Advanced Micro Devices PCnet-PCI Ethernet Controller for PCI.
ln97xEndLoad( ) - initialize the driver and device
END_OBJ * ln97xEndLoad ( char * initString /* string to be parse by the driver */ )
This routine initializes the driver and the device to the operational state. All of the device-specific parameters are passed in initString, which expects a string of the following format:
unit:devMemAddr:devIoAddr:pciMemBase:
:intLvl:memAdrs :memSize:memWidth:csr3b:offset:flags This routine can be called in two modes. If it is called with an empty but allocated string, it places the name of this device (that is, "lnPci") into the initString and returns 0.
If the string is allocated and not empty, the routine attempts to load the driver using the values specified in the string.
An END object pointer, or NULL on error, or 0 and the name of the device if the initString was NULL.
ln97xInitParse( ) - parse the initialization string
STATUS ln97xInitParse ( LN_97X_DRV_CTRL * pDrvCtrl, /* pointer to the control structure */ char * initString /* initialization string */ )
Parse the input string. This routine is called from ln97xEndLoad( ) which intializes some values in the driver control structure with the values passed in the intialization string.
The initialization string format is: unit:devMemAddr:devIoAddr:pciMemBase:
:intLvl:memAdrs :memSize:memWidth:csr3b:offset:flags
- unit
- Device unit number, a small integer.
- devMemAddr
- Device register base memory address
- devIoAddr
- Device register base IO address
- pciMemBase
- Base address of PCI memory space
- vecNum
- Interrupt vector number.
- intLvl
- Interrupt level.
- memAdrs
- Memory pool address or NONE.
- memSize
- Memory pool size or zero.
- memWidth
- Memory system size, 1, 2, or 4 bytes (optional).
- CSR3
- Value of CSR3 (for endian-ness mainly)
- offset
- Offset of starting of data in the device buffers.
- flags
- Device specific flags, for future use.
OK, or ERROR if any arguments are invalid.