diff options
Diffstat (limited to '')
-rw-r--r-- | private/ntos/ndis/lance/lancesft.h | 962 |
1 files changed, 962 insertions, 0 deletions
diff --git a/private/ntos/ndis/lance/lancesft.h b/private/ntos/ndis/lance/lancesft.h new file mode 100644 index 000000000..945b21687 --- /dev/null +++ b/private/ntos/ndis/lance/lancesft.h @@ -0,0 +1,962 @@ +/*++ + +Copyright (c) 1990 Microsoft Corporation + +Module Name: + + lancesft.h + +Abstract: + + The main header for a LANCE (Local Area Network Controller + Am 7990) MAC driver. + +Author: + + Anthony V. Ercolano (tonye) creation-date 19-Jun-1990 + +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: + + 31-Jul-1992 R.D. Lanser: + + Changed DECST card type to DECTC for the DEC TurboChannel option + PMAD-AA (Lance ethernet). This option will be available for all + TurboChannel systems regardless of CPU type or system. + + Added InterruptRequestLevel to the _LANCE_ADAPTER structure because + 'lance.c' was passing the InterruptVector as the IRQL to the interrupt + connect routine which is not correct. This works on JAZZ because the + JAZZ HalGetInterruptVector is hardcoded to return a fixed IRQL for + EISA devices. + + Removed PhysicalBuffersContained and UsedLanceBuffer field from + _ADAPTER structure. SeanSe says that the code related to this + field was used for adevice that is no longer supported. I removed + the dependent code(or at least what was obvious) from 'send.c'. + +--*/ + +#ifndef _LANCESFT_ +#define _LANCESFT_ + +#define LANCE_NDIS_MAJOR_VERSION 3 +#define LANCE_NDIS_MINOR_VERSION 0 + +#if DBG + +#define LANCELOG 1 +#define LANCE_TRACE 0 + +#else + +#define LANCELOG 0 +#define LANCE_TRACE 0 + +#endif + +#if LANCELOG + +#define LOG_SIZE 256 + +#define TIMER '.' +#define IN_ISR 'i' +#define OUT_ISR 'I' +#define IN_DPC 'd' +#define OUT_DPC 'D' +#define RECEIVE 'R' +#define TRANSMIT 'x' +#define TRANSMIT_COMPLETE 'X' +#define PEND 'p' +#define UNPEND 'P' +#define INDICATE 'r' +#define IN_SEND 's' +#define OUT_SEND 'S' +#define START 'G' +#define RESET_STEP_1 '1' +#define RESET_STEP_2 '2' +#define RESET_SAVE_PACKET 'b' +#define RESET_RECOVER_PACKET 'B' +#define RESET_COMPLETE_PACKET 'c' +#define RESET_STEP_3 '3' +#define REMOVE 'V' +#define CLOSE 'C' +#define UNLOAD 'U' + + + +extern UCHAR Log[LOG_SIZE]; + +extern UCHAR LogPlace; +extern UCHAR LogWrapped; + + + +#define LOG(c) { Log[LogPlace] = (c); Log[(LogPlace+3) % 255] ='\0'; \ + LogPlace = (LogPlace + 1) % 255; } + +#else + +#define LOG(c) + +#endif + + + +extern NDIS_PHYSICAL_ADDRESS HighestAcceptableMax; + +// +// ZZZ These macros are peculiar to NT. +// + +#define LANCE_ALLOC_PHYS(pp, s) NdisAllocateMemory((PVOID *)(pp),(s),0,HighestAcceptableMax) +#define LANCE_FREE_PHYS(p, s) NdisFreeMemory((PVOID)(p),(s),0) +#define LANCE_MOVE_MEMORY(Destination,Source,Length) NdisMoveMemory(Destination,Source,Length) +#define LANCE_ZERO_MEMORY(Destination,Length) NdisZeroMemory(Destination,Length) + + + +// +// Definitions for all the different card types. +// + + +#define LANCE_DE100 0x01 // DE100 card +#define LANCE_DE201 0x02 // DE201 card +#define LANCE_DEPCA 0x04 // Card in a Dec PC x86 machine +#define LANCE_DECST 0x08 // Card in a decstation +#define LANCE_DE422 0x10 // DE422 card +#define LANCE_DECTC 0x20 // TurboChannel PMAD-AA option + +#define LANCE_DE100_NAME LANCE_DEFAULT_NAME +#define LANCE_DE201_NAME LANCE_DEFAULT_NAME +#define LANCE_DEPCA_NAME LANCE_DEFAULT_NAME +#define LANCE_DECST_NAME LANCE_DEFAULT_NAME +#define LANCE_DE422_NAME LANCE_DEFAULT_NAME +#define LANCE_DECTC_NAME LANCE_DEFAULT_NAME +#define LANCE_DEFAULT_NAME "\\Device\\Lance01" + + +// +// This structure is passed as context from the receive interrupt +// processor. Eventually it will be used as a parameter to +// LanceTransferData. LanceTransferData can get two kinds of +// context. It will receive either an ndis packet or it will +// receive a LANCE_RECEIVE_CONTEXT. It will be able to tell +// the difference since the LANCE_RECEIVE_CONTEXT will have +// its low bit set. No pointer to an ndis packet can have its low +// bit set. +// +typedef union _LANCE_RECEIVE_CONTEXT { + + UINT WholeThing; + struct _INFO { + // + // Used to mark that this is context rather than a pointer + // to a packet. + // + UINT IsContext:1; + + // + // The first receive ring descriptor used to hold the packet. + // + UINT FirstBuffer:7; + + // + // The last receive ring descriptor used to hold the packet. + // + UINT LastBuffer:7; + } INFO; + +} LANCE_RECEIVE_CONTEXT,*PLANCE_RECEIVE_CONTEXT; + + + + + + +// +// This record type is inserted into the MacReserved portion +// of the packet header when the packet is going through the +// staged allocation of buffer space prior to the actual send. +// +typedef struct _LANCE_RESERVED { + + // + // Points to the next packet in the chain of queued packets + // being allocated, loopbacked, or waiting for the finish + // of transmission. + // + // The packet will either be on the stage list for allocation, + // the loopback list for loopback processing, on an adapter + // wide doubly linked list (see below) for post transmission + // processing. + // + // We always keep the packet on a list so that in case the + // the adapter is closing down or resetting, all the packets + // can easily be located and "canceled". + // + PNDIS_PACKET Next; + + // + // This gives the index into the array of adapter buffer + // descriptors that contains the packet information. + // + USHORT LanceBuffersIndex; + + // + // When the hardware send is done this will record whether + // the send was successful or not. + // + BOOLEAN SuccessfulTransmit; + +} LANCE_RESERVED,*PLANCE_RESERVED; + +// +// This macro will return a pointer to the lance reserved portion +// of a packet given a pointer to a packet. +// +#define PLANCE_RESERVED_FROM_PACKET(Packet) \ + ((PLANCE_RESERVED)((Packet)->MacReserved)) + +// +// This structure is used to map entries in the ring descriptors +// back to the packets from which the data in the ring descriptor +// originated. +// + +typedef struct _LANCE_RING_TO_PACKET { + + // + // Points to the packet from which data is being transmitted + // through this ring entry. + // + PNDIS_PACKET OwningPacket; + + // + // Index of the ring entry that is being used by the packet. + // + UINT RingIndex; + + // + // When a packet is submitted to the hardware we record + // here whether it used adapter buffers and if so, the buffer + // index. + // + UINT LanceBuffersIndex; + +} LANCE_RING_TO_PACKET,*PLANCE_RING_TO_PACKET; + +// +// If an ndis packet does not meet the hardware contraints then +// an adapter buffer will be allocated. Enough data will be copied +// out of the ndis packet so that by using a combination of the +// adapter buffer and remaining ndis buffers the hardware +// constraints are satisfied. +// +// In the LANCE_ADAPTER structure three threaded lists are kept in +// one array. One points to a list of LANCE_BUFFER_DESCRIPTORS +// that point to small adapter buffers. Another is for medium sized +// buffers and the last for full sized (large) buffers. +// +// The allocation is controlled via a free list head and +// the free lists are "threaded" by a field in the adapter buffer +// descriptor. +// +typedef struct _LANCE_BUFFER_DESCRIPTOR { + + // + // A virtual pointer to a small, medium, or large buffer. + // + PVOID VirtualLanceBuffer; + + // + // Threads the elements of an array of these descriptors into + // a free list. -1 implies no more entries in the list. + // + INT Next; + + // + // Holds the amount of space (in bytes) available in the buffer + // + UINT BufferSize; + + // + // Holds the length of data placed into the buffer. This + // can (and likely will) be less that the actual buffers + // length. + // + UINT DataLength; + +} LANCE_BUFFER_DESCRIPTOR,*PLANCE_BUFFER_DESCRIPTOR; + + +#define LANCE_LENGTH_OF_ADDRESS 6 + +// +// Define the size of the ethernet header. +// +#define LANCE_HEADER_SIZE 14 + +// +// Define Maximum number of bytes a protocol can read during a +// receive data indication. +// +#define LANCE_MAX_LOOKAHEAD ( 248 - LANCE_HEADER_SIZE ) + + + + + +typedef struct _LANCE_ADAPTER { + + // + // The card type of this adapter. + // + UCHAR LanceCard; + + // + // Holds the interrupt object for this adapter. + // + NDIS_MINIPORT_INTERRUPT Interrupt; + + NDIS_MINIPORT_TIMER DeferredTimer; + + // + // Non OS fields of the adapter. + // + + // + // Contains Address first byte of adapter memory is mapped to. + // + PVOID MmMappedBaseAddr; + + // + // Contains address of the hardware memory. + // + PVOID HardwareBaseAddr; + + // + // Offset for Init block from the Lance chip's point of view. + // + ULONG HardwareBaseOffset; + + // + // Amount of memory + // + ULONG AmountOfHardwareMemory; + + // + // For lance implementation that uses dual ported memory this + // field is used to point to the first available memory. + // + PVOID CurrentMemoryFirstFree; + + // + // Address of the first byte following the memory. + // + PVOID MemoryFirstUnavailable; + + // + // Physical address of base io port address + // + ULONG IoBaseAddr; + + // + // Pointer to the RAP register. + // + ULONG RAP; + + // + // Pointer to the RDP register. + // + ULONG RDP; + + // + // Pointer to the NICSR register. + // + ULONG Nicsr; + + // + // Slot Number the De422 is in. + // + UINT SlotNumber; + + // + // Default information to add to the NICSR register value + // + USHORT NicsrDefaultValue; + + // + // Have the interrupts from the card been turned off. + // + BOOLEAN InterruptsStopped; + + // + // Address in memory of the network address + // + ULONG NetworkHardwareAddress; + + // + // The network address from the hardware. + // + CHAR NetworkAddress[LANCE_LENGTH_OF_ADDRESS]; + + // + // The network address from the hardware. + // + CHAR CurrentNetworkAddress[LANCE_LENGTH_OF_ADDRESS]; + + // + // Interrupt number + // + CCHAR InterruptNumber; + + // + // IRQL + // + CCHAR InterruptRequestLevel; + + // + // Holds the number of transmit ring entries. + // + // NOTE NOTE NOTE + // + // There is code that depends on the number of transmit entries + // being a power of two. + // + UINT NumberOfTransmitRings; + + // + // Holds the number of receive ring entries. + // + UINT NumberOfReceiveRings; + + // + // Holds the size of receive buffers. + // + UINT SizeOfReceiveBuffer; + + // + // Holds number of each buffer size. + // + UINT NumberOfSmallBuffers; + UINT NumberOfMediumBuffers; + UINT NumberOfLargeBuffers; + + // + // The log base two of the number of transmit ring entries. + // + UINT LogNumberTransmitRings; + + // + // The log base two of the number of receive ring entries. + // + UINT LogNumberReceiveRings; + + // + // Handle given by NDIS when the MAC registered itself. + // + NDIS_HANDLE NdisDriverHandle; + + // + // Handle given by NDIS when the adapter was registered. + // + NDIS_HANDLE MiniportAdapterHandle; + + // + // Pointer to the LANCE initialization block. + // + PLANCE_INITIALIZATION_BLOCK InitBlock; + + // + // Counter that records the number of transmit rings currently + // available for allocation. + // + UINT NumberOfAvailableRings; + + // + // Pointer to transmit descriptor ring entry that is the + // first ring entry available for allocation of transmit + // buffers. + // + // Can only be accessed when the adapter lock + // is held. + // + PLANCE_TRANSMIT_ENTRY AllocateableRing; + + // + // Pointer to a transmit descriptor ring entry that is the + // first ring entry that the MAC currently has made available + // for transmission. + // + // Can only be accessed when the adapter lock + // is held. + // + PLANCE_TRANSMIT_ENTRY TransmittingRing; + + // + // Pointer to the first packet that has been allocated to + // a transmit packet but has not yet been relinquished to + // the hardware. We need this pointer to keep the transmit + // post processing from running into a packet that has not + // been transmitted. + // + PLANCE_TRANSMIT_ENTRY FirstUncommittedRing; + + // + // Pointer to an array of structs that map transmit ring entries + // back to a packet. + // + PLANCE_RING_TO_PACKET RingToPacket; + + // + // Pointer to the transmit ring. + // + PLANCE_TRANSMIT_ENTRY TransmitRing; + + // + // Pointer to the last transmit ring entry. + // + PLANCE_TRANSMIT_ENTRY LastTransmitRingEntry; + + // + // Pointer to the receive ring. + // + PLANCE_RECEIVE_ENTRY ReceiveRing; + + // + // Listheads for the adapters buffers. If the list + // head is equal to -1 then there are no free elements + // on the list. + // + // The list heads must only be accessed when the + // adapter lock is held. + // + // Note that the listhead at index 0 will always be -1. + // + INT LanceBufferListHeads[4]; + + // + // Pointers to an array of adapter buffer descriptors. + // The array will actually be threaded together by + // three free lists. The lists will be for small, + // medium and full sized packets. + // + PLANCE_BUFFER_DESCRIPTOR LanceBuffers; + + // + // Did we indicate a packet? Used to tell if NdisIndicateReceiveComplete + // should be called. + // + BOOLEAN IndicatedAPacket; + + // + // Pointer to an array of virtual addresses that describe + // the virtual address of each receive ring descriptor buffer. + // + PVOID *ReceiveVAs; + + // + // Index of the receive ring descriptor that started the + // last packet not completely received by the hardware. + // + UINT CurrentReceiveIndex; + + // + // Counters to hold the various number of errors/statistics for both + // reception and transmission. + // + // Can only be accessed when the adapter lock is held. + // + UINT OutOfReceiveBuffers; + UINT CRCError; + UINT FramingError; + UINT RetryFailure; + UINT LostCarrier; + UINT LateCollision; + UINT UnderFlow; + UINT Deferred; + UINT OneRetry; + UINT MoreThanOneRetry; + + // + // Holds counts of more global errors for the driver. If we + // get a memory error then the device needs to be reset. + // + UINT MemoryError; + UINT Babble; + UINT MissedPacket; + + // + // Holds other cool counts. + // + + ULONG Transmit; + ULONG Receive; + + // + // Flag that when enabled lets routines know that a reset + // is in progress. + // + BOOLEAN ResetInProgress; + + // + // Flag that when enabled lets routines know that a reset + // is in progress and the initialization needs doing. + // + BOOLEAN ResetInitStarted; + + // + // The type of the request that caused the adapter to reset. + // + NDIS_REQUEST_TYPE ResetRequestType; + + // + // During an indication this is set to the current indications context + // + LANCE_RECEIVE_CONTEXT IndicatingMacReceiveContext; + + + // + // Look ahead information. + // + + ULONG MaxLookAhead; + + // + // Open information + // + UCHAR MaxMulticastList; + + // + // Will be true the first time that the hardware is initialized + // by the driver initialization. + // + BOOLEAN FirstInitialization; + + // + // Is the adapter being removed + // + BOOLEAN BeingRemoved; + + // + // Will be true if the hardware fails for some reason + // + BOOLEAN HardwareFailure; + + USHORT SavedMemBase; + UINT Reserved1; + UINT Reserved2; + // + // Lookahead buffer for loopback packets + // + UCHAR Lookahead[LANCE_MAX_LOOKAHEAD + LANCE_HEADER_SIZE]; + + UINT PacketFilter; + UINT NumberOfAddresses; + UCHAR MulticastAddresses[32][LANCE_LENGTH_OF_ADDRESS]; + +} LANCE_ADAPTER,*PLANCE_ADAPTER; + +// +// Given a MacContextHandle return the PLANCE_ADAPTER +// it represents. +// +#define PLANCE_ADAPTER_FROM_CONTEXT_HANDLE(Handle) \ + ((PLANCE_ADAPTER)(Handle)) + +// +// Given a pointer to a LANCE_ADAPTER return the +// proper MacContextHandle. +// +#define CONTEXT_HANDLE_FROM_PLANCE_ADAPTER(Ptr) \ + ((NDIS_HANDLE)(Ptr)) + +// +// This macro will act a "epilogue" to every routine in the +// *interface*. It will check whether any requests need +// to defer their processing. It will also decrement the reference +// count on the adapter. If the reference count is zero and there +// is deferred work to do it will insert the interrupt processing +// routine in the DPC queue. +// +// Note that we don't need to include checking for blocked receives +// since blocked receives imply that there will eventually be an +// interrupt. +// +// NOTE: This macro assumes that it is called with the lock acquired. +// +// ZZZ This routine is NT specific. +// +#define LANCE_DO_DEFERRED(Adapter) \ +{ \ + PLANCE_ADAPTER _A = (Adapter); \ + if (_A->ResetInProgress) { \ + NdisMSetTimer(&_A->DeferredTimer, 0);\ + } \ +} + + + + +// +// Procedures which log errors. +// + +typedef enum _LANCE_PROC_ID { + processInterrupt +} LANCE_PROC_ID; + + +#define LANCE_ERRMSG_NDIS_ALLOC_MEM (ULONG)0x01 + + + + + + + + + + + + + + +// +// This macro is used to "allocate" memory for the structures that +// must be shared with the hardware. It assigns a pvoid that is +// at least quadword aligned. +// +#define LANCE_ALLOCATE_MEMORY_FOR_HARDWARE(A,S,P) \ +{ \ + PLANCE_ADAPTER _Adapter = (A); \ + UINT _Size = (((S) + 7)/8)*8; \ + PVOID _HighWater; \ + if (!_Size) { \ + *(P) = NULL; \ + } else { \ + _HighWater = ((PCHAR)_Adapter->CurrentMemoryFirstFree) + _Size; \ + if (((PUCHAR)_HighWater) > \ + (((PUCHAR)_Adapter->MemoryFirstUnavailable) + 1)) { \ + *(P) = NULL; \ + } else { \ + *(P) = _Adapter->CurrentMemoryFirstFree; \ + _Adapter->CurrentMemoryFirstFree = _HighWater; \ + } \ + } \ +} + +// +// We now convert the virtual address to the actual physical address. +// +#define LANCE_GET_HARDWARE_PHYSICAL_ADDRESS(A,P) \ + (ULONG)((PCHAR)P - (PCHAR)(A)->MmMappedBaseAddr + (A)->HardwareBaseOffset) + +// +// This macro is used to "deallocate the memory from the hardware. +// Since this is hardware memory that is only allocated and deallocated +// once this macro really doesn't do anything. +// +#define LANCE_DEALLOCATE_MEMORY_FOR_HARDWARE(A,P)\ +{\ +} + + + + + +// +// These are routines for synchronizing with the ISR +// + + +// +// This structure is used to synchronize reading and writing to ports +// with the ISR. +// + +typedef struct _LANCE_SYNCH_CONTEXT { + + // + // Pointer to the lance adapter for which interrupts are + // being synchronized. + // + PLANCE_ADAPTER Adapter; + + // + // Pointer to a local variable that will receive the value + // + PUSHORT LocalRead; + + // + // Value to write + // + USHORT LocalWrite; + +} LANCE_SYNCH_CONTEXT,*PLANCE_SYNCH_CONTEXT; + + + +#define LANCE_WRITE_RAP(A,C) { \ + LANCE_ISR_WRITE_RAP(A,C);\ +} + + +#define LANCE_WRITE_RDP(A,C) { \ + LANCE_ISR_WRITE_RDP(A,C);\ +} + +#define LANCE_READ_RDP(A,C) { \ + LANCE_ISR_READ_RDP(A,C);\ +} + +#define LANCE_WRITE_NICSR(A,C) { \ + PLANCE_ADAPTER _A = A; \ + LANCE_SYNCH_CONTEXT _C; \ + _C.Adapter = _A; \ + _C.LocalWrite = (C | _A->NicsrDefaultValue); \ + NdisMSynchronizeWithInterrupt( \ + &(_A)->Interrupt, \ + LanceSyncWriteNicsr, \ + &_C \ + ); \ +} + +BOOLEAN +LanceSyncWriteNicsr( + IN PVOID Context + ); + +BOOLEAN +LanceSyncGetInterruptsStopped( + IN PVOID Context + ); + +BOOLEAN +LanceSyncStopChip( + IN PVOID Context + ); + + +// +// We define the external interfaces to the lance driver. +// These routines are only external to permit separate +// compilation. Given a truely fast compiler they could +// all reside in a single file and be static. +// + + +NDIS_STATUS +LanceTransferData( + OUT PNDIS_PACKET Packet, + OUT PUINT BytesTransferred, + IN NDIS_HANDLE MiniportAdapterContext, + IN NDIS_HANDLE MiniportReceiveContext, + IN UINT ByteOffset, + IN UINT BytesToTransfer + ); + +NDIS_STATUS +LanceSend( + IN NDIS_HANDLE MiniportAdapterContext, + IN PNDIS_PACKET Packet, + IN UINT Flags + ); + +extern +VOID +LanceStagedAllocation( + IN PLANCE_ADAPTER Adapter + ); + +extern +VOID +LanceCopyFromPacketToBuffer( + IN PNDIS_PACKET Packet, + IN UINT Offset, + IN UINT BytesToCopy, + OUT PCHAR Buffer, + OUT PUINT BytesCopied + ); + +extern +VOID +LanceCopyFromPacketToPacket( + IN PNDIS_PACKET Destination, + IN UINT DestinationOffset, + IN UINT BytesToCopy, + IN PNDIS_PACKET Source, + IN UINT SourceOffset, + OUT PUINT BytesCopied + ); + +extern +BOOLEAN +LanceHardwareDetails( + IN PLANCE_ADAPTER Adapter + ); + +extern +NDIS_STATUS +LanceRegisterAdapter( + IN PLANCE_ADAPTER Adapter + ); + +VOID +SetupAllocate( + IN PLANCE_ADAPTER Adapter, + IN NDIS_HANDLE MacBindingHandle, + IN PNDIS_PACKET Packet + ); + +VOID +LanceDisableInterrupt( + IN NDIS_HANDLE MiniportAdapterContext + ); + +VOID +LanceEnableInterrupt( + IN NDIS_HANDLE MiniportAdapterContext + ); + +VOID +LanceHalt( + IN PVOID MiniportAdapterContext + ); + +VOID +LanceHandleInterrupt( + IN NDIS_HANDLE Context + ); + +VOID +LanceIsr( + OUT PBOOLEAN InterruptRecognized, + OUT PBOOLEAN QueueDpc, + IN PVOID Context + ); + +NDIS_STATUS +LanceInitialize( + OUT PNDIS_STATUS OpenErrorStatus, + OUT PUINT SelectedMediumIndex, + IN PNDIS_MEDIUM MediumArray, + IN UINT MediumArraySize, + IN NDIS_HANDLE MiniportAdapterHandle, + IN NDIS_HANDLE ConfigurationHandle + ); + +#endif // _LANCESFT_ |