// Sample code file: cneamd.c
// Warning: This code has been marked up for HTML
/***********************************************************************\
* $name: CNEAMD.C
* $version: 8
* $date_modified: 12181998
* $description: C version of the ne2100, PCnetISA, PCnetISA+, PCnetPCI,
* PCnetPCI_II, PCnet-Fast (100 MBps) family driver.
* $owner: ODI LAN Driver Manager
* Copyright (c) 1996, 1997, 1998 Novell, Inc. All Rights Reserved.
*
* THIS WORK IS SUBJECT TO U.S. AND INTERNATIONAL COPYRIGHT LAWS AND
* TREATIES. USE AND REDISTRIBUTION OF THIS WORK IS SUBJECT TO THE LICENSE
* AGREEMENT ACCOMPANYING THE SOFTWARE DEVELOPMENT KIT (SDK) THAT CONTAINS
* THIS WORK. PURSUANT TO THE SDK LICENSE AGREEMENT, NOVELL HEREBY GRANTS
* TO DEVELOPER A ROYALTY-FREE, NON-EXCLUSIVE LICENSE TO INCLUDE NOVELL'S
* SAMPLE CODE IN ITS PRODUCT. NOVELL GRANTS DEVELOPER WORLDWIDE
* DISTRIBUTION RIGHTS TO MARKET, DISTRIBUTE, OR SELL NOVELL'S SAMPLE CODE
* AS A COMPONENT OF DEVELOPER'S PRODUCTS. NOVELL SHALL HAVE NO
* OBLIGATIONS TO DEVELOPER OR DEVELOPER'S CUSTOMERS WITH RESPECT TO THIS
* CODE.
************************************************************************/
/***********************************************************************\
* *
*
* Name:
* cneamd.c
*
* Description:
*
* C version of the ne2100, PCnetISA, PCnetISA+, PCnetPCI, PCnetPCI_II
* PCnet-Fast (100 MBps) family driver.
*
* Notes:
*
* Origin:
*
* Derived from cne15_21.c
*
* Created by:
* AYD 1995-96
*
* AYD 11-15-96, 11-18-96, 14-12-96
* Added Style 3 descriptors, burst Read and Write. Added
* new structures PCI_32_RX_DESC, PCI_32_TX_DESC to support
* Style 2 descriptors for older revs. of PCnetPCI. Added
* a new flag PCNETPCI_II which indicate PCnetPCI_II or/and
* PCnetFast NICs. Changed scatter/gather count in case of
* PCnetISA, PCnetPCI/II/Fast to 16.
*
* AYD 02-12-97
* Added code to detect dynamically a link speed, currently
* running and put the value in MLID config table.
*
* AYD 02-14-97
* Added a new call in DriverInit CMSMParseSingleParameter for
* preliminary parsing.
*
* AYD 02-21-97
* Added an API CMSMInitParser in DriverInit
*
* AYD 07-01-97
* Added code in DriverISRs to prevent receive if shutdown
* bit is set and in DriverShutdown check if shutdown for the
* whole adapter (OP_SCOPE_ADAPTER).
*
* AYD 08-29-97
* Commented out SPARE_ECB_STATUS checks.
*
* AYD 11-10-97
* Changed CommonMaximumSize to 2048 to receive jabber
* packets. Removed unnecessary code from DriverISRPCI and
* DriverISRPCI_II. Removed Line Speed check from DriverCallBack.
* Added CMSMUpdateConfigTables call in DriverReset to update
* a Line Speed value in config table.
*
* AYD 01-23-98
* Because the CMSMTCBPhysToLogFrags API has changed the DriverSendLANCE procedure has
* changed. The return value for CMSMTCBPhysToLogFrags has changed in the spec and code.
* CMSMTCBPhysToLogFrags now returns an ECB pointer where it use to return a pointer
* to the ECB_FragmentCount field in the ECB. The cneamd.lan expected the return of
* the ECB_FragmentCount pointer.
************************************************************************/
#include <portable.h>
#include <odi.h>
#include <odi_nbi.h>
#include <odi_nesl.h>
#include <nesl_str.h>
#include <parser.h>
#include <cmsm.h>
#include <cneamd.txt>
#include <debug.txt>
/* AYD include to use a debug function NiosBreak and NiosDprintf */
#ifdef DEBUG
#include <nios.h>
#include <nstdlib.h>
#endif
/***********************************************************************\
* *
* cneamd Definitions. *
* *
************************************************************************/
/* 7990, PCnetISA, PCnetPCI Control/Status Register Offsets and Bit Values. */
#define CSR0 0 /* Offset of CSR 0 Status and Control */
#define CSR1 1 /* Offset of CSR 1 Lower IADR */
#define CSR2 2 /* Offset of CSR 2 Upper IADR */
#define CSR3 3 /* Offset of CSR 3 Int mask, Config */
#define CSR4 4 /* Offset of CSR 4 Int mask, Config & status */
#define CSR80 80 /* Offset of CSR 80 FIFO threshold */
#define CSR82 82 /* Offset of CSR 82 Bus timer */
#define CSR88 88 /* Offset of CSR 88 Chip ID. */
#define CSR89 89 /* Offset of CSR 89 Chip ID. */
#define CSR124 124 /* Offset of CSR 124 Test Register */
#define BCR9 9 /* Offset of BCR 9 Full-Duplex Control */
#define BCR18 18 /* Offset of BCR 18 Burst and Bus Control Reg. */
#define BCR19 19 /* Offset of BCR 19 EEPROM Control and Status */
#define BCR20 20 /* Offset of BCR 20 Software Stile */
#define BCR33 33 /* Offset of BCR 33 MII Address Register */
#define BCR34 34 /* Offset of BCR 34 MII Management Data Register */
/* CSR0 bits. */
#define ERR 0x8000 /* Bit 15 - BABL, CERR, MISS OR MERR. */
#define BABL 0x4000 /* Bit 14 - Tx Babbled error. */
#define CERR 0x2000 /* Bit 13 - Tx Collision error. */
#define MISS 0x1000 /* Bit 12 - Rx missed error. */
#define MERR 0x0800 /* Bit 11 - Memory access error. */
#define RINT 0x0400 /* Bit 10 - Rx interrupt. */
#define TINT 0x0200 /* Bit 09 - Tx interrupt. */
#define IDON 0x0100 /* Bit 08 - Init done. */
#define INTR 0x0080 /* Bit 07 - Interrupt occurred. */
#define INEA 0x0040 /* Bit 06 - Interrupt enable. */
#define RXON 0x0020 /* Bit 05 - Receiver on. */
#define TXON 0x0010 /* Bit 04 - Transmitter on. */
#define TDMD 0x0008 /* Bit 03 - Transmit demand. */
#define STOP 0x0004 /* Bit 02 - Stop Lance. */
#define STRT 0x0002 /* Bit 01 - Start Lance. */
#define INIT 0x0001 /* Bit 00 - Initialize Lance. */
#define IMASK 0x0300 /* PCNetISA Interrupt MASK */
/* Transmit Message Descriptor 1 bits. */
#define T_OWN 0x80
#define T_ERR 0x40
#define T_RES 0x20
#define T_MORE 0x10
#define T_ONE 0x08
#define T_DEF 0x04
#define T_STP 0x02
#define T_ENP 0x01
#define T_BUF 0x8000
#define T_UFL 0x4000
#define T_LAT 0x1000
#define T_CAR 0x0800
#define T_COL 0x0400
/* Receive Message Descriptor 1 bits. */
#define R_OWN 0x80
#define R_ERR 0x40
#define R_FRM 0x20
#define R_OFL 0x10
#define R_CRC 0x08
#define R_BUF 0x04
#define R_STP 0x02
#define R_ENP 0x01
/* Transmit Message Descriptor for SWSTYLE = 3 */
#define T_OWN_32 0x8000 /* Bit 31 - Descriptor owned by HOST OWN = 0 */
#define T_ERR_32 0x4000 /* Bit 30 */
#define T_RES_32 0x2000 /* Bit 29 */
#define T_MORE_32 0x1000 /* Bit 28 */
#define T_ONE_32 0x0800 /* Bit 27 */
#define T_DEF_32 0x0400 /* Bit 26 */
#define T_STP_32 0x0200 /* Bit 25 - Start of the Packet */
#define T_ENP_32 0x0100 /* Bit 24 - End of the Packet */
/* Receive Message Descriptor for SWSTYLE = 3 */
#define R_OWN_32 0x8000 /* Bit 31 - Descriptor owned by HOST OWN = 0 */
#define R_ERR_32 0x4000 /* Bit 30 */
#define R_FRM_32 0x2000 /* Bit 29 */
#define R_OFL_32 0x1000 /* Bit 28 */
#define R_CRC_32 0x0800 /* Bit 27 */
#define R_BUF_32 0x0400 /* Bit 26 */
#define R_STP_32 0x0200 /* Bit 25 - Start of the Packet */
#define R_ENP_32 0x0100 /* Bit 24 - End of the Packet */
#define MASK_ENP_STP 0xFCFF
#define MASK_ENP 0xFEFF
/* Tx & Rx Buffer equates. */
#define TX_BUFFERS 2 /* 2, 4, 8, 16, 32, 64 or 128. */
/* AYD 12-04-96 */
#define TX_BUFFERS_FRAG 64 /* PCnetISA - 32, 64, 128 */
#define RX_BUFFERS 32 /* 2, 4, 8, 16, 32, 64 or 128. */
#define BUFFER_SIZE (1518+2) /* Keep on dword boundary. */
/* PCnetISA configuration init values */
#define RCVFW_INIT 0x1000 /* 32 bytes. */
#define XMTSP_INIT 0x0800 /* 64 bytes. */
#define XMTFW_INIT 0x0000 /* 8 cycles. */
#define DMAPLUS_INIT 0x0000 /* DMAPLUS disabled. */
#define ENTST 0x8000 /* Enable Runt Packet Accept see CSR124*/
#define LEVEL_INIT 0x0000 /* Level disabled. */
#define FASTISA_INIT 0x0000 /* Fast ISA disabled. */
#define BNC_INIT 0x0000 /* Not BNC. */
/* NIC types */
#define LANCE 0
#define PCNETISA 1
#define PCNETPCI 2
#define PCNETPCI_II 3
/***********************************************************************\
* *
* CNEAMD Structure definitions. *
* *
************************************************************************/
typedef struct _ATTR_ {
UINT16 LAddr;
UINT8 HAddr;
UINT8 Attr;
} ATTR;
typedef struct _TX_DESC_ {
union {
UINT32 TxAddr;
ATTR TxAttr;
}TxDescAddr;
UINT16 TxDescSize;
UINT16 TxDescStatus;
} TX_DESC;
typedef struct _RX_DESC_ {
union {
UINT32 RxAddr;
ATTR RxAttr;
}RxDescAddr;
UINT16 RxDescBufferCount;
UINT16 RxDescMessageCount;
} RX_DESC;
/***********************************************************************\
* *
* Full 32 bit mode structure definitions. SWSTYLE = 1 or 2 *
* *
************************************************************************/
typedef struct _PCI_INIT {
UINT16 Mode; /* Mode - Use defaults */
UINT16 PCI_Len;
UINT8 PCI_PhysicalAddress[6]; /* Adapter Physical address */
UINT16 PCI_Unused;
UINT8 PCI_LogicalAddressFilter[8];/* Multicast hash table */
void *PCI_RxDescriptorRingPtr; /* -> Rx Ring */
void *PCI_TxDescriptorRingPtr; /* -> Tx Ring */
} PCI_INIT;
typedef struct _PCI_TX_DESC_ {
UINT32 TxAddr_32; /* TMD0 */
UINT16 BufferByteCnt; /* TMD1 */
UINT16 TxDescStatus_32;
UINT16 TxRetryCount; /* TMD2 */
UINT16 TxError;
UINT32 Reserved; /* TMD3 */
} PCI_TX_DESC;
typedef struct _PCI_RX_DESC_ {
UINT32 RxAddr_32; /* RMD0 */
UINT16 BufferByteCnt; /* RMD1 */
UINT16 RxDescStatus_32;
UINT16 MessageByteCnt; /* RMD2 */
UINT16 RxStats;
UINT32 Reserved; /* RMD3 */
} PCI_RX_DESC;
/* AYD 11-15-96 These two structures used only if SWSTYLE = 3*/
/* SWSTYLE = 3 supported in PCnetPCI II and PCnetFast */
typedef struct _PCI_II_TX_DESC_ {
UINT16 TxRetryCount_II; /* TMD0 */
UINT16 TxError_II;
UINT16 BufferByteCnt_II; /* TMD1 */
UINT16 TxDescStatus_32_II;
UINT32 TxAddr_32_II; /* TMD2 */
UINT32 Reserved; /* TMD3 */
} PCI_II_TX_DESC;
typedef struct _PCI_II_RX_DESC_ {
UINT16 MessageByteCnt_II; /* RMD0 */
UINT16 RxStats_II;
UINT16 BufferByteCnt_II; /* RMD1 */
UINT16 RxDescStatus_32_II;
UINT32 RxAddr_32_II; /* RMD2 */
UINT32 Reserved; /* RMD3 */
} PCI_II_RX_DESC;
typedef struct _PCI_32_TX_DESC_ {
union {
PCI_TX_DESC ST2; /* Style 2 */
PCI_II_TX_DESC ST3; /* Style 3 */
} U;
} PCI_32_TX_DESC;
typedef struct _PCI_32_RX_DESC_ {
union {
PCI_RX_DESC ST2; /* Style 2 */
PCI_II_RX_DESC ST3; /* Style 3 */
} U;
} PCI_32_RX_DESC;
typedef struct _DRIVER_DATA_ {
void *TxBuffers;
UINT16 InitializationBlock; /* Mode - Use defaults */
UINT8 PhysicalAddress[6]; /* Adapter Physical address */
UINT8 LogicalAddressFilter[8]; /* Multicast hash table */
void *RxDescriptorRingPtr; /* -> Rx Ring */
void *TxDescriptorRingPtr; /* -> Tx Ring */
/* Message Descriptors must be at QWORD boundary.
The following 2 Tables could float backwards by one dword. */
UINT32 Reserved0QwordAlign; /* Reserve for QWORD align */
UINT32 Reserved1QwordAlign;
RX_DESC RxDescriptorTable[RX_BUFFERS];
TX_DESC TxDescriptorTable[TX_BUFFERS_FRAG]; /* PCnetISA */
RX_DESC *RxDescriptorTablePtr; /* Points to RxDescriptorTable*/
TX_DESC *TxDescriptorTablePtr; /* Points to TxDescriptorTable*/
UINT32 RDP;
UINT32 RAP;
UINT32 Reset;
UINT32 IDP_BDP;
/* AYD */
UINT32 TxNextToReturn;
UINT32 TxNextToSend;
void *TxBufferTable[TX_BUFFERS];
struct _TCB_ *TCBTable[TX_BUFFERS_FRAG];
UINT32 TxStartTime[TX_BUFFERS_FRAG];
UINT32 PaddedValue; /* AYD */
UINT32 TxLastDesc[TX_BUFFERS_FRAG];
UINT32 TxBufferIndex;
UINT32 RxNextToReturn;
UINT32 RxNextToAllocate;
struct _RCB_ *RCBTable[RX_BUFFERS];
UINT32 NeedRCBCount;
UINT32 CheckRxCount;
UINT32 LastTotalRxPacketCount;
/* UINT8 TempBuffer[2000]; */ /* AYD 04-08-96 */
/* UINT8 RxDescrTempBuffer[8*16]; */
UINT32 PCnetFlag;
UINT32 CommonMaximumSize;
UINT32 BusType;
void *BusTag;
UINT8 ResetFlag;
UINT8 BNCFlag;
UINT32 uniqueID;
UINT32 FullDuplex;
UINT32 ReservedForDWordAlign; /* Reserve for DWORD align */
PCI_INIT PCI_InitializationBlock; /* PCI Init block */
PCI_INIT *PCI_InitializationBlockPtr; /* Pointer to init block */
/* Message Descriptors must be at QWORD boundary.
The following 2 Tables could float backwards by one dword. */
UINT32 PCI_Reserved0QwordAlign; /* Reserve for 16 byte align */
UINT32 PCI_Reserved1QwordAlign;
UINT32 PCI_Reserved2QwordAlign;
UINT32 PCI_Reserved3QwordAlign;
PCI_32_RX_DESC PCI_RxDescriptorTable[RX_BUFFERS];
PCI_32_TX_DESC PCI_TxDescriptorTable[TX_BUFFERS_FRAG];
PCI_32_RX_DESC *PCI_RxDescriptorTablePtr; /* Points to RxDescriptorTable*/
PCI_32_TX_DESC *PCI_TxDescriptorTablePtr; /* Points to TxDescriptorTable*/
MLID_AES_ECB DAES;
MLID_StatsTable StatsTable;
StatTableEntry TotalTxPacketTable;
StatTableEntry TotalRxPacketTable;
StatTableEntry NoECBAvailableTable;
StatTableEntry PacketTxTooBigTable;
StatTableEntry PacketTxTooSmallTable;
StatTableEntry PacketRxOverflowTable;
StatTableEntry PacketRxTooBigTable;
StatTableEntry PacketRxTooSmallTable;
StatTableEntry PacketTxMiscErrorTable;
StatTableEntry PacketRxMiscErrorTable;
StatTableEntry RetryTxTable;
StatTableEntry ChecksumErrorTable;
StatTableEntry HardwareRxMismatchTable;
StatTableEntry TotalTxOKByteTable;
StatTableEntry TotalRxOKByteTable;
StatTableEntry TotalGroupAddrTxTable;
StatTableEntry TotalGroupAddrRxTable;
StatTableEntry AdapterResetTable;
StatTableEntry AdapterOprTimeStampTable;
StatTableEntry QDepthTable;
StatTableEntry TxOKSingleCollisionTable;
StatTableEntry TxOKMultipleCollisionsTable;
StatTableEntry TxOKButDeferredTable;
StatTableEntry TxAbortLateCollisionTable;
StatTableEntry TxAbortExcessCollisionsTable;
StatTableEntry TxAbortCarrierSenseTable;
StatTableEntry TxAbortExDeferralTable;
StatTableEntry RxAbortFrameAlignmentTable;
StatTableEntry HeartbeatErrorTable;
StatTableEntry MemoryErrorTable;
StatTableEntry TxOverflowTable;
StatTableEntry TxUnderflowTable;
StatTableEntry TxBufferErrorTable;
StatTableEntry ECBsOver16MegTable;
StatTableEntry TxECBsOver16MegTable;
StatTableEntry ECBOverflowTable;
UINT32 TotalTxPacketCount;
UINT32 TotalRxPacketCount;
UINT32 NoECBAvailableCount;
UINT32 PacketTxTooBigCount;
UINT32 PacketTxTooSmallCount;
UINT32 PacketRxOverflowCount;
UINT32 PacketRxTooBigCount;
UINT32 PacketRxTooSmallCount;
UINT32 PacketTxMiscErrorCount;
UINT32 PacketRxMiscErrorCount;
UINT32 RetryTxCount;
UINT32 ChecksumErrorCount;
UINT32 HardwareRxMismatchCount;
UINT64 TotalTxOKByteCount;
UINT64 TotalRxOKByteCount;
UINT32 TotalGroupAddrTxCount;
UINT32 TotalGroupAddrRxCount;
UINT32 AdapterResetCount;
UINT32 AdapterOprTimeStamp;
UINT32 QDepth;
UINT32 TxOKSingleCollision;
UINT32 TxOKMultipleCollisions;
UINT32 TxOKButDeferred;
UINT32 TxAbortLateCollision;
UINT32 TxAbortExcessCollisions;
UINT32 TxAbortCarrierSense;
UINT32 TxAbortExDeferral;
UINT32 RxAbortFrameAlignment;
UINT32 HeartbeatError;
UINT32 MemoryError;
UINT32 TxOverflow;
UINT32 TxUnderflow;
UINT32 TxBufferError;
UINT32 ECBsOver16Meg;
UINT32 TxECBsOver16Meg;
UINT32 ECBOverflowCount;
} DRIVER_DATA;
#include <ethertsm.h>
/***********************************************************************\
* *
* CNEAMD function prototypes. *
* *
************************************************************************/
void CFixUpStatStrings(
DRIVER_DATA *DriverData);
void DriverEnableInterrupt(
DRIVER_DATA *DriverData);
void DriverCallBack(
DRIVER_DATA *DriverData,
CONFIG_TABLE *configTable);
BOOLEAN DriverDisableInterrupt(
DRIVER_DATA *DriverData,
BOOLEAN Flag);
void DriverISRISA(
DRIVER_DATA *DriverData);
void DriverISRPCI(
DRIVER_DATA *DriverData);
void DriverISRPCI_II(
DRIVER_DATA *DriverData);
UINT32 DriverISRErrorHandler(
DRIVER_DATA *DriverData,
CONFIG_TABLE *configTable,
UINT32 InterruptStatus);
UINT32 DriverISRTxErrorHandler(
DRIVER_DATA *DriverData,
CONFIG_TABLE *configTable);
ODISTAT DriverMulticastChange(
DRIVER_DATA *DriverData,
CONFIG_TABLE *configTable,
GROUP_ADDR_LIST_NODE *mcTable,
UINT32 NumEntries,
UINT32 functionalTable);
void DriverPromiscuousChange(
DRIVER_DATA *DriverData,
CONFIG_TABLE *configTable,
UINT32 promiscuousMode);
void DriverSendLANCE(
DRIVER_DATA *DriverData,
CONFIG_TABLE *configTable,
TCB *tcb,
UINT32 packetSize,
void *physTcb);
void DriverSendISA(
DRIVER_DATA *DriverData,
CONFIG_TABLE *configTable,
TCB *tcb,
UINT32 packetSize,
void *physTcb);
void DriverSendPCI(
DRIVER_DATA *DriverData,
CONFIG_TABLE *configTable,
TCB *tcb,
UINT32 packetSize,
void *physTcb);
void DriverSendPCI_II(
DRIVER_DATA *DriverData,
CONFIG_TABLE *configTable,
TCB *tcb,
UINT32 packetSize,
void *physTcb);
ODISTAT DriverShutdown(
DRIVER_DATA *DriverData,
CONFIG_TABLE *configTable,
UINT32 shutdownType,
OPERATION_SCOPE operationScope);
ODISTAT DriverReset(
DRIVER_DATA *DriverData,
CONFIG_TABLE *configTable,
OPERATION_SCOPE operationScope);
void SetMulticast(
DRIVER_DATA *DriverData,
GROUP_ADDR_LIST_NODE *mcTable);
ODISTAT DriverInitISA( UINT32 *PCnetFlagISA,
CONFIG_TABLE *configTable);
MEON_STRING CHSMSPEC[] = {CNEAMD_SPECVER_TXTMSG};
/* TNL 12/06/95 Data pointers needed for NESL event production */
EPB *NESL_EPBPtr = NULL;
NESL_ECB *NESLServiceResumeNECBPtr = NULL;
BOOLEAN NESLRegisterDone = FALSE;
/* DriverMessages will be filled in by MSM(<TSM>RegisterHSM) to point */
/* to message enabled messages. */
MEON **DriverMessages = NULL;
/* Driver Data Space template. MSMRegisterHardwareOptions will initialize */
/* each adapter data space with the values in this template. */
/* AYD 03-09-95 */
#define NUMBER_OF_GENERICS &((DRIVER_DATA *)0)->QDepth - \
&((DRIVER_DATA *)0)->TotalTxPacketCount - 1
#define NUMBER_OF_MEDIAS &((DRIVER_DATA *)0)->RxAbortFrameAlignment - \
&((DRIVER_DATA *)0)->TxOKSingleCollision +1
#define NUMBER_OF_CUSTOMS &((DRIVER_DATA *)0)->ECBOverflowCount - \
&((DRIVER_DATA *)0)->HeartbeatError +1
/* AYD */
/*#define NUMBER_OF_GENERICS 20L
#define NUMBER_OF_MEDIAS 8L
#define NUMBER_OF_CUSTOMS 8L */
/* AYD used to align for test
UINT8 DriverDataSignature[] = {'D','D','T','S'}; */
static DRIVER_DATA DriverDataTemplate = {
NULL, /* TxBuffers */
0, /* InitializationBlock */
{0,0,0,0,0,0}, /* PhysicalAddress */
{0,0,0,0,0,0,0,0}, /* LogicalAddressFilter */
NULL, /* *RxDescriptorRingPtr */
NULL, /* *TxDescriptorRingPtr */
0, /* Reserved0QwordAlign */
0, /* Reserved1QwordAlign */
{0}, /* RxDescriptorTable */
{0}, /* TxDescriptorTable */
NULL, /* *RxDescriptorTablePtr */
NULL, /* *TxDescriptorTablePtr */
0, /* RDP */
0, /* RAP */
0, /* Reset */
0, /* IDP_BDP */
0, /* TxNextToReturn */
0, /* TxNextToSend */
{NULL}, /* TxBufferTable */
{NULL}, /* TCBTable */
{0}, /* TxStartTime */
0, /* AYD PaddedValue */
{0}, /* TxLastDesc */
0, /* TxBufferIndex */
0, /* RxNextToReturn */
0, /* RxNextToAllocate */
{NULL}, /* RCBTable */
RX_BUFFERS, /* NeedRCBCount */
16, /* CheckRxCount */
0, /* LastTotalRxPacketCount */
/*{0}, */ /* AYD 04-08-96*/
/*{0}, */
0, /* PCnetFlag */
0, /* CommonMaximumSize */
0, /* BusType */
NULL, /* *BusTag */
0, /* ResetFlag */
0, /* BNCFlag */
0, /* uniqueID */
0, /* FullDuplex */
0, /* ReservedForDWordAlign */
{0}, /* PCI_InitializationBlock */
NULL, /* PCI_InitializationBlockPtr */
0, /* PCI_Reserved0QwordAlign */
0, /* PCI_Reserved1QwordAlign */
0, /* PCI_Reserved2QwordAlign */
0, /* PCI_Reserved3QwordAlign */
{0}, /* PCI_RxDescriptorTable[RX_BUFFERS] */
{0}, /* PCI_TxDescriptorTable[TX_BUFFERS_FRAG] */
NULL, /* *PCI_RxDescriptorTablePtr */
NULL, /* *PCI_TxDescriptorTablePtr */
{ NULL, /* DAES->NextLink */
DriverCallBack, /* DAES->DriverAES */
AES_TYPE_PROCESS_CONTINUOUS, /* DAES->AesType */
1000, /* DAES->TimeInterval */
NULL, /* DAES->AesContext */
{0}}, /* DAES->AesReserved */
{4, /* StatsTable->MStatTableMajorVer */
00, /* StatsTable->MStatTableMinorVer */
NUMBER_OF_GENERICS, /* StatsTable->MNumGenericCounters */
&DriverDataTemplate.TotalTxPacketTable,
/* StatsTable->MGenericCountsPtr */
NUMBER_OF_MEDIAS, /* StatsTable->MNumMediaCounters */
&DriverDataTemplate.TxOKSingleCollisionTable,
/* StatsTable->MMediaCountersPtr */
NUMBER_OF_CUSTOMS, /* StatsTable->MNumCustomCounters */
&DriverDataTemplate.HeartbeatErrorTable},
/* StatsTable->MCustomCountersPtr */
{ODI_STAT_UINT32, /* TotalTxPacketTable->StatUseFlag */
&DriverDataTemplate.TotalTxPacketCount, /* ->StatCounter */
NULL}, /* ->StatString */
{ODI_STAT_UINT32, /* TotalRxPacketTable->StatUseFlag */
&DriverDataTemplate.TotalRxPacketCount, /* ->StatCounter */
NULL}, /* ->StatString */
{ODI_STAT_UINT32, /* NoECBAvailableTable->StatUseFlag */
&DriverDataTemplate.NoECBAvailableCount, /* ->StatCounter */
NULL}, /* ->StatString */
{ODI_STAT_UINT32, /* PacketTxTooBigTable->StatUseFlag */
&DriverDataTemplate.PacketTxTooBigCount, /* ->StatCounter */
NULL}, /* ->StatString */
{ODI_STAT_UINT32, /* PacketTxTooSmallTable->StatUseFlag */
&DriverDataTemplate.PacketTxTooSmallCount, /* ->StatCounter */
NULL}, /* ->StatString */
{ODI_STAT_UINT32, /* PacketRxOverflowTable->StatUseFlag */
&DriverDataTemplate.PacketRxOverflowCount, /* ->StatCounter */
NULL}, /* ->StatString */
{ODI_STAT_UINT32, /* PacketRxTooBigTable->StatUseFlag */
&DriverDataTemplate.PacketRxTooBigCount, /* ->StatCounter */
NULL}, /* ->StatString */
{ODI_STAT_UINT32, /* PacketRxTooSmallTable->StatUseFlag */
&DriverDataTemplate.PacketRxTooSmallCount, /* ->StatCounter */
NULL}, /* ->StatString */
{ODI_STAT_UINT32, /* PacketTxMiscErrorTable->StatUseFlag */
&DriverDataTemplate.PacketTxMiscErrorCount, /* ->StatCounter */
NULL}, /* ->StatString */
{ODI_STAT_UINT32, /* PacketRxMiscErrorTable->StatUseFlag */
&DriverDataTemplate.PacketRxMiscErrorCount, /* ->StatCounter */
NULL}, /* ->StatString */
{ODI_STAT_UINT32, /* RetryTxTable->StatUseFlag */
&DriverDataTemplate.RetryTxCount, /* ->StatCounter */
NULL}, /* ->StatString */
{ODI_STAT_UINT32, /* ChecksumErrorTable->StatUseFlag */
&DriverDataTemplate.ChecksumErrorCount, /* ->StatCounter */
NULL}, /* ->StatString */
{ODI_STAT_UINT32, /* HardwareRxMismatchTable->StatUseFlag */
&DriverDataTemplate.HardwareRxMismatchCount, /* ->StatCounter */
NULL}, /* ->StatString */
{ODI_STAT_UINT64, /* TotalTxOKByteTable->StatUseFlag */
&DriverDataTemplate.TotalTxOKByteCount, /* ->StatCounter */
NULL}, /* ->StatString */
{ODI_STAT_UINT64, /* TotalRxOKByteTable->StatUseFlag */
&DriverDataTemplate.TotalRxOKByteCount, /* ->StatCounter */
NULL}, /* ->StatString */
{ODI_STAT_UINT32, /* TotalGroupAddrTxTable->StatUseFlag */
&DriverDataTemplate.TotalGroupAddrTxCount, /* ->StatCounter */
NULL}, /* ->StatString */
{ODI_STAT_UINT32, /* TotalGroupAddrRxTable->StatUseFlag */
&DriverDataTemplate.TotalGroupAddrRxCount, /* ->StatCounter */
NULL}, /* ->StatString */
{ODI_STAT_UINT32, /* AdapterResetTable->StatUseFlag */
&DriverDataTemplate.AdapterResetCount, /*->StatCounter */
NULL}, /*->StatString */
{ODI_STAT_UINT32, /* AdapterOprTimeStampTable->StatUseFlag */
&DriverDataTemplate.AdapterOprTimeStamp, /* ->StatCounter */
NULL}, /* ->StatString */
{ODI_STAT_UINT32, /* QDepthTable->StatUseFlag */
&DriverDataTemplate.QDepth, /*->StatCounter */
NULL}, /*->StatString */
{ODI_STAT_UINT32, /* TxOKSingleCollisionTable->StatUseFlag */
&DriverDataTemplate.TxOKSingleCollision, /* ->StatCounter */
NULL}, /* ->StatString */
{ODI_STAT_UINT32, /* TxOKMultipleCollisionsTable->StatUseFlag */
&DriverDataTemplate.TxOKMultipleCollisions, /* ->StatCounter */
NULL}, /* ->StatString */
{ODI_STAT_UINT32, /* TxOKButDeferredTable->StatUseFlag */
&DriverDataTemplate.TxOKButDeferred, /* ->StatCounter */
NULL}, /* ->StatString */
{ODI_STAT_UINT32, /* TxAbortLateCollisionTable->StatUseFlag */
&DriverDataTemplate.TxAbortLateCollision, /* ->StatCounter */
NULL}, /* ->StatString */
{ODI_STAT_UINT32, /* TxAbortExcessCollisionTable->StatUseFlag */
&DriverDataTemplate.TxAbortExcessCollisions, /* ->StatCounter */
NULL}, /* ->StatString */
{ODI_STAT_UINT32, /* TxAbortCarrierSenseTable->StatUseFlag */
&DriverDataTemplate.TxAbortCarrierSense, /* ->StatCounter */
NULL}, /* ->StatString */
{ODI_STAT_UINT32, /* TxAbortExDeferralTable->StatUseFlag */
&DriverDataTemplate.TxAbortExDeferral, /* ->StatCounter */
NULL}, /* ->StatString */
{ODI_STAT_UINT32, /* RxAbortFrameAlignmentTable->StatUseFlag */
&DriverDataTemplate.RxAbortFrameAlignment, /* ->StatCounter */
NULL}, /* ->StatString */
{ODI_STAT_UINT32, /* HeartbeatErrorTable->StatUseFlag */
&DriverDataTemplate.HeartbeatError, /* ->StatCounter */
NULL}, /* ->StatString */
{ODI_STAT_UINT32, /* MemoryErrorTable->StatUseFlag */
&DriverDataTemplate.MemoryError, /* ->StatCounter */
NULL}, /* ->StatString */
{ODI_STAT_UINT32, /* TxOverflowTable->StatUseFlag */
&DriverDataTemplate.TxOverflow, /* ->StatCounter */
NULL}, /* ->StatString */
{ODI_STAT_UINT32, /* TxUnderflowTable->StatUseFlag */
&DriverDataTemplate.TxUnderflow, /* ->StatCounter */
NULL}, /* ->StatString */
{ODI_STAT_UINT32, /* TxBufferErrorTable->StatUseFlag */
&DriverDataTemplate.TxBufferError, /* ->StatCounter */
NULL}, /* ->StatString */
{ODI_STAT_UINT32, /* ECBsOver16MegTable->StatUseFlag */
&DriverDataTemplate.ECBsOver16Meg, /* ->StatCounter */
NULL}, /* ->StatString */
{ODI_STAT_UINT32, /* TxECBsOver16MegTable->StatUseFlag */
&DriverDataTemplate.TxECBsOver16Meg, /* ->StatCounter */
NULL}, /* ->StatString */
{ODI_STAT_UINT32, /* ECBOverflowCountTable->StatUseFlag */
&DriverDataTemplate.ECBOverflowCount, /* ->StatCounter */
NULL}, /* ->StatString */
0, /* TotalTxPacketCount */
0, /* TotalRxPacketCount */
0, /* NoECBAvailableCount */
0, /* PacketTxTooBigCount */
0, /* PacketTxTooSmallCount */
0, /* PacketRxOverflowCount */
0, /* PacketRxTooBigCount */
0, /* PacketRxTooSmallCount */
0, /* PacketTxMiscErrorCount */
0, /* PacketRxMiscErrorCount */
0, /* RetryTxCount */
0, /* ChecksumErrorCount */
0, /* HardwareRxMismatchCount */
{0, 0}, /* TotalRxOKByteCount */
{0, 0}, /* TotalTxOKByteCount */
0, /* TotalGroupAddrTxCount */
0, /* TotalGroupAddrRxCount */
0, /* AdapterResetCount */
0, /* AdapterOprTimeStamp */
0, /* QDepth */
0, /* TxOKSingleCollision */
0, /* TxOKMultipleCollsions */
0, /* TxOKButDeferred */
0, /* TxAbortLateCollision */
0, /* TxAbortExcessCollisions */
0, /* TxAbortCarrierSense */
0, /* TxAbortExDeferral */
0, /* RxAbortFrameAlignment */
0, /* HeartbeatError */
0, /* MemoryError */
0, /* TxOverflow */
0, /* TxUnderflow */
0, /* TxBufferError */
0, /* ECBsOver16Meg */
0, /* TxECBsOver16Meg */
0 /* ECBOverflowCount */
}; /* End DriverDataTemplate */
/* Configuration Table Template. <TSM>RegisterHSM will initialize the */
/* configuration table in each frame data space will be initialized with */
/* values in this template. */
/* AYD 07-05-95 */
#define ModeFlags MM_MULTICAST_BIT \
| MM_C_HSM_BIT \
| MM_PROMISCUOUS_BIT \
| MM_PREFILLED_ECB_BIT \
| MM_FRAGS_PHYS_BIT
#define MFlags 0
#define SharingFlags 0
MEON_STRING NICShortName[] = {CNEAMD_SHORTNAME_TXTMSG};
/* AYD used to align for test
UINT8 DriverConfigSignature[] = {'D','C','T','S','0','0','0','0'}; */
static CONFIG_TABLE DriverConfigTemplate = {
CNEAMD_CONFIGSIG_TXTMSG, /* MLIDCFG_Signature */
01, /* MLIDCFG_MajorVersion */
21, /* MLIDCFG_MinorVersion */
{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, /* MLIDCFG_NodeAddress */
ModeFlags, /* MLIDCFG_ModeFlags */
0x0000, /* MLIDCFG_BoardNumber */
0x0000, /* MLIDCFG_BoardInstance */
0x000005F0, /* MLIDCFG_MaxFrameSize */
0x000005E2, /* MLIDCFG_BestDataSize */
0x000005E2, /* MLIDCFG_WorstDataSize */
NULL, /* MLIDCFG_CardName */
NICShortName, /* MLIDCFG_ShortName */
NULL, /* MLIDCFG_FrameTypeString */
0x0000, /* MLIDCFG_Reserved0 */
0x0000, /* MLIDCFG_FrameID */
0x0001, /* MLIDCFG_TransportTime */
NULL, /* MLIDCFG_SourceRouting */
10, /* MLIDCFG_LineSpeed */
0x0000, /* MLIDCFG_LookAheadSize */
2, /* MLIDCFG_SGCount */
0, /* MLIDCFG_Reserved1 */
0, /* MLIDCFG_PrioritySup */
NULL, /* MLIDCFG_Reserved2 */
0x00, /* MLIDCFG_DriverMajorVer */
0, /* MLIDCFG_DriverMinorVer */
MFlags, /* MLIDCFG_Flags */
10, /* MLIDCFG_SendRetries */
NULL, /* MLIDCFG_DriverLink */
SharingFlags, /* MLIDCFG_SharingFlags */
-1, /* MLIDCFG_Slot */
0x0300, /* MLIDCFG_IOPort0 */
32, /* MLIDCFG_IORange0 */
0x0000, /* MLIDCFG_IOPort1 */
0, /* MLIDCFG_IORange1 */
NULL, /* MLIDCFG_MemoryAddress0 */
0x0000, /* MLIDCFG_MemorySize0 */
NULL, /* MLIDCFG_MemoryAddress1 */
0x0000, /* MLIDCFG_MemorySize1 */
0x03, /* MLIDCFG_Interrupt0 */
0xff, /* MLIDCFG_Interrupt1 */
0x05, /* MLIDCFG_DMALine0 */
0xff, /* MLIDCFG_DMALine1 */
NULL, /* MLIDCFG_ResourceTag */
NULL, /* MLIDCFG_Config */
NULL, /* MLIDCFG_CommandString */
{0,0,0,0,0,0,
0,0,0,0,0,0,
0,0,0,0,0,0}, /* MLIDCFG_LogicalName */
0x00000000, /* MLIDCFG_LinearMemory0 */
0x00000000, /* MLIDCFG_LinearMemory1 */
0x0000, /* MLIDCFG_ChannelNumber */
NULL, /* MLIDCFG_DBusTag */
0x01, /* MLIDCFG_DIOConfigMajorVer */
0x00, /* MLIDCFG_DIOConfigMinorVer */
}; /* End DriverConfigTemplate */
/* Driver Parameter Block. This information gives the MSM/TSM the */
/* information it needs to manage this HSM. */
/* AYD used to align for test
UINT8 DriverParameterBlockSignature[] = {'D','P','B','S','0','0'}; */
static struct _DRIVER_PARM_BLOCK_ DriverParameterBlock = {
sizeof(DRIVER_PARM_BLOCK), /* DriverParameterSize */
NULL, /* DriverInitParmPointer */
NULL, /* DriverModuleHandle */
NULL, /* DBP_Reserved0 */
NULL, /* DriverAdapterPointer */
&DriverConfigTemplate, /* DriverConfigTemplatePtr */
0x00000000, /* DriverFirmwareSize */
NULL, /* DriverFirmwareBuffer */
0, /* DPB_Reserved1 */
NULL, /* DPB_Reserved2 */
NULL, /* DPB_Reserved3 */
NULL, /* DPB_Reserved4 */
sizeof(DRIVER_DATA), /* DriverAdapterDataSpaceSize */
&DriverDataTemplate, /* DriverAdapterDataSpacePtr */
(UINT32)&(((DRIVER_DATA *)0)->StatsTable),/* DriverStatisticsTableOffset*/
0, /* DriverEndOfChainFlag */
0, /* DriverSendWantsECBs */
-1, /* DriverMaxMulticast */
1, /* DriverNeedsBelow16Meg */
NULL, /* DPB_Reserved5 */
NULL, /* DPB_Reserved6 */
DriverISRISA, /* DriverISRPtr */
/* NULL, */
DriverMulticastChange, /* DriverMulticastChangePtr */
NULL, /* DriverPollPtr */
DriverReset, /* DriverResetPtr */
DriverSendLANCE, /* DriverSendPtr */
/* NULL, */
DriverShutdown, /* DriverShutdownPtr */
NULL, /* DriverTxTimeoutPtr */
DriverPromiscuousChange, /* DriverPromiscuousChangePtr */
NULL, /* DriverStatisticsChangePtr */
NULL, /* DriverRxLookAheadChangePtr */
NULL, /* DriverManagementPtr */
DriverEnableInterrupt, /* DriverEnableInterruptPtr */
DriverDisableInterrupt, /* DriverDisableInterruptPtr */
NULL, /* DriverISRPtr2 */
&DriverMessages, /* DriverMessagesPtr */
&CHSMSPEC, /* HSM Specification Version */
NULL, /* Driver Priority Queue Ptr */
NULL /* DriverDisableInterrupt2Ptr */
}; /* End DriverParameterBlock */
/* Parameter Option Description Structures */
/* PCI */
struct
{
UINT32 OptionCount;
UINT32 Slot[8];
} SlotsWithMyBoard = {0,{0,0,0,0, 0,0,0,0}};
DRIVER_OPTION SlotOption =
{ NULL, NULL, (PARAMETER_OPTIONS *)&SlotsWithMyBoard, 0, 0, SLOTPARAM,
REQUIREDPARAM | ENUMPARAM, };
DRIVER_OPTION FullDuplexOption =
{ NULL, CNEAMD_FullDuplex, NULL, 0, 0, CUSTOMPARAM, KEYWORDPARAM };
/* LANCE, PCnetISA */
struct
{
UINT32 OptionCount;
UINT32 UNumOptVal[12];
} IoOptionList = {12, {0x300,0x320,0x340,0x360,0x200,0x220,0x240,0x260,0x280,0x2A0,0x2C0,0x2E0}};
struct
{
UINT32 OptionCount;
UINT32 UNumOptVal[8];
} IntOptionList = {8, {3, 4, 5, 9, 10, 11, 12, 15}};
struct
{
UINT32 OptionCount;
UINT32 UNumOptVal[4];
} DMAOptionList = {4, {5, 6, 7, 3}};
DRIVER_OPTION IoOption =
{ NULL, NULL, (PARAMETER_OPTIONS *)&IoOptionList, 0, 0x300, PORTPARAM,
REQUIREDPARAM | DEFAULTPRESENT | ENUMPARAM, };
DRIVER_OPTION IntOption =
{ &IoOption, NULL, (PARAMETER_OPTIONS *)&IntOptionList, 0, 0x3, INTPARAM,
REQUIREDPARAM | DEFAULTPRESENT | ENUMPARAM, };
DRIVER_OPTION DMAOption =
{ &IntOption, NULL, (PARAMETER_OPTIONS *)&DMAOptionList, 0, 0x5, DMAPARAM,
REQUIREDPARAM | DEFAULTPRESENT | ENUMPARAM, };
DRIVER_OPTION ISAOption =
{ NULL, CNEAMD_ISA, NULL, 0, 0, CUSTOMPARAM, KEYWORDPARAM };
static UINT8 BroadcastAddress[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
/***********************************************************************\
* *
*
* Name:
* void DriverMulticastChange(
* DRIVER_DATA *driverData,
* PONFIG_TABLE configTable,
* GROUP_ADDR_LIST_NODE *mcTable,
* UINT32 numEntries,
* UINT32 functionalTable)
*
* Description:
*
* This function passes a copy of the current multicast table
* so that the HSM can update the adapters multicast hash table.
*
* Parameters in:
*
* driverData - Pointer to HSM's Adapter Data Space.
* configTable - Pointer to HSM's Default Configuration Table.
* mcTable - Pointer to multicast table.
* numEntries - Number of valid entries in multicast table.
* functionalTable - Functional Address(not used).
*
* Values returned:
*
* *
************************************************************************/
ODISTAT DriverMulticastChange(
DRIVER_DATA *driverData,
CONFIG_TABLE *configTable,
GROUP_ADDR_LIST_NODE *mcTable,
UINT32 numEntries,
UINT32 functionalTable)
{
functionalTable = functionalTable;
/* Clear hash table */
/* AYD 08-01-95 to zero all 8 bytes */
/* AYD 11-15-96 */
if ( (driverData->PCnetFlag == PCNETPCI) || (driverData->PCnetFlag == PCNETPCI_II) )
{
*(UINT32 *)&(driverData->PCI_InitializationBlockPtr->PCI_LogicalAddressFilter[0]) = 0;
*(UINT32 *)&(driverData->PCI_InitializationBlockPtr->PCI_LogicalAddressFilter[4]) = 0;
}
else
{
*(UINT32 *)&(driverData->LogicalAddressFilter[0]) = 0;
*(UINT32 *)&(driverData->LogicalAddressFilter[4]) = 0;
}
/* Calculate hash bit for each multicast address */
while(numEntries) {
SetMulticast(driverData, mcTable);
mcTable++;
numEntries--;
}
/* Reset adapter so that it can accept new hash table */
DriverReset(driverData, configTable, OP_SCOPE_ADAPTER);
driverData->AdapterResetCount--;
return ODISTAT_SUCCESSFUL;
}
/***********************************************************************
*
*
* Name:
* void SetMulticast(
* DRIVER_DATA *driverData,
* GROUP_ADDR_LIST_NODE *mcTableEntry)
*
* Description:
*
* This function sets the adapter hash table according to the
* multicast address passed in. The bit set in the hash table
* is calculated the same way the hardware calculates it using
* a CRC algorithm.
*
* Parameters in:
*
* driverData - Pointer to HSM's Adapter Data Space.
* mcTableEntry - Pointer to multicast address.
*
* Values returned:
*
*
************************************************************************/
#define POLYNOMIAL 0x4C11DB6
void SetMulticast(
DRIVER_DATA *driverData,
GROUP_ADDR_LIST_NODE *mcTableEntry)
{
UINT32 CRC = 0xffffffff; /* CRC accumulator */
UINT32 NodeAddr, CRC31;
int WordCount, BitCount;
UINT32 HashIndex;
UINT8 CRCLow, CRCHigh;
for(WordCount = 0; WordCount < 6; WordCount += 2)
{
NodeAddr = GET_UINT16(&mcTableEntry->GRP_ADDR.nodeAddress[WordCount]);
for(BitCount = 16; BitCount; BitCount--)
{
CRC31 = ((CRC >> 31) ^ NodeAddr) & 1; /* Get Control bit */
CRC = CRC << 1;
if (CRC31)
CRC = CRC ^ POLYNOMIAL; /* XOR if Control bit == 1 */
CRC = CRC | CRC31; /* Put control bit in CRC0 */
NodeAddr = NodeAddr >> 1; /* Rotate word address right */
}
}
CRCLow = (UINT8)CRC;
CRC >>= 8;
CRCHigh = (UINT8)CRC;
/* Formation of CRC complete, CRCLow contains the reversed hash code. */
/* Reverse the order of the bits in bits 0-7 of CRC accumulator into */
/* bits 8-15. */
for(BitCount = 10; BitCount; BitCount--)
{
CRCHigh >>= 1;
CRCHigh |= (CRCLow & 0x80);
CRCLow <<= 1;
}
/* CRCHigh now contains the hash code */
HashIndex = CRCHigh >> 3; /* Hash Index = Hash Code / 8 */
CRCLow = 1 << ((UINT8)CRCHigh & 0x07); /* CRC bit = 1 << Hash Code */
/* Set Hash Filter */
/* AYD 11-15-96 */
if ( (driverData->PCnetFlag == PCNETPCI) || (driverData->PCnetFlag == PCNETPCI_II) )
driverData->PCI_InitializationBlockPtr->PCI_LogicalAddressFilter[HashIndex] |= CRCLow;
else
driverData->LogicalAddressFilter[HashIndex] |= CRCLow;
return;
}
/***********************************************************************\
* *
*
* Name:
* void DriverPromiscuousChange(
* DRIVER_DATA *driverData,
* CONFIG_TABLE *configTable,
* UINT32 promiscuousMode) {
*
* Description:
*
* This function enables/disables the adapters promiscuous mode.
* If promiscuous mode is enabled, we will also pass bad packets
* up to the TSM.
*
* Parameters in:
*
* driverData - Pointer to HSM's Adapter Data Space.
* configTable - Pointer to HSM's Default Configuration Table.
* promsicuousMode - PROM_STATE_OFF to disable promiscuous mode.
* PROM_STATE_ON to enable promiscuous mode.
*
* Values returned:
*
* *
************************************************************************/
void DriverPromiscuousChange(
DRIVER_DATA *driverData,
CONFIG_TABLE *configTable,
UINT32 promiscuousMode)
{
/* AYD 11-15-96 */
if ( (driverData->PCnetFlag == PCNETPCI) || (driverData->PCnetFlag == PCNETPCI_II) )
{
if (promiscuousMode)
PUT_UINT16(&driverData->PCI_InitializationBlockPtr->Mode, 0x8000);
else
PUT_UINT16(&driverData->PCI_InitializationBlockPtr->Mode, 0x0000);
}
else
{
if (promiscuousMode)
PUT_UINT16(&driverData->InitializationBlock, 0x8000);
else
PUT_UINT16(&driverData->InitializationBlock, 0x0000);
}
/* Reset Adapter to enable/disable promiscuous mode */
DriverReset(driverData, configTable, OP_SCOPE_ADAPTER);
driverData->AdapterResetCount--;
return;
}
/***********************************************************************\
* *
*
* Name:
* void DriverSend(
* DRIVER_DATA *driverData,
* CONFIG_TABLE *configTable,
* TCB *tcb,
* UINT32 packetSize,
* void *physTcb) {
*
* Description:
*
* This function sends a packet described in the TCB to the
* Am7990 LANCE adapter.
*
* Parameters in:
*
* driverData - Pointer to HSM's Adapter Data Space.
* configTable - Pointer to HSM's Default Configuration Table.
* tcb - Pointer to the Transmit Control Block.
* packetSize - Padded, evenized size of packet.
* (The size the adapter must put on the wire)
* physTcb - Physical pointer to TCB(not used).
*
* Values returned:
*
* *
************************************************************************/
void DriverSendLANCE(
DRIVER_DATA *driverData,
CONFIG_TABLE *configTable,
TCB *tcb,
UINT32 packetSize,
void *physTcb)
{
int i;
void *txBuffer;
int fragCount;
FRAGMENTSTRUCT *fragStruct;
ECB *originalECBPtr;
physTcb = physTcb;
i = driverData->TxNextToSend;
driverData->TCBTable[i] = tcb;
/* Set up transmit descriptor size field */
PUT_UINT16(&driverData->TxDescriptorTablePtr[i].TxDescSize,
-(UINT16)packetSize);
/* Copy TCB Media Header to the transmit buffer */
txBuffer = (void *)driverData->TxBufferTable[i];
/* AYD */
MovFastToBus(0, 0, txBuffer, &tcb->TCB_MediaHeader, tcb->TCB_MediaHeaderLen);
txBuffer = (void *)((UINT8 *)txBuffer + tcb->TCB_MediaHeaderLen);
/* Copy ECB fragments to the transmit buffer */
/* AYD 10-11-95 To use the linear addresses to move a data*/
/* AYD 01-23-98 Because the CMSMTCBPhysToLogFrags API changed the following 3 lines changed */
originalECBPtr = CMSMTCBPhysToLogFrags(tcb);
fragCount = originalECBPtr->ECB_FragmentCount;
fragStruct = originalECBPtr->ECB_Fragment;
while (fragCount)
{
MovFastToBus(0, 0, (UINT8 *)txBuffer,
(UINT8 *)fragStruct->FragmentAddress,
fragStruct->FragmentLength);
txBuffer = (void *)((UINT8 *)txBuffer + fragStruct->FragmentLength);
fragStruct++;
fragCount--;
}
/* Setting T_OWN bit will flag adapter to transmit this packet */
driverData->TxDescriptorTablePtr[i].TxDescAddr.TxAttr.Attr |= T_OWN;
/* Send TDMD command so that adapter reads transmit descriptor */
Out16(configTable->MLIDCFG_DBusTag, (void *)driverData->RDP, TDMD | INEA);
/* Stamp descriptor for timeout detection */
driverData->TxStartTime[i] = CMSMGetCurrentTime();
i= (i+1) & (TX_BUFFERS - 1);
driverData->TxNextToSend = i;
CEtherTSMFastSendComplete(driverData, tcb, 0);
} /* End DriverSendLANCE */
/***********************************************************************\
* *
*
* Name:
* void DriverSend ISA or PCI(
* DRIVER_DATA *driverData,
* CONFIG_TABLE *configTable,
* TCB *tcb,
* UINT32 packetSize,
* void *physTcb) {
*
* Description:
*
* This function sends a packet to the Am79C960 PCnetISA adapter.
* The TCB is guaranteed to have physically addressed buffers
* below 16 megabytes. The HSM uses this function instead of
* DriverSend since the Am79C960 PCnetISA, PCnetPCI chip can
* accept transmit descriptors of any size, allowing us to let the adapter
* gather the fragments, thus preventing a double copy.
*
* Parameters in:
*
* driverData - Pointer to HSM's Adapter Data Space.
* configTable - Pointer to HSM's Default Configuration Table.
* tcb - Pointer to the Transmit Control Block.
* packetSize - Padded, evenized size of packet.
* (The size the adapter must put on the wire)
* physTcb - Physical pointer to TCB(not used).
*
* Values returned:
*
* *
************************************************************************/
void DriverSendISA(
DRIVER_DATA *driverData,
CONFIG_TABLE *configTable,
TCB *tcb,
UINT32 packetSize,
void *physTcb)
{
int i, firstIndex;
UINT32 fragCount;
FRAGMENTSTRUCT *fragStruct;
UINT16 paddedValue, lastSize;
configTable = configTable;
physTcb = physTcb;
packetSize = packetSize;
/* Update Tx Over ECB statistic counter */
driverData->TxECBsOver16Meg += tcb->TCB_DriverWS[1];
/* paddedValue will be added to the last descriptor if the TSM has
evenized the packet */
paddedValue = 0;
if ( (packetSize != 60) && (packetSize != tcb->TCB_DataLen) )
paddedValue = 1;
i = firstIndex = driverData->TxNextToSend;
driverData->TCBTable[i] = tcb;
fragCount = tcb->TCB_FragBlockPtr->TCB_FragmentCount;
fragStruct = &tcb->TCB_FragBlockPtr->TCB_Fragment;
/*#ifdef DEBUG
NiosDprintf(FRAGMENT_COUNT, fragCount);
#endif */
if (tcb->TCB_MediaHeaderLen)
{
/* Point first descriptor to TCB media header */
PUT_UINT32(&driverData->TxDescriptorTablePtr[i].TxDescAddr.TxAddr,
tcb->TCB_DriverWS[2]);
PUT_UINT16(&driverData->TxDescriptorTablePtr[i].TxDescSize,
-(UINT16)(tcb->TCB_MediaHeaderLen));
driverData->TxDescriptorTablePtr[i].TxDescAddr.TxAttr.Attr &= 0xFC;
}
else
{
/* No TCB media header. Point first descriptor to first fragment */
PUT_UINT32(&driverData->TxDescriptorTablePtr[i].TxDescAddr.TxAddr,
(UINT32)fragStruct->FragmentAddress);
PUT_UINT16(&driverData->TxDescriptorTablePtr[i].TxDescSize,
-(UINT16)(fragStruct->FragmentLength));
driverData->TxDescriptorTablePtr[i].TxDescAddr.TxAttr.Attr &= 0xFC;
fragStruct++;
fragCount--;
}
/* Point next desriptors to the rest of the fragments */
while(fragCount)
{
if (fragStruct->FragmentLength)
{
i = (i + 1) & (TX_BUFFERS_FRAG - 1);
PUT_UINT32(&driverData->TxDescriptorTablePtr[i].TxDescAddr.TxAddr,
(UINT32)fragStruct->FragmentAddress);
PUT_UINT16(&driverData->TxDescriptorTablePtr[i].TxDescSize,
-(UINT16)(fragStruct->FragmentLength));
driverData->TxDescriptorTablePtr[i].TxDescAddr.TxAttr.Attr &= 0xFC;
}
fragStruct++;
fragCount--;
}
/* Add possible evenization padding, set last descriptor to T_ENP and
first descriptor T_STP. */
/* AYD 02-14-96 */
lastSize = GET_UINT16(&driverData->TxDescriptorTablePtr[i].TxDescSize);
lastSize -= paddedValue;
PUT_UINT16(&driverData->TxDescriptorTablePtr[i].TxDescSize, lastSize);
driverData->TxDescriptorTablePtr[driverData->TxNextToSend].TxDescAddr.TxAttr.Attr &= 0xFE;
driverData->TxDescriptorTablePtr[i].TxDescAddr.TxAttr.Attr |= T_ENP;
driverData->TxDescriptorTablePtr[driverData->TxNextToSend].TxDescAddr.TxAttr.Attr |= T_STP;
driverData->TxLastDesc[driverData->TxNextToSend] = i;
i = (i+1) & (TX_BUFFERS_FRAG - 1);
driverData->TxNextToSend = i;
/* Set adapter ownership bit(T_OWN) starting with the last descriptor
since setting the bit on the first descriptor will start
transmission. */
do
{
i = (i - 1) & (TX_BUFFERS_FRAG - 1);
/* AYD 02-14-96 */
driverData->TxDescriptorTablePtr[i].TxDescAddr.TxAttr.Attr |= T_OWN;
}
while(i != firstIndex);
Out16(configTable->MLIDCFG_DBusTag, (void *)driverData->RDP, TDMD | INEA);
driverData->TxStartTime[i] = CMSMGetCurrentTime();
return;
} /* End DriverSendISA */
void DriverSendPCI(
DRIVER_DATA *driverData,
CONFIG_TABLE *configTable,
TCB *tcb,
UINT32 packetSize,
void *physTcb)
{
int i, firstIndex;
UINT32 fragCount;
FRAGMENTSTRUCT *fragStruct;
UINT16 paddedValue, lastSize;
configTable = configTable;
physTcb = physTcb;
packetSize = packetSize;
/* paddedValue will be added to the last descriptor if the TSM has
evenized the packet */
paddedValue = 0;
if ( (packetSize != 60) && (packetSize != tcb->TCB_DataLen) )
paddedValue = 1;
i = firstIndex = driverData->TxNextToSend;
driverData->TCBTable[i] = tcb;
fragCount = tcb->TCB_FragBlockPtr->TCB_FragmentCount;
fragStruct = &tcb->TCB_FragBlockPtr->TCB_Fragment;
/* #ifdef DEBUG
NiosDprintf(FRAGMENT_COUNT, fragCount);
#endif*/
/* if(fragCount == 4)
NiosBreak(); */
if (tcb->TCB_MediaHeaderLen)
{
/* Point first descriptor to TCB media header */
PUT_UINT32(&driverData->PCI_TxDescriptorTablePtr[i].U.ST2.TxAddr_32,
tcb->TCB_DriverWS[2]);
PUT_UINT16(&driverData->PCI_TxDescriptorTablePtr[i].U.ST2.BufferByteCnt,
-(UINT16)(tcb->TCB_MediaHeaderLen));
driverData->PCI_TxDescriptorTablePtr[i].U.ST2.TxDescStatus_32 &= MASK_ENP_STP;
}
else
{
/* No TCB media header. Point first descriptor to first fragment */
PUT_UINT32(&driverData->PCI_TxDescriptorTablePtr[i].U.ST2.TxAddr_32,
(UINT32)fragStruct->FragmentAddress);
PUT_UINT16(&driverData->PCI_TxDescriptorTablePtr[i].U.ST2.BufferByteCnt,
-(UINT16)(fragStruct->FragmentLength));
driverData->PCI_TxDescriptorTablePtr[i].U.ST2.TxDescStatus_32 &= MASK_ENP_STP;
fragStruct++;
fragCount--;
}
/* Point next desriptors to the rest of the fragments */
while(fragCount)
{
if (fragStruct->FragmentLength)
{
i = (i + 1) & (TX_BUFFERS_FRAG - 1);
PUT_UINT32(&driverData->PCI_TxDescriptorTablePtr[i].U.ST2.TxAddr_32,
(UINT32)fragStruct->FragmentAddress);
PUT_UINT16(&driverData->PCI_TxDescriptorTablePtr[i].U.ST2.BufferByteCnt,
-(UINT16)(fragStruct->FragmentLength));
driverData->PCI_TxDescriptorTablePtr[i].U.ST2.TxDescStatus_32 &= MASK_ENP_STP;
}
fragStruct++;
fragCount--;
}
/* Add possible evenization padding, set last descriptor to T_ENP and
first descriptor T_STP. */
/* AYD 02-14-96 */
lastSize = GET_UINT16(&driverData->PCI_TxDescriptorTablePtr[i].U.ST2.BufferByteCnt);
lastSize -= paddedValue;
PUT_UINT16(&driverData->PCI_TxDescriptorTablePtr[i].U.ST2.BufferByteCnt, lastSize);
driverData->PCI_TxDescriptorTablePtr[driverData->TxNextToSend].U.ST2.TxDescStatus_32 &= MASK_ENP;
driverData->PCI_TxDescriptorTablePtr[i].U.ST2.TxDescStatus_32 |= T_ENP_32;
driverData->PCI_TxDescriptorTablePtr[driverData->TxNextToSend].U.ST2.TxDescStatus_32 |= T_STP_32;
driverData->TxLastDesc[driverData->TxNextToSend] = i;
i = (i+1) & (TX_BUFFERS_FRAG - 1);
driverData->TxNextToSend = i;
/* Set adapter ownership bit(T_OWN) starting with the last descriptor
since setting the bit on the first descriptor will start
transmission. */
do
{
i = (i - 1) & (TX_BUFFERS_FRAG - 1);
/* AYD 02-14-96 */
driverData->PCI_TxDescriptorTablePtr[i].U.ST2.TxDescStatus_32 |= T_OWN_32;
}
while(i != firstIndex);
Out16(configTable->MLIDCFG_DBusTag, (void *)driverData->RDP, TDMD | INEA);
driverData->TxStartTime[i] = CMSMGetCurrentTime();
return;
} /* End DriverSendPCI */
void DriverSendPCI_II(
DRIVER_DATA *driverData,
CONFIG_TABLE *configTable,
TCB *tcb,
UINT32 packetSize,
void *physTcb)
{
int i, firstIndex;
UINT32 fragCount;
FRAGMENTSTRUCT *fragStruct;
UINT16 paddedValue, lastSize;
configTable = configTable;
physTcb = physTcb;
packetSize = packetSize;
/* paddedValue will be added to the last descriptor if the TSM has
evenized the packet */
paddedValue = 0;
if ( (packetSize != 60) && (packetSize != tcb->TCB_DataLen) )
paddedValue = 1;
i = firstIndex = driverData->TxNextToSend;
driverData->TCBTable[i] = tcb;
fragCount = tcb->TCB_FragBlockPtr->TCB_FragmentCount;
fragStruct = &tcb->TCB_FragBlockPtr->TCB_Fragment;
/* #ifdef DEBUG
NiosDprintf(FRAGMENT_COUNT, fragCount);
#endif */
if (tcb->TCB_MediaHeaderLen)
{
/* Point first descriptor to TCB media header */
PUT_UINT32(&driverData->PCI_TxDescriptorTablePtr[i].U.ST3.TxAddr_32_II,
tcb->TCB_DriverWS[2]);
PUT_UINT16(&driverData->PCI_TxDescriptorTablePtr[i].U.ST3.BufferByteCnt_II,
-(UINT16)(tcb->TCB_MediaHeaderLen));
driverData->PCI_TxDescriptorTablePtr[i].U.ST3.TxDescStatus_32_II &= MASK_ENP_STP;
}
else
{
/* No TCB media header. Point first descriptor to first fragment */
PUT_UINT32(&driverData->PCI_TxDescriptorTablePtr[i].U.ST3.TxAddr_32_II,
(UINT32)fragStruct->FragmentAddress);
PUT_UINT16(&driverData->PCI_TxDescriptorTablePtr[i].U.ST3.BufferByteCnt_II,
-(UINT16)(fragStruct->FragmentLength));
driverData->PCI_TxDescriptorTablePtr[i].U.ST3.TxDescStatus_32_II &= MASK_ENP_STP;
fragStruct++;
fragCount--;
}
/* Point next desriptors to the rest of the fragments */
while(fragCount)
{
if (fragStruct->FragmentLength)
{
i = (i + 1) & (TX_BUFFERS_FRAG - 1);
PUT_UINT32(&driverData->PCI_TxDescriptorTablePtr[i].U.ST3.TxAddr_32_II,
(UINT32)fragStruct->FragmentAddress);
PUT_UINT16(&driverData->PCI_TxDescriptorTablePtr[i].U.ST3.BufferByteCnt_II,
-(UINT16)(fragStruct->FragmentLength));
driverData->PCI_TxDescriptorTablePtr[i].U.ST3.TxDescStatus_32_II &= MASK_ENP_STP;
}
fragStruct++;
fragCount--;
}
/* Add possible evenization padding, set last descriptor to T_ENP_32 and
first descriptor T_STP_32. */
/* AYD 02-14-96 */
lastSize = GET_UINT16(&driverData->PCI_TxDescriptorTablePtr[i].U.ST3.BufferByteCnt_II);
lastSize -= paddedValue;
PUT_UINT16(&driverData->PCI_TxDescriptorTablePtr[i].U.ST3.BufferByteCnt_II, lastSize);
driverData->PCI_TxDescriptorTablePtr[driverData->TxNextToSend].U.ST3.TxDescStatus_32_II &= MASK_ENP;
driverData->PCI_TxDescriptorTablePtr[i].U.ST3.TxDescStatus_32_II |= T_ENP_32;
driverData->PCI_TxDescriptorTablePtr[driverData->TxNextToSend].U.ST3.TxDescStatus_32_II |= T_STP_32;
driverData->TxLastDesc[driverData->TxNextToSend] = i;
i = (i+1) & (TX_BUFFERS_FRAG - 1);
driverData->TxNextToSend = i;
/* Set adapter ownership bit(T_OWN_32) starting with the last descriptor
since setting the bit on the first descriptor will start
transmission. */
do
{
i = (i - 1) & (TX_BUFFERS_FRAG - 1);
/* AYD 02-14-96 */
driverData->PCI_TxDescriptorTablePtr[i].U.ST3.TxDescStatus_32_II |= T_OWN_32;
}
while(i != firstIndex);
Out16(configTable->MLIDCFG_DBusTag, (void *)driverData->RDP, TDMD | INEA);
driverData->TxStartTime[i] = CMSMGetCurrentTime();
return;
} /* End DriverSendPCI_II */
/***********************************************************************\
* *
*
* Name:
* void DriverISR(
* DRIVER_DATA *driverData)
*
* Description:
*
* This function handles packet reception, transmit complete and
* error handling.
*
* Parameters in:
*
* driverData - Pointer to HSM's Adapter Data Space.
*
* Values returned:
*
* *
************************************************************************/
void DriverISRISA(DRIVER_DATA *driverData) {
CONFIG_TABLE *configTable;
UINT16 interruptStatus;
int i;
/* UINT8 *TempRCB; */
/* , bufferCount; */
UINT8 txStatus;
UINT8 rxDescStatus;
UINT32 receiveStatus=0;
RCB *rcb;
UINT32 RxPacketSize;
configTable = DADSP_TO_CMSMADSP(driverData)->CMSMDefaultVirtualBoard;
interruptStatus = In16(configTable->MLIDCFG_DBusTag, (void *)driverData->RDP);
Out16(configTable->MLIDCFG_DBusTag, (void *)driverData->RDP, interruptStatus);
/* Reset flag set by timer. Reset adapter and get out */
if (driverData->ResetFlag)
{
driverData->ResetFlag = 0;
DriverReset(driverData, configTable, OP_SCOPE_ADAPTER);
return;
}
/* Error Interrupt Handler */
if (interruptStatus & ERR)
if ( DriverISRErrorHandler(driverData, configTable, interruptStatus) )
return;
/* Receive Interrupt Handler */
if (interruptStatus & RINT)
{
/* If Shutdown bit set just exit */
if( DADSP_TO_CMSMADSP(driverData)->CMSMStatusFlags & SHUTDOWN )
return;
while (driverData->NeedRCBCount != RX_BUFFERS) /*AYD != */
{
i = driverData->RxNextToReturn;
rxDescStatus = driverData->RxDescriptorTablePtr[i].RxDescAddr.RxAttr.Attr;
if (rxDescStatus & R_OWN)
break;
/* If MISS set, reset adapter to prevent reading garbage */
/* AYD 09-17-96 */
/* if ( In16(configTable->MLIDCFG_DBusTag, (void *)driverData->RDP) & MISS)
{
driverData->PacketRxOverflowCount++;
driverData->PacketRxMiscErrorCount++;
DriverReset(driverData, configTable, OP_SCOPE_ADAPTER);
return;
} */
rcb = driverData->RCBTable[i];
/* AYD 04-02-96 */
/* if( ((UINT32)rcb->RCBFragStruct.FragmentAddress & 0x00FFFFFF)
!= (driverData->RxDescriptorTablePtr[i].RxDescAddr.RxAddr & 0x00FFFFFF) )
EnterDebugger(); */
if (rxDescStatus & R_STP)
{
/* This is the start of the packet */
if ( (rxDescStatus & R_ENP) == 0)
{
rxDescStatus |= (R_ERR|R_CRC);
/* AYD 03-18-96 Changed this code to handel correctly large packets */
/*
End of packet bit not set. Search thru descriptors for it
bufferCount = RX_BUFFERS;
while (bufferCount--)
{
i++;
i &= (RX_BUFFERS - 1);
rxDescStatus =
driverData->RxDescriptorTablePtr[i].RxDescAddr.RxAttr.Attr;
if (rxDescStatus & R_ENP)
break;
}
if (bufferCount == 0)
{
Never found end of packet descriptor. Reset time.
NiosDprintf(NEVER_FOUND_END_OF_PACKET);
DriverReset(driverData, configTable, OP_SCOPE_ADAPTER);
return;
}
*/
}
/* Found last descriptor. Check its error status */
if (rxDescStatus & R_ERR)
{
/* Receive Error Handler */
receiveStatus = 0;
if (rxDescStatus & R_FRM)
{
driverData->RxAbortFrameAlignment++;
driverData->PacketRxMiscErrorCount++;
receiveStatus |= 2;
}
if (rxDescStatus & R_OFL)
driverData->PacketRxOverflowCount++;
if (rxDescStatus & R_CRC)
{
driverData->ChecksumErrorCount++;
receiveStatus |= 1;
}
if (rxDescStatus & R_BUF)
driverData->PacketRxOverflowCount++;
}
if ( ( (rxDescStatus & R_ERR) &&
( (GET_UINT16(&driverData->InitializationBlock) & 0x8000) ) )
|| ((rxDescStatus & R_ERR) == 0) )
{
/* Either good packet or bad packet with promiscuous mode enabled */
driverData->NeedRCBCount++;
RxPacketSize = (UINT32)GET_UINT16(&driverData->RxDescriptorTablePtr[i].RxDescMessageCount);
RxPacketSize -= 4; /* Do not include CRC 4 bytes */
/* AYD 04-08-96 */
driverData->RxDescriptorTablePtr[i].RxDescAddr.RxAddr = 0;
/* TempRCB = (UINT8 *)((RX_DESC *)driverData->RxDescriptorTablePtr);
for( j=0; j < 8*16; j++, TempRCB++ )
driverData->RxDescrTempBuffer[j] = *TempRCB; */
/* TempRCB = (UINT8 *)((RCB *)rcb);
for( j=0; j < 1590; j++, TempRCB++ )
driverData->TempBuffer[j] = *TempRCB; */
rcb = CEtherTSMFastProcessGetRCB(driverData,
rcb,
RxPacketSize,
receiveStatus,
driverData->CommonMaximumSize);
if (rcb)
{
/* TSM gave us an RCB back. */
driverData->NeedRCBCount--;
/* AYD 08-29-97 */
/*if ( ((ECB *)rcb)->ECB_Status == SPARE_ECB_STATUS )
driverData->ECBsOver16Meg++;*/
}
}
}
else
{
/* Start bit not set. */
if ( (rxDescStatus & R_ENP) == 0 )
{
/* Neither start nor stop bit set. This should never happen */
/* NiosDprintf(NO_START_NO_STOP_BIT); */
DriverReset(driverData, configTable, OP_SCOPE_ADAPTER);
return;
}
driverData->ECBOverflowCount++;
}
/* Finish receive by placing new(or old) RCB back into list */
/* AYD 03-28-95*/
i = driverData->RxNextToReturn;
i++;
i &= (RX_BUFFERS - 1);
driverData->RxNextToReturn = i;
if (rcb)
{
/* AYD 04-09-96 */
/* for( j=0; j < 16; j++ )
if( ((UINT32)rcb->RCBFragStruct.FragmentAddress & 0x00FFFFFF)
== (driverData->RxDescriptorTablePtr[j].RxDescAddr.RxAddr & 0x00FFFFFF) )
EnterDebugger(); */
i = driverData->RxNextToAllocate;
driverData->RCBTable[i] = rcb;
PUT_UINT32(&driverData->RxDescriptorTablePtr[i].RxDescAddr.RxAddr,
(UINT32)rcb->RCBFragStruct.FragmentAddress | (R_OWN << 24) );
PUT_UINT16(&driverData->RxDescriptorTablePtr[i].RxDescBufferCount,
-((UINT16)driverData->CommonMaximumSize));
i++;
i &= (RX_BUFFERS - 1);
driverData->RxNextToAllocate = i;
}
if (driverData->NeedRCBCount != RX_BUFFERS) /* AYD != */
{
interruptStatus |= In16(configTable->MLIDCFG_DBusTag,
(void *)driverData->RDP);
Out16(configTable->MLIDCFG_DBusTag, (void *)driverData->RDP,
interruptStatus);
if (interruptStatus & ERR)
if ( DriverISRErrorHandler(driverData, configTable,
interruptStatus) )
return;
}
} /* while NeedRCBCount */
} /* interruptStatus & RINT */
/* Attempt to allocate RCBs if we need some */
while (driverData->NeedRCBCount)
{
rcb = CMSMAllocateRCB(driverData, driverData->CommonMaximumSize, NULL);
if (rcb == NULL)
break;
driverData->NeedRCBCount--;
/*if ( ((ECB *)rcb)->ECB_Status == SPARE_ECB_STATUS )
driverData->ECBsOver16Meg++;*/
/* AYD 04-09-96 */
/* for( j=0; j < 16; j++ )
if( ((UINT32)rcb->RCBFragStruct.FragmentAddress & 0x00FFFFFF)
== (driverData->RxDescriptorTablePtr[j].RxDescAddr.RxAddr & 0x00FFFFFF) )
EnterDebugger(); */
i = driverData->RxNextToAllocate;
driverData->RCBTable[i] = rcb;
PUT_UINT32(&driverData->RxDescriptorTablePtr[i].RxDescAddr.RxAddr,
(UINT32)rcb->RCBFragStruct.FragmentAddress | (R_OWN << 24));
PUT_UINT16(&driverData->RxDescriptorTablePtr[i].RxDescBufferCount,
-((UINT16)driverData->CommonMaximumSize));
i++;
i &= (RX_BUFFERS - 1);
driverData->RxNextToAllocate = i;
}
/* AYD 09-25-95 Changed TX_BUFFERS to TX_BUFFERS_FRAG/16 for PCnet */
/* Transmit Interrupt Handler */
if (interruptStatus & TINT)
if (driverData->PCnetFlag)
{
i = driverData->TxLastDesc[driverData->TxNextToReturn];
txStatus = driverData->TxDescriptorTablePtr[i].TxDescAddr.TxAttr.Attr;
while ( (DADSP_TO_CMSMADSP(driverData)->CMSMTxFreeCount != TX_BUFFERS_FRAG/16)
&& ( (txStatus & T_OWN) == 0))
{
/* AYD 03-29-96 Check if this is an end of the TCB list */
if( driverData->TCBTable[driverData->TxNextToReturn] == NULL )
break;
if ((txStatus & T_ERR) == 0)
{
if (txStatus & T_DEF)
driverData->TxOKButDeferred++;
}
else
{
if (DriverISRTxErrorHandler(driverData, configTable))
return;
}
driverData->TxStartTime[driverData->TxNextToReturn] = 0;
DADSP_TO_CMSMADSP(driverData)->CMSMTxFreeCount++;
CEtherTSMFastSendComplete(driverData,
driverData->TCBTable[driverData->TxNextToReturn], 0);
i = (i+1) & (TX_BUFFERS_FRAG - 1); /* AYD 03-31-95*/
driverData->TxNextToReturn = i;
i = driverData->TxLastDesc[i];
txStatus = driverData->TxDescriptorTablePtr[i].TxDescAddr.TxAttr.Attr;
}
}
else /* Am7990 LANCE chipset */
{
i = driverData->TxNextToReturn;
txStatus = driverData->TxDescriptorTablePtr[i].TxDescAddr.TxAttr.Attr;
while ( (DADSP_TO_CMSMADSP(driverData)->CMSMTxFreeCount != TX_BUFFERS)
&& ( (txStatus & T_OWN) == 0))
{
/* AYD 09-17-96 */
if ((txStatus & T_ERR) == 0)
{
if (txStatus & T_DEF)
driverData->TxOKButDeferred++;
}
else
{
if (DriverISRTxErrorHandler(driverData, configTable))
return;
}
driverData->TxStartTime[i] = 0;
DADSP_TO_CMSMADSP(driverData)->CMSMTxFreeCount++;
i = (i+1) & (TX_BUFFERS - 1);
driverData->TxNextToReturn = i;
txStatus = driverData->TxDescriptorTablePtr[i].TxDescAddr.TxAttr.Attr;
}
}
return;
} /* End DriverISRISA */
void DriverISRPCI(DRIVER_DATA *driverData) {
CONFIG_TABLE *configTable;
UINT16 interruptStatus;
int i;
UINT16 rxDescStatus_32, txDescStatus_32;
UINT32 receiveStatus=0;
RCB *rcb;
UINT32 RxPacketSize;
configTable = DADSP_TO_CMSMADSP(driverData)->CMSMDefaultVirtualBoard;
interruptStatus = In16(configTable->MLIDCFG_DBusTag, (void *)driverData->RDP);
Out16(configTable->MLIDCFG_DBusTag, (void *)driverData->RDP, interruptStatus);
/* Reset flag set by timer. Reset adapter and get out */
if (driverData->ResetFlag)
{
driverData->ResetFlag = 0;
DriverReset(driverData, configTable, OP_SCOPE_ADAPTER);
return;
}
/* Error Interrupt Handler */
if (interruptStatus & ERR)
if ( DriverISRErrorHandler(driverData, configTable, interruptStatus) )
return;
/* Receive Interrupt Handler */
if (interruptStatus & RINT)
{
/* If Shutdown bit set just exit */
if( DADSP_TO_CMSMADSP(driverData)->CMSMStatusFlags & SHUTDOWN )
return;
while (driverData->NeedRCBCount != RX_BUFFERS) /*AYD != */
{
i = driverData->RxNextToReturn;
rxDescStatus_32 = driverData->PCI_RxDescriptorTablePtr[i].U.ST2.RxDescStatus_32;
if (rxDescStatus_32 & R_OWN_32)
break;
/* #ifdef DEBUG
NiosDprintf(RX_DESCR_STATUS, rxDescStatus);
#endif */
rcb = driverData->RCBTable[i];
if (rxDescStatus_32 & R_STP_32)
{
/* This is the start of the packet */
if ( (rxDescStatus_32 & R_ENP_32) == 0)
{
rxDescStatus_32 |= (R_ERR_32|R_CRC_32);
/* AYD 03-18-96 Changed this code to handel correctly large packets */
}
/* Found last descriptor. Check its error status */
if (rxDescStatus_32 & R_ERR_32)
{
/* Receive Error Handler */
receiveStatus = 0;
if (rxDescStatus_32 & R_FRM_32)
{
driverData->RxAbortFrameAlignment++;
driverData->PacketRxMiscErrorCount++;
receiveStatus |= 2;
}
if (rxDescStatus_32 & R_OFL_32)
driverData->PacketRxOverflowCount++;
if (rxDescStatus_32 & R_CRC_32)
{
driverData->ChecksumErrorCount++;
receiveStatus |= 1;
}
if (rxDescStatus_32 & R_BUF_32)
driverData->PacketRxOverflowCount++;
}
/* AYD 02-14-96 */
if ( ( (rxDescStatus_32 & R_ERR_32) &&
( (GET_UINT16(&driverData->PCI_InitializationBlockPtr->Mode) & 0x8000) ) )
|| ((rxDescStatus_32 & R_ERR_32) == 0) )
{
/* Either good packet or bad packet with promiscuous mode enabled */
driverData->NeedRCBCount++;
RxPacketSize = (UINT32)GET_UINT16(&driverData->PCI_RxDescriptorTablePtr[i].U.ST2.MessageByteCnt);
RxPacketSize -= 4; /* Do not include CRC 4 bytes */
/* AYD 04-08-96 */
driverData->PCI_RxDescriptorTablePtr[i].U.ST2.RxAddr_32 = 0;
rcb = CEtherTSMFastProcessGetRCB(driverData,
rcb,
RxPacketSize,
receiveStatus,
driverData->CommonMaximumSize);
if (rcb)
{
/* TSM gave us an RCB back. */
driverData->NeedRCBCount--;
}
}
}
else
{
/* Start bit not set. */
if ( (rxDescStatus_32 & R_ENP_32) == 0 )
{
/* Neither start nor stop bit set. This should never happen */
/* #ifdef DEBUG
NiosDprintf(NO_START_NO_STOP_BIT);
#endif */
DriverReset(driverData, configTable, OP_SCOPE_ADAPTER);
return;
}
driverData->ECBOverflowCount++;
}
/* Finish receive by placing new(or old) RCB back into list */
/* AYD 03-28-95*/
i = driverData->RxNextToReturn;
i++;
i &= (RX_BUFFERS - 1);
driverData->RxNextToReturn = i;
if (rcb)
{
i = driverData->RxNextToAllocate;
driverData->RCBTable[i] = rcb;
PUT_UINT32(&driverData->PCI_RxDescriptorTablePtr[i].U.ST2.RxAddr_32,
(UINT32)rcb->RCBFragStruct.FragmentAddress);
PUT_UINT16(&driverData->PCI_RxDescriptorTablePtr[i].U.ST2.BufferByteCnt,
-((UINT16)driverData->CommonMaximumSize));
driverData->PCI_RxDescriptorTablePtr[i].U.ST2.RxDescStatus_32 |= R_OWN_32;
i++;
i &= (RX_BUFFERS - 1);
driverData->RxNextToAllocate = i;
}
if (driverData->NeedRCBCount != RX_BUFFERS) /* AYD != */
{
interruptStatus |= In16(configTable->MLIDCFG_DBusTag,
(void *)driverData->RDP);
Out16(configTable->MLIDCFG_DBusTag, (void *)driverData->RDP,
interruptStatus);
if (interruptStatus & ERR)
if ( DriverISRErrorHandler(driverData, configTable, interruptStatus) )
return;
}
} /* while NeedRCBCount */
} /* interruptStatus & RINT */
/* Attempt to allocate RCBs if we need some */
while (driverData->NeedRCBCount)
{
rcb = CMSMAllocateRCB(driverData, driverData->CommonMaximumSize, NULL);
if (rcb == NULL)
break;
driverData->NeedRCBCount--;
i = driverData->RxNextToAllocate;
driverData->RCBTable[i] = rcb;
PUT_UINT32(&driverData->PCI_RxDescriptorTablePtr[i].U.ST2.RxAddr_32,
(UINT32)rcb->RCBFragStruct.FragmentAddress);
PUT_UINT16(&driverData->PCI_RxDescriptorTablePtr[i].U.ST2.BufferByteCnt,
-((UINT16)driverData->CommonMaximumSize));
driverData->PCI_RxDescriptorTablePtr[i].U.ST2.RxDescStatus_32 |= R_OWN_32;
i++;
i &= (RX_BUFFERS - 1);
driverData->RxNextToAllocate = i;
}
/* AYD 09-25-95 Changed TX_BUFFERS to TX_BUFFERS_FRAG/16 for PCnet */
/* Transmit Interrupt Handler */
if (interruptStatus & TINT)
{
i = driverData->TxLastDesc[driverData->TxNextToReturn];
txDescStatus_32 = driverData->PCI_TxDescriptorTablePtr[i].U.ST2.TxDescStatus_32;
while ( (DADSP_TO_CMSMADSP(driverData)->CMSMTxFreeCount != TX_BUFFERS_FRAG/16)
&& ( (txDescStatus_32 & T_OWN_32) == 0))
{
/* AYD 03-29-96 Check if this is an end of the TCB list */
if( driverData->TCBTable[driverData->TxNextToReturn] == NULL )
break;
/* AYD 09-17-96 */
if ((txDescStatus_32 & T_ERR_32) == 0)
{
if (txDescStatus_32 & T_DEF_32)
driverData->TxOKButDeferred++;
}
else
{
if (DriverISRTxErrorHandler(driverData, configTable))
return;
}
driverData->TxStartTime[driverData->TxNextToReturn] = 0;
DADSP_TO_CMSMADSP(driverData)->CMSMTxFreeCount++;
CEtherTSMFastSendComplete(driverData,
driverData->TCBTable[driverData->TxNextToReturn], 0);
i = (i+1) & (TX_BUFFERS_FRAG - 1); /* AYD 03-31-95*/
driverData->TxNextToReturn = i;
i = driverData->TxLastDesc[i];
txDescStatus_32 = driverData->PCI_TxDescriptorTablePtr[i].U.ST2.TxDescStatus_32;
}
}
return;
} /* End DriverISRPCI */
void DriverISRPCI_II(DRIVER_DATA *driverData) {
CONFIG_TABLE *configTable;
UINT16 interruptStatus;
int i;
UINT16 rxDescStatus_32, txDescStatus_32;
UINT32 receiveStatus=0;
RCB *rcb;
UINT32 RxPacketSize;
configTable = DADSP_TO_CMSMADSP(driverData)->CMSMDefaultVirtualBoard;
interruptStatus = In16(configTable->MLIDCFG_DBusTag, (void *)driverData->RDP);
Out16(configTable->MLIDCFG_DBusTag, (void *)driverData->RDP, interruptStatus);
/*#ifdef DEBUG
NiosDprintf(ISR, driverData->RDP );
#endif*/
/* Reset flag set by timer. Reset adapter and get out */
if (driverData->ResetFlag)
{
driverData->ResetFlag = 0;
DriverReset(driverData, configTable, OP_SCOPE_ADAPTER);
return;
}
/* Error Interrupt Handler */
if (interruptStatus & ERR)
if ( DriverISRErrorHandler(driverData, configTable, interruptStatus) )
return;
/* Receive Interrupt Handler */
if (interruptStatus & RINT)
{
/* If Shutdown bit set just exit */
if( DADSP_TO_CMSMADSP(driverData)->CMSMStatusFlags & SHUTDOWN )
return;
while (driverData->NeedRCBCount != RX_BUFFERS) /*AYD != */
{
i = driverData->RxNextToReturn;
rxDescStatus_32 = driverData->PCI_RxDescriptorTablePtr[i].U.ST3.RxDescStatus_32_II;
if (rxDescStatus_32 & R_OWN_32)
break;
rcb = driverData->RCBTable[i];
/* #ifdef DEBUG
NiosDprintf(RX_DESCR_STATUS);
#endif */
/*#ifdef DEBUG
NiosDprintf(RCB_COUNT,driverData->NeedRCBCount);
#endif*/
if (rxDescStatus_32 & R_STP_32)
{
/* This is the start of the packet */
if ( (rxDescStatus_32 & R_ENP_32) == 0)
{
rxDescStatus_32 |= (R_ERR_32|R_CRC_32);
/* AYD 03-18-96 Changed this code to handel correctly large packets */
}
/* Found last descriptor. Check its error status */
if (rxDescStatus_32 & R_ERR_32)
{
/* Receive Error Handler */
receiveStatus = 0;
if (rxDescStatus_32 & R_FRM_32)
{
driverData->RxAbortFrameAlignment++;
driverData->PacketRxMiscErrorCount++;
receiveStatus |= 2;
}
if (rxDescStatus_32 & R_OFL_32)
driverData->PacketRxOverflowCount++;
if (rxDescStatus_32 & R_CRC_32)
{
driverData->ChecksumErrorCount++;
receiveStatus |= 1;
}
if (rxDescStatus_32 & R_BUF_32)
driverData->PacketRxOverflowCount++;
}
/* AYD 02-14-96 */
if ( ( (rxDescStatus_32 & R_ERR_32) &&
( (GET_UINT16(&driverData->PCI_InitializationBlockPtr->Mode) & 0x8000) ) )
|| ((rxDescStatus_32 & R_ERR_32) == 0) )
{
/* Either good packet or bad packet with promiscuous mode enabled */
driverData->NeedRCBCount++;
RxPacketSize = (UINT32)GET_UINT16(&driverData->PCI_RxDescriptorTablePtr[i].U.ST3.MessageByteCnt_II);
RxPacketSize -= 4; /* Do not include CRC 4 bytes */
/* AYD 04-08-96 */
driverData->PCI_RxDescriptorTablePtr[i].U.ST3.RxAddr_32_II = 0;
rcb = CEtherTSMFastProcessGetRCB(driverData,
rcb,
RxPacketSize,
receiveStatus,
driverData->CommonMaximumSize);
if (rcb)
{
/* TSM gave us an RCB back. */
driverData->NeedRCBCount--;
}
}
}
else
{
/* Start bit not set. */
if ( (rxDescStatus_32 & R_ENP_32) == 0 )
{
/* Neither start nor stop bit set. This should never happen */
/* #ifdef DEBUG
NiosDprintf(NO_START_NO_STOP_BIT);
#endif */
DriverReset(driverData, configTable, OP_SCOPE_ADAPTER);
return;
}
driverData->ECBOverflowCount++;
}
/* Finish receive by placing new(or old) RCB back into list */
/* AYD 03-28-95*/
i = driverData->RxNextToReturn;
i++;
i &= (RX_BUFFERS - 1);
driverData->RxNextToReturn = i;
if (rcb)
{
i = driverData->RxNextToAllocate;
driverData->RCBTable[i] = rcb;
PUT_UINT32(&driverData->PCI_RxDescriptorTablePtr[i].U.ST3.RxAddr_32_II,
(UINT32)rcb->RCBFragStruct.FragmentAddress);
driverData->PCI_RxDescriptorTablePtr[i].U.ST3.RxDescStatus_32_II |= R_OWN_32;
i++;
i &= (RX_BUFFERS - 1);
driverData->RxNextToAllocate = i;
}
if (driverData->NeedRCBCount != RX_BUFFERS) /* AYD != */
{
interruptStatus |= In16(configTable->MLIDCFG_DBusTag,
(void *)driverData->RDP);
Out16(configTable->MLIDCFG_DBusTag, (void *)driverData->RDP,
interruptStatus);
if (interruptStatus & ERR)
if ( DriverISRErrorHandler(driverData, configTable,
interruptStatus) )
return;
}
} /* while NeedRCBCount */
} /* interruptStatus & RINT */
/* Attempt to allocate RCBs if we need some */
while (driverData->NeedRCBCount)
{
rcb = CMSMAllocateRCB(driverData, driverData->CommonMaximumSize, NULL);
if (rcb == NULL)
break;
/* #ifdef DEBUG
NiosDprintf(ALLOC);
#endif */
driverData->NeedRCBCount--;
i = driverData->RxNextToAllocate;
driverData->RCBTable[i] = rcb;
PUT_UINT32(&driverData->PCI_RxDescriptorTablePtr[i].U.ST3.RxAddr_32_II,
(UINT32)rcb->RCBFragStruct.FragmentAddress);
driverData->PCI_RxDescriptorTablePtr[i].U.ST3.RxDescStatus_32_II |= R_OWN_32;
i++;
i &= (RX_BUFFERS - 1);
driverData->RxNextToAllocate = i;
}
/* AYD 09-25-95 Changed TX_BUFFERS to TX_BUFFERS_FRAG/16 for PCnet */
/* Transmit Interrupt Handler */
if (interruptStatus & TINT)
{
i = driverData->TxLastDesc[driverData->TxNextToReturn];
txDescStatus_32 = driverData->PCI_TxDescriptorTablePtr[i].U.ST3.TxDescStatus_32_II;
while ( (DADSP_TO_CMSMADSP(driverData)->CMSMTxFreeCount != TX_BUFFERS_FRAG/16)
&& ( (txDescStatus_32 & T_OWN_32) == 0))
{
/* AYD 03-29-96 Check if this is an end of the TCB list */
if( driverData->TCBTable[driverData->TxNextToReturn] == NULL )
break;
/* AYD 09-17-96 */
if ((txDescStatus_32 & T_ERR_32) == 0)
{
if (txDescStatus_32 & T_DEF_32)
driverData->TxOKButDeferred++;
}
else
{
if (DriverISRTxErrorHandler(driverData, configTable))
return;
}
/*#ifdef DEBUG
NiosDprintf(TRANSMIT_COMPLETE);
#endif*/
driverData->TxStartTime[driverData->TxNextToReturn] = 0;
DADSP_TO_CMSMADSP(driverData)->CMSMTxFreeCount++;
CEtherTSMFastSendComplete(driverData,
driverData->TCBTable[driverData->TxNextToReturn], 0);
i = (i+1) & (TX_BUFFERS_FRAG - 1); /* AYD 03-31-95*/
driverData->TxNextToReturn = i;
i = driverData->TxLastDesc[i];
txDescStatus_32 = driverData->PCI_TxDescriptorTablePtr[i].U.ST3.TxDescStatus_32_II;
}
}
return;
} /* End DriverISRPCI_II */
/***********************************************************************\
* *
*
* Name:
* UINT32 DriverISRErrorHandler(
* DRIVER_DATA *driverData,
* CONFIG_TABLE *configTable,
* UINT32 interruptStatus)
*
* Description:
*
* This function determines the error type, increments the
* appropriate statistic counters, and resets the adapter
* on fatal errors.
*
* Parameters in:
*
* driverData - Pointer to HSM's Adapter Data Space.
* configTable - Pointer to HSM's Default Configuration Table.
* interruptStatus - Adapters interrupt status.
*
* Values returned:
* 0 - If non-fatal error(caller can continue normal execution)
* 1 - If fatal error(DriverReset has been called)
*
* *
************************************************************************/
UINT32 DriverISRErrorHandler(
DRIVER_DATA *driverData,
CONFIG_TABLE *configTable,
UINT32 interruptStatus)
{
if (interruptStatus & MISS)
{
driverData->PacketRxOverflowCount++;
driverData->PacketRxMiscErrorCount++;
DriverReset(driverData, configTable, OP_SCOPE_ADAPTER);
return 1;
}
if (interruptStatus & CERR)
{
driverData->HeartbeatError++;
driverData->PacketRxMiscErrorCount++;
}
if (interruptStatus & BABL)
{
DriverReset(driverData, configTable, OP_SCOPE_ADAPTER);
return 1;
}
if (interruptStatus & MERR)
{
if (driverData->PCnetFlag)
return 0;
DriverReset(driverData, configTable, OP_SCOPE_ADAPTER);
return 1;
}
return 0;
}
/***********************************************************************\
* *
*
* Name:
* UINT32 DriverISRTxErrorHandler(
* DRIVER_DATA *driverData,
* CONFIG_TABLE *configTable)
*
* Description:
*
* This function determines the transmit error type, increments the
* appropriate statistic counters, and resets the adapter
* on fatal errors.
*
* Parameters in:
*
* driverData - Pointer to HSM's Adapter Data Space.
* configTable - Pointer to HSM's Default Configuration Table.
*
* Values returned:
* 0 - If non-fatal error(caller can continue normal execution)
* 1 - If fatal error(DriverReset has been called)
*
* *
************************************************************************/
UINT32 DriverISRTxErrorHandler(
DRIVER_DATA *driverData,
CONFIG_TABLE *configTable)
{
UINT16 txError;
/* AYD 11-18-96 Added switch statement */
switch ( driverData->PCnetFlag )
{
case PCNETPCI:
txError = GET_UINT16(
&driverData->PCI_TxDescriptorTablePtr[driverData->TxNextToReturn].U.ST2.TxError);
break;
case PCNETPCI_II:
txError = GET_UINT16(
&driverData->PCI_TxDescriptorTablePtr[driverData->TxNextToReturn].U.ST3.TxError_II);
break;
default:
txError = GET_UINT16(
&driverData->TxDescriptorTablePtr[driverData->TxNextToReturn].TxDescStatus);
break;
}
if (txError & T_BUF)
{
driverData->TxBufferError++;
driverData->PacketTxMiscErrorCount++;
DriverReset(driverData, configTable, OP_SCOPE_ADAPTER);
return(1);
}
if (txError & T_UFL)
{
driverData->TxUnderflow++;
driverData->PacketTxMiscErrorCount++;
DriverReset(driverData, configTable, OP_SCOPE_ADAPTER);
return(1);
}
if (txError & T_LAT)
{
driverData->TxAbortLateCollision++;
driverData->PacketTxMiscErrorCount++;
}
if (txError & T_CAR)
{
driverData->TxAbortCarrierSense++;
driverData->PacketTxMiscErrorCount++;
}
return 0;
}
/***********************************************************************\
* *
*
* Name:
* BOOLEAN DriverDisableInterrupt(
* DRIVER_DATA *driverData
* BOOLEAN Flag )
*
* Description:
*
* This function disables the adapter from interrupting the system.
* It is called before DriverISR or DriverSend is called. We will
* always return a zero since the MSM interrupt handler will use it
* to determine if it needs to EOI the PIC and call DriverISR.
*
* Parameters in:
*
* driverData - Pointer to HSM's Adapter Data Space.
*
* Values returned:
* 0 - Our adapter initiated the interrupt.
*
* *
************************************************************************/
BOOLEAN DriverDisableInterrupt(DRIVER_DATA *driverData,
BOOLEAN Flag)
{
UINT16 interruptStatus;
/* NiosBreak(); */
if( Flag == FALSE)
{
Out16(DADSP_TO_CMSMADSP(driverData)->CMSMDefaultVirtualBoard->MLIDCFG_DBusTag,
(void *)driverData->RDP,
0);
/* NiosDprintf(ID); */
return TRUE;
}
else
{
interruptStatus = In16(DADSP_TO_CMSMADSP(driverData)->CMSMDefaultVirtualBoard->MLIDCFG_DBusTag,
(void *)driverData->RDP);
if( interruptStatus & INTR )
{
Out16(DADSP_TO_CMSMADSP(driverData)->CMSMDefaultVirtualBoard->MLIDCFG_DBusTag,
(void *)driverData->RDP,
0);
/* NiosDprintf(ID); */
return TRUE;
}
else
return FALSE;
}
} /* End DriverDisableInterrupt */
/***********************************************************************\
* *
*
* Name:
* void DriverEnableInterrupt(
* DRIVER_DATA *driverData)
*
* Description:
*
* This function enables the adapter to interrupt the system.
*
* Parameters in:
*
* driverData - Pointer to HSM's Adapter Data Space.
*
* Values returned:
*
* *
************************************************************************/
void DriverEnableInterrupt(DRIVER_DATA *driverData)
{
Out16(DADSP_TO_CMSMADSP(driverData)->CMSMDefaultVirtualBoard->MLIDCFG_DBusTag,
(void *)driverData->RDP,
INEA);
/* NiosDprintf(IE); */
return;
} /* End DriverEnableInterrupt */
/***********************************************************************\
* *
*
* Name:
* void DriverCallBack(
* DRIVER_DATA *driverData,
* CONFIG_TABLE *configTable)
*
* Description:
*
* This function is called by the MSM due to DriverInit calling
* CMSMScheduleAES. It is called continuously at the
* interval specified during DriverInit. It is being used to detect
* transmit timeouts and receive timeouts(on Am7990 only). If transmit
* timeout, make sure adapter isn't trying to interrupt system. If it
* isn't, reset the adapter.
*
* Parameters in:
*
* driverData - Pointer to HSM's Adapter Data Space.
* configTable - Pointer to HSM's default Configuration Table.
*
* Values returned:
*
* Things To Do:
* 1) Should CMSMGetCurrentTime return int?
*
* *
************************************************************************/
void DriverCallBack(
DRIVER_DATA *driverData,
CONFIG_TABLE *configTable)
{
UINT32 startTime;
UINT16 Status;
// UINT16 ioValue;
// if(driverData->PCnetFlag == PCNETPCI_II)
// {
// /* Update link speed value in Config Table */
// /* Read BCR33, bit #10 should indicate link speed. 0 - 10, 1 - 100 MBPS*/
// Out16(configTable->MLIDCFG_DBusTag, (void *)driverData->RAP, BCR33);
// ioValue = In16( configTable->MLIDCFG_DBusTag, (void *)driverData->IDP_BDP);
//
// if (ioValue & 0x0400)
// configTable->MLIDCFG_LineSpeed = 100;
// else
// configTable->MLIDCFG_LineSpeed = 10;
//
// /* Restore address of CSR0 in RAP */
// Out16(configTable->MLIDCFG_DBusTag, (void *)driverData->RAP, CSR0);
// }
startTime = driverData->TxStartTime[driverData->TxNextToReturn];
if ( startTime )
{
if ( (CMSMGetCurrentTime() - startTime) > 36 )
{
/* Transmit Timeout */
/* Send Alert if driverData->BNCFlag == 0 */
if( driverData->BNCFlag == 0)
{
CMSMPrintString(configTable, MSG_TYPE_RUNTIME_WARNING,
CNEAMD_CABLEDISC_MSG,
NULL ,NULL);
driverData->BNCFlag++;
}
DriverDisableInterrupt(driverData, FALSE);
/* AYD */
Status = In16(configTable->MLIDCFG_DBusTag, (void *)driverData->RDP);
Out16( configTable->MLIDCFG_DBusTag, (void *)driverData->RDP, Status );
if ( Status & (ERR | BABL | CERR | MISS | MERR | RINT | TINT | INTR) )
{
/* Adapter is interrupting system. Set reset flag and let
DriverISR reset the adapter. */
driverData->ResetFlag++;
DriverEnableInterrupt(driverData);
return;
}
}
else /* Transmit in progress, hasn't timed out yet */
return;
}
else
{
if (driverData->PCnetFlag)
/* Am79C960 PCnetISA chip doesn't have receiver lock bug */
{
return;
}
if (--driverData->CheckRxCount)
return;
driverData->CheckRxCount = 16;
/* Return if TotalRxPacketCount has changed */
if (driverData->TotalRxPacketCount != driverData->LastTotalRxPacketCount)
{
driverData->LastTotalRxPacketCount = driverData->TotalRxPacketCount;
return;
}
else
driverData->LastTotalRxPacketCount = driverData->TotalRxPacketCount;
}
/* Either transmit or receive timeout. Reset adapter. */
DriverReset(driverData, configTable, OP_SCOPE_ADAPTER);
} /* End DriverCallBack */
/***********************************************************************\
* *
*
* Name:
* ODISTAT DriverReset(
* DRIVER_DATA *driverData,
* CONFIG_TABLE *configTable,
* OPERATION_SCOPE operationScope)
*
* Description:
*
* This function resets the adapter.
*
* Parameters in:
*
* driverData - Pointer to HSM's Adapter Data Space.
* configTable - Pointer to HSM's default Configuration Table.
* operationScope - OP_SCOPE_ADAPTER or OP_SCOPE_LOGICAL_BOARD.
*
* Values returned:
* ODISTAT_SUCCESSFUL Adapter Reset successfully
* ODISTAT_FAIL Unable to reset adapter(hardware failure)
*
* *
************************************************************************/
ODISTAT DriverReset(
DRIVER_DATA *driverData,
CONFIG_TABLE *configTable,
OPERATION_SCOPE operationScope)
{
RCB *rcb;
UINT32 rxFragmentPtr;
UINT32 bufferCount, bufferLength;
UINT16 ioValue, ioRPA;
void *initPtr, *descPtr;
UINT32 startTime, currentTime;
int i;
void *bufferPtr;
TX_DESC *txDescPtr;
UINT32 *txBufferPtr;
if (operationScope == OP_SCOPE_ADAPTER)
{
/* AYD 11-15-96 */
if( (driverData->PCnetFlag == PCNETPCI) || (driverData->PCnetFlag == PCNETPCI_II ) )
{
initPtr = &driverData->PCI_InitializationBlock;
initPtr = (void *)((UINT32)initPtr & 0xfffffffc); /* Force to DWORD */
PUT_UINT32(&driverData->PCI_InitializationBlockPtr, initPtr);
}
else
initPtr = &driverData->InitializationBlock;
initPtr = CMSMGetPhysical(initPtr);
initPtr = (void *)GET_UINT32(&initPtr);
/* AYD 11-15-96 */
if( (driverData->PCnetFlag == PCNETPCI) || (driverData->PCnetFlag == PCNETPCI_II ) )
{
COPY_ADDR(&driverData->PCI_InitializationBlockPtr->PCI_PhysicalAddress,&configTable->MLIDCFG_NodeAddress);
/* Set up Receive Descriptor Table Ptr. */
descPtr = &driverData->PCI_RxDescriptorTable;
descPtr = (void *)((UINT32)descPtr & 0xfffffff0); /* Force to 16 bytes */
PUT_UINT32(&driverData->PCI_RxDescriptorTablePtr, descPtr);
descPtr = CMSMGetPhysical(descPtr);
PUT_UINT32(&driverData->PCI_InitializationBlockPtr->PCI_RxDescriptorRingPtr, (void *)(UINT32)descPtr);
bufferLength = 0xffffffff;
bufferCount = RX_BUFFERS;
while(bufferCount != 0)
{
bufferLength++;
bufferCount >>= 1;
}
bufferLength <<= 4;
PUT_UINT16(&driverData->PCI_InitializationBlockPtr->PCI_Len, (UINT16)bufferLength);
/* Set up Transmit Descriptor Table Ptr. */
descPtr = &driverData->PCI_TxDescriptorTable;
descPtr = (void *)((UINT32)descPtr & 0xfffffff0); /* Force to 16 bytes */
PUT_UINT32(&driverData->PCI_TxDescriptorTablePtr, descPtr);
descPtr = CMSMGetPhysical(descPtr);
PUT_UINT32(&driverData->PCI_InitializationBlockPtr->PCI_TxDescriptorRingPtr, (void *)(UINT32)descPtr);
bufferLength = 0xffffffff;
bufferCount = TX_BUFFERS_FRAG;
while(bufferCount != 0)
{
bufferLength++;
bufferCount >>= 1;
}
bufferLength <<= 12;
ioValue = GET_UINT16(&driverData->PCI_InitializationBlockPtr->PCI_Len);
ioValue &= 0x0fff;
ioValue |= (UINT16)bufferLength;
PUT_UINT16(&driverData->PCI_InitializationBlockPtr->PCI_Len, ioValue);
}
else
{
COPY_ADDR(&driverData->PhysicalAddress,&configTable->MLIDCFG_NodeAddress);
/* AYD 03-03-97 Set aligment to 32 byte boundary to use beter cache lines on
Pentium CPU*/
/* Set up Receive Descriptor Table Ptr. */
descPtr = &driverData->RxDescriptorTable;
descPtr = (void *)((UINT32)descPtr & 0xfffffff8); /* Force to QWORD */
PUT_UINT32(&driverData->RxDescriptorTablePtr, descPtr);
descPtr = CMSMGetPhysical(descPtr);
bufferLength = 0xffffffff;
bufferCount = RX_BUFFERS;
while(bufferCount != 0)
{
bufferLength++;
bufferCount >>= 1;
}
bufferLength <<= 29;
PUT_UINT32(&driverData->RxDescriptorRingPtr,
(void *)((UINT32)descPtr | bufferLength));
/* Set up Transmit Descriptor Table Ptr. */
descPtr = &driverData->TxDescriptorTable;
descPtr = (void *)((UINT32)descPtr & 0xfffffff8); /* Force to QWORD */
PUT_UINT32(&driverData->TxDescriptorTablePtr, descPtr);
descPtr = CMSMGetPhysical(descPtr);
bufferLength = 0xffffffff;
if (driverData->PCnetFlag == LANCE)
bufferCount = TX_BUFFERS;
else
bufferCount = TX_BUFFERS_FRAG;
while(bufferCount != 0)
{
bufferLength++;
bufferCount >>= 1;
}
bufferLength <<= 29;
PUT_UINT32(&driverData->TxDescriptorRingPtr,
(void *)((UINT32)descPtr | bufferLength));
if (driverData->PCnetFlag == LANCE)
{
/* Setp up Transmit Descriptors. */
for(bufferCount = 0, bufferPtr=driverData->TxBuffers,
txDescPtr = (TX_DESC *)GET_UINT32(&driverData->TxDescriptorTablePtr),
txBufferPtr = (UINT32 *)&driverData->TxBufferTable;
bufferCount < TX_BUFFERS;
bufferCount++,
txDescPtr++,
txBufferPtr++)
{
PUT_UINT32(txBufferPtr, (UINT32)bufferPtr);
PUT_UINT32(&txDescPtr->TxDescAddr.TxAddr,
((UINT32)CMSMGetPhysical(bufferPtr) | 0x03000000)); /* STP & ENP */
bufferPtr = (void *)((UINT8 *)bufferPtr + BUFFER_SIZE);
}
}
}
DriverDisableInterrupt(driverData, FALSE);
DriverShutdown(driverData, configTable, SHUTDOWN_PARTIAL, OP_SCOPE_ADAPTER);
driverData->AdapterResetCount++;
/* Allocate as many RCBs as possible. */
while (driverData->NeedRCBCount)
{
rcb = CMSMAllocateRCB(driverData, driverData->CommonMaximumSize, NULL);
if (rcb == NULL)
break;
/* AYD 08-29-97 */
/*if ( ((ECB *)rcb)->ECB_Status == SPARE_ECB_STATUS)
driverData->ECBsOver16Meg++;*/
i = driverData->RxNextToAllocate;
driverData->RCBTable[i] = rcb;
rxFragmentPtr = (UINT32)GET_UINT32(&rcb->RCBFragStruct.FragmentAddress);
/* AYD 11-18-96 Added switch */
switch ( driverData->PCnetFlag )
{
case PCNETPCI:
PUT_UINT32(&driverData->PCI_RxDescriptorTablePtr[i].U.ST2.RxAddr_32,
rxFragmentPtr);
PUT_UINT16(&driverData->PCI_RxDescriptorTablePtr[i].U.ST2.BufferByteCnt,
-((UINT16)driverData->CommonMaximumSize));
driverData->PCI_RxDescriptorTablePtr[i].U.ST2.RxDescStatus_32 |= R_OWN_32;
break;
case PCNETPCI_II:
PUT_UINT32(&driverData->PCI_RxDescriptorTablePtr[i].U.ST3.RxAddr_32_II,
rxFragmentPtr);
PUT_UINT16(&driverData->PCI_RxDescriptorTablePtr[i].U.ST3.BufferByteCnt_II,
-((UINT16)driverData->CommonMaximumSize));
driverData->PCI_RxDescriptorTablePtr[i].U.ST3.RxDescStatus_32_II |= R_OWN_32;
break;
default:
rxFragmentPtr |= (R_OWN << 24);
PUT_UINT32(&driverData->RxDescriptorTablePtr[i].RxDescAddr.RxAddr,
rxFragmentPtr);
PUT_UINT16(&driverData->RxDescriptorTablePtr[i].RxDescBufferCount,
-((UINT16)driverData->CommonMaximumSize));
break;
}
i = (i+1) & (RX_BUFFERS - 1);
driverData->RxNextToAllocate = i;
driverData->NeedRCBCount--;
}
/* AYD 06-11-96 Moved DMAStart in to DriverReset */
/* Set up DMA channel */
if ( (driverData->PCnetFlag == PCNETISA) || (driverData->PCnetFlag == LANCE) )
DMAStart( (void *)driverData->BusTag, 0, 0,
(void *)driverData->BusTag, 0, 0,
0, (UINT32)configTable->MLIDCFG_DMALine0, 0xc0, 0);
/* Reset the NIC */
Out16(configTable->MLIDCFG_DBusTag, (void *)driverData->RAP, CSR0);
/* Pulse hardware reset line */
In16(configTable->MLIDCFG_DBusTag, (void *)driverData->Reset);
Slow();
DriverEnableInterrupt(driverData);
if ( (driverData->PCnetFlag == PCNETPCI) || (driverData->PCnetFlag == PCNETPCI_II) )
{
/* Enable 32 bit Discriptors */
Out16(configTable->MLIDCFG_DBusTag, (void *)driverData->RAP, BCR20);
ioValue = In16( configTable->MLIDCFG_DBusTag, (void *)driverData->IDP_BDP);
ioValue &= 0xff00;
/* AYD 11-15-96 */
if (driverData->PCnetFlag == PCNETPCI)
ioValue |= 0x02; /* SWSTYLE = 2 */
else
ioValue |= 0x03; /* SWSTYLE = 3 */
Out16(configTable->MLIDCFG_DBusTag, (void *)driverData->IDP_BDP, ioValue);
if (driverData->PCnetFlag == PCNETPCI_II)
{
/* AYD 11-15-96 */
/* Enable Burst Read/Write Mode and Set No Underflow on Transmit. */
Out16(configTable->MLIDCFG_DBusTag, (void *)driverData->RAP, BCR18);
ioValue = In16( configTable->MLIDCFG_DBusTag, (void *)driverData->IDP_BDP);
/* Set NOUFLO, BREADE and BWRITE. Bits 11, 6 and 5 */
/* ioValue |= 0x0860; */
ioValue |= 0x0800;
Out16(configTable->MLIDCFG_DBusTag, (void *)driverData->IDP_BDP, ioValue);
/* #ifdef DEBUG
NiosBreak();
#endif */
/* Read BCR33, bit #10 should indicate link speed. 0 - 10, 1 - 100 MBPS*/
Out16(configTable->MLIDCFG_DBusTag, (void *)driverData->RAP, BCR33);
ioValue = In16( configTable->MLIDCFG_DBusTag, (void *)driverData->IDP_BDP);
if (ioValue & 0x0400)
configTable->MLIDCFG_LineSpeed = 100;
else
configTable->MLIDCFG_LineSpeed = 10;
}
/* AYD 02-09-96 Set Full Duplex Mode */
if ( driverData->FullDuplex )
{
Out16(configTable->MLIDCFG_DBusTag, (void *)driverData->RAP, BCR9);
ioValue = In16( configTable->MLIDCFG_DBusTag, (void *)driverData->IDP_BDP);
ioValue |= 0x3;
Out16(configTable->MLIDCFG_DBusTag, (void *)driverData->IDP_BDP, ioValue);
}
}
if (driverData->PCnetFlag)
{
if (driverData->PCnetFlag == PCNETISA)
{
/* Configure Bus register */
Out16(configTable->MLIDCFG_DBusTag, (void *)driverData->RAP, CSR2);
ioValue = (driverData->BusType == ODI_BUSTYPE_EISA) ? (LEVEL_INIT | 0x02) :
(FASTISA_INIT | 0x02);
Out16(configTable->MLIDCFG_DBusTag, (void *)driverData->IDP_BDP, ioValue);
/* Configure FIFO/DMA Burst register */
Out16(configTable->MLIDCFG_DBusTag, (void *)driverData->RAP, CSR80);
Out16(configTable->MLIDCFG_DBusTag, (void *)driverData->RDP,
RCVFW_INIT | XMTFW_INIT | XMTSP_INIT | 0x020);
/* Configure Bus Timer register */
Out16(configTable->MLIDCFG_DBusTag, (void *)driverData->RAP, CSR82);
Out16(configTable->MLIDCFG_DBusTag, (void *)driverData->RDP, 0x91);
}
/* Configure config register */
Out16(configTable->MLIDCFG_DBusTag, (void *)driverData->RAP, CSR4);
ioValue = In16(configTable->MLIDCFG_DBusTag, (void *)driverData->RDP);
/* AYD 10-13-95 */
if (driverData->PCnetFlag == PCNETISA)
ioValue = (((ioValue & 0xbfff) | 0x2800) | DMAPLUS_INIT);
else
ioValue = ( ioValue | 0x0800 ); /* APAD_XMT Auto Pad */
ioValue |= ENTST; /* Enable Test Mode or Runt Packet Accept */
Slow();
Out16(configTable->MLIDCFG_DBusTag, (void *)driverData->RDP, ioValue);
/* AYD 12-18-95 */ /* AYD 02-13-96 */
if (driverData->PCnetFlag == PCNETISA)
ioRPA = GET_UINT16(&driverData->InitializationBlock);
else
ioRPA = GET_UINT16(&driverData->PCI_InitializationBlockPtr->Mode);
/* AYD 03-29-96 Using ioRPA for temp. storage Mode word */
if ( ioRPA & 0x8000 )
{
Out16(configTable->MLIDCFG_DBusTag, (void *)driverData->RAP, CSR124);
ioRPA = In16(configTable->MLIDCFG_DBusTag, (void *)driverData->RDP);
ioRPA |= 0x0008; /* Enable RPA */
Slow();
Out16(configTable->MLIDCFG_DBusTag, (void *)driverData->RDP, ioRPA);
}
Out16(configTable->MLIDCFG_DBusTag, (void *)driverData->RAP, CSR4);
ioValue &= ~ENTST; /* Disable Test Mode or Runt Packet Accept */
Slow();
Out16(configTable->MLIDCFG_DBusTag, (void *)driverData->RDP, ioValue);
}
/* Send low word of physical address of Initialization Block */
Out16(configTable->MLIDCFG_DBusTag, (void *)driverData->RAP, CSR1);
Out16(configTable->MLIDCFG_DBusTag, (void *)driverData->RDP,
(UINT16)initPtr);
/* Send high word of physical address of Initialization Block */
Out16(configTable->MLIDCFG_DBusTag, (void *)driverData->RAP, CSR2);
initPtr = (void *)((UINT32)initPtr >> 16);
Out16(configTable->MLIDCFG_DBusTag, (void *)driverData->RDP,
(UINT16)initPtr);
/* Send initialize command to NIC */
Out16(configTable->MLIDCFG_DBusTag, (void *)driverData->RAP, CSR0);
Out16(configTable->MLIDCFG_DBusTag, (void *)driverData->RDP, INIT);
/* Wait up to 100us for IDON bit to set */
startTime = CMSMGetMicroTimer();
/* NiosDprintf(START_TIME, startTime); */
startTime = -startTime;
do
{
ioValue = In16(configTable->MLIDCFG_DBusTag, (void *)driverData->RDP);
/* NiosDprintf(STATUS, ioValue); */
/* NiosBreak(); */
if ((ioValue & IDON) != 0)
break;
}
while ( ((currentTime=CMSMGetMicroTimer()) + startTime) < 0x20000);
/* NiosDprintf(CURRENT_TIME, currentTime+startTime); */
if ((ioValue & IDON) == 0)
return ODISTAT_FAIL;
/* Clear IDON bit */
Out16(configTable->MLIDCFG_DBusTag, (void *)driverData->RDP, ioValue);
/* Start the NIC */
Out16(configTable->MLIDCFG_DBusTag, (void *)driverData->RDP, STRT);
Slow();
ioValue = In16(configTable->MLIDCFG_DBusTag, (void *)driverData->RDP);
/* AYD 05-30-96 Clear all other bits in case if NIC received a packet */
ioValue &= (RXON | TXON | STRT | INIT);
if ( ioValue != (RXON | TXON | STRT | INIT))
return ODISTAT_FAIL;
/* Enable the NIC */
Out16(configTable->MLIDCFG_DBusTag, (void *)driverData->RDP, INEA);
CMSMUpdateConfigTables(driverData, configTable);
return ODISTAT_SUCCESSFUL;
}
else
return ODISTAT_SUCCESSFUL;
} /* End DriverReset */
/***********************************************************************\
* *
*
* Name:
* UINT32 DriverInit(struct _HSM_STACK *hsmStack)
*
* Description:
*
* This routine will call CEtherTSMRegisterHSM,
* CMSMParseDriverParameters, CMSMRegisterHardwareOptions,
* CMSMSetHardwareInterrupt, CMSMRegisterMLID, initialize
* variables in the Adapter Data Space and reset/initialize
* the card.
*
* Parameters in:
*
* hsmStack - Pointer to HSM's stack parameters which will
* dealt with by the MSM at different stages of
* DriverInit.
*
* Things to do:
*
* 1) Set up PCnetISA adapter data space variables that are
* configurable from the command line when AddOption/ParseOptions
* is implemented.
*
* Values returned:
*
* 0 if successful
* ALL_ONES if failure
*
* *
************************************************************************/
UINT32 DriverInit(CHSM_STACK *hsmStack)
{
CONFIG_TABLE *configTable;
DRIVER_DATA *driverData;
REG_TYPE retValue;
UINT16 ioValue;
UINT32 nodeIndex;
UINT32 checksum;
UINT8 ioValue8;
UINT32 LocalPCnetFlag = 0;
UINT32 scanSeq, uniqueID, busTag, busType;
UINT16 slot;
UINT8 cfgBlock[256];
CMSM_PNP_ISA_CONFIG_INFO *cfgBlockPnPPtr;
UINT8 cfgBlockPnP[512];
static MEON productID[4] = {0x22, 0x10, 0x00, 0x20}; /* PCnetPCI */
static MEON productIDPnP[4] = {0x04, 0x96, 0x55, 0xAA}; /* PCnetISA+ */
/* VendorID for PCnetISA+ is "ADV55AA" 00001, 00100, 10110
compressed ASCII (0x0496) and 0x55AA */
DriverParameterBlock.DriverInitParmPointer = (CHSM_STACK *)&hsmStack;
CMSMInitParser(&DriverParameterBlock);
IoOption.Parameter1.Range = 0;
if( CMSMParseSingleParameter(&ISAOption) == ODISTAT_SUCCESSFUL )
{
DriverParameterBlock.DriverNeedsBelow16Meg = 1;
DriverConfigTemplate.MLIDCFG_SGCount = 2;
}
else
{
scanSeq = -1;
if( CMSMSearchAdapter (&scanSeq, ODI_BUSTYPE_PCI, 4, productID,
(void **)&busTag, &uniqueID)
== ODI_NBI_SUCCESSFUL)
{
DriverParameterBlock.DriverNeedsBelow16Meg = 0;
DriverConfigTemplate.MLIDCFG_SGCount = 16;
}
}
/* Let TSM/MSM know we are here */
if (CEtherTSMRegisterHSM(&DriverParameterBlock, &configTable)
!= ODISTAT_SUCCESSFUL)
{
CMSMReturnDriverResources(configTable);
return (ALL_ONES);
}
/* DMAOption.Flags &= ~REQUIREDPARAM;
DMAOption.Link = NULL; */
/* Find out if we load the driver for ISA type of adapter which will
require DMA, PORT, IRQ parameters on command line in case if machine
has two or more different kind (PCI, ISA etc.) of NICs */
if( CMSMParseSingleParameter(&ISAOption) == ODISTAT_SUCCESSFUL )
{
if ( DriverInitISA(&LocalPCnetFlag, configTable) != ODISTAT_SUCCESSFUL )
return ALL_ONES;
}
else
{
SlotsWithMyBoard.OptionCount = 0;
scanSeq = -1;
/* Find all of the PCnetISA+'s in the machine */
while (SlotsWithMyBoard.OptionCount < 8 && CMSMSearchAdapter (
&scanSeq,
ODI_BUSTYPE_ISA,
4,
productIDPnP,
(void **)&busTag,
&uniqueID)
== ODI_NBI_SUCCESSFUL)
{
if( CMSMGetInstanceNumber( (void *)busTag, uniqueID, &slot ) ==
ODI_NBI_SUCCESSFUL)
{
SlotsWithMyBoard.Slot[SlotsWithMyBoard.OptionCount] = (UINT32)slot;
SlotsWithMyBoard.OptionCount++;
}
/* NiosDprintf(UNIQUE_ID, uniqueID); */
}
scanSeq = -1;
/* Find all of the PCnetPCI's in the machine */
while (SlotsWithMyBoard.OptionCount < 8 && CMSMSearchAdapter (
&scanSeq,
ODI_BUSTYPE_PCI,
4,
productID,
(void **)&busTag,
&uniqueID)
== ODI_NBI_SUCCESSFUL)
{
if(CMSMGetInstanceNumber( (void *)busTag, uniqueID, &slot ) ==
ODI_NBI_SUCCESSFUL)
{
SlotsWithMyBoard.Slot[SlotsWithMyBoard.OptionCount] = (UINT32)slot;
SlotsWithMyBoard.OptionCount++;
}
/* NiosDprintf(UNIQUE_ID, uniqueID); */
}
if (SlotsWithMyBoard.OptionCount)
{
configTable->MLIDCFG_Slot = SlotsWithMyBoard.Slot[0];
if (SlotsWithMyBoard.OptionCount > 1)
{
if (CMSMParseDriverParameters(&DriverParameterBlock, &SlotOption) != ODISTAT_SUCCESSFUL)
{
CMSMReturnDriverResources(configTable);
return ODISTAT_FAIL;
}
}
else
{
/* Call CMSMParseDriverParameters at least ones to parse for frame */
if (CMSMParseDriverParameters(&DriverParameterBlock, NULL) != ODISTAT_SUCCESSFUL)
{
CMSMReturnDriverResources(configTable);
return ODISTAT_FAIL;
}
}
if (CMSMGetInstanceNumberMapping(configTable->MLIDCFG_Slot, (void **)&busTag, &uniqueID) ==
ODI_NBI_SUCCESSFUL &&
CMSMGetBusType((void *)busTag, &busType) == ODI_NBI_SUCCESSFUL)
{
switch ( busType )
{
case ODI_BUSTYPE_ISA:
cfgBlockPnPPtr = (CMSM_PNP_ISA_CONFIG_INFO *)cfgBlockPnP;
if ( CMSMGetCardConfigInfo ( (void *)busTag,
uniqueID,
512,
0,
NULL,
cfgBlockPnPPtr) == ODI_NBI_SUCCESSFUL )
{
configTable->MLIDCFG_DBusTag = (void *)busTag;
configTable->MLIDCFG_IOPort0 = *(cfgBlockPnPPtr->CPNPIOPortBase);
configTable->MLIDCFG_Interrupt0 = *(cfgBlockPnPPtr->CPNPIRQRegisters);
configTable->MLIDCFG_DMALine0 = *(cfgBlockPnPPtr->CPNPDMAList);
LocalPCnetFlag = PCNETISA;
/*#ifdef DEBUG
NiosDprintf(PORT, configTable->MLIDCFG_IOPort0);
NiosDprintf(IRQ , configTable->MLIDCFG_Interrupt0);
NiosDprintf(DMA , configTable->MLIDCFG_DMALine0);
NiosDprintf(SLOT, configTable->MLIDCFG_Slot);
#endif*/
}
else
LocalPCnetFlag = -1;
break;
case ODI_BUSTYPE_PCI:
if( CMSMGetCardConfigInfo ( (void *)busTag,
uniqueID,
256,
0,
NULL,
cfgBlock) == ODI_NBI_SUCCESSFUL )
{
/* Check if I/O space bit enabled in PCI Command Register */
if( (*((UINT16*)((UINT8*)cfgBlock+0x4)) & 0x0001) == 0)
{
CMSMPrintString (
configTable,
MSG_TYPE_INIT_ERROR,
CNEAMD_NOPORTERR_MSG,
NULL,
NULL);
CMSMReturnDriverResources (configTable);
return (ODISTAT_FAIL);
}
/* AYD 11-15-96 Re-init DriverParameterBlock for PCI */
if ( *(cfgBlock+0x8) >= 0x16 )
{
DriverParameterBlock.DriverSendPtr = (void (*)())DriverSendPCI_II;
DriverParameterBlock.DriverISRPtr = (void (*)())DriverISRPCI_II;
LocalPCnetFlag = PCNETPCI_II; /* PCnetPCI_II or PCnetFast */
}
else
{
DriverParameterBlock.DriverSendPtr = (void (*)())DriverSendPCI;
DriverParameterBlock.DriverISRPtr = (void (*)())DriverISRPCI;
LocalPCnetFlag = PCNETPCI; /* PCnetPCI or PCnet-32 */
}
DriverParameterBlock.DriverEndOfChainFlag = 1;
configTable->MLIDCFG_SharingFlags |= MS_SHARE_IRQ0_BIT;
configTable->MLIDCFG_DBusTag = (void *)busTag;
configTable->MLIDCFG_IOPort0 = *((UINT16*)((UINT8*)cfgBlock+0x10)) & 0xfffc;
configTable->MLIDCFG_Interrupt0 = *(cfgBlock+0x3c); /* int number */
configTable->MLIDCFG_DMALine0 = 0xff;
/* #ifdef DEBUG
NiosDprintf(PORT, configTable->MLIDCFG_IOPort0);
NiosDprintf(IRQ , configTable->MLIDCFG_Interrupt0);
NiosDprintf(DMA , configTable->MLIDCFG_Slot);
#endif */
/* To enable Bus Master bit in PCI Config Space of PCnetPCI */
/* Some PCI BIOSs do not set this bit on PCnetPCI */
/* Let use NBI API to enable Bus Master bit in PCnetPCI Config Space */
/* CMSMWrtConfigSpace16((void *)busTag,
uniqueID,
0x4,
(*( (UINT16 *)( (UINT8 *)cfgBlock+0x04 )) | 0x0004) & 0xFFBF); */
}
else
LocalPCnetFlag = -1;
break;
default:
LocalPCnetFlag = -1;
break;
}
if( LocalPCnetFlag == -1)
{
CMSMReturnDriverResources (configTable);
return (ODISTAT_FAIL);
}
}
else
{
CMSMReturnDriverResources (configTable);
return (ODISTAT_FAIL);
}
}
else /* if not a PCnetPCI or PCnetISA+ */
{
if ( DriverInitISA(&LocalPCnetFlag, configTable) != ODISTAT_SUCCESSFUL )
return ALL_ONES;
} /* End of not PCnetPCI */
}
switch ( LocalPCnetFlag )
{
case 1: /* PCnetISA or PCnetISA+ */
DriverParameterBlock.DriverNeedsBelow16Meg = 1;
DriverParameterBlock.DriverEndOfChainFlag = 0;
DriverParameterBlock.DriverSendPtr = (void (*)())DriverSendISA;
DriverParameterBlock.DriverISRPtr = (void (*)())DriverISRISA;
configTable->MLIDCFG_SGCount = 16;
break;
case 2: /* PCnetPCI */
break;
case 3: /* PCnetPCI_II or PCnetFast */
break;
default: /* LANCE */
DriverParameterBlock.DriverNeedsBelow16Meg = 1;
DriverParameterBlock.DriverEndOfChainFlag = 0;
DriverParameterBlock.DriverSendPtr = (void (*)())DriverSendLANCE;
DriverParameterBlock.DriverISRPtr = (void (*)())DriverISRISA;
break;
}
/* Register hardware with OS */
if ((retValue = CMSMRegisterHardwareOptions(configTable, &driverData)) == REG_TYPE_FAIL)
{
/* Another adapter is using one of the resources we tried to register */
CMSMReturnDriverResources(configTable);
return (ALL_ONES);
}
/* AYD 09-25-95 Added Switch */
switch ( LocalPCnetFlag )
{
case 1:
driverData->PCnetFlag = PCNETISA; /* 1 */
break;
case 2:
driverData->PCnetFlag = PCNETPCI; /* 2 */
break;
case 3:
driverData->PCnetFlag = PCNETPCI_II; /* 3 */
break;
default:
driverData->PCnetFlag = LANCE; /* 0 */
break;
}
/* Allocate memory for transmit buffers if using Am7990 LANCE chipset. */
/* AYD 09-20-95 */
/* AYD 05-29-96 Moved memory allocation in front of DriverReset */
if (retValue != REG_TYPE_NEW_FRAME)
{
if ( driverData->PCnetFlag == LANCE )
{
driverData->TxBuffers = CMSMAlloc(driverData, BUFFER_SIZE * TX_BUFFERS);
if (driverData->TxBuffers == NULL)
{
CMSMPrintString(configTable, MSG_TYPE_INIT_ERROR,
CNEAMD_ALLOCMEMERR_MSG,
NULL ,NULL);
CMSMReturnDriverResources(configTable);
return ALL_ONES;
}
}
}
/* AYD 06-07-96 */
/* Save highly used I/O port values in Adapter Data Space */
driverData->RDP = configTable->MLIDCFG_IOPort0 + 0x10;
driverData->RAP = configTable->MLIDCFG_IOPort0 + 0x12;
driverData->Reset = configTable->MLIDCFG_IOPort0 + 0x14;
driverData->IDP_BDP = configTable->MLIDCFG_IOPort0 + 0x16;
/* AYD 04-01-95 Reset the adapter because in DriverInitISA we stopped
the chip */
if ( (driverData->PCnetFlag == PCNETISA) || (driverData->PCnetFlag == LANCE) )
{
DriverReset(driverData, configTable, OP_SCOPE_ADAPTER);
configTable->MLIDCFG_SharingFlags &= ~MS_SHUTDOWN_BIT;
}
if (retValue == REG_TYPE_NEW_FRAME)
{
/* This is a new frame type for an existing board */
/* We have already Initialized the hardware. */
/* Set up to produce NESL MLID Card Insertion Complete event */
NESL_EPBPtr->EPBDataPtr0 = configTable;
/* Generate NESL MLID Card Insertion Complete Event */
CMSMNESLProduceEvent(NESLServiceResumeNECBPtr,
NULL,
NESL_EPBPtr);
return (ODISTAT_SUCCESSFUL);
}
/* To enable Bus Master bit in PCI Config Space of PCnetPCI */
/* Some PCI BIOSs do not set this bit on PCnetPCI */
/* Let use NBI API to enable Bus Master bit in PCnetPCI Config Space */
if( (driverData->PCnetFlag == PCNETPCI) || (driverData->PCnetFlag == PCNETPCI_II ) )
CMSMWrtConfigSpace16((void *)busTag,
uniqueID,
0x4,
(*( (UINT16 *)( (UINT8 *)cfgBlock+0x04 )) | 0x0004) & 0xFFBF);
/* AYD 03-14-95 Made Full-Duplex mode optional */
if( CMSMParseSingleParameter(&FullDuplexOption) == ODISTAT_SUCCESSFUL )
driverData->FullDuplex = 1;
else
driverData->FullDuplex = 0;
/* New adapter being loaded */
CFixUpStatStrings(driverData); /* Initialize statistic strings */
/* Get bus type. DriverReset needs it in case we're on an EISA bus. */
CMSMGetBusType(configTable->MLIDCFG_DBusTag, &driverData->BusType);
/* Save bus tag. This will make run time functions more effecient */
driverData->BusTag = configTable->MLIDCFG_DBusTag;
/* Read node address from adapter unless there was a node override */
if ( ADDR_EQUAL((&configTable->MLIDCFG_NodeAddress), &BroadcastAddress) )
for(nodeIndex = 0; nodeIndex < 6; nodeIndex += 2)
{
ioValue=In16(driverData->BusTag,
(void *)(configTable->MLIDCFG_IOPort0 + nodeIndex));
PUT_UINT16(&configTable->MLIDCFG_NodeAddress.nodeAddress[nodeIndex], ioValue);
}
/* 2048 to fit jabber packets */
driverData->CommonMaximumSize = 2048;
/* Check ROM for valid NE2100 or PCnet family NIC. */
for(checksum = 0, nodeIndex=0 ;
nodeIndex < 12;
nodeIndex++)
{
ioValue8=In8(driverData->BusTag,
(void *)(configTable->MLIDCFG_IOPort0 + nodeIndex));
checksum += (UINT32)ioValue8;
}
nodeIndex += 2;
ioValue8=In8(driverData->BusTag,
(void *)(configTable->MLIDCFG_IOPort0 + nodeIndex));
checksum += (UINT32)ioValue8;
nodeIndex += 1;
ioValue8=In8(driverData->BusTag,
(void *)(configTable->MLIDCFG_IOPort0 + nodeIndex));
checksum += (UINT32)ioValue8;
nodeIndex -= 3;
ioValue=In16(driverData->BusTag,
(void *)(configTable->MLIDCFG_IOPort0 + nodeIndex));
if (checksum != (UINT32)ioValue)
{
CMSMPrintString(configTable, MSG_TYPE_INIT_ERROR,
CNEAMD_BADCHECKSUM_MSG,
NULL ,NULL);
CMSMReturnDriverResources(configTable);
return ALL_ONES;
}
/* AYD 06-11-96 Moved DMAStart in to DriverReset */
/* Set up DMA channel */
/* if ( (driverData->PCnetFlag == PCNETISA) || (driverData->PCnetFlag == LANCE) )
DMAStart( (void *)driverData->BusTag, 0, 0,
(void *)driverData->BusTag, 0, 0,
0, (UINT32)configTable->MLIDCFG_DMALine0, 0xc0, 0); */
/* AYD 09-25-95 */
if ( driverData->PCnetFlag == 0 )
DADSP_TO_CMSMADSP(driverData)->CMSMTxFreeCount = TX_BUFFERS;
else
DADSP_TO_CMSMADSP(driverData)->CMSMTxFreeCount = TX_BUFFERS_FRAG/16;
/* Initialize/Reset adapter */
if ( DriverReset(driverData, configTable, OP_SCOPE_ADAPTER) != ODISTAT_SUCCESSFUL )
{
CMSMPrintString(configTable, MSG_TYPE_INIT_ERROR,
CNEAMD_BADBOARD_MSG,
NULL ,NULL);
CMSMReturnDriverResources(configTable);
return ALL_ONES;
}
/* Allow MSM to register the MLID with the LSL */
if ( (CMSMRegisterMLID(driverData, configTable) ) != ODISTAT_SUCCESSFUL )
{
CMSMReturnDriverResources(configTable);
return ALL_ONES;
}
/* Set up our interrupt procedure. */
if ( CMSMSetHardwareInterrupt(driverData, configTable) != ODISTAT_SUCCESSFUL)
{
CMSMReturnDriverResources(configTable);
return (ALL_ONES);
}
/* Set up call back to detect transmit and receive timeouts */
if ( (CMSMScheduleAES(driverData, (MLID_AES_ECB *)&driverData->DAES))
!= ODISTAT_SUCCESSFUL)
{
CMSMReturnDriverResources(configTable);
return ALL_ONES;
}
/***********************************************************************\
** TNL 12/06/95 Register with NESL as producer of Service Resume event.
\***********************************************************************/
if (!NESLRegisterDone)
{
if ((NESLServiceResumeNECBPtr = (
NESL_ECB *)CMSMInitAlloc(sizeof(NESL_ECB))) == NULL)
{
CMSMReturnDriverResources(configTable);
return ODISTAT_FAIL;
}
NESLServiceResumeNECBPtr->NecbVersion = NESL_VERSION2;
NESLServiceResumeNECBPtr->NecbEventName = NESL_Service_Resume;
NESLServiceResumeNECBPtr->NecbRefData = NESL_NOT_UNIQUE_PRODUCER |
NESL_BROADCAST_EVENT | NESL_SORT_CONSUMER_BOTTOM_UP;
NESLServiceResumeNECBPtr->NecbOwner =
DriverParameterBlock.DriverModuleHandle;
NESLServiceResumeNECBPtr->NecbContext = NULL;
if (CMSMNESLRegisterProducer(NESLServiceResumeNECBPtr) != NESL_OK)
{
CMSMReturnDriverResources(configTable);
return ODISTAT_FAIL;
}
if ((NESL_EPBPtr = (EPB *)CMSMInitAlloc(sizeof(EPB))) == NULL)
{
CMSMReturnDriverResources(configTable);
return ODISTAT_FAIL;
}
NESL_EPBPtr->EPBMajorVersion = EPBMajVer;
NESL_EPBPtr->EPBMinorVersion = EPBMinVer;
NESLRegisterDone = TRUE;
}
/* Set up to produce NESL MLID Card Insertion Complete event */
NESL_EPBPtr->EPBEventName = NESL_Service_Resume;
NESL_EPBPtr->EPBEventType = NESL_MLID_Card_Insertion_Complete;
NESL_EPBPtr->EPBModuleName = NICShortName;
NESL_EPBPtr->EPBDataPtr0 = configTable;
NESL_EPBPtr->EPBDataPtr1 = NULL;
NESL_EPBPtr->EPBEventScope = EPB_SPECIFIC_EVENT;
NESL_EPBPtr->EPBReserved = 0;
/* Generate NESL MLID Card Insertion Complete Event */
CMSMNESLProduceEvent(NESLServiceResumeNECBPtr,
NULL,
NESL_EPBPtr);
return 0;
} /* End DriverInit */
/* This is a sample code how to enable Bus Master bit in PCI Config Space
of PCnetPCI. Some PCI BIOSs do not set this bit on PCnetPCI */
/* Mechanism #2 */
/* Function */
/*
Out8(configTable->MLIDCFG_DBusTag, (void *)0x0cf8,
0x10 | ((uniqueID & 0x00000007) << 1) );
Out8(configTable->MLIDCFG_DBusTag, (void *)0x0cfa,
(uniqueID & 0x0000ff00) >> 8 );
ioValue = 0xc000 + ( ( (uniqueID & 0x00f8 ) >> 3) * 256 + 4 );
scanSeq = In32( configTable->MLIDCFG_DBusTag, (void *) ioValue);
NiosDprintf("StatusComReg = %X \r\n", scanSeq);
Out32(configTable->MLIDCFG_DBusTag,
(void *)ioValue, scanSeq | 0x4);
Out8(configTable->MLIDCFG_DBusTag, (void *)0x0cf8, 0);
*/
/* Mechanism #1 */
/*
Out32(configTable->MLIDCFG_DBusTag, (void *)0x0cf8,
0x80000000 | (uniqueID << 8) | 4 );
scanSeq = In32( configTable->MLIDCFG_DBusTag, (void *)0x0cfc);
NiosDprintf("StatusComReg = %X \r\n", scanSeq);
Out32(configTable->MLIDCFG_DBusTag, (void *)0x0cf8,
0x80000000 | (uniqueID << 8) | 4 );
Out32(configTable->MLIDCFG_DBusTag, (void *)0x0cfc,
scanSeq & 0xffff0004 );
Out32(configTable->MLIDCFG_DBusTag, (void *)0x0cf8,
( (uniqueID << 8) | 4) & 0x7fffffff );
*/
/***********************************************************************\
* *
*
* Name:
* ODISTAT DriverInitISA( *PCnetFlagISA, *configTable)
*
* Description:
*
*
* Parameters in:
* NONE
* Parameters out:
* LocalPCnetFlag = 0 - LANCE
* 1 - PCnetISA
*
*
* Values returned:
*
* ODISTAT_SUCCESSFUL if successful
* ODISTAT_FAIL if failure
*
* *
************************************************************************/
ODISTAT DriverInitISA( UINT32 *PCnetFlagISA, CONFIG_TABLE *configTable )
{
UINT16 ioValue;
DMAOption.Flags |= REQUIREDPARAM;
DMAOption.Link = &IntOption;
/* Parse resources in case of LANCE, PCnetISA, PCnetISA+ */
if (CMSMParseDriverParameters(&DriverParameterBlock, &DMAOption) != ODISTAT_SUCCESSFUL)
{
CMSMReturnDriverResources(configTable);
return ODISTAT_FAIL;
}
/* AYD 06-11-96 Set the bus tag in case of ISA */
configTable->MLIDCFG_DBusTag = 0;
configTable->MLIDCFG_SharingFlags |= MS_SHUTDOWN_BIT;
/* AYD 06-11-96 Mask DMA before stoping NIC to prevent hang on SMP box */
DMACleanup((UINT32)configTable->MLIDCFG_DMALine0);
/* AYD 04-01-95 Stop the adapter to read Chip ID for PCnetISA */
Out16(configTable->MLIDCFG_DBusTag,
(void *)(configTable->MLIDCFG_IOPort0 + 0x12), CSR0);
/* Disable adapter's interrupts */
Out16(configTable->MLIDCFG_DBusTag,
(void *)(configTable->MLIDCFG_IOPort0 + 0x10), 0);
/* Stop the adapter */
Out16(configTable->MLIDCFG_DBusTag,
(void *)(configTable->MLIDCFG_IOPort0 + 0x10), STOP);
/* Get Chip ID and set PCnetFlag */
/* AYD 10-04-95 */
Out16(configTable->MLIDCFG_DBusTag,
(void *)(configTable->MLIDCFG_IOPort0 + 0x12), CSR88);
ioValue = In16(configTable->MLIDCFG_DBusTag,
(void *)(configTable->MLIDCFG_IOPort0 + 0x10));
ioValue &= 0x0003;
if ( ioValue == 0x0003 )
{
Out16(configTable->MLIDCFG_DBusTag,
(void *)(configTable->MLIDCFG_IOPort0 + 0x12), CSR89);
ioValue = In16(configTable->MLIDCFG_DBusTag,
(void *)(configTable->MLIDCFG_IOPort0 + 0x10));
if ( ((ioValue & 0x0fff) == 0) || ((ioValue & 0x0fff) == 0x0226) )
*PCnetFlagISA = 1; /* PCnetISA or PCnetISA+ */
else
*PCnetFlagISA = 0; /* LANCE */
}
else
*PCnetFlagISA = 0; /* LANCE */
return ODISTAT_SUCCESSFUL;
} /* End of DriverInitISA */
/***********************************************************************\
* *
*
* Name:
* void CFixUpStatStrings(
* DRIVER_DATA *driverData)
*
* Description:
*
* This function initializes the statistic table entry strings to
* point to the language enabled message strings.
*
* Parameters in:
*
* driverData - Pointer to HSM's Adapter Data Space.
*
* Values returned:
*
* *
************************************************************************/
void CFixUpStatStrings(DRIVER_DATA *driverData)
{
/* driverData->TotalTxPacketTable.StatString=(MEON_STRING *)CMLID_TOTALTX_STR;
driverData->TotalRxPacketTable.StatString=(MEON_STRING *)CMLID_TOTALRX_STR;
driverData->NoECBAvailableTable.StatString=(MEON_STRING *)CMLID_NOECB_STR;
driverData->PacketTxTooBigTable.StatString=(MEON_STRING *)CMLID_TXTOOBIG_STR;
driverData->PacketTxTooSmallTable.StatString=(MEON_STRING *)CMLID_TXTOOSMALL_STR;
driverData->PacketRxOverflowTable.StatString=(MEON_STRING *)CMLID_RXOVERFLOW_STR;
driverData->PacketRxTooBigTable.StatString=(MEON_STRING *)CMLID_RXTOOBIG_STR;
driverData->PacketRxTooSmallTable.StatString=(MEON_STRING *)CMLID_RXTOOSMALL_STR;
driverData->PacketTxMiscErrorTable.StatString=(MEON_STRING *)CMLID_TXMISC_STR;
driverData->PacketRxMiscErrorTable.StatString=(MEON_STRING *)CMLID_RXMISC_STR;
driverData->RetryTxTable.StatString=(MEON_STRING *)CMLID_RETRYTX_STR;
driverData->ChecksumErrorTable.StatString=(MEON_STRING *)CMLID_CRCERR_STR;
driverData->HardwareRxMismatchTable.StatString=(MEON_STRING *)CMLID_HWRXMISMATCH_STR;
driverData->TotalRxOKByteTable.StatString=(MEON_STRING *)CMLID_RXOKMYTES_STR;
driverData->TotalTxOKByteTable.StatString=(MEON_STRING *)CMLID_TXOKBYTES_STR;
driverData->TotalGroupAddrTxTable.StatString=(MEON_STRING *)CMLID_TXGROUPADDR_STR;
driverData->TotalGroupAddrRxTable.StatString=(MEON_STRING *)CMLID_RXGROUPADDR_STR;
driverData->AdapterResetTable.StatString=(MEON_STRING *)CMLID_RESET_STR;
driverData->AdapterOprTimeStampTable.StatString=(MEON_STRING *)CMLID_OPRTIME_STR;
driverData->QDepthTable.StatString=(MEON_STRING *)CMLID_TXQDEPTH_STR;
driverData->TxOKSingleCollisionTable.StatString=(MEON_STRING *)CETHER_SINGLECOL_STR;
driverData->TxOKMultipleCollisionsTable.StatString=(MEON_STRING *)CETHER_MULTICOL_STR;
driverData->TxOKButDeferredTable.StatString=(MEON_STRING *)CETHER_DEFERRED_STR;
driverData->TxAbortLateCollisionTable.StatString=(MEON_STRING *)CETHER_LATECOL_STR;
driverData->TxAbortExcessCollisionsTable.StatString=(MEON_STRING *)CETHER_EXCESSCOL_STR;
driverData->TxAbortCarrierSenseTable.StatString=(MEON_STRING *)CETHER_CARRSENSE_STR;
driverData->TxAbortExDeferralTable.StatString=(MEON_STRING *)CETHER_TXABORT_STR;
driverData->RxAbortFrameAlignmentTable.StatString=(MEON_STRING *)CETHER_RXABORT_STR;
*/
driverData->HeartbeatErrorTable.StatString=(MEON_STRING *)CNEAMD_HEARTBEAT_STR;
driverData->MemoryErrorTable.StatString=(MEON_STRING *)CNEAMD_MEMERR_STR;
driverData->TxOverflowTable.StatString=(MEON_STRING *)CNEAMD_TXOVERFLOW_STR;
driverData->TxUnderflowTable.StatString=(MEON_STRING *)CNEAMD_TXUNDERFLOW_STR;
driverData->TxBufferErrorTable.StatString=(MEON_STRING *)CNEAMD_TXBUFFERERR_STR;
driverData->ECBsOver16MegTable.StatString=(MEON_STRING *)CNEAMD_ECBOVER16MEG_STR;
driverData->TxECBsOver16MegTable.StatString=(MEON_STRING *)CNEAMD_TXECBOVER16MEG_STR;
driverData->ECBOverflowTable.StatString=(MEON_STRING *)CNEAMD_ECBOVERFLOW_STR;
} /* End CFixUpStatStrings */
/***********************************************************************\
* *
*
* Name:
* ODISTAT DriverShutdown(
* DRIVER_DATA *driverData,
* CONFIG_TABLE *configTable,
* UINT32 shutdownType,
* OPERATION_SCOPE operationScope)
*
* Description:
*
* This function shuts down the adapter. If its a permanent shutdown,
* return any memory allocated at DriverInit.
*
* Parameters in:
*
* driverData - Pointer to HSM's Adapter Data Space.
* configTable - Pointer to HSM's default Configuration Table.
* shutdownType - PERMANENT_SHUTDOWN
* TEMPORARY_SHUTDOWN
* operationScope - OP_SCOPE_ADAPTER or OP_SCOPE_LOGICAL_BOARD
*
* Values returned:
*
* *
************************************************************************/
ODISTAT DriverShutdown(
DRIVER_DATA *driverData,
CONFIG_TABLE *configTable,
UINT32 shutdownType,
OPERATION_SCOPE operationScope)
{
UINT32 startTime, currentTime;
RCB *rcb;
TX_DESC *txTable;
UINT32 descriptor;
TCB *tcb;
if (operationScope == OP_SCOPE_ADAPTER)
{
if (shutdownType == SHUTDOWN_PERMANENT)
{
if (driverData->TxBuffers)
{
CMSMFree(driverData, driverData->TxBuffers);
driverData->TxBuffers = NULL;
}
/* if ( (driverData->PCnetFlag == PCNETISA) || (driverData->PCnetFlag == LANCE) )
DMACleanup((UINT32)configTable->MLIDCFG_DMALine0); */
}
/* AYD 06-11-96 Call DMACleanup always */
if ( (driverData->PCnetFlag == PCNETISA) || (driverData->PCnetFlag == LANCE) )
DMACleanup((UINT32)configTable->MLIDCFG_DMALine0);
if ( (driverData->PCnetFlag == PCNETISA) || (driverData->PCnetFlag == LANCE) )
{
/* Wait upt to 100ms for DMA request line to drop */
startTime = CMSMGetMicroTimer();
startTime = -startTime;
while ( ((currentTime=CMSMGetMicroTimer()) + startTime) < 100000) /* AYD */
if ( (DMAStatus((UINT32)configTable->MLIDCFG_DMALine0) & 0x02) == 0)
break;
}
/* Stop the adapter */
/* AYD 10-13-95 */
Out16(configTable->MLIDCFG_DBusTag, (void *)driverData->RAP, CSR0);
Out16(configTable->MLIDCFG_DBusTag, (void *)driverData->RDP, STOP);
/* AYD 05-20-96 Return all RCB before clearing the discriptors */
/* Return any RCBs that we have queued up */
while(driverData->NeedRCBCount != RX_BUFFERS) /* AYD != */
{
rcb = driverData->RCBTable[driverData->RxNextToReturn];
driverData->RxNextToReturn++;
driverData->RxNextToReturn &= (RX_BUFFERS - 1);
driverData->NeedRCBCount++;
CMSMReturnRCB(driverData, rcb);
}
/* AYD 04-09-96 added code to clear Receive Descriptors */
/* Clear receive descriptors if Am79C960 PCnetISA */
if ( (driverData->PCnetFlag == PCNETISA) || (driverData->PCnetFlag == LANCE) )
Set32(configTable->MLIDCFG_DBusTag,
NULL,
driverData->RxDescriptorTablePtr,
0,
(sizeof(RX_DESC) * RX_BUFFERS) / 4);
/* AYD 05-20-96 Changed RX_DESC to PCI_RX_DESC */
if ( (driverData->PCnetFlag == PCNETPCI) || (driverData->PCnetFlag == PCNETPCI_II) )
Set32(configTable->MLIDCFG_DBusTag,
NULL,
driverData->PCI_RxDescriptorTablePtr,
0,
(sizeof(PCI_RX_DESC) * RX_BUFFERS) / 4);
driverData->RxNextToReturn = 0;
driverData->RxNextToAllocate = 0;
/* Initialize Am7990 LANCE transmit descriptors */
if ( driverData->PCnetFlag == 0)
{
txTable = (TX_DESC *)GET_UINT32(&driverData->TxDescriptorTablePtr);
if (txTable)
for (descriptor=0; descriptor < TX_BUFFERS; descriptor++)
{
txTable[descriptor].TxDescAddr.TxAttr.Attr = (T_ENP | T_STP);
driverData->TxStartTime[descriptor] = 0;
}
DADSP_TO_CMSMADSP(driverData)->CMSMTxFreeCount = TX_BUFFERS;
}
/* Initialize Am79C960 PCnetISA transmit descriptors */
/* AYD 09-25-95 Changed TX_BUFFERS to TX_BUFFERS_FRAG/16 */
/* AYD 04-19-96 Changed initializetion of transmit descriptors */
if (driverData->PCnetFlag)
{
while(DADSP_TO_CMSMADSP(driverData)->CMSMTxFreeCount < TX_BUFFERS_FRAG/16)
{
tcb = driverData->TCBTable[driverData->TxNextToReturn];
/* AYD 03-29-96 Check if this is an end of the TCB list */
if (tcb == NULL)
break;
driverData->TxStartTime[driverData->TxNextToReturn] = 0;
driverData->TxNextToReturn =(UINT32)
((driverData->TxLastDesc[driverData->TxNextToReturn] + 1)
& (TX_BUFFERS_FRAG-1));
DADSP_TO_CMSMADSP(driverData)->CMSMTxFreeCount++;
CEtherTSMFastSendComplete(driverData, tcb, 0);
}
}
/* AYD 05-20-96 Clear all transmit discriptors after returning TCBs */
/* Clear transmit descriptors if Am79C960 PCnetISA */
if (driverData->PCnetFlag == PCNETISA)
Set32(configTable->MLIDCFG_DBusTag,
NULL,
driverData->TxDescriptorTablePtr,
0,
(sizeof(TX_DESC) * TX_BUFFERS_FRAG) / 4);
/* AYD 05-20-96 Changed TX_DESC to PCI_TX_DESC */
if ( (driverData->PCnetFlag == PCNETPCI) || (driverData->PCnetFlag == PCNETPCI_II) )
Set32(configTable->MLIDCFG_DBusTag,
NULL,
driverData->PCI_TxDescriptorTablePtr,
0,
(sizeof(PCI_TX_DESC) * TX_BUFFERS_FRAG) / 4);
driverData->TxNextToReturn = 0;
driverData->TxNextToSend = 0;
return(ODISTAT_SUCCESSFUL);
}
else
return(ODISTAT_SUCCESSFUL);
} /* End DriverShutdown */
/***********************************************************************\
* *
*
* Name:
* void DriverRemove(void)
*
* Description:
* HSM being unloaded. Call CMSMDriverRemove to let the CMSM
* give back all of our resources and call our DriverShutdown
* routine for all instances of our driver.
*
* Parameters in:
*
* None
*
* Values returned:
*
* None
*
* *
************************************************************************/
void DriverRemove(void)
{
/* TNL 12/06/95 Clean up all NESL related stuff */
CMSMNESLDeRegisterProducer(NESLServiceResumeNECBPtr);
CMSMFree(NULL,NESLServiceResumeNECBPtr);
CMSMFree(NULL,NESL_EPBPtr);
CMSMDriverRemove(DriverParameterBlock.DriverModuleHandle);
return;
} /* End DriverRemove */