VxWorks API Reference : Driver 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 Am79C970A, 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 with in the driver. The second part of the interface is comprised of the I/O control registers and their programming. The third part of the interface is comprised 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.
Some big-endian processors may be connected to a PCI bus through a host/PCI bridge which performs byte swapping during data phases. On such platforms, the PCnet-PCI controller need not perform byte swapping during a DMA access to memory shared with the host processor.
This device is on-board. No jumpering diagram is necessary.
The drvier provides one standard external interface, ln97xEndLoad( ). As input, this routine takes a string of colon-separated parameters. The parameters should be specified in hexadecimal (optionally preceded by 0x or a minus sign -). The parameter string is parsed using strtok_r( ).
The format of the parameter string is:
unit:devMemAddr:devIoAddr:pciMemBase:vecNum:intLvl: memAdrs:memSize:memWidth:csr3b:offset:flags
- unit
- The unit number of the device. Unit numbers start at zero and increase for each device controlled by the same driver. The driver does not use this value directly. The unit number is passed through the MUX API where it is used to differentiate between multiple instances of a particular driver.
- devMemAddr
- This parameter is the memory mapped I/O base address of the device registers in the memory map of the CPU. The driver will locate device registers as offsets from this base address.
The PCnet 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 is a required parameter.
- devIoAddr
- This parameter specifies the I/O base address of the device registers in the I/O map of some CPUs. It indicates to the driver where to find the RDP register. This parameter is no longer used, but is retained so that the load string format will be compatible with legacy initialization routines. The driver will always use memory mapped I/O registers specified via the devMemAddr parameter.
- pciMemBase
- This parameter is the base address of the host processor 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 PCnet 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 PCnet 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 PCnet 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 memory pool. The PCnet 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 PCnet. 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 PCnet-PCI Control and Status Register 3 (CSR3) controls, among other things, big-endian and little-endian modes of operation. When big-endian mode is selected, the PCnet-PCI controller will swap the order of bytes on the AD bus during a data phase on access to the FIFOs only: AD[31:24] is byte 0, AD[23:16] is byte 1, AD[15:8] is byte 2 and AD[7:0] is byte 3. In order to select the big-endian mode, set this parameter to (0x0004). Most implementations, including natively big-endian host architectures, should set this parameter to (0x0000) in order to select little-endian access to the FIFOs, as the driver is currently designed to perform byte swapping as appropriate to the host architecture.
- offset
- This parameter specifies a memory alignment offset. Normally this parameter is zero except for architectures which can only access 32-bit words on 4-byte aligned address boundaries. 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 five externally defined support functions that can be customized by modifying global pointers. The function pointer types and default "bindings" are specified below. To change the defaults, the BSP should create an appropriate routine and set the function pointer before first use. This would normally be done within sysHwInit2( ).
Note that all of the pointers to externally defined functions must be set to a valid executable code address. Also, note that sysLan97xIntEnable( ), sysLan97xIntDisable( ), and sysLan97xEnetAddrGet( ) must be defined in the BSP. This was done so that the driver would be compatible with initialization code and support routines in existing BSPs.
The function pointer convention has been introduced to facilitate future driver versions that do not explicitly reference a named BSP-defined function. Among other things, this would allow a BSP designer to define, for example, one endIntEnable( ) routine to support multple END drivers.
- ln97xIntConnect
IMPORT STATUS (* ln97xIntConnect) ( VOIDFUNCPTR * vector, /* interrupt vector to attach to */ VOIDFUNCPTR routine, /* routine to be called */ int parameter /* parameter to be passed to routine */ ); /* default setting */ ln97xIntConnect = pciIntConnect;The ln97xIntConnect pointer specifies a function used to connect the driver interrupt handler to the appropriate vector. By default it is the pciIntLib routine pciIntConnect( ).
- ln97xIntDisconnect
IMPORT STATUS (* ln97xIntDisconnect) ( VOIDFUNCPTR * vector, /* interrupt vector to attach to */ VOIDFUNCPTR routine, /* routine to be called */ int parameter /* routine parameter */ ); /* default setting */ ln97xIntDisconnect = pciIntDisconnect2;The ln97xIntDisconnect pointer specifies a function used to disconnect the interrupt handler prior to unloading the driver. By default it is the pciIntLib routine pciIntDisconnect2( ).
- ln97xIntEnable
IMPORT STATUS (* ln97xIntEnable) ( int level /* interrupt level to be enabled */ ); /* default setting */ ln97xIntEnable = sysLan97xIntEnable;The ln97xIntEnable pointer specifies a function used to enable the interrupt level for the END device. It is called once during initialization. By default it is a BSP routine named sysLan97xIntEnable( ). The implementation of this routine can vary between architectures, and even between BSPs for a given architecture family. Generally, the parameter to this routine will specify an interrupt level defined for an interrupt controller on the host platform. For example, MIPS and PowerPC BSPs may implement this routine by invoking the WRS intEnable( ) library routine. WRS Intel Pentium BSPs may implement this routine via sysIntEnablePIC( ).
- ln97xIntDisable
IMPORT STATUS (* ln97xIntDisable) ( int level /* interrupt level to be disabled */ ); /* default setting */ ln97xIntDisable = sysLan97xIntDisable;The ln97xIntDisable pointer specifies a function used to disable the interrupt level for the END device. It is called during stop. By default it is a BSP routine named sysLan97xIntDisable( ). The implementation of this routine can vary between architectures, and even between BSPs for a given architecture family. Generally, the parameter to this routine will specify an interrupt level defined for an interrupt controller on the host platform. For example, MIPS and PowerPC BSPs may implement this routine by invoking the WRS intDisable( ) library routine. WRS Intel Pentium BSPs may implement this routine via sysIntDisablePIC( ).
- ln97xEnetAddrGet
IMPORT STATUS (* ln97xEnetAddrGet) (LN_97X_DRV_CTRL * pDrvCtrl, char * pStationAddr); /* default setting */ ln97xEnetAddrGet = sysLan97xEnetAddrGet;The ln97xEnetAddrGet pointer specifies a function used to get the Ethernet (IEEE station) address of the device. By default it is a BSP routine named sysLan97xEnetAddrGet( ).
When implemented, this driver requires the following system resources:
- one mutual exclusion semaphore
- one interrupt vector
- 14240 bytes in text for a PENTIUM3 target
- 120 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.
"Network Protocol Toolkit User's Guide"
"PCnet-PCI II Single-Chip Full-Duplex Ethernet Controller for PCI Local Bus Product"
"PCnet-FAST Single-Chip Full-Duplex 10/100 Mbps Ethernet Controller for PCI Local Bus Product"
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:vecnum: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:vecNum:intLvl:memAdrs :memSize:memWidth:csr3b:offset:flags
- unit
- The device unit number. Unit numbers are integers starting at zero and increasing for each device contolled by the driver.
- devMemAddr
- The device memory mapped I/O register base address. Device registers must be mapped into the host processor address space in order for the driver to be functional. Thus, this is a required parameter.
- devIoAddr
- Device register base I/O address (obsolete).
- pciMemBase
- Base address of PCI memory space.
- vecNum
- Interrupt vector number.
- intLvl
- Interrupt level. Generally, this value specifies an interrupt level defined for an external interrupt controller.
- memAdrs
- Memory pool address or NONE.
- memSize
- Memory pool size or zero.
- memWidth
- Memory system size, 1, 2, or 4 bytes (optional).
- CSR3
- Control and Status Register 3 (CSR3) options.
- offset
- Memory alignment offset.
- flags
- Device specific flags reserved for future use.
OK, or ERROR if any arguments are invalid.