2020-09-30 17:12:29 +02:00

825 lines
17 KiB
C

/*++
Copyright (c) 1990 Microsoft Corporation
Module Name:
elnksft.h
Abstract:
The main header for an Etherlink II MAC driver.
Author:
Anthony V. Ercolano (tonye) creation-date 19-Jun-1990 (Driver Model)
Adam Barr (adamba) - original Elnkii code.
Environment:
This driver is expected to work in DOS, OS2 and NT at the equivalent
of kernal mode.
Architecturally, there is an assumption in this driver that we are
on a little endian machine.
Notes:
optional-notes
Revision History:
Dec-1991 by Sean Selitrennikoff - Fit AdamBa's code into TonyE's model
--*/
#ifndef _ELNKIISFT_
#define _ELNKIISFT_
#define ELNKII_NDIS_MAJOR_VERSION 3
#define ELNKII_NDIS_MINOR_VERSION 0
//
// This macro is used along with the flags to selectively
// turn on debugging.
//
#if DBG
#define IF_ELNKIIDEBUG(f) if (ElnkiiDebugFlag & (f))
extern ULONG ElnkiiDebugFlag;
#define ELNKII_DEBUG_LOUD 0x00000001 // debugging info
#define ELNKII_DEBUG_VERY_LOUD 0x00000002 // excessive debugging info
#define ELNKII_DEBUG_LOG 0x00000004 // enable ElnkiiLog
#define ELNKII_DEBUG_CHECK_DUP_SENDS 0x00000008 // check for duplicate sends
#define ELNKII_DEBUG_TRACK_PACKET_LENS 0x00000010 // track directed packet lens
#define ELNKII_DEBUG_WORKAROUND1 0x00000020 // drop DFR/DIS packets
#define ELNKII_DEBUG_CARD_BAD 0x00000040 // dump data if CARD_BAD
#define ELNKII_DEBUG_CARD_TESTS 0x00000080 // print reason for failing
//
// Macro for deciding whether to dump lots of debugging information.
//
#define IF_LOUD(A) IF_ELNKIIDEBUG( ELNKII_DEBUG_LOUD ) { A }
#define IF_VERY_LOUD(A) IF_ELNKIIDEBUG( ELNKII_DEBUG_VERY_LOUD ) { A }
#else
#define IF_LOUD(A)
#define IF_VERY_LOUD(A)
#endif
//
// Whether to use the ElnkiiLog
//
#if DBG
#define IF_LOG(A) IF_ELNKIIDEBUG( ELNKII_DEBUG_LOG ) { A }
extern VOID ElnkiiLog(UCHAR);
#else
#define IF_LOG(A)
#endif
//
// Whether to do loud init failure
//
#if DBG
#define IF_INIT(A) A
#else
#define IF_INIT(A)
#endif
//
// Whether to do loud card test failures
//
#if DBG
#define IF_TEST(A) IF_ELNKIIDEBUG( ELNKII_DEBUG_CARD_TESTS ) { A }
#else
#define IF_TEST(A)
#endif
//
// Macros for services that differ between DOS and NT, we may consider adding these
// into the NDIS spec.
//
//
// AdaptP->NumBuffers
//
// controls the number of transmit buffers on the packet.
// Choices are 1 or 2.
//
#define DEFAULT_NUMBUFFERS 2
#define ELNKII_MOVE_MEM_TO_SHARED_RAM(dest,src,size) \
NdisMoveToMappedMemory(dest, src, size)
#define ELNKII_MOVE_SHARED_RAM_TO_MEM(dest,src,size) \
NdisMoveFromMappedMemory(dest, src, size)
#define ELNKII_MOVE_MEM(dest,src,size) NdisMoveMemory(dest,src,size)
//
// The status of transmit buffers.
//
typedef enum { EMPTY, FILLING, FULL } BUFFER_STATUS;
//
// Type of an interrupt.
//
typedef enum { RECEIVE = 0x01,
TRANSMIT = 0x02,
OVERFLOW = 0x04,
COUNTER = 0x08,
UNKNOWN = 0x10} INTERRUPT_TYPE;
//
// Result of ElnkiiIndicate[Loopback]Packet().
//
typedef enum { INDICATE_OK, SKIPPED, ABORT, CARD_BAD } INDICATE_STATUS;
//
// Number of bytes in an ethernet header
//
#define ELNKII_HEADER_SIZE 14
//
// Number of bytes allowed in a lookahead (max)
//
#define ELNKII_MAX_LOOKAHEAD (252 - ELNKII_HEADER_SIZE)
//
// Maximum number of transmit buffers on the card.
//
#define MAX_XMIT_BUFS 2
//
// A transmit buffer (usually 0 or 1).
//
typedef UINT XMIT_BUF;
//
// Number of 256-byte buffers in a transmit buffer.
//
#define BUFS_PER_TX 6
//
// Size of a single transmit buffer.
//
#define TX_BUF_SIZE (BUFS_PER_TX*256)
//
// Only have one of these structures.
//
typedef struct _DRIVER_BLOCK
{
//
// Returned from NdisMInitializeWrapper.
//
NDIS_HANDLE NdisWrapperHandle;
//
// Adapters registered for this miniport.
//
struct _ELNKII_ADAPTER *AdapterQueue;
}
DRIVER_BLOCK,
*PDRIVER_BLOCK;
//
// One of these structures per adapter registered.
//
typedef struct _ELNKII_ADAPTER
{
//
// Handle given by the wrapper for calling NDIS functions.
//
NDIS_HANDLE MiniportAdapterHandle;
//
// Miniport's interrupt object.
//
NDIS_MINIPORT_INTERRUPT Interrupt;
//
// Used by the DriverBlock->AdapterQueue
//
struct _ELNKII_ADAPTER *pNextElnkiiAdapter;
//
// This is a count of the number of receives that have been
// indicated in a row. This is used to limit the number
// of sequential receives so that one can periodically check
// for transmit complete interrupts.
//
ULONG ReceivePacketCount;
//
// Configuration information
//
UINT NumBuffers; // Number of buffers in this adapter.
PVOID IoBaseAddr; // Physical address of the IoBaseAddress.
CHAR InterruptNumber; // Interrupt number adapter is using.
UINT MulticastListMax; // Number of multicast address that
// this adapter is to support.
PVOID MemBaseAddr; // Actually read off the card.
BOOLEAN ExternalTransceiver; // Is the external transceiver in use?
BOOLEAN MemMapped; // Actually read off the card
BOOLEAN InCardTest; // Are we testing the card?
PUCHAR MappedIoBaseAddr;
PUCHAR MappedGaBaseAddr;
//
// Transmit queue.
//
PNDIS_PACKET XmitQueue; // packets waiting to be transmitted
PNDIS_PACKET XmitQTail;
//
// Transmit information.
//
XMIT_BUF NextBufToFill; // where to copy next packet to
XMIT_BUF NextBufToXmit; // valid if CurBufXmitting is -1
XMIT_BUF CurBufXmitting; // -1 if none is
BOOLEAN TransmitInterruptPending; // transmitting, but DPC not yet queued
BOOLEAN OverflowRestartXmitDpc; // transmitting, but DPC not yet queued
BUFFER_STATUS BufferStatus[MAX_XMIT_BUFS];
PNDIS_PACKET Packets[MAX_XMIT_BUFS]; // as passed to MacSend
UINT PacketLens[MAX_XMIT_BUFS];
PUCHAR XmitStart; // start of card transmit area
PUCHAR PageStart; // start of card receive area
PUCHAR PageStop; // end of card receive area
UCHAR NicXmitStart; // MSB, LSB assumed 0
UCHAR NicPageStart; // MSB, LSB assumed 0
UCHAR NicPageStop; // MSB, LSB assumed 0
UCHAR GaControlBits; // values for xsel and dbsel bits
BOOLEAN TransmitTimeOut; // Set to TRUE if a packet was sent
// but no transmit interrupt was
// received within 2 seconds.
//
// Receive information
//
UCHAR NicNextPacket; // MSB, LSB assumed 0
UCHAR Current; // MSB, LSB assumed 0 (last known value)
UCHAR XmitStatus; // status of last transmit
//
// These are for the current packet being indicated.
//
UCHAR PacketHeader[4]; // the NIC appended header
UCHAR Lookahead[252]; // the first 252 bytes of the packet
UINT PacketLen; // the overall length of the packet
PUCHAR PacketHeaderLocation;
//
// Operational information.
//
UCHAR StationAddress[ETH_LENGTH_OF_ADDRESS]; // filled in at init time
UCHAR PermanentAddress[ETH_LENGTH_OF_ADDRESS]; // filled in at init time
BOOLEAN BufferOverflow; // does an overflow need to be handled
//
// TRUE if the driver needs to call NdisMEthIndicateReceiveComplete.
//
BOOLEAN IndicateReceiveDone;
//
// Statistics used by Set/QueryInformation.
//
ULONG FramesXmitGood; // Good Frames Transmitted
ULONG FramesRcvGood; // Good Frames Received
ULONG FramesXmitBad; // Bad Frames Transmitted
ULONG FramesXmitOneCollision; // Frames Transmitted with one collision
ULONG FramesXmitManyCollisions; // Frames Transmitted with > 1 collision
ULONG FrameAlignmentErrors; // FAE errors counted
ULONG CrcErrors; // CRC errors counted
ULONG MissedPackets; // missed packet counted
//
// Pointer to the filter database for the MAC.
//
UCHAR NicMulticastRegs[8]; // contents of card MC registers
UCHAR NicReceiveConfig; // contents of NIC RCR
UCHAR NicInterruptMask; // contents of NIC IMR
//
// Look Ahead information.
//
ULONG MaxLookAhead;
//
// NOTE:
// new stuff that i have added.
//
//
// InterruptStatus tracks interrupt sources that still need to be
// serviced, it is the logical OR of all card interrupts that have been
// received and not processed and cleared.
// (see also INTERRUPT_TYPE definition above)
//
UINT InterruptStatus;
//
// Current packet filter in use.
//
ULONG PacketFilter;
//
// List of multicast addresses in use.
//
CHAR MulticastAddresses[DEFAULT_MULTICASTLISTMAX][ETH_LENGTH_OF_ADDRESS];
}
ELNKII_ADAPTER,
*PELNKII_ADAPTER;
//
// Macros to extract high and low bytes of a word.
//
#define MSB(Value) ((UCHAR)(((Value) >> 8) & 0xff))
#define LSB(Value) ((UCHAR)((Value) & 0xff))
//
// What we map into the reserved section of a packet.
// Cannot be more than 16 bytes (see ASSERT in elnkii.c).
//
typedef struct _MAC_RESERVED
{
PNDIS_PACKET NextPacket; // used to link in the queues (4 bytes)
} MAC_RESERVED, * PMAC_RESERVED;
//
// Retrieve the MAC_RESERVED structure from a packet.
//
#define RESERVED(Packet) ((PMAC_RESERVED)((Packet)->MacReserved))
//
// Procedures which log errors.
//
typedef enum _ELNKII_PROC_ID
{
openAdapter,
cardReset,
cardCopyDownPacket,
cardCopyDownBuffer,
cardCopyUp
}
ELNKII_PROC_ID;
#define ELNKII_ERRMSG_CARD_SETUP (ULONG)0x01
#define ELNKII_ERRMSG_DATA_PORT_READY (ULONG)0x02
#define ELNKII_ERRMSG_MAX_OPENS (ULONG)0x03
#define ELNKII_ERRMSG_HANDLE_XMIT_COMPLETE (ULONG)0x04
//++
//
// XMIT_BUF
// NextBuf(
// IN PELNKII_ADAPTER AdaptP,
// IN XMIT_BUF XmitBuf
// )
//
// Routine Description:
//
// NextBuf "increments" a transmit buffer number. The next
// buffer is returned; the number goes back to 0 when it
// reaches AdaptP->NumBuffers.
//
// Arguments:
//
// AdaptP - The adapter block.
// XmitBuf - The current transmit buffer number.
//
// Return Value:
//
// The next transmit buffer number.
//
//--
#define NextBuf(AdaptP, XmitBuf) \
((XMIT_BUF)(((XmitBuf) + 1) % (AdaptP)->NumBuffers))
/*++
Routine Description:
Determines the type of the interrupt on the card. The order of
importance is overflow, then receive, then transmit complete.
Counter MSB is handled first since it is simple.
Arguments:
Return Value:
The type of the interrupt
--*/
#define CardGetInterruptType(_pAdapter, _InterruptStatus, _InterruptType) \
{ \
if (_InterruptStatus & ISR_COUNTER) \
{ \
_InterruptType = COUNTER; \
} \
else if (_InterruptStatus & ISR_OVERFLOW ) \
{ \
SyncCardUpdateCounters(_pAdapter); \
_InterruptType = OVERFLOW; \
} \
else if (_InterruptStatus & (ISR_XMIT | ISR_XMIT_ERR)) \
{ \
_InterruptType = TRANSMIT; \
} \
else if (_InterruptStatus & ISR_RCV) \
{ \
_InterruptType = RECEIVE; \
} \
else if (_InterruptStatus & ISR_RCV_ERR) \
{ \
SyncCardUpdateCounters(_pAdapter); \
_InterruptType = RECEIVE; \
} \
else \
{ \
_InterruptType = UNKNOWN; \
} \
}
//
// Prototypes for functions in elnkii.c
//
VOID ElnkiiHalt(
IN NDIS_HANDLE MiniportAdapterContext
);
NDIS_STATUS ElnkiiInitialize(
OUT PNDIS_STATUS OpenErrorStatus,
OUT PUINT SelectedMediumIndex,
IN PNDIS_MEDIUM MediumArray,
IN UINT MediumArraySize,
IN NDIS_HANDLE MiniportAdapterHandle,
IN NDIS_HANDLE ConfigurationHandle
);
NDIS_STATUS ElnkiiQueryInformation(
IN NDIS_HANDLE MiniportAdapterContext,
IN NDIS_OID Oid,
IN PVOID InformationBuffer,
IN ULONG InformationBufferLength,
OUT PULONG BytesWritten,
OUT PULONG BytesNeeded
);
NDIS_STATUS ElnkiiReset(
OUT PBOOLEAN pfAddressingReset,
IN NDIS_HANDLE MiniportAdapterContext
);
NDIS_STATUS ElnkiiSetInformation(
IN NDIS_HANDLE MiniportAdapterContext,
IN NDIS_OID Oid,
IN PVOID InformationBuffer,
IN ULONG InformationBufferLength,
OUT PULONG BytesRead,
OUT PULONG BytesNeeded
);
VOID ReadInterruptNumber(
OUT PNDIS_STATUS pStatus,
OUT PCCHAR pInterruptNumber,
IN NDIS_HANDLE hConfig,
IN NDIS_HANDLE MiniportAdapterHandle
);
VOID ReadBaseIoAddress(
OUT PNDIS_STATUS pStatus,
OUT PVOID *ppIoBaseAddress,
IN NDIS_HANDLE hConfig,
IN NDIS_HANDLE MiniportAdapterHandle
);
NDIS_STATUS ElnkiiInitialize(
OUT PNDIS_STATUS OpenErrorStatus,
OUT PUINT SelectedMediumIndex,
IN PNDIS_MEDIUM MediumArray,
IN UINT MediumArraySize,
IN NDIS_HANDLE MiniportAdapterHandle,
IN NDIS_HANDLE ConfigurationHandle
);
NDIS_STATUS ElnkiiQueryInformation(
IN NDIS_HANDLE MiniportAdapterContext,
IN NDIS_OID Oid,
IN PVOID InformationBuffer,
IN ULONG InformationBufferLength,
OUT PULONG BytesWritten,
OUT PULONG BytesNeeded
);
NDIS_STATUS ElnkiiSetInformation(
IN NDIS_HANDLE MiniportAdapterContext,
IN NDIS_OID Oid,
IN PVOID InformationBuffer,
IN ULONG InformationBufferLength,
OUT PULONG BytesRead,
OUT PULONG BytesNeeded
);
VOID ElnkiiHalt(
IN NDIS_HANDLE MiniportAdapterContext
);
NDIS_STATUS ElnkiiReset(
OUT PBOOLEAN pfAddressingReset,
IN NDIS_HANDLE MiniportAdapterContext
);
NDIS_STATUS DispatchSetMulticastAddressList(
IN PELNKII_ADAPTER pAdapter
);
//
// Prototypes for functions in interrup.c
//
VOID ElnkiiDisableInterrupt(
IN NDIS_HANDLE MiniportAdapterContext
);
VOID ElnkiiEnableInterrupt(
IN NDIS_HANDLE MiniportAdapterContext
);
VOID ElnkiiHandleInterrupt(
IN NDIS_HANDLE MiniportAdapterContext
);
VOID ElnkiiIsr(
OUT PBOOLEAN InterruptRecognized,
OUT PBOOLEAN QueueDpc,
IN PVOID Context
);
BOOLEAN ElnkiiCheckForHang(
IN NDIS_HANDLE MiniportAdapterContext
);
//
// Prototypes for functions in send.c
//
NDIS_STATUS ElnkiiSend(
IN NDIS_HANDLE MiniportAdapterContext,
IN PNDIS_PACKET Packet,
IN UINT Flags
);
VOID OctogmetusceratorRevisited(
IN PELNKII_ADAPTER pAdapter
);
VOID ElnkiiXmitDpc(
IN PELNKII_ADAPTER pAdapter
);
//
// Prototypes for functions in rcv.c
//
NDIS_STATUS ElnkiiTransferData(
OUT PNDIS_PACKET Packet,
OUT PUINT BytesTransferred,
IN NDIS_HANDLE MiniportAdapterContext,
IN NDIS_HANDLE MiniportReceiveContext,
IN UINT ByteOffset,
IN UINT BytesToTransfer
);
BOOLEAN ElnkiiRcvDpc(
IN PELNKII_ADAPTER pAdapter
);
//
// Prototypes for functions in card.c
//
BOOLEAN SyncCardSetAllMulticast(
IN PVOID SynchronizeContext
);
BOOLEAN SyncCardSetReceiveConfig(
IN PVOID SynchronizeContext
);
BOOLEAN SyncCardCopyMulticastRegs(
IN PVOID SynchronizeContext
);
PUCHAR CardGetMemBaseAddr(
IN PELNKII_ADAPTER pAdapter,
OUT PBOOLEAN pfCardPresent,
OUT PBOOLEAN pfIoBaseCorrect
);
VOID CardReadEthernetAddress(
IN PELNKII_ADAPTER pAdapter
);
BOOLEAN SyncCardStop(
IN PVOID SynchronizeContext
);
VOID DelayComplete(
IN PVOID SystemSpecific1,
IN PVOID TimerExpired,
IN PVOID SystemSpecific2,
IN PVOID SystemSpecific3
);
BOOLEAN CardTest(
IN PELNKII_ADAPTER pAdapter
);
BOOLEAN CardCopyDownBuffer(
IN PELNKII_ADAPTER pAdapter,
IN PUCHAR SourceBuffer,
IN XMIT_BUF XmitBufferNum,
IN UINT Offset,
IN UINT Length
);
BOOLEAN CardCopyUp(
IN PELNKII_ADAPTER pAdapter,
IN PUCHAR Target,
IN PUCHAR Source,
IN UINT Length
);
VOID CardGetPacketCrc(
IN PUCHAR Buffer,
IN UINT Length,
OUT UCHAR Crc[4]
);
BOOLEAN SyncCardStop(
IN PVOID SynchronizeContext
);
BOOLEAN SyncCardUpdateCounters(
IN PVOID SynchronizeContext
);
BOOLEAN SyncCardStop(
IN PVOID SynchronizeContext
);
BOOLEAN CardSetup(
IN PELNKII_ADAPTER pAdapter
);
VOID CardFillMulticastRegs(
IN PELNKII_ADAPTER pAdapter
);
VOID CardStop(
IN PELNKII_ADAPTER pAdapter
);
BOOLEAN CardReset(
IN PELNKII_ADAPTER pAdapter
);
BOOLEAN SyncCardGetXmitStatus(
IN PVOID SynchronizeContext
);
BOOLEAN SyncCardGetCurrent(
IN PVOID SynchronizeContext
);
BOOLEAN SyncCardHandleOverflow(
IN PVOID SynchronizeContext
);
VOID CardSetBoundary(
IN PELNKII_ADAPTER pAdapter
);
BOOLEAN CardReset(
IN PELNKII_ADAPTER pAdapter
);
BOOLEAN SyncCardAcknowledgeOverflow(
IN PVOID SynchronizeContext
);
VOID CardStartXmit(
IN PELNKII_ADAPTER pAdapter
);
BOOLEAN CardCopyDownPacket(
IN PELNKII_ADAPTER pAdapter,
IN PNDIS_PACKET Packet,
IN XMIT_BUF XmitBufferNum,
OUT UINT * Length
);
#if DBG
VOID ElnkiiDisplayStatus(
PELNKII_ADAPTER pAdapter
);
#endif
#endif // ELNKIISFT