summaryrefslogtreecommitdiffstats
path: root/private/ntos/ndis/dc21x4
diff options
context:
space:
mode:
Diffstat (limited to 'private/ntos/ndis/dc21x4')
-rw-r--r--private/ntos/ndis/dc21x4/alloc.c825
-rw-r--r--private/ntos/ndis/dc21x4/copy.c205
-rw-r--r--private/ntos/ndis/dc21x4/crc.h68
-rw-r--r--private/ntos/ndis/dc21x4/d21x4def.h827
-rw-r--r--private/ntos/ndis/dc21x4/d21x4det.h80
-rw-r--r--private/ntos/ndis/dc21x4/d21x4fct.h809
-rw-r--r--private/ntos/ndis/dc21x4/d21x4hrd.h828
-rw-r--r--private/ntos/ndis/dc21x4/d21x4oid.h102
-rw-r--r--private/ntos/ndis/dc21x4/d21x4rgs.h140
-rw-r--r--private/ntos/ndis/dc21x4/dc21x4.c134
-rw-r--r--private/ntos/ndis/dc21x4/dc21x4.hlpbin0 -> 13339 bytes
-rw-r--r--private/ntos/ndis/dc21x4/dc21x4.hpj47
-rw-r--r--private/ntos/ndis/dc21x4/dc21x4.rc66
-rw-r--r--private/ntos/ndis/dc21x4/dc21x4.rtf199
-rw-r--r--private/ntos/ndis/dc21x4/filter.c758
-rw-r--r--private/ntos/ndis/dc21x4/init.c881
-rw-r--r--private/ntos/ndis/dc21x4/interrup.c1726
-rw-r--r--private/ntos/ndis/dc21x4/mactophy.c701
-rw-r--r--private/ntos/ndis/dc21x4/makefile7
-rw-r--r--private/ntos/ndis/dc21x4/makefile.inc5
-rw-r--r--private/ntos/ndis/dc21x4/media.c2047
-rw-r--r--private/ntos/ndis/dc21x4/mii.h453
-rw-r--r--private/ntos/ndis/dc21x4/miigen.c524
-rw-r--r--private/ntos/ndis/dc21x4/miiphy.c1913
-rw-r--r--private/ntos/ndis/dc21x4/monitor.c354
-rw-r--r--private/ntos/ndis/dc21x4/precomp.h9
-rw-r--r--private/ntos/ndis/dc21x4/register.c2469
-rw-r--r--private/ntos/ndis/dc21x4/request.c530
-rw-r--r--private/ntos/ndis/dc21x4/reset.c337
-rw-r--r--private/ntos/ndis/dc21x4/send.c664
-rw-r--r--private/ntos/ndis/dc21x4/sources58
-rw-r--r--private/ntos/ndis/dc21x4/srom.c1521
-rw-r--r--private/ntos/ndis/dc21x4/transfer.c82
-rw-r--r--private/ntos/ndis/dc21x4/version.h7
34 files changed, 19376 insertions, 0 deletions
diff --git a/private/ntos/ndis/dc21x4/alloc.c b/private/ntos/ndis/dc21x4/alloc.c
new file mode 100644
index 000000000..90d5fbea2
--- /dev/null
+++ b/private/ntos/ndis/dc21x4/alloc.c
@@ -0,0 +1,825 @@
+/*+
+ * file: alloc.c
+ *
+ * Copyright (C) 1994 by
+ * Digital Equipment Corporation, Maynard, Massachusetts.
+ * All rights reserved.
+ *
+ * This software is furnished under a license and may be used and copied
+ * only in accordance of the terms of such license and with the
+ * inclusion of the above copyright notice. This software or any other
+ * copies thereof may not be provided or otherwise made available to any
+ * other person. No title to and ownership of the software is hereby
+ * transferred.
+ *
+ * The information in this software is subject to change without notice
+ * and should not be construed as a commitment by digital equipment
+ * corporation.
+ *
+ * Digital assumes no responsibility for the use or reliability of its
+ * software on equipment which is not supplied by digital.
+ *
+ *
+ * Abstract: This file is part of the NDIS 4.0 miniport driver for
+ * DEC's DC21X4 Ethernet controller family.
+ *
+ *
+ * Author: Philippe Klein
+ *
+ * Revision History:
+ *
+ * phk 31-Jul-1994 Initial entry
+ * phk 11-Dec-1994 Allocate the shared data buffers in
+ * cached memory.
+ *
+-*/
+
+#include <precomp.h>
+
+#pragma NDIS_PAGABLE_FUNCTION(AllocateAdapterMemory)
+#pragma NDIS_PAGABLE_FUNCTION(FreeAdapterMemory)
+#pragma NDIS_PAGABLE_FUNCTION(AlignStructure)
+
+
+
+
+
+
+
+
+
+
+/*+
+ *
+ * AllocateAdapterMemory
+ *
+ * Routine Description:
+ *
+ * This routine allocates memory for:
+ *
+ * - Transmit descriptor ring
+ * - Receive descriptor ring
+ * - Receive buffers
+ * - Transmit buffer
+ * - Setup buffer
+ *
+ * Arguments:
+ *
+ * Adapter - The adapter to allocate memory for.
+ *
+ * Functional description
+ *
+ * For each allocated zone, we maintain a set of pointers:
+ * - virtual & physical addresses of the allocated block
+ * - virtual & physical addresses of the aligned structure (descriptor ring, buffer,...)
+ * whithin the block
+ *
+ * Return Value:
+ *
+ * Returns FALSE if an allocation fails.
+ *
+-*/
+extern
+BOOLEAN
+AllocateAdapterMemory(
+ IN PDC21X4_ADAPTER Adapter
+ )
+{
+ PDC21X4_TRANSMIT_DESCRIPTOR TransmitDescriptor;
+ PDC21X4_RECEIVE_DESCRIPTOR ReceiveDescriptor;
+
+ NDIS_STATUS Status;
+
+ PRCV_HEADER RcvHeader;
+ PNDIS_PACKET Packet;
+
+ ULONG AllocSize;
+ PULONG AllocVa;
+ NDIS_PHYSICAL_ADDRESS AllocPa;
+ ULONG Va;
+
+ ULONG Pa;
+
+ UINT i;
+ ULONG Offset;
+
+ INT TransmitDescriptorRingSize;
+ INT ReceiveDescriptorRingSize;
+
+ Adapter->RcvHeaderSize =
+ ((RCV_HEADER_SIZE + Adapter->CacheLineSize - 1) / Adapter->CacheLineSize)
+ * Adapter->CacheLineSize;
+
+
+#if _DBG
+ DbgPrint("Alloc Rcv_ring[%d desc.], Txm_ring[%d desc.], setup_buf[%d]...\n",
+ Adapter->ReceiveRingSize,
+ TRANSMIT_RING_SIZE,
+ DC21X4_SETUP_BUFFER_SIZE
+ );
+#endif
+
+ // Allocate space for transmit descriptor ring,
+ // the receive descriptor ring and the setup buffer
+
+ TransmitDescriptorRingSize =
+ Adapter->DescriptorSize * TRANSMIT_RING_SIZE;
+ ReceiveDescriptorRingSize =
+ Adapter->DescriptorSize * Adapter->ReceiveRingSize;
+
+ Adapter->DescriptorRing.AllocSize =
+ TransmitDescriptorRingSize
+ + ReceiveDescriptorRingSize
+ + DC21X4_SETUP_BUFFER_SIZE
+ + Adapter->CacheLineSize;
+
+ NdisMAllocateSharedMemory(
+ Adapter->MiniportAdapterHandle,
+ Adapter->DescriptorRing.AllocSize,
+ FALSE, // NON-CACHED
+ (PVOID *)&Adapter->DescriptorRing.AllocVa, // virtual ...
+ &Adapter->DescriptorRing.AllocPa // and physical address of the allocation
+ );
+
+ // Check the allocation success
+
+ if ((PVOID)Adapter->DescriptorRing.AllocVa == (PVOID)NULL) {
+ return FALSE;
+ }
+ if (NdisGetPhysicalAddressHigh(Adapter->DescriptorRing.AllocPa) != 0) {
+ return FALSE;
+ }
+
+ NdisZeroMemory (
+ (PVOID)(Adapter->DescriptorRing.AllocVa),
+ (ULONG)(Adapter->DescriptorRing.AllocSize)
+ );
+
+ // Align to the next cache line boundary
+
+ AlignStructure (
+ &Adapter->DescriptorRing,
+ Adapter->CacheLineSize
+ );
+
+ Adapter->TransmitDescriptorRingVa = Adapter->DescriptorRing.Va;
+ Adapter->TransmitDescriptorRingPa = Adapter->DescriptorRing.Pa;
+ Offset = TransmitDescriptorRingSize;
+
+ Adapter->ReceiveDescriptorRingVa = Adapter->DescriptorRing.Va + Offset;
+ Adapter->ReceiveDescriptorRingPa = Adapter->DescriptorRing.Pa + Offset;
+ Offset += ReceiveDescriptorRingSize;
+
+ Adapter->SetupBufferVa = Adapter->DescriptorRing.Va + Offset;
+ Adapter->SetupBufferPa = Adapter->DescriptorRing.Pa + Offset;
+
+ //Initialize the setup buffer
+
+ NdisZeroMemory (
+ (PVOID)(Adapter->SetupBufferVa),
+ DC21X4_SETUP_BUFFER_SIZE
+ );
+
+
+ // Allocate a pool of NDIS buffers
+
+ NdisAllocateBufferPool(
+ &Status,
+ &Adapter->FlushBufferPoolHandle,
+ ( Adapter->ReceiveRingSize
+ + Adapter->ExtraReceiveBuffers
+ + DC21X4_NUMBER_OF_MAX_TRANSMIT_BUFFERS
+ + DC21X4_NUMBER_OF_MIN_TRANSMIT_BUFFERS )
+ );
+
+ if (Status != NDIS_STATUS_SUCCESS) {
+ return FALSE;
+ }
+
+
+ // Allocate a pool of packets.
+#if _DBG
+ DbgPrint("Allocate PacketPool [%d packets]\n",
+ Adapter->ExtraReceivePackets);
+#endif
+ NdisAllocatePacketPool(
+ &Status,
+ &Adapter->ReceivePacketPool,
+ Adapter->ExtraReceivePackets,
+ 0
+ );
+
+ if (Status != NDIS_STATUS_SUCCESS) {
+ return FALSE;
+ }
+
+ // Allocate all of the packets out of the packet pool
+ // and place them on a queue.
+
+ for (i = 0; i < Adapter->ExtraReceivePackets; i++) {
+
+ // Allocate a packet from the pool.
+ NdisAllocatePacket(
+ &Status,
+ &Packet,
+ Adapter->ReceivePacketPool
+ );
+ if (Status != NDIS_STATUS_SUCCESS) {
+ return(FALSE);
+ }
+
+ // Set the header size in the packet's Out-Of-Band information.
+ // All other fields in the Out-Of-Band information have been
+ // initialized to 0 by NdisAllocatePacket().
+
+ NDIS_SET_PACKET_HEADER_SIZE(Packet, ETH_HEADER_SIZE);
+
+ // Place it on the receive packet free list.
+
+ RCV_RESERVED(Packet)->Next = Adapter->FreePacketList;
+ Adapter->FreePacketList = Packet;
+ }
+
+ // Clear out the free receive list of buffers.
+ Adapter->FreeRcvList = NULL;
+
+
+ // We allocate the receive buffers. We allocate both
+ // the buffers for the descriptor ring and the extra
+ // buffers and place them all on the free queue.
+
+#if _DBG
+ DbgPrint("Allocate Receive Buffers [%d]\n",
+ Adapter->ExtraReceiveBuffers+Adapter->ReceiveRingSize);
+#endif
+
+ // Attempt to allocate all the receive buffer space
+ // in one block
+ // If it fails,allocate each buffer individually
+
+ // Allocation size
+ Adapter->RcvBufferSpace.AllocSize =
+ ((Adapter->ExtraReceiveBuffers + Adapter->ReceiveRingSize)
+ * (DC21X4_RECEIVE_BUFFER_SIZE + Adapter->RcvHeaderSize))
+ + Adapter->CacheLineSize;
+
+
+ NdisMAllocateSharedMemory(
+ Adapter->MiniportAdapterHandle,
+ Adapter->RcvBufferSpace.AllocSize,
+ TRUE,
+ (PVOID *)&Adapter->RcvBufferSpace.AllocVa,
+ &Adapter->RcvBufferSpace.AllocPa
+ );
+
+ // Check the allocation success
+ if (((PVOID)Adapter->RcvBufferSpace.AllocVa != (PVOID)NULL)
+ && (NdisGetPhysicalAddressHigh(Adapter->RcvBufferSpace.AllocPa) == 0)) {
+
+ NdisZeroMemory (
+ (PVOID)(Adapter->RcvBufferSpace.AllocVa),
+ (ULONG)(Adapter->RcvBufferSpace.AllocSize)
+ );
+
+ // Align to the next cache line boundary
+
+ AlignStructure (
+ &Adapter->RcvBufferSpace,
+ Adapter->CacheLineSize
+ );
+
+ // Allocation size needed for the receive buffer
+ AllocSize = DC21X4_RECEIVE_BUFFER_SIZE
+ + Adapter->RcvHeaderSize;
+ Offset=0;
+ }
+ else
+ {
+ // Allocation size needed for the receive buffer
+ AllocSize = DC21X4_RECEIVE_BUFFER_SIZE
+ + Adapter->RcvHeaderSize
+ + Adapter->CacheLineSize;
+
+
+ Adapter->RcvBufferSpace.Va=0;
+ }
+
+ for (i = 0;
+ i < (Adapter->ExtraReceiveBuffers + Adapter->ReceiveRingSize);
+ i++
+ ) {
+
+ if (Adapter->RcvBufferSpace.Va != 0) {
+
+ Va = Adapter->RcvBufferSpace.Va + Offset;
+ Pa = Adapter->RcvBufferSpace.Pa + Offset;
+ Offset += AllocSize;
+
+ }
+ else
+ {
+ // Allocate a receive buffer.
+
+ NdisMAllocateSharedMemory(
+ Adapter->MiniportAdapterHandle,
+ AllocSize,
+ TRUE,
+ (PVOID *)&AllocVa,
+ &AllocPa
+ );
+ if (((PVOID)AllocVa == (PVOID)NULL)
+ || (NdisGetPhysicalAddressHigh(AllocPa) != 0)) {
+ return FALSE;
+ }
+
+ NdisZeroMemory(AllocVa, AllocSize);
+
+ // Align on the cache line boundary
+
+ Offset = Adapter->CacheLineSize - ((ULONG)AllocVa % Adapter->CacheLineSize);
+ Va = (ULONG)(AllocVa) + Offset;
+ Pa = NdisGetPhysicalAddressLow(AllocPa) + Offset;
+
+ }
+
+ //The receive header points to the aligned va.
+
+ RcvHeader = (PRCV_HEADER)Va;
+
+ RcvHeader->AllocVa = (ULONG)AllocVa;
+ RcvHeader->AllocPa = AllocPa;
+ RcvHeader->AllocSize = (USHORT)AllocSize;
+
+ // These addresses point to the data buffer
+
+ RcvHeader->Va = (ULONG)(Va + Adapter->RcvHeaderSize);
+ RcvHeader->Pa = Pa + Adapter->RcvHeaderSize;
+ RcvHeader->Size = DC21X4_RECEIVE_BUFFER_SIZE;
+
+#if DBG
+ RcvHeader->Signature = 'dHxR';
+#if _DBG
+ DbgPrint(
+ "%-3d RcvHeader: %lx, RcvBuffer: %lx/%lx, HeaderSize: %lx\n",
+ i,RcvHeader,
+ RcvHeader->Va,
+ RcvHeader->Pa,
+ Adapter->RcvHeaderSize
+ );
+#endif
+#endif
+ // Allocate an NDIS flush buffer for each receive buffer.
+
+ NdisAllocateBuffer(
+ &Status,
+ &RcvHeader->FlushBuffer,
+ Adapter->FlushBufferPoolHandle,
+ (PVOID)RcvHeader->Va,
+ DC21X4_RECEIVE_BUFFER_SIZE
+ );
+ if (Status != NDIS_STATUS_SUCCESS) {
+ return FALSE;
+ }
+
+ // Grab a packet off of the free packet list and
+ // associate it with the buffer.
+
+ Packet = Adapter->FreePacketList;
+ Adapter->FreePacketList = RCV_RESERVED(Packet)->Next;
+
+ // Chain the buffer on the packet.
+
+ NdisChainBufferAtFront(Packet, RcvHeader->FlushBuffer);
+
+ // Save a pointer to the receive header with the packet.
+
+ RCV_RESERVED(Packet)->RcvHeader = RcvHeader;
+
+ // Save the packet with the receive header.
+
+ RcvHeader->Packet = Packet;
+
+ // Place the descriptor on the free queue.
+
+ RcvHeader->Next = Adapter->FreeRcvList;
+ Adapter->FreeRcvList = RcvHeader;
+
+ Adapter->CurrentReceiveBufferCount++;
+ }
+
+
+#if _DBG
+ DbgPrint("Init Rcv ring..\n");
+#endif
+
+ // Assign the receive buffers to the descriptors.
+
+ for (i = 0,
+ ReceiveDescriptor = (PDC21X4_RECEIVE_DESCRIPTOR)Adapter->ReceiveDescriptorRingVa,
+ Pa = Adapter->ReceiveDescriptorRingPa;
+ i < Adapter->ReceiveRingSize;
+ i++,
+ (PCHAR)ReceiveDescriptor += Adapter->DescriptorSize,
+ Pa += Adapter->DescriptorSize
+ ) {
+
+ // Grab a receive buffer from the free list.
+
+ ASSERT(Adapter->FreeRcvList != NULL);
+ RcvHeader = Adapter->FreeRcvList;
+ Adapter->FreeRcvList = RcvHeader->Next;
+
+ Adapter->CurrentReceiveBufferCount--;
+
+ // Associate the buffer with the descriptor.
+
+ ReceiveDescriptor->RcvHeader = RcvHeader;
+ ReceiveDescriptor->FirstBufferAddress = RcvHeader->Pa;
+
+
+ ReceiveDescriptor->Status = DESC_OWNED_BY_DC21X4;
+ ReceiveDescriptor->Control = DC21X4_RECEIVE_BUFFER_SIZE;
+
+ ReceiveDescriptor->Next =
+ (PDC21X4_RECEIVE_DESCRIPTOR)((PCHAR)ReceiveDescriptor + Adapter->DescriptorSize);
+
+ }
+
+ //last descriptor of the ring
+
+ (PCHAR)ReceiveDescriptor -= Adapter->DescriptorSize;
+ ReceiveDescriptor->Control |= DC21X4_RDES_SECOND_ADDR_CHAINED;
+ ReceiveDescriptor->SecondBufferAddress = Adapter->ReceiveDescriptorRingPa;
+ ReceiveDescriptor->Next =
+ (PDC21X4_RECEIVE_DESCRIPTOR)Adapter->ReceiveDescriptorRingVa;
+
+#if _DBG
+ DbgPrint("Init Txm ring..\n");
+#endif
+
+ // Initialize the Transmit Descriptor ring
+
+ for (i=0,
+ TransmitDescriptor = (PDC21X4_TRANSMIT_DESCRIPTOR)Adapter->TransmitDescriptorRingVa,
+ Pa = Adapter->TransmitDescriptorRingPa;
+ i < TRANSMIT_RING_SIZE;
+ i++,
+ (PCHAR)TransmitDescriptor += Adapter->DescriptorSize,
+ Pa += Adapter->DescriptorSize
+ ) {
+
+ TransmitDescriptor->MapTableIndex = i * NUMBER_OF_SEGMENT_PER_DESC;
+ TransmitDescriptor->DescriptorPa = Pa;
+ TransmitDescriptor->Next =
+ (PDC21X4_TRANSMIT_DESCRIPTOR)((PCHAR)TransmitDescriptor + Adapter->DescriptorSize);
+
+ }
+
+ //last descriptor of the ring
+ (PCHAR)TransmitDescriptor -= Adapter->DescriptorSize;
+ TransmitDescriptor->Control = DC21X4_TDES_SECOND_ADDR_CHAINED;
+ TransmitDescriptor->SecondBufferAddress = Adapter->TransmitDescriptorRingPa;
+ TransmitDescriptor->Next =
+ (PDC21X4_TRANSMIT_DESCRIPTOR)Adapter->TransmitDescriptorRingVa;
+
+
+ // Txm buffers
+
+ for (i = 0;i < DC21X4_NUMBER_OF_MAX_TRANSMIT_BUFFERS;i ++) {
+
+ Adapter->MaxTransmitBuffer[i].AllocSize =
+ DC21X4_MAX_TRANSMIT_BUFFER_SIZE + Adapter->CacheLineSize;
+
+ NdisMAllocateSharedMemory(
+ Adapter->MiniportAdapterHandle,
+ Adapter->MaxTransmitBuffer[i].AllocSize,
+ TRUE, // CACHED
+ (PVOID *)&Adapter->MaxTransmitBuffer[i].AllocVa, // virtual ...
+ &Adapter->MaxTransmitBuffer[i].AllocPa // and physical address of the buffer allocation
+ );
+
+ // Check the allocation success
+
+ if (((PVOID)Adapter->MaxTransmitBuffer[i].AllocVa == (PVOID)NULL)
+ || (NdisGetPhysicalAddressHigh(Adapter->MaxTransmitBuffer[i].AllocPa) != 0)) {
+ return FALSE;
+ }
+
+ // Align the buffer on the cache line boundary
+
+ AlignStructure (
+ &Adapter->MaxTransmitBuffer[i],
+ Adapter->CacheLineSize
+ );
+
+
+ // Allocate an NDIS flush buffer for each transmit buffer
+
+ NdisAllocateBuffer(
+ &Status,
+ &Adapter->MaxTransmitBuffer[i].FlushBuffer,
+ Adapter->FlushBufferPoolHandle,
+ (PVOID)Adapter->MaxTransmitBuffer[i].Va,
+ DC21X4_MAX_TRANSMIT_BUFFER_SIZE
+ );
+
+ if (Status != NDIS_STATUS_SUCCESS) {
+ return FALSE;
+ }
+ }
+
+ // Allocate the minimal packet buffers
+
+ Adapter->MinTransmitBuffer[0].AllocSize =
+ (DC21X4_NUMBER_OF_MIN_TRANSMIT_BUFFERS * DC21X4_MIN_TRANSMIT_BUFFER_SIZE)
+ + Adapter->CacheLineSize;
+
+ NdisMAllocateSharedMemory(
+ Adapter->MiniportAdapterHandle,
+ Adapter->MinTransmitBuffer[0].AllocSize,
+ TRUE, // CACHED
+ (PVOID *)&Adapter->MinTransmitBuffer[0].AllocVa, // virtual ...
+ &Adapter->MinTransmitBuffer[0].AllocPa // and physical address of the buffer allocation
+ );
+
+ // Check the allocation success
+
+ if (((PVOID)Adapter->MinTransmitBuffer[0].AllocVa == (PVOID)NULL)
+ || (NdisGetPhysicalAddressHigh(Adapter->MinTransmitBuffer[0].AllocPa) != 0)) {
+
+ Adapter->DontUseMinTransmitBuffer = TRUE;
+ return TRUE;
+ }
+
+ // Align the buffer on the cache line boundary
+
+ AlignStructure (
+ &Adapter->MinTransmitBuffer[0],
+ Adapter->CacheLineSize
+ );
+
+ for (i = 0;i < DC21X4_NUMBER_OF_MIN_TRANSMIT_BUFFERS;i ++) {
+
+ Offset = i * DC21X4_MIN_TRANSMIT_BUFFER_SIZE;
+
+ Adapter->MinTransmitBuffer[i].Va =
+ Adapter->MinTransmitBuffer[0].Va + Offset;
+
+ Adapter->MinTransmitBuffer[i].Pa =
+ Adapter->MinTransmitBuffer[0].Pa + Offset;
+
+ // Allocate an NDIS flush buffer for each transmit buffer
+
+ NdisAllocateBuffer(
+ &Status,
+ &Adapter->MinTransmitBuffer[i].FlushBuffer,
+ Adapter->FlushBufferPoolHandle,
+ (PVOID)Adapter->MinTransmitBuffer[i].Va,
+ DC21X4_MIN_TRANSMIT_BUFFER_SIZE
+ );
+
+ if (Status != NDIS_STATUS_SUCCESS) {
+ return FALSE;
+ }
+ }
+
+ // Allocation has completed successfully
+
+ return TRUE;
+}
+
+
+
+
+
+
+
+
+/*+
+ *
+ * FreeAdapterMemory
+ *
+ * Routine Description:
+ *
+ * Frees the memory previously allocated by
+ * AllocateAdapterMemory
+ *
+ * Arguments:
+ *
+ * Adapter - The adapter to deallocate memory for.
+ *
+ * Return Value:
+ *
+ * None.
+ *
+-*/
+extern
+VOID
+FreeAdapterMemory(
+ IN PDC21X4_ADAPTER Adapter
+ )
+{
+
+ PDC21X4_RECEIVE_DESCRIPTOR ReceiveDescriptor;
+ PRCV_HEADER RcvHeader;
+ PNDIS_PACKET Packet;
+ UINT i;
+
+ if ((PVOID)Adapter->DescriptorRing.AllocVa == (PVOID)NULL) {
+ // AllocateAdapterMemory failed on the first allocation:
+ // no ressources were allocated
+ return;
+ }
+
+ for (i = 0,
+ ReceiveDescriptor = (PDC21X4_RECEIVE_DESCRIPTOR)Adapter->ReceiveDescriptorRingVa;
+ i < Adapter->ReceiveRingSize;
+ i++,
+ (PCHAR)ReceiveDescriptor += Adapter->DescriptorSize
+ ) {
+
+ if (ReceiveDescriptor->RcvHeader) {
+
+ RcvHeader = ReceiveDescriptor->RcvHeader;
+
+ if (RcvHeader->FlushBuffer) {
+ NdisFreeBuffer(RcvHeader->FlushBuffer);
+ }
+ if (RcvHeader->Packet) {
+ NdisFreePacket(RcvHeader->Packet);
+ }
+
+ if (!Adapter->RcvBufferSpace.Va)
+
+ {
+ NdisMFreeSharedMemory(
+ Adapter->MiniportAdapterHandle,
+ RcvHeader->AllocSize,
+ TRUE,
+ (PVOID)RcvHeader->AllocVa,
+ RcvHeader->AllocPa
+ );
+ }
+
+ }
+ }
+
+ while (Adapter->FreeRcvList != NULL) {
+
+ RcvHeader = Adapter->FreeRcvList;
+ Adapter->FreeRcvList = RcvHeader->Next;
+
+ if (RcvHeader->FlushBuffer) {
+ NdisFreeBuffer(RcvHeader->FlushBuffer);
+ }
+ if ( !Adapter->RcvBufferSpace.Va
+ && RcvHeader->AllocVa)
+ {
+ NdisMFreeSharedMemory(
+ Adapter->MiniportAdapterHandle,
+ RcvHeader->AllocSize,
+ TRUE,
+ (PVOID)RcvHeader->AllocVa,
+ RcvHeader->AllocPa
+ );
+ }
+ }
+
+ while (Adapter->FreePacketList != NULL)
+ {
+ Packet = Adapter->FreePacketList;
+ Adapter->FreePacketList = RCV_RESERVED(Packet)->Next;
+
+ if (NULL != Packet)
+ {
+ NdisFreePacket(Packet);
+ }
+ }
+
+ if (Adapter->RcvBufferSpace.Va) {
+
+ NdisMFreeSharedMemory(
+ Adapter->MiniportAdapterHandle,
+ Adapter->RcvBufferSpace.AllocSize,
+ TRUE,
+ (PVOID)Adapter->RcvBufferSpace.AllocVa,
+ Adapter->RcvBufferSpace.AllocPa
+ );
+ }
+
+ if (Adapter->ReceivePacketPool) {
+ NdisFreePacketPool((PVOID)Adapter->ReceivePacketPool);
+ }
+
+
+ for (i = 0; i < DC21X4_NUMBER_OF_MAX_TRANSMIT_BUFFERS;i ++ ) {
+
+ if (Adapter->MaxTransmitBuffer[i].AllocVa) {
+
+ NdisMFreeSharedMemory(
+ Adapter->MiniportAdapterHandle,
+ Adapter->MaxTransmitBuffer[i].AllocSize,
+ TRUE,
+ (PVOID)Adapter->MaxTransmitBuffer[i].AllocVa,
+ Adapter->MaxTransmitBuffer[i].AllocPa
+ );
+
+ }
+
+ if (Adapter->MaxTransmitBuffer[i].FlushBuffer) {
+ NdisFreeBuffer(Adapter->MaxTransmitBuffer[i].FlushBuffer);
+ }
+ }
+
+ if (Adapter->MinTransmitBuffer[0].AllocVa &&
+ !Adapter->DontUseMinTransmitBuffer) {
+
+ NdisMFreeSharedMemory(
+ Adapter->MiniportAdapterHandle,
+ Adapter->MinTransmitBuffer[0].AllocSize,
+ TRUE,
+ (PVOID)Adapter->MinTransmitBuffer[0].AllocVa,
+ Adapter->MinTransmitBuffer[0].AllocPa
+ );
+
+ }
+
+ for (i = 0; i < DC21X4_NUMBER_OF_MIN_TRANSMIT_BUFFERS;i ++ ) {
+
+ if (Adapter->MinTransmitBuffer[i].FlushBuffer) {
+ NdisFreeBuffer(Adapter->MinTransmitBuffer[i].FlushBuffer);
+ }
+ }
+
+
+ if (Adapter->FlushBufferPoolHandle) {
+ NdisFreeBufferPool(Adapter->FlushBufferPoolHandle);
+ }
+
+
+ if (Adapter->DescriptorRing.AllocVa) {
+
+ NdisMFreeSharedMemory(
+ Adapter->MiniportAdapterHandle,
+ Adapter->DescriptorRing.AllocSize,
+ FALSE,
+ (PVOID)Adapter->DescriptorRing.AllocVa,
+ Adapter->DescriptorRing.AllocPa
+ );
+
+ }
+
+}
+
+
+
+
+
+
+
+
+/*
+ * AlignStructure
+ *
+ * Align a structure within a bloc of allocated memory
+ * on a specified boundary
+ *
+ */
+VOID
+AlignStructure (
+ IN PALLOCATION_MAP Map,
+ IN UINT Boundary
+ )
+{
+ ULONG AlignmentOffset;
+
+ AlignmentOffset = Boundary - ((ULONG)(Map->AllocVa) % Boundary);
+ Map->Va = (ULONG)(Map->AllocVa) + AlignmentOffset;
+ Map->Pa = NdisGetPhysicalAddressLow(Map->AllocPa)+ AlignmentOffset;
+
+}
+
+
+
+
+
+
+/*
+ * DC21X4AllocateComplete
+ *
+ *
+ *
+ */
+VOID
+DC21X4AllocateComplete(
+ IN NDIS_HANDLE MiniportAdapterContext,
+ IN PVOID VirtualAddress,
+ IN PNDIS_PHYSICAL_ADDRESS PhysicalAddress,
+ IN ULONG Length,
+ IN PVOID Context
+ )
+{
+
+}
+
+
diff --git a/private/ntos/ndis/dc21x4/copy.c b/private/ntos/ndis/dc21x4/copy.c
new file mode 100644
index 000000000..39442d2e5
--- /dev/null
+++ b/private/ntos/ndis/dc21x4/copy.c
@@ -0,0 +1,205 @@
+/*+
+ * file: copy.c
+ *
+ * Copyright (C) 1992-1995 by
+ * Digital Equipment Corporation, Maynard, Massachusetts.
+ * All rights reserved.
+ *
+ * This software is furnished under a license and may be used and copied
+ * only in accordance of the terms of such license and with the
+ * inclusion of the above copyright notice. This software or any other
+ * copies thereof may not be provided or otherwise made available to any
+ * other person. No title to and ownership of the software is hereby
+ * transferred.
+ *
+ * The information in this software is subject to change without notice
+ * and should not be construed as a commitment by digital equipment
+ * corporation.
+ *
+ * Digital assumes no responsibility for the use or reliability of its
+ * software on equipment which is not supplied by digital.
+ *
+ *
+ * Abstract: This file is the part of the NDIS 4.0 miniport driver for DEC's
+ * DC21X4 Ethernet Adapter family.
+ * This module implements the routines to move data
+ * between NDIS packets and buffers
+ *
+ * Author: Philippe Klein
+ *
+ * Revision History:
+ *
+ * phk 28-Aug-1994 Initial entry
+ *
+-*/
+
+#include <precomp.h>
+
+
+
+
+
+
+
+
+/*+
+ * CopyFromPacketToBuffer
+ *
+ * Routine Description:
+ *
+ * Copy from an ndis packet into a buffer.
+ *
+ * Arguments:
+ *
+ * Packet - Source
+ *
+ * Offset - The offset whitin the packet of the first byte
+ * to copy
+ *
+ * Buffer - Destination
+ *
+ * BytesToCopy - The number of bytes to copy
+ *
+ * BytesCopied - The number of bytes actually copied. Can be less then
+ * BytesToCopy if the packet is shorter than BytesToCopy.
+ *
+ * Return Value:
+ *
+ * None
+ *
+-*/
+extern
+VOID
+CopyFromPacketToBuffer (
+ IN PNDIS_PACKET Packet,
+ IN UINT Offset,
+ IN PCHAR Buffer,
+ IN UINT BytesToCopy,
+ OUT PUINT BytesCopied
+ )
+
+{
+
+ UINT NdisBufferCount;
+ PNDIS_BUFFER CurrentBuffer;
+ PVOID VirtualAddress;
+ UINT CurrentLength;
+ UINT LocalBytesCopied;
+ UINT AmountToMove;
+
+
+ NdisQueryPacket(
+ Packet,
+ NULL,
+ &NdisBufferCount,
+ &CurrentBuffer,
+ NULL
+ );
+
+
+ // Check if zero length copy or null packet
+
+ if (!BytesToCopy || !NdisBufferCount) {
+ *BytesCopied = 0;
+ return;
+ }
+
+ // Get the first buffer.
+
+ NdisQueryBuffer(
+ CurrentBuffer,
+ &VirtualAddress,
+ &CurrentLength
+ );
+
+
+ LocalBytesCopied = 0;
+
+ // If there is an offset move first to the beginning of the data
+ // block which may be in a subsequent buffer
+
+ if (Offset) {
+
+ while (Offset > CurrentLength) {
+
+ // No data are copied from this buffer;
+
+ Offset -= CurrentLength;
+
+ //Get the next buffer
+
+ NdisGetNextBuffer(
+ CurrentBuffer,
+ &CurrentBuffer
+ );
+
+ if (!CurrentBuffer) {
+ *BytesCopied = LocalBytesCopied;
+ return;
+ }
+
+ NdisQueryBuffer(
+ CurrentBuffer,
+ &VirtualAddress,
+ &CurrentLength
+ );
+
+ }
+
+ VirtualAddress = (PCHAR)VirtualAddress + Offset;
+ CurrentLength -= Offset;
+ }
+
+
+ // Copy the data
+
+ while (LocalBytesCopied < BytesToCopy) {
+
+ if (!CurrentLength) {
+
+ //The current buffer has been fully copied
+ //Get the next one
+
+ NdisGetNextBuffer(
+ CurrentBuffer,
+ &CurrentBuffer
+ );
+
+ if (!CurrentBuffer) {
+ // There is no more buffer.
+ break;
+ }
+
+ NdisQueryBuffer(
+ CurrentBuffer,
+ &VirtualAddress,
+ &CurrentLength
+ );
+ }
+
+ // Copy the data.
+
+ AmountToMove = min (CurrentLength , BytesToCopy - LocalBytesCopied);
+
+ MOVE_MEMORY(
+ Buffer,
+ VirtualAddress,
+ AmountToMove
+ );
+
+ LocalBytesCopied += AmountToMove;
+ CurrentLength -= AmountToMove;
+
+ Buffer = (PCHAR)Buffer + AmountToMove;
+ VirtualAddress = (PCHAR)VirtualAddress + AmountToMove;
+
+ }
+
+ *BytesCopied = LocalBytesCopied;
+
+}
+
+
+
+
+
diff --git a/private/ntos/ndis/dc21x4/crc.h b/private/ntos/ndis/dc21x4/crc.h
new file mode 100644
index 000000000..aa54be6d8
--- /dev/null
+++ b/private/ntos/ndis/dc21x4/crc.h
@@ -0,0 +1,68 @@
+ULONG CrcTable[256] =
+{
+ 0x00000000L, 0x77073096L, 0xEE0E612CL, 0x990951BAL,
+ 0x076DC419L, 0x706AF48FL, 0xE963A535L, 0x9E6495A3L,
+ 0x0EDB8832L, 0x79DCB8A4L, 0xE0D5E91EL, 0x97D2D988L,
+ 0x09B64C2BL, 0x7EB17CBDL, 0xE7B82D07L, 0x90BF1D91L,
+ 0x1DB71064L, 0x6AB020F2L, 0xF3B97148L, 0x84BE41DEL,
+ 0x1ADAD47DL, 0x6DDDE4EBL, 0xF4D4B551L, 0x83D385C7L,
+ 0x136C9856L, 0x646BA8C0L, 0xFD62F97AL, 0x8A65C9ECL,
+ 0x14015C4FL, 0x63066CD9L, 0xFA0F3D63L, 0x8D080DF5L,
+ 0x3B6E20C8L, 0x4C69105EL, 0xD56041E4L, 0xA2677172L,
+ 0x3C03E4D1L, 0x4B04D447L, 0xD20D85FDL, 0xA50AB56BL,
+ 0x35B5A8FAL, 0x42B2986CL, 0xDBBBC9D6L, 0xACBCF940L,
+ 0x32D86CE3L, 0x45DF5C75L, 0xDCD60DCFL, 0xABD13D59L,
+ 0x26D930ACL, 0x51DE003AL, 0xC8D75180L, 0xBFD06116L,
+ 0x21B4F4B5L, 0x56B3C423L, 0xCFBA9599L, 0xB8BDA50FL,
+ 0x2802B89EL, 0x5F058808L, 0xC60CD9B2L, 0xB10BE924L,
+ 0x2F6F7C87L, 0x58684C11L, 0xC1611DABL, 0xB6662D3DL,
+ 0x76DC4190L, 0x01DB7106L, 0x98D220BCL, 0xEFD5102AL,
+ 0x71B18589L, 0x06B6B51FL, 0x9FBFE4A5L, 0xE8B8D433L,
+ 0x7807C9A2L, 0x0F00F934L, 0x9609A88EL, 0xE10E9818L,
+ 0x7F6A0DBBL, 0x086D3D2DL, 0x91646C97L, 0xE6635C01L,
+ 0x6B6B51F4L, 0x1C6C6162L, 0x856530D8L, 0xF262004EL,
+ 0x6C0695EDL, 0x1B01A57BL, 0x8208F4C1L, 0xF50FC457L,
+ 0x65B0D9C6L, 0x12B7E950L, 0x8BBEB8EAL, 0xFCB9887CL,
+ 0x62DD1DDFL, 0x15DA2D49L, 0x8CD37CF3L, 0xFBD44C65L,
+ 0x4DB26158L, 0x3AB551CEL, 0xA3BC0074L, 0xD4BB30E2L,
+ 0x4ADFA541L, 0x3DD895D7L, 0xA4D1C46DL, 0xD3D6F4FBL,
+ 0x4369E96AL, 0x346ED9FCL, 0xAD678846L, 0xDA60B8D0L,
+ 0x44042D73L, 0x33031DE5L, 0xAA0A4C5FL, 0xDD0D7CC9L,
+ 0x5005713CL, 0x270241AAL, 0xBE0B1010L, 0xC90C2086L,
+ 0x5768B525L, 0x206F85B3L, 0xB966D409L, 0xCE61E49FL,
+ 0x5EDEF90EL, 0x29D9C998L, 0xB0D09822L, 0xC7D7A8B4L,
+ 0x59B33D17L, 0x2EB40D81L, 0xB7BD5C3BL, 0xC0BA6CADL,
+ 0xEDB88320L, 0x9ABFB3B6L, 0x03B6E20CL, 0x74B1D29AL,
+ 0xEAD54739L, 0x9DD277AFL, 0x04DB2615L, 0x73DC1683L,
+ 0xE3630B12L, 0x94643B84L, 0x0D6D6A3EL, 0x7A6A5AA8L,
+ 0xE40ECF0BL, 0x9309FF9DL, 0x0A00AE27L, 0x7D079EB1L,
+ 0xF00F9344L, 0x8708A3D2L, 0x1E01F268L, 0x6906C2FEL,
+ 0xF762575DL, 0x806567CBL, 0x196C3671L, 0x6E6B06E7L,
+ 0xFED41B76L, 0x89D32BE0L, 0x10DA7A5AL, 0x67DD4ACCL,
+ 0xF9B9DF6FL, 0x8EBEEFF9L, 0x17B7BE43L, 0x60B08ED5L,
+ 0xD6D6A3E8L, 0xA1D1937EL, 0x38D8C2C4L, 0x4FDFF252L,
+ 0xD1BB67F1L, 0xA6BC5767L, 0x3FB506DDL, 0x48B2364BL,
+ 0xD80D2BDAL, 0xAF0A1B4CL, 0x36034AF6L, 0x41047A60L,
+ 0xDF60EFC3L, 0xA867DF55L, 0x316E8EEFL, 0x4669BE79L,
+ 0xCB61B38CL, 0xBC66831AL, 0x256FD2A0L, 0x5268E236L,
+ 0xCC0C7795L, 0xBB0B4703L, 0x220216B9L, 0x5505262FL,
+ 0xC5BA3BBEL, 0xB2BD0B28L, 0x2BB45A92L, 0x5CB36A04L,
+ 0xC2D7FFA7L, 0xB5D0CF31L, 0x2CD99E8BL, 0x5BDEAE1DL,
+ 0x9B64C2B0L, 0xEC63F226L, 0x756AA39CL, 0x026D930AL,
+ 0x9C0906A9L, 0xEB0E363FL, 0x72076785L, 0x05005713L,
+ 0x95BF4A82L, 0xE2B87A14L, 0x7BB12BAEL, 0x0CB61B38L,
+ 0x92D28E9BL, 0xE5D5BE0DL, 0x7CDCEFB7L, 0x0BDBDF21L,
+ 0x86D3D2D4L, 0xF1D4E242L, 0x68DDB3F8L, 0x1FDA836EL,
+ 0x81BE16CDL, 0xF6B9265BL, 0x6FB077E1L, 0x18B74777L,
+ 0x88085AE6L, 0xFF0F6A70L, 0x66063BCAL, 0x11010B5CL,
+ 0x8F659EFFL, 0xF862AE69L, 0x616BFFD3L, 0x166CCF45L,
+ 0xA00AE278L, 0xD70DD2EEL, 0x4E048354L, 0x3903B3C2L,
+ 0xA7672661L, 0xD06016F7L, 0x4969474DL, 0x3E6E77DBL,
+ 0xAED16A4AL, 0xD9D65ADCL, 0x40DF0B66L, 0x37D83BF0L,
+ 0xA9BCAE53L, 0xDEBB9EC5L, 0x47B2CF7FL, 0x30B5FFE9L,
+ 0xBDBDF21CL, 0xCABAC28AL, 0x53B39330L, 0x24B4A3A6L,
+ 0xBAD03605L, 0xCDD70693L, 0x54DE5729L, 0x23D967BFL,
+ 0xB3667A2EL, 0xC4614AB8L, 0x5D681B02L, 0x2A6F2B94L,
+ 0xB40BBE37L, 0xC30C8EA1L, 0x5A05DF1BL, 0x2D02EF8DL
+};
+
diff --git a/private/ntos/ndis/dc21x4/d21x4def.h b/private/ntos/ndis/dc21x4/d21x4def.h
new file mode 100644
index 000000000..3a64c7a23
--- /dev/null
+++ b/private/ntos/ndis/dc21x4/d21x4def.h
@@ -0,0 +1,827 @@
+/*+
+ * file: d21x4def.h
+ *
+ * Copyright (C) 1992-1995 by
+ * Digital Equipment Corporation, Maynard, Massachusetts.
+ * All rights reserved.
+ *
+ * This software is furnished under a license and may be used and copied
+ * only in accordance of the terms of such license and with the
+ * inclusion of the above copyright notice. This software or any other
+ * copies thereof may not be provided or otherwise made available to any
+ * other person. No title to and ownership of the software is hereby
+ * transferred.
+ *
+ * The information in this software is subject to change without notice
+ * and should not be construed as a commitment by digital equipment
+ * corporation.
+ *
+ * Digital assumes no responsibility for the use or reliability of its
+ * software on equipment which is not supplied by digital.
+ *
+ *
+ * Abstract: This file contains the definitions of the macros used by
+ * the NDIS 4.0 miniport driver for DEC's DC21X4 PCI Ethernet
+ * Adapter family
+ *
+ * Author: Philippe Klein
+ *
+ * Revision History:
+ *
+ * phk 28-Aug-1994 Initial entry
+ *
+-*/
+
+
+
+
+
+
+
+
+
+
+
+// NDIS Revision level
+
+#define DC21X4_NDIS_MAJOR_VERSION 4
+#define DC21X4_NDIS_MINOR_VERSION 0
+
+// static is defined as EXTERN during the debug phase to allow
+// breakpoints to be set on them.
+
+#define DC21X4_DEVL 0
+
+//Filtering mode
+
+typedef enum _FILTERING_MODE {
+ DC21X4_PERFECT_FILTERING,
+ DC21X4_HASH_FILTERING
+} FILTERING_MODE;
+
+//CAM load
+
+typedef enum _LOAD_CAM {
+ LOAD_COMPLETED,
+ LOAD_PENDING,
+ LOAD_IN_PROGRESS
+} LOAD_CAM;
+
+// Packet Type
+
+typedef enum _PACKET_TYPE {
+ TXM_DIRECTED_FRAME,
+ TXM_MULTICAST_FRAME,
+ TXM_BROADCAST_FRAME,
+ RCV_DIRECTED_FRAME,
+ RCV_MULTICAST_FRAME,
+ RCV_BROADCAST_FRAME,
+} PACKET_TYPE;
+
+//LINK STATUS
+
+typedef enum _LINK_STATUS {
+ LinkFail=0,
+ LinkPass,
+ MiiLinkPass
+} LINK_STATUS;
+
+//TIMER
+
+typedef enum _TIMER_FLAG {
+ NoTimer=0,
+ SpaTimer,
+ AncTimeout,
+ DeferredLinkCheck,
+ AncPolling,
+ DeferredAnc
+} TIMER_FLAG;
+
+
+//INTERRUPT
+
+typedef enum _INTERRUPT_MSK {
+ NoInterruptMasked=0,
+ TxmInterruptMasked,
+ TxmRcvInterruptMasked
+} INTERRUPT_MSK;
+
+typedef enum _LINK_HANDLER_MODE {
+ NoNway,
+ NwayWorkAround,
+ Nway,
+ FullNway
+} LINK_HANDLER_MODE;
+
+//SEND MODE
+
+typedef enum _SEND_MODE {
+ CopyMinBuffer,
+ CopyMaxBuffer,
+ MappedBuffer
+} SEND_MODE;
+
+
+// Error log values
+
+#define DC21X4_ERRMSG_REGISTRY (ULONG)0x01
+#define DC21X4_ERRMSG_ALLOC_MEMORY (ULONG)0x02
+#define DC21X4_ERRMSG_SROM (ULONG)0x03
+#define DC21X4_ERRMSG_MEDIA (ULONG)0x04
+#define DC21X4_ERRMSG_LOAD_CAM (ULONG)0x05
+#define DC21X4_ERRMSG_INIT_DEVICE (ULONG)0x06
+#define DC21X4_ERRMSG_SYSTEM_ERROR (ULONG)0x07
+#define DC21X4_ERRMSG_TXM_JABBER_TIMEOUT (ULONG)0x08
+
+#define min(a,b) ((a)<(b) ? (a) : (b))
+#define max(a,b) ((a)>(b) ? (a) : (b))
+
+// OID parsing
+
+#define OID_TYPE_MASK 0xffff0000
+#define OID_TYPE_GENERAL_OPERATIONAL 0x00010000
+#define OID_TYPE_GENERAL_STATISTICS 0x00020000
+#define OID_TYPE_802_3_OPERATIONAL 0x01010000
+#define OID_TYPE_802_3_STATISTICS 0x01020000
+
+#define OID_REQUIRED_MASK 0x0000ff00
+#define OID_REQUIRED_MANDATORY 0x00000100
+#define OID_REQUIRED_OPTIONAL 0x00000200
+
+#define OID_INDEX_MASK 0x000000ff
+
+// Indexes in the GeneralMandatory array.
+
+#define GM_TRANSMIT_OK 0x00
+#define GM_RECEIVE_OK 0x01
+#define GM_TRANSMIT_ERROR 0x02
+#define GM_RECEIVE_ERROR 0x03
+#define GM_MISSED_FRAMES 0x04
+#define GM_ARRAY_SIZE 0x05
+
+// Indexes in the GeneralOptional array.
+
+#define GO_DIRECTED_TRANSMITS 0x00
+#define GO_MULTICAST_TRANSMITS 0x01
+#define GO_BROADCAST_TRANSMITS 0x02
+
+#define GO_DIRECTED_RECEIVES 0x00
+#define GO_MULTICAST_RECEIVES 0x01
+#define GO_BROADCAST_RECEIVES 0x02
+
+#define GO_COUNT_ARRAY_SIZE 0x06
+
+#define GO_RECEIVE_CRC_ERROR 0x00
+#define GO_TRANSMIT_QUEUE_LENGTH 0x01
+#define GO_ARRAY_SIZE 0x02
+
+// Indexes in the MediaMandatory array.
+
+#define MM_RECEIVE_ALIGNMENT_ERROR 0x00
+#define MM_TRANSMIT_ONE_COLLISION 0x01
+#define MM_TRANSMIT_MULT_COLLISIONS 0x02
+#define MM_ARRAY_SIZE 0x03
+
+// Indexes in the MediaOptional array
+#define MO_TRANSMIT_DEFERRED 0x00
+#define MO_TRANSMIT_EXC_COLLISIONS 0x01
+#define MO_RECEIVE_OVERFLOW 0x02
+#define MO_TRANSMIT_UNDERRUN 0x03
+#define MO_TRANSMIT_HEARTBEAT_FAILURE 0x04
+#define MO_TRANSMIT_CRS_LOST 0x05
+#define MO_TRANSMIT_LATE_COLLISION 0x06
+#define MO_ARRAY_SIZE 0x07
+
+// 64_bit counter
+
+typedef struct _DC21X4_LARGE_INTEGER {
+
+ ULONG LowPart;
+ ULONG HighPart;
+
+} DC21X4_LARGE_INTEGER, *PDC21X4_LARGE_INTEGER;
+
+
+// GeneralOptional counters
+
+typedef struct _GEN_OPTIONAL_COUNT{
+ DC21X4_LARGE_INTEGER ByteCount;
+ ULONG FrameCount;
+} GEN_OPTIONAL_COUNT, *PGEN_OPTIONAL_COUNT;
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+// This type defines the physical addresses used by DC21X4
+
+typedef ULONG DC21X4_PHYSICAL_ADDRESS,*PDC21X4_PHYSICAL_ADDRESS;
+
+
+// Receive descriptor
+
+typedef struct _DC21X4_RECEIVE_DESCRIPTOR {
+
+ ULONG Status; // Status bits returned upon completion
+ ULONG Control; // Control bits and byte_counts
+ DC21X4_PHYSICAL_ADDRESS FirstBufferAddress; // First Buffer Address
+ DC21X4_PHYSICAL_ADDRESS SecondBufferAddress; // Second Buffer Address
+
+ // Driver's reserved field (12 ULONG max)
+
+ struct _DC21X4_RECEIVE_DESCRIPTOR *Next; // Next Descriptor;
+ struct _RCV_HEADER *RcvHeader;
+
+} DC21X4_RECEIVE_DESCRIPTOR, *PDC21X4_RECEIVE_DESCRIPTOR;
+
+// Transmit descriptor
+
+typedef struct _DC21X4_TRANSMIT_DESCRIPTOR {
+
+ ULONG Status; // Status bits returned upon completion
+ ULONG Control; // Control bits and byte_counts
+ DC21X4_PHYSICAL_ADDRESS FirstBufferAddress; // First Buffer Address
+ DC21X4_PHYSICAL_ADDRESS SecondBufferAddress; // Second Buffer Address
+
+ // Driver's reserved field (12 ULONG max)
+
+ ULONG DescriptorPa; // Descriptor's Physical Address
+ ULONG MapTableIndex; // index into the Mapping Table
+
+ struct _DC21X4_TRANSMIT_DESCRIPTOR *Next; // Next Descriptor;
+
+ struct _DC21X4_TRANSMIT_DESCRIPTOR *DescPointer; // Pointer to the first or last segment's desc.
+
+ PNDIS_PACKET Packet; // Pointer to the packet mapped by this descriptor
+ USHORT PacketSize; // Size of the packet
+ UCHAR PacketType; // Packet Type (Directed,Multicast,...)
+ UCHAR SendStatus; // Status
+
+} DC21X4_TRANSMIT_DESCRIPTOR, *PDC21X4_TRANSMIT_DESCRIPTOR;
+
+
+#define DC21X4_MAX_MULTICAST_ADDRESSES 36 // This number is arbitrary
+ // and can be increased if needed
+
+// Number of entries in the Setup buffer.
+
+#define DC21X4_SETUP_PERFECT_ENTRIES 16
+#define DC21X4_SETUP_HASH_ENTRIES 512
+
+// Maximum number of multicast address for Perfect filtering
+// The two first addresses are reserved for the adapter and the
+// Broadcast addresses
+
+#define DC21X4_MAX_MULTICAST_PERFECT 14
+
+// Setup buffer
+//
+// In perfect filtering mode, the setup buffer
+// contains 16 Ethernet address
+// The Ethernet address, divided into three pieces in
+// order from most significant to least significant.
+// In each piece only the low-order 16 bits are used.
+// For example address A8-09-65-12-34-36 will be stored as
+// 0x000009A8
+// 0x00001265
+// 0x00007634
+//
+// In Hashing mode , the setup buffer contains
+// a single physical address and a 512_bit hash filter
+
+typedef union _DC21X4_SETUP_BUFFER {
+
+ struct {
+ ULONG PhysicalAddress[DC21X4_SETUP_PERFECT_ENTRIES][3];
+ } Perfect;
+
+ struct {
+ ULONG Filter[32];
+ ULONG Mbz1[7];
+ ULONG PhysicalAddress[3];
+ ULONG Mbz2[6];
+ } Hash;
+
+} DC21X4_SETUP_BUFFER, *PDC21X4_SETUP_BUFFER;
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+// **********************************************************************
+// DC21X4 PCI configuration space
+// **********************************************************************
+
+#define CFID 0 //ID Register
+#define CFCS 1 //Command/Status Register
+#define CFRV 2 //Revision Register
+#define CFLT 3 //Latency Timer Register
+#define CBIO 4 //Base I/O Address Register
+#define CBMA 5 //Base Memory Address Register
+#define SSID 11 //Subsystem ID Register
+#define CBER 12 //Expansion ROM Address Register
+#define CFIT 15 //Interrupt Register
+#define CFDA 16 //Driver Area register
+
+#define PCI_CONFIG_SIZE 17
+
+
+typedef struct _DC21X4_PCI_CONFIGURATION {
+
+ ULONG Reg[PCI_CONFIG_SIZE];
+
+}DC21X4_PCI_CONFIGURATION, *PDC21X4_PCI_CONFIGURATION;
+
+
+// **********************************************************************
+// DC21X4 configuration
+// Hold the values of the Registry keys
+// **********************************************************************
+
+typedef struct _DC21X4_CONFIGURATION {
+
+ BOOLEAN Present; // Registry key status
+ ULONG RegistryValue; // Registry Value
+ ULONG CsrValue; // Csr Value
+
+}DC21X4_CONFIGURATION, *PDC21X4_CONFIGURATION;
+
+
+
+
+
+
+
+
+
+
+
+
+// **********************************************************************
+// Allocation Map
+//
+// This structure holds the mapping parameters of a structure allocated
+// in memory
+// **********************************************************************
+typedef struct _ALLOCATION_MAP {
+
+ ULONG AllocVa; // virtual address of the memory block allocated to the structure
+ NDIS_PHYSICAL_ADDRESS AllocPa; // physical address of the memory block allocated to the structure
+ ULONG AllocSize; // size of the allocated block
+ ULONG Va; // virtual address of the aligned structure
+ ULONG Pa; // physical address of the aligned structure
+ ULONG Size; // size of the structure
+ PNDIS_BUFFER FlushBuffer; // NDIS Flush Buffer
+
+} ALLOCATION_MAP,*PALLOCATION_MAP;
+
+
+// **********************************************************************
+// Header for receive buffers so that we can keep track of them
+// **********************************************************************
+
+typedef struct _RCV_HEADER {
+ ALLOCATION_MAP;
+ struct _RCV_HEADER *Next; // Pointer to the next receive buffer.
+ PNDIS_PACKET Packet; // NDIS packet associated with the buffer.
+#if DBG
+ ULONG Signature; // Used to identify the receive header.
+#endif
+}RCV_HEADER,*PRCV_HEADER;
+
+#define RCV_HEADER_SIZE (sizeof(RCV_HEADER))
+
+// Reserved section for receive packets
+// that are released up to the bindings.
+
+typedef struct _RCV_PACKET_RESERVED {
+
+ PRCV_HEADER RcvHeader;
+ union {
+ PNDIS_PACKET Next;
+ PDC21X4_RECEIVE_DESCRIPTOR Descriptor;
+ };
+} RCV_PACKET_RESERVED,*PRCV_PACKET_RESERVED;
+
+#define RCV_RESERVED(x) ((PRCV_PACKET_RESERVED)(x)->MiniportReserved)
+
+#define MAX_PACKET_ARRAY 32
+
+
+
+// **********************************************************************
+// DC21X4 Physical Mapping
+//
+// Holds the physical mapping information
+// **********************************************************************
+
+typedef struct _PHYSICAL_MAPPING {
+
+ ULONG Register;
+ PNDIS_BUFFER Buffer;
+ BOOLEAN Valid;
+
+}PHYSICAL_MAPPING, *PPHYSICAL_MAPPING;
+
+// **********************************************************************
+// DC21X4 Media Table
+//
+// Holds the media programming values
+// **********************************************************************
+
+typedef struct _MEDIA_TABLE {
+
+ ULONG GeneralPurposeCtrl;
+ ULONG GeneralPurposeData;
+ ULONG SiaRegister[3];
+ ULONG Mode;
+ ULONG Polarity;
+ ULONG SenseMask;
+
+}MEDIA_TABLE, *PMEDIA_TABLE;
+
+
+// **********************************************************************
+// DC21X4 PHY Table
+//
+// Holds the PHY values
+// **********************************************************************
+
+typedef struct _PHY_TABLE {
+
+ BOOLEAN Present;
+ INT GepSequenceLength;
+ INT ResetSequenceLength;
+ USHORT MediaCapabilities;
+ USHORT NwayAdvertisement;
+ USHORT FullDuplexBits;
+ USHORT TxThresholdModeBits;
+ USHORT GeneralPurposeCtrl;
+ USHORT GepSequence[MAX_GPR_SEQUENCE];
+ UCHAR ResetSequence[MAX_RESET_SEQUENCE];
+ ULONG GepInterruptMask;
+
+}PHY_TABLE, *PPHY_TABLE;
+
+
+
+
+
+
+
+
+
+
+
+// *******************************************************************
+// DC21X4_ADAPTER
+//
+// This Adapter block contains the state of an adapter.
+// Initialized during the adapter registration.
+//
+// *******************************************************************
+
+typedef struct _DC21X4_ADAPTER {
+
+ NDIS_HANDLE MiniportAdapterHandle; // Handle given by NDIS when the adapter is registered.
+
+ NDIS_HANDLE FlushBufferPoolHandle; // Handle returned by NDIS which
+ // identifies a pool of flush buffers
+
+ NDIS_MINIPORT_INTERRUPT Interrupt; // Holds the interrupt object for this adapter.
+
+ NDIS_MINIPORT_TIMER Timer; // Holds the timer object
+ NDIS_MINIPORT_TIMER MonitorTimer;
+ NDIS_MINIPORT_TIMER ResetTimer;
+
+ UINT LinkCheckCount;
+
+ NDIS_SPIN_LOCK EnqueueSpinLock; // Send/Request SpinLock
+ NDIS_SPIN_LOCK FullDuplexSpinLock; // Send/Receive SpinLock
+
+ ULONG AdapterType; // The type of the adapter (EISA,PCI,...)
+ ULONG DeviceId; // The adapter CFID
+ ULONG SlotNumber; // The Slot Number of this adapter;
+ UINT RevisionNumber; // The Revision Number of this adapter
+
+ BOOLEAN InterruptLatched;
+ BOOLEAN PermanentAddressValid;
+ BOOLEAN FullDuplex;
+ BOOLEAN FullDuplexLink;
+ BOOLEAN DynamicAutoSense;
+ BOOLEAN DefaultMediumFlag;
+ BOOLEAN ParityError;
+ BOOLEAN ResetInProgress;
+ BOOLEAN Initializing;
+ BOOLEAN MediaNway;
+ BOOLEAN NwayEnabled;
+ BOOLEAN NwayProtocol;
+ BOOLEAN FirstAncInterrupt;
+ INT AutoNegotiationCount;
+ BOOLEAN OverflowWorkAround;
+ BOOLEAN IndicateOverflow;
+
+ UINT LinkStatus;
+ UINT PreviousLinkStatus;
+
+ ULONG LinkSpeed;
+
+ INT TransceiverDelay;
+
+ ULONG PciRegMap[DC21X4_MAX_CONFIGURATION]; // Pci Configuration Register Mapping
+ ULONG CsrMap[DC21X4_MAX_CSR]; // DC21X4 Csr Mapping
+
+ // The burnt-in network address from the hardware.
+ UCHAR PermanentNetworkAddress[ETH_LENGTH_OF_ADDRESS];
+
+ // The current network address from the hardware.
+ UCHAR CurrentNetworkAddress[ETH_LENGTH_OF_ADDRESS];
+
+ ULONG MaxMulticastAddresses;
+
+
+ ULONG CacheLineSize; // The size of the Cache lines
+
+ ULONG PciCommand;
+ ULONG PciLatencyTimer;
+ ULONG PciDriverArea;
+
+ ULONG IOBaseAddress; // Base address of the DC21X4 ports.
+ ULONG PortOffset;
+ ULONG IOSpace;
+
+ ULONG OperationMode;
+ ULONG InterruptMask;
+ ULONG BusMode;
+
+ ULONG Gep_Sia2;
+
+ UINT MediaType; // DC21X4 Connection mode
+ UINT MediaCapable;
+ INT DefaultMedium;
+ INT SelectedMedium;
+ INT MediaCount;
+
+ INT MediaPrecedence[MAX_MEDIA_TABLE]; // Hold the Media precedences
+ MEDIA_TABLE Media[MAX_MEDIA_TABLE]; // Hold the Media parameters
+
+ BOOLEAN PhyMediumInSrom; // Phy medium listed in SROM
+ BOOLEAN PhyPresent; // Phy adapter present
+ BOOLEAN PhyNwayCapable;
+ BOOLEAN Indicate10BTLink;
+ BOOLEAN Force10;
+
+ UINT PhyNumber;
+ UINT MiiMediaType; // DC21X4 MiiConnection mode
+
+ MII_GEN_INFO MiiGen; // Hold the PHY information
+ PHY_TABLE Phy[MAX_PHY_TABLE]; // Hold the PHY parameters
+
+ BOOLEAN IgnoreTimer;
+ INT TimerFlag;
+ INT PollCount;
+
+ NDIS_PHYSICAL_ADDRESS HighestAllocAddress; // Upper boundary for allocation
+
+ ULONG InterruptStatus; // Holds a value of the interrupt status
+ // (set by the ISR, cleared by the
+ // interrupt handler routine)
+
+ ULONG SiaStatus; // Holds the value of the SIA status
+
+
+ UINT DescriptorSize; // The size of a descriptor entry into the descriptor ring
+ // (Reflects bus_mode<skip_length>)
+
+ UINT FilteringMode; // Filtering mode (Perfect/Hashing)
+ UINT FilterClass; // Filter class
+
+ ALLOCATION_MAP DescriptorRing; // Descriptor Ring Allocation Map
+
+ ULONG ReceiveDescriptorRingVa; // Receive Descriptor Ring Virtual Address
+ ULONG ReceiveDescriptorRingPa; // Receive Descriptor Ring Physical Address
+ ALLOCATION_MAP RcvBufferSpace;
+
+ PDC21X4_RECEIVE_DESCRIPTOR DequeueReceiveDescriptor;
+
+ UINT ReceiveRingSize; // Receive Descriptor Ring Size
+
+ ULONG TransmitDescriptorRingVa; // Transmit Descriptor Ring Virtual Address
+ ULONG TransmitDescriptorRingPa; // Transmit Descriptor Ring Physical Address
+
+ BOOLEAN DisableTransmitPolling; // Transmit Polling Flag
+
+ ALLOCATION_MAP
+ MaxTransmitBuffer[DC21X4_NUMBER_OF_MAX_TRANSMIT_BUFFERS];
+
+ ALLOCATION_MAP
+ MinTransmitBuffer[DC21X4_NUMBER_OF_MIN_TRANSMIT_BUFFERS];
+ BOOLEAN DontUseMinTransmitBuffer;
+
+ ULONG SetupBufferVa; // Setup Buffer Virtual address
+ ULONG SetupBufferPa; // Setup Buffer Physical address
+
+ PHYSICAL_MAPPING
+ PhysicalMapping [TRANSMIT_RING_SIZE * NUMBER_OF_SEGMENT_PER_DESC];
+
+ PDC21X4_TRANSMIT_DESCRIPTOR EnqueueTransmitDescriptor;
+ PDC21X4_TRANSMIT_DESCRIPTOR DequeueTransmitDescriptor;
+ UINT FreeTransmitDescriptorCount; // Free Transmit Descriptor Count
+
+ UINT AllocMapRegisters; // Allocated Map Registers
+ UINT FreeMapRegisters; // Free Map Register count
+ UINT MapRegisterIndex;
+
+ UINT TxmThreshold; // Transmit threshold
+ ULONG Threshold10Mbps; // Threshold 10Mbps
+ ULONG Threshold100Mbps; // Threshold 100Mbps
+ ULONG TransmitDefaultDescriptorErrorMask; // Transmit Descriptor Error bit mask
+ ULONG TransmitDescriptorErrorMask; // Transmit Descriptor Error bit mask
+
+ UINT PhysicalSegmentThreshold;
+
+ UINT MaxTransmitBufferIndex; // Max Transmit Buffer Index;
+ UINT MaxTransmitBufferInUse; // Max Transmit Buffer Count;
+
+ UINT MinTransmitBufferIndex; // Min Transmit Buffer Index;
+ UINT MinTransmitBufferInUse; // Min Transmit Buffer Count;
+
+ UINT NoCarrierCount;
+ UINT ExcessCollisionsCount;
+ UINT UnderrunRetryCount;
+ UINT UnderrunMaxRetries;
+ UINT UnderrunThreshold;
+
+
+ ULONG InterruptModeration;
+ ULONG Polling;
+ ULONG TxmPolling;
+ ULONG RcvTxmPolling;
+
+ INT InterruptThreshold;
+ INT InterruptCount;
+ INT LastInterruptCount;
+
+ INT FrameThreshold;
+ INT FrameCount;
+
+ ULONG TiPeriod; // Transmit Interrupt period
+ ULONG TiCount; // Transmit interrupt period counter
+
+ ULONG SoftwareCRC; // CRC Sofware generation mode
+
+ INT TransmitFrameCount; // Holds the last snapshoted Txm frame count
+ INT ReceiveFrameCount; // Holds the last snapshoted Rcv frame count
+
+ ULONG LinkHandlerMode;
+
+
+ UINT RcvHeaderSize;
+
+ // Information for releasing of the receive buffers.
+
+ NDIS_HANDLE ReceivePacketPool;
+ ULONG ExtraReceivePackets;
+ PNDIS_PACKET FreePacketList;
+ PNDIS_PACKET PacketArray[MAX_PACKET_ARRAY];
+
+ ULONG ExtraReceiveBuffers;
+ PRCV_HEADER FreeRcvList;
+ ULONG CurrentReceiveBufferCount;
+ ULONG NeededReceiveBuffers;
+
+
+ // Adapter statistics
+
+ ULONG GeneralMandatory[GM_ARRAY_SIZE];
+
+ GEN_OPTIONAL_COUNT GeneralOptionalCount[GO_COUNT_ARRAY_SIZE];
+
+ ULONG GeneralOptional[GO_ARRAY_SIZE];
+
+ ULONG MediaMandatory[MM_ARRAY_SIZE];
+ ULONG MediaOptional[MO_ARRAY_SIZE];
+
+
+} DC21X4_ADAPTER,*PDC21X4_ADAPTER;
+
+// **********************************************************************
+// DC21X4_SYNCH_CONTEXT
+//
+//Context structure while synchronizing with interrupt
+//
+// **********************************************************************
+
+typedef struct _DC21X4_SYNCH_CONTEXT {
+
+ PDC21X4_ADAPTER Adapter;
+ ULONG IsrStatus;
+
+} DC21X4_SYNCH_CONTEXT,*PDC21X4_SYNCH_CONTEXT;
+
+// **********************************************************************
+// CHECKSUM structure
+//
+// Structure for holding checksum and its status when reading the SROM.
+//
+// **********************************************************************
+
+typedef struct _CHECKSUM
+{
+ USHORT Accumulator;
+ USHORT Value;
+ UCHAR Status;
+} CHECKSUM, *PCHECKSUM;
+
+
+
+
+
+
+
+
+
+
+
+
+// Macros used for memory allocation and deallocation.
+
+#define ALLOC_MEMORY(Status, Address, Length) { \
+ \
+ NDIS_PHYSICAL_ADDRESS HighestAddress; \
+ NdisSetPhysicalAddressLow(HighestAddress,0xffffffff); \
+ NdisSetPhysicalAddressHigh(HighestAddress,0xffffffff); \
+ *(Status) = NdisAllocateMemory((PVOID)(Address), \
+ (UINT)(Length), \
+ 0, \
+ HighestAddress \
+ ); \
+}
+
+#define FREE_MEMORY(Address, Length) \
+ \
+ NdisFreeMemory((PVOID)(Address), \
+ (UINT)(Length), \
+ 0 \
+ )
+
+#define MOVE_MEMORY(Destination,Source,Length) \
+ \
+ NdisMoveMemory((PVOID)(Destination), \
+ (PVOID)(Source), \
+ (ULONG)(Length) \
+ ) \
+
+#define ZERO_MEMORY(Destination,Length) \
+ \
+ NdisZeroMemory((PVOID)(Destination), \
+ (ULONG)(Length) \
+ )
+
+
+// 64_bit counter addition
+
+#define ADD_ULONG_TO_LARGE_INTEGER(LargeInteger,Ulong ) { \
+ (LargeInteger).LowPart += (Ulong); \
+ if ((LargeInteger).LowPart < (Ulong)) \
+ (LargeInteger).HighPart++; \
+}
+
+//Frame type
+
+#define IS_MULTICAST(_addr) \
+ ((*(UNALIGNED UCHAR *)(_addr) & 1) == 1)
+
+#define IS_BROADCAST(_addr) \
+ ( (*(UNALIGNED ULONG *)(_addr) == 0xffffffff) && \
+ (*(UNALIGNED USHORT *)((UINT)(_addr) + 4) == 0xffff) \
+ )
+
+#define CHECK_PACKET_TYPE(dst) \
+ ( IS_MULTICAST(dst) ? \
+ ( IS_BROADCAST(dst) ? TXM_BROADCAST_FRAME : \
+ TXM_MULTICAST_FRAME) : TXM_DIRECTED_FRAME \
+ )
+
+#define IS_NULL_ADDRESS(_addr) \
+ ( (*(UNALIGNED ULONG *)(_addr) == 0) && \
+ (*(UNALIGNED USHORT *)((UINT)(_addr) + 4) == 0) \
+ )
diff --git a/private/ntos/ndis/dc21x4/d21x4det.h b/private/ntos/ndis/dc21x4/d21x4det.h
new file mode 100644
index 000000000..02650ce8c
--- /dev/null
+++ b/private/ntos/ndis/dc21x4/d21x4det.h
@@ -0,0 +1,80 @@
+/*
+ * file: d21x4det.h
+ *
+ * Copyright (C) 1992-1995,1992-1995 by
+ * Digital Equipment Corporation, Maynard, Massachusetts.
+ * All rights reserved.
+ *
+ * This software is furnished under a license and may be used and copied
+ * only in accordance of the terms of such license and with the
+ * inclusion of the above copyright notice. This software or any other
+ * copies thereof may not be provided or otherwise made available to any
+ * other person. No title to and ownership of the software is hereby
+ * transferred.
+ *
+ * The information in this software is subject to change without notice
+ * and should not be construed as a commitment by digital equipment
+ * corporation.
+ *
+ * Digital assumes no responsibility for the use or reliability of its
+ * software on equipment which is not supplied by digital.
+ *
+ *
+ * Abstract:
+ * NDIS 4.0 miniport driver for DEC's DC21X4 Ethernet Adapter
+ * family.
+ *
+ * Author: Philippe Klein
+ *
+ * Revision History:
+ *
+ * phk 28-Aug-1994 Initial entry
+ *
+-*/
+
+
+
+#define DC21X4_WRITE_PORT(_Port, _Value) { \
+ \
+ NdisRawWritePortUlong( \
+ Adapter->CsrMap[(_Port)], \
+ (ULONG)(_Value) \
+ ); \
+}
+
+#define DC21X4_READ_PORT(_Port, _Value) { \
+ \
+ NdisRawReadPortUlong( \
+ Adapter->CsrMap[(_Port)], \
+ (PULONG)(_Value) \
+ ); \
+}
+
+#define DC21X4_WRITE_PCI_REGISTER(_Reg, _Value) { \
+ \
+ NdisRawWritePortUlong( \
+ Adapter->PciRegMap[_Reg], \
+ (ULONG)(_Value) \
+ ); \
+}
+
+#define DC21X4_READ_PCI_REGISTER(_Reg, _Value) { \
+ \
+ NdisRawReadPortUlong( \
+ Adapter->PciRegMap[_Reg], \
+ (PULONG)(_Value) \
+ ); \
+}
+
+#define DC21X4_INTERRUPT_LEVEL_DEFAULT 5
+#define DC21X4_INTERRUPT_MODE_DEFAULT NdisInterruptLevelSensitive
+#define DC21X4_ADAPTER_TYPE_DEFAULT NdisInterfaceEisa
+
+// Intel PCI memory controller
+
+#define PCI_CDC_CFID 0x04838086
+#define PCI_PCMC_CFID 0x04A38086
+
+#define PCI_HBC_OFFSET 0x53
+#define PCI_HBC_HPPE 0x02
+
diff --git a/private/ntos/ndis/dc21x4/d21x4fct.h b/private/ntos/ndis/dc21x4/d21x4fct.h
new file mode 100644
index 000000000..9978f54f7
--- /dev/null
+++ b/private/ntos/ndis/dc21x4/d21x4fct.h
@@ -0,0 +1,809 @@
+/*+
+ * file: d21x4fct.h
+ *
+ * Copyright (C) 1992-1995 by
+ * Digital Equipment Corporation, Maynard, Massachusetts.
+ * All rights reserved.
+ *
+ * This software is furnished under a license and may be used and copied
+ * only in accordance of the terms of such license and with the
+ * inclusion of the above copyright notice. This software or any other
+ * copies thereof may not be provided or otherwise made available to any
+ * other person. No title to and ownership of the software is hereby
+ * transferred.
+ *
+ * The information in this software is subject to change without notice
+ * and should not be construed as a commitment by digital equipment
+ * corporation.
+ *
+ * Digital assumes no responsibility for the use or reliability of its
+ * software on equipment which is not supplied by digital.
+ *
+ *
+ * Abstract: This file contains the functions prototyping for the
+ * NDIS 4.0 miniport driver for DEC's DC21X4 Ethernet controler
+ *
+ * Author: Philippe Klein
+ *
+ * Revision History:
+ *
+ * phk 28-Aug-1994 Initial entry
+ *
+-*/
+
+// DC21X4.C
+
+NTSTATUS
+DriverEntry(
+ IN PDRIVER_OBJECT DriverObject,
+ IN PUNICODE_STRING RegistryPath
+ );
+
+
+// ALLOC.C
+
+extern
+BOOLEAN
+AllocateAdapterMemory(
+ IN PDC21X4_ADAPTER Adapter
+ );
+
+extern
+VOID
+FreeAdapterMemory(
+ IN PDC21X4_ADAPTER Adapter
+ );
+
+VOID
+AlignStructure (
+ IN PALLOCATION_MAP Map,
+ IN UINT Boundary
+ );
+
+
+VOID
+DC21X4AllocateComplete(
+ IN NDIS_HANDLE MiniportAdapterContext,
+ IN PVOID VirtualAddress,
+ IN PNDIS_PHYSICAL_ADDRESS PhysicalAddress,
+ IN ULONG Length,
+ IN PVOID Context
+ );
+
+
+// COPY.C
+
+extern
+VOID
+CopyFromPacketToBuffer (
+ IN PNDIS_PACKET Packet,
+ IN UINT Offset,
+ IN PCHAR Buffer,
+ IN UINT BytesToCopy,
+ OUT PUINT BytesCopied
+ );
+
+
+// FILTER.C
+
+extern
+VOID
+DC21X4InitializeCam (
+ IN PDC21X4_ADAPTER Adapter,
+ IN PUSHORT Address
+ );
+
+extern
+BOOLEAN
+DC21X4LoadCam (
+ IN PDC21X4_ADAPTER Adapter,
+ IN BOOLEAN InterruptMode
+ );
+
+extern
+NDIS_STATUS
+DC21X4ChangeFilter (
+ IN PDC21X4_ADAPTER Adapter,
+ IN ULONG NewFilterClass
+ );
+
+VOID
+AddBroadcastToSetup (
+ IN PDC21X4_ADAPTER Adapter
+ );
+
+VOID
+RemoveBroadcastFromSetup (
+ IN PDC21X4_ADAPTER Adapter
+ );
+
+extern
+NDIS_STATUS
+DC21X4ChangeMulticastAddresses(
+ IN PDC21X4_ADAPTER Adapter,
+ IN PVOID MulticastAddresses,
+ IN UINT AddressCount
+ );
+
+// INIT.C
+
+extern
+VOID
+DC21X4InitializeRegisters(
+ IN PDC21X4_ADAPTER Adapter
+ );
+
+extern
+VOID
+DC21X4StopAdapter(
+ IN PDC21X4_ADAPTER Adapter
+ );
+
+extern
+VOID
+DC21X4StartAdapter(
+ IN PDC21X4_ADAPTER Adapter
+ );
+
+extern
+VOID
+DC21X4WriteGepRegister(
+ IN PDC21X4_ADAPTER Adapter,
+ IN ULONG Data
+ );
+
+extern
+VOID
+DC21X4InitializeGepRegisters(
+ IN PDC21X4_ADAPTER Adapter,
+ IN BOOLEAN Phy
+ );
+
+extern
+VOID
+DC21X4InitializeMediaRegisters(
+ IN PDC21X4_ADAPTER Adapter,
+ IN BOOLEAN Phy
+ );
+
+extern
+VOID
+DC2104InitializeSiaRegisters(
+ IN PDC21X4_ADAPTER Adapter
+ );
+
+extern
+VOID
+DC21X4InitPciConfigurationRegisters(
+ IN PDC21X4_ADAPTER Adapter
+ );
+
+
+extern
+VOID
+DC21X4StopReceiverAndTransmitter(
+ IN PDC21X4_ADAPTER Adapter
+ );
+
+// INTERRUP.C;
+
+extern
+VOID
+DC21X4Isr(
+ OUT PBOOLEAN InterruptRecognized,
+ OUT PBOOLEAN QueueMiniportHandleInterrupt,
+ IN NDIS_HANDLE MiniportAdapterContext
+ );
+
+VOID
+DC21X4SynchClearIsr(
+ IN PDC21X4_SYNCH_CONTEXT SyncContext
+ );
+
+VOID
+DC21X4HandleInterrupt(
+ IN NDIS_HANDLE MiniportAdapterContext
+ );
+
+VOID
+HandleGepInterrupt(
+ IN PDC21X4_ADAPTER Adapter
+ );
+
+VOID
+HandleLinkPassInterrupt(
+ IN PDC21X4_ADAPTER Adapter,
+ IN OUT PULONG IsrStatus
+ );
+
+VOID
+HandleLinkFailInterrupt(
+ IN PDC21X4_ADAPTER Adapter,
+ IN OUT PULONG IsrStatus
+ );
+
+
+VOID
+SwitchMediumToTpNway(
+ IN PDC21X4_ADAPTER Adapter
+ );
+
+PDC21X4_RECEIVE_DESCRIPTOR
+ProcessReceiveDescRing(
+ IN PDC21X4_ADAPTER Adapter
+ );
+
+PDC21X4_TRANSMIT_DESCRIPTOR
+ProcessTransmitDescRing(
+ IN PDC21X4_ADAPTER Adapter
+ );
+
+extern
+VOID
+DC21X4EnableInterrupt(
+ IN NDIS_HANDLE MiniportAdapterContext
+ );
+
+extern
+VOID
+DC21X4DisableInterrupt(
+ IN NDIS_HANDLE MiniportAdapterContext
+ );
+
+
+extern
+NDIS_STATUS
+DC21X4ReturnPacket(
+ IN NDIS_HANDLE MiniportAdapterContext,
+ IN PNDIS_PACKET Packet
+ );
+
+
+// MEDIA.C
+
+extern
+BOOLEAN
+DC21X4MediaDetect(
+ IN PDC21X4_ADAPTER Adapter
+ );
+
+extern
+BOOLEAN
+DC2114Sense100BaseTxLink(
+ IN PDC21X4_ADAPTER Adapter
+ );
+
+extern
+VOID
+DC21X4DynamicAutoSense (
+ IN PVOID Systemspecific1,
+ IN PDC21X4_ADAPTER Adapter,
+ IN PVOID Systemspecific2,
+ IN PVOID Systemspecific3
+ );
+
+extern
+BOOLEAN
+DC21X4AutoSense (
+ IN PDC21X4_ADAPTER Adapter
+ );
+
+extern
+VOID
+DC21X4SwitchMedia(
+ IN PDC21X4_ADAPTER Adapter,
+ IN LONG NextMedia
+ );
+
+extern
+VOID
+DC21X4StartAutoSenseTimer(
+ IN PDC21X4_ADAPTER Adapter,
+ IN UINT Value
+ );
+
+extern
+VOID
+DC21X4StopAutoSenseTimer(
+ IN PDC21X4_ADAPTER Adapter
+ );
+
+extern
+VOID
+DC21X4EnableNway(
+ IN PDC21X4_ADAPTER Adapter
+ );
+
+extern
+VOID
+DC21X4DisableNway(
+ IN PDC21X4_ADAPTER Adapter
+ );
+
+
+extern
+VOID
+DC21X4IndicateMediaStatus(
+ IN PDC21X4_ADAPTER Adapter,
+ IN UINT Status
+ );
+
+
+// MACTOPHY.C
+
+extern
+BOOLEAN
+DC21X4PhyInit(
+ IN PDC21X4_ADAPTER Adapter
+);
+
+
+extern
+BOOLEAN
+DC21X4SetPhyConnection(
+ IN PDC21X4_ADAPTER Adapter
+);
+
+
+void
+SetMacConnection(
+ IN PDC21X4_ADAPTER Adapter
+);
+
+
+extern
+BOOLEAN
+DC21X4MiiAutoDetect(
+ IN PDC21X4_ADAPTER Adapter
+);
+
+
+extern
+BOOLEAN
+DC21X4MiiAutoSense(
+ IN PDC21X4_ADAPTER Adapter
+);
+
+
+extern
+VOID
+SelectNonMiiPort(
+ IN PDC21X4_ADAPTER Adapter
+);
+
+extern
+VOID
+DC21X4SetPhyControl(
+ PDC21X4_ADAPTER Adapter,
+ USHORT AdminControl
+);
+
+
+// MIIGEN.C
+
+extern
+BOOLEAN
+MiiGenInit(
+ IN PDC21X4_ADAPTER Adapter
+);
+
+extern
+BOOLEAN
+FindAndInitMiiPhys(
+ IN PDC21X4_ADAPTER Adapter
+);
+
+extern
+USHORT
+MiiGenGetCapabilities(
+ PDC21X4_ADAPTER Adapter
+);
+
+extern
+BOOLEAN
+MiiGenCheckConnection(
+ PDC21X4_ADAPTER Adapter,
+ USHORT Connection
+);
+
+extern
+BOOLEAN
+MiiGenSetConnection(
+ PDC21X4_ADAPTER Adapter,
+ UINT Connection,
+ USHORT NwayAdvertisement
+);
+
+
+extern
+BOOLEAN
+MiiGenGetConnectionStatus (
+ PDC21X4_ADAPTER Adapter,
+ PUSHORT ConnectionStatus
+);
+
+
+extern
+BOOLEAN
+MiiGenGetConnection(
+ PDC21X4_ADAPTER Adapter,
+ PUSHORT Connection
+);
+
+extern
+void
+MiiGenAdminStatus(
+ PDC21X4_ADAPTER Adapter,
+ PUSHORT AdminStatus
+);
+
+
+extern
+BOOLEAN
+MiiGenAdminControl(
+ PDC21X4_ADAPTER Adapter,
+ USHORT AdminControl
+);
+
+
+void
+MiiFreeResources(
+ PDC21X4_ADAPTER Adapter
+);
+
+// MIIPHY.C
+
+BOOLEAN
+MiiPhyInit(
+ PDC21X4_ADAPTER Adapter,
+ PMII_PHY_INFO PhyInfoPtr
+ );
+
+void
+MiiPhyGetCapabilities(
+ PMII_PHY_INFO PhyInfoPTR,
+ PCAPABILITY Capabilities
+ );
+
+BOOLEAN
+MiiPhySetConnectionType(
+ PDC21X4_ADAPTER Adapter,
+ PMII_PHY_INFO PhyInfoPtr,
+ USHORT Connection,
+ USHORT Advertisement
+ );
+
+BOOLEAN
+MiiPhyGetConnectionType(
+ PDC21X4_ADAPTER Adapter,
+ PMII_PHY_INFO PhyInfoPtr,
+ PUSHORT ConnectionStatus
+ );
+
+BOOLEAN
+MiiPhyGetConnectionStatus(
+ PDC21X4_ADAPTER Adapter,
+ PMII_PHY_INFO PhyInfoPtr,
+ PUSHORT ConnectionStatus
+ );
+
+void
+MiiPhyAdminStatus(
+ PDC21X4_ADAPTER Adapter,
+ PMII_PHY_INFO PhyInfoPtr,
+ PMII_STATUS Status
+ );
+
+void
+MiiPhyAdminControl(
+ PDC21X4_ADAPTER Adapter,
+ PMII_PHY_INFO PhyInfoPtr,
+ MII_STATUS Control
+ );
+
+BOOLEAN
+MiiPhyReadRegister(
+ PDC21X4_ADAPTER Adapter,
+ PMII_PHY_INFO PhyInfoPtr,
+ USHORT RegNum,
+ PUSHORT Register
+ );
+
+void
+MiiPhyWriteRegister(
+ PDC21X4_ADAPTER Adapter,
+ PMII_PHY_INFO PhyInfoPtr,
+ USHORT RegNum,
+ USHORT Register
+ );
+
+void
+MiiPhyNwayGetLocalAbility(
+ PDC21X4_ADAPTER Adapter,
+ PMII_PHY_INFO PhyInfoPtr,
+ PCAPABILITY Ability
+ );
+
+void
+MiiPhyNwaySetLocalAbility(
+ PDC21X4_ADAPTER Adapter,
+ PMII_PHY_INFO PhyInfoPtr,
+ USHORT MediaBits
+ );
+
+void
+MiiPhyNwayGetPartnerAbility(
+ PDC21X4_ADAPTER Adapter,
+ PMII_PHY_INFO PhyInfoPtr,
+ PCAPABILITY Ability
+ );
+
+
+BOOLEAN
+FindMiiPhyDevice(
+ PDC21X4_ADAPTER Adapter,
+ PMII_PHY_INFO PhyInfoPtr
+ );
+
+void
+WriteMii(
+ PDC21X4_ADAPTER Adapter,
+ ULONG MiiData,
+ INT DataSize
+ );
+
+void
+MiiOutThreeState(
+ PDC21X4_ADAPTER Adapter
+);
+
+void
+InitPhyInfoEntries(
+ PMII_PHY_INFO PhyInfoPtr
+ );
+
+void
+ConvertConnectionToControl(
+ PMII_PHY_INFO PhyInfoPtr,
+ PUSHORT Connection
+ );
+
+void
+ConvertMediaTypeToNwayLocalAbility(
+ USHORT MediaType,
+ PCAPABILITY NwayLocalAbility
+ );
+
+BOOLEAN
+ConvertNwayToConnectionType(
+ CAPABILITY NwayReg,
+ PUSHORT Connection
+ );
+
+BOOLEAN
+CheckConnectionSupport(
+ PMII_PHY_INFO PhyInfoPtr,
+ USHORT ConCommand
+ );
+
+
+extern
+BOOLEAN
+GetBroadcomPhyConnectionType(
+ PDC21X4_ADAPTER Adapter,
+ PMII_PHY_INFO PhyInfoPtr,
+ PUSHORT Connection
+ );
+
+void
+HandleBroadcomMediaChangeFrom10To100(
+ PDC21X4_ADAPTER Adapter,
+ PMII_PHY_INFO PhyInfoPtr
+ );
+
+
+// MONITOR.C
+
+extern
+VOID
+DC21X4ModerateInterrupt (
+ IN PVOID Systemspecific1,
+ IN PDC21X4_ADAPTER Adapter,
+ IN PVOID Systemspecific2,
+ IN PVOID Systemspecific3
+ );
+
+
+extern
+BOOLEAN
+DC21X4CheckforHang(
+ IN NDIS_HANDLE MiniportAdapterContext
+ );
+
+
+// REGISTER.C
+
+extern
+NDIS_STATUS
+DC21X4Initialize(
+ OUT PNDIS_STATUS OpenErrorStatus,
+ OUT PUINT SelectedMediumIndex,
+ IN PNDIS_MEDIUM MediumArray,
+ IN UINT MediumArraySize,
+ IN NDIS_HANDLE MiniportAdapterHandle,
+ IN NDIS_HANDLE ConfigurationHandle
+ );
+
+extern
+VOID
+FreeAdapterResources(
+ IN PDC21X4_ADAPTER Adapter,
+ IN INT Step
+ );
+
+NDIS_STATUS
+FindPciConfiguration(
+ IN NDIS_HANDLE MiniportAdapterHandle,
+ IN ULONG SlotNumber,
+ OUT PULONG PortStart,
+ OUT PULONG PortLength,
+ OUT PULONG InterruptLevel,
+ OUT PULONG InterruptVector
+ );
+
+extern
+VOID
+DC21X4Halt(
+ IN NDIS_HANDLE MiniportAdapterContext
+ );
+
+extern
+VOID
+DC21X4Shutdown(
+ IN PVOID ShutdownContext
+ );
+
+#if _MIPS_
+
+NTSTATUS
+DC21X4HardwareSaveInformation(
+ IN PWSTR ValueName,
+ IN ULONG ValueType,
+ IN PVOID ValueData,
+ IN ULONG ValueLength,
+ IN PVOID Context,
+ IN PVOID EntryContext
+ );
+
+BOOLEAN
+DC21X4HardwareVerifyChecksum(
+ IN PDC21X4_ADAPTER Adapter,
+ IN PUCHAR EthernetAddress
+ );
+
+NDIS_STATUS
+DC21X4HardwareGetDetails(
+ IN PDC21X4_ADAPTER Adapter,
+ IN UINT Controller,
+ IN UINT MultifunctionAdapter
+ );
+
+#endif
+
+
+// REQUEST.C
+
+extern
+NDIS_STATUS
+DC21X4QueryInformation(
+ IN NDIS_HANDLE MiniportAdapterContext,
+ IN NDIS_OID Oid,
+ IN PVOID InformationBuffer,
+ IN ULONG InformationBufferLength,
+ OUT PULONG BytesWritten,
+ OUT PULONG BytesNeeded
+ );
+
+extern
+NDIS_STATUS
+DC21X4SetInformation(
+ IN NDIS_HANDLE MiniportAdapterContext,
+ IN NDIS_OID Oid,
+ IN PVOID InformationBuffer,
+ IN ULONG InformationBufferLength,
+ OUT PULONG BytesRead,
+ OUT PULONG BytesNeeded
+ );
+
+// RESET.C
+
+extern
+NDIS_STATUS
+DC21X4Reset(
+ OUT PBOOLEAN AddressingReset,
+ IN NDIS_HANDLE MiniportAdapterContext
+ );
+
+extern
+VOID
+DC21X4DeferredReset(
+ IN PVOID Systemspecific1,
+ IN PDC21X4_ADAPTER Adapter,
+ IN PVOID Systemspecific2,
+ IN PVOID Systemspecific3
+ );
+
+// SEND.C
+
+extern
+NDIS_STATUS
+DC21X4Send(
+ IN NDIS_HANDLE MiniportAdapterContext,
+ IN PNDIS_PACKET Packet,
+ IN UINT Flags
+ );
+
+
+extern
+NDIS_STATUS
+DC21X4SendPackets(
+ IN NDIS_HANDLE MiniportAdapterContext,
+ IN PPNDIS_PACKET PacketArray,
+ IN UINT NumberOfPackets
+ );
+
+
+extern
+ULONG
+CRC32 (
+ IN PUCHAR Data,
+ IN UINT Len
+ );
+
+//SROM.C
+
+extern
+NDIS_STATUS
+DC21X4ReadSerialRom (
+ IN PDC21X4_ADAPTER Adapter
+ );
+
+BOOLEAN
+VerifyChecksum(
+ IN UNALIGNED UCHAR *EthAddress
+ );
+
+NDIS_STATUS
+DC21X4ParseSRom(
+ IN PDC21X4_ADAPTER Adapter
+ );
+
+extern
+VOID
+DC21X4ParseExtendedBlock(
+ IN PDC21X4_ADAPTER Adapter,
+ IN OUT UNALIGNED UCHAR **MediaBlock,
+ IN USHORT GeneralPurposeCtrl,
+ OUT PUCHAR PMediaCode
+ );
+
+extern
+VOID
+DC21X4ParseFixedBlock(
+ IN PDC21X4_ADAPTER Adapter,
+ IN OUT UNALIGNED UCHAR **MediaBlock,
+ IN USHORT GeneralPurposeCtrl,
+ OUT PUCHAR PMediaCode
+ );
+
+BOOLEAN
+DC21X4ReadSRom(
+ IN PDC21X4_ADAPTER Adapter,
+ IN OUT PULONG Offset,
+ IN USHORT Len,
+ OUT PUCHAR Buffer
+ );
+
+
+
+
diff --git a/private/ntos/ndis/dc21x4/d21x4hrd.h b/private/ntos/ndis/dc21x4/d21x4hrd.h
new file mode 100644
index 000000000..35fdba3fc
--- /dev/null
+++ b/private/ntos/ndis/dc21x4/d21x4hrd.h
@@ -0,0 +1,828 @@
+/*
+ * file: d21x4hrd.h
+ *
+ * Copyright (C) 1992-1995 by
+ * Digital Equipment Corporation, Maynard, Massachusetts.
+ * All rights reserved.
+ *
+ * This software is furnished under a license and may be used and copied
+ * only in accordance of the terms of such license and with the
+ * inclusion of the above copyright notice. This software or any other
+ * copies thereof may not be provided or otherwise made available to any
+ * other person. No title to and ownership of the software is hereby
+ * transferred.
+ *
+ * The information in this software is subject to change without notice
+ * and should not be construed as a commitment by digital equipment
+ * corporation.
+ *
+ * Digital assumes no responsibility for the use or reliability of its
+ * software on equipment which is not supplied by digital.
+ *
+ *
+ * Abstract: This file contains the hardware related definitions for the
+ * DEC's DC21X4 NDIS 4.0 miniport driver
+ *
+ * Author: Philippe Klein
+ *
+ * Revision History:
+ *
+ * phk 28-Aug-1994 Initial entry
+ *
+ *
+-*/
+
+
+
+
+
+
+
+
+
+
+// Adapter ID & revisions
+
+#define DC21040_CFID 0x00021011
+#define DC21040_REV1 0x00
+#define DC21040_REV2_0 0x20
+#define DC21040_REV2_2 0x22
+
+
+#define DC21041_CFID 0x00141011
+#define DC21041_REV1_0 0x10
+#define DC21041_REV1_1 0x11
+#define DC21041_REV2_0 0x20
+
+#define DC21140_CFID 0x00091011
+#define DC21140_REV1_1 0x11
+#define DC21140_REV1_2 0x12
+#define DC21140_REV2_0 0x20
+#define DC21140_REV2_1 0x21
+#define DC21140_REV2_2 0x22
+
+#define DC21142_CFID 0x00191011
+#define DC21142_REV1 0x10
+#define DC21142_REV1_0 0x10
+#define DC21142_REV1_1 0x11
+
+
+typedef enum _CFID_INDEX {
+ DefaultCfidIndex,
+ DC21040CfidIndex,
+ DC21041CfidIndex,
+ DC21140CfidIndex,
+ MAX_CFIDS
+} CFID_INDEX;
+
+
+#define DE425_COMPRESSED_ID 0x5042A310 //"DEC4250"
+#define DC21X4_INTERRUPT_LEVEL_SENSITIVE 0
+#define DC21X4_INTERRUPT_LATCHED 1
+
+// Media types
+
+typedef enum _MEDIA_TYPE {
+ Medium10BaseT,
+ Medium10Base2,
+ Medium10Base5,
+ Medium100BaseTx,
+ Medium10BaseTFd,
+ Medium100BaseTxFd,
+ Medium100BaseT4,
+ Medium100BaseFx,
+ Medium100BaseFxFd,
+ MAX_MEDIA_TABLE
+} MEDIA_TYPE;
+
+#define Medium10Base2_5 0xff
+
+
+// PHY Media
+
+typedef enum _PHY_MEDIA_TYPE {
+ MediumMii10BaseT=MAX_MEDIA_TABLE,
+ MediumMii10BaseTFd,
+ MediumMii10Base2,
+ MediumMii10Base5,
+ MediumMii100BaseTx,
+ MediumMii100BaseTxFd,
+ MediumMii100BaseT4,
+ MediumMii100BaseFx,
+ MediumMii100BaseFxFd,
+ MAX_PHY_MEDIA
+} PHY_MEDIA_TYPE;
+
+
+#define MEDIA_MASK 0x00ff
+#define CONTROL_MASK 0xFF00
+
+// Media modes
+
+#define MEDIA_NWAY 0x0100
+#define MEDIA_FULL_DUPLEX 0x0200
+#define MEDIA_LINK_DISABLE 0x0400
+#define MEDIA_AUTOSENSE 0x0800
+
+#define MediaAutoSense (MEDIA_AUTOSENSE | MEDIA_NWAY)
+#define MediaAutoSenseNoNway (MEDIA_AUTOSENSE)
+
+#define Medium10BaseTNway (Medium10BaseT | MEDIA_NWAY)
+#define Medium10BaseTFullDuplex (Medium10BaseTFd | MEDIA_FULL_DUPLEX)
+#define Medium10BaseTLinkDisable (Medium10BaseT | MEDIA_LINK_DISABLE)
+
+#define Medium100BaseTxFullDuplex (Medium100BaseTxFd | MEDIA_FULL_DUPLEX)
+
+
+#define MediumMii10BaseTFullDuplex (MediumMii10BaseTFd | MEDIA_FULL_DUPLEX)
+#define MediumMii100BaseTxFullDuplex (MediumMii100BaseTxFd | MEDIA_FULL_DUPLEX)
+#define MediaMiiAutoSense (MediumMii10BaseT | MEDIA_AUTOSENSE)
+
+
+// Media Capable mask
+
+#define MEDIUM_10BT (1<<Medium10BaseT)
+#define MEDIUM_10B2 (1<<Medium10Base2)
+#define MEDIUM_10B5 (1<<Medium10Base5)
+#define MEDIUM_100BTX (1<<Medium100BaseTx)
+
+//Default Cache Line Size (in bytes)
+#define DC21X4_DEFAULT_CACHE_LINE_SIZE 64
+
+//DC21X4 Register index
+
+//PCI Configuration registers
+
+#define DC21X4_PCI_ID 0
+#define DC21X4_PCI_COMMAND 1
+#define DC21X4_PCI_REVISION 2
+#define DC21X4_PCI_LATENCY_TIMER 3
+#define DC21X4_PCI_BASE_IO_ADDRESS 4
+#define DC21X4_PCI_INTERRUPT 5
+#define DC21X4_PCI_DRIVER_AREA 6
+
+#define DC21X4_MAX_CONFIGURATION 7
+
+//Command & Status Registers
+
+#define DC21X4_BUS_MODE 0
+#define DC21X4_TXM_POLL_DEMAND 1
+#define DC21X4_RCV_POLL_DEMAND 2
+#define DC21X4_RCV_DESC_RING 3
+#define DC21X4_TXM_DESC_RING 4
+#define DC21X4_STATUS 5
+#define DC21X4_OPERATION_MODE 6
+#define DC21X4_INTERRUPT_MASK 7
+#define DC21X4_MISSED_FRAME 8
+#define DC21X4_IDPROM 9
+#define DC21X4_RESERVED 10
+#define DC21X4_TIMER 11
+#define DC21X4_SIA_STATUS 12
+#define DC21X4_GEN_PURPOSE 12
+#define DC21X4_SIA_MODE_0 13
+#define DC21X4_SIA_MODE_1 14
+#define DC21X4_SIA_MODE_2 15
+#define DC21X4_MAX_CSR 16
+
+
+//EISA Mapping
+
+#define EISA_REG0_OFFSET 0xc88
+#define EISA_REG1_OFFSET 0xc89
+
+#define EISA_CFGSCR1_OFFSET 0x8C
+#define EISA_CFGSCR2_OFFSET 0x98
+
+#define EISA_CFID_OFFSET 0x08
+#define EISA_CFCS_OFFSET 0x0c
+#define EISA_CFRV_OFFSET 0x18
+#define EISA_CFLT_OFFSET 0x1C
+#define EISA_CBIO_OFFSET 0x28
+
+#define EISA_CSR_OFFSET 0x10
+
+#define EISA_ID_PROM_OFFSET 0xc90
+
+#define EISA_DC21040_REGISTER_SPACE 240
+#define EISA_DC21140_REGISTER_SPACE 240
+
+//PCI mapping
+
+#define PCI_CFID_OFFSET 0x00
+#define PCI_CFCS_OFFSET 0x04
+#define PCI_CFRV_OFFSET 0x08
+#define PCI_CFLT_OFFSET 0x0C
+#define PCI_CBIO_OFFSET 0x10
+#define PCI_CFIT_OFFSET 0x3C
+#define PCI_CFDA_OFFSET 0x40
+
+#define PCI_CSR_OFFSET 0x08
+
+# define SLOT_NUMBER_OFFSET 12
+# define IRQ_BIT_NUMBER 1
+
+
+//Constants for the CONFIG_ID register
+
+#define DC21X4_DEVICE_ID ((ULONG)(0x0000FFFF))
+#define DC21X4_VENDOR_ID ((ULONG)(0xFFFF0000))
+
+//Constants for the CONFIG_COMMAND register
+
+#define DC21X4_MEMORY_SPACE_ACCESS ((ULONG)(0x00000001))
+#define DC21X4_MASTER_OPERATION ((ULONG)(0x00000002))
+#define DC21X4_PARITY_ERROR_RESPONSE ((ULONG)(0x00000004))
+#define DC21X4_DEVSEL_TIMING ((ULONG)(0x00000008))
+
+#define DC21X4_PCI_COMMAND_DEFAULT_VALUE 0x05 // Parity Response = 0
+ // Master Operation = 1
+ // Memory Space Access = 0
+ // IO Space Access = 1
+
+//Constants for the CONFIG_REVISION register
+
+#define DC21X4_REVISION_ID ((ULONG)(0x000000FF))
+#define DC21X4_MAJOR_REV ((ULONG)(0x000000F0))
+#define DC21X4_MINOR_REV ((ULONG)(0x0000000F))
+
+//Constants for the CONFIG_LATENCY_TIMER register
+
+#define DC21X4_LATENCY_TIMER ((ULONG)(0x0000FF00))
+
+#define DC21X4_PCI_LATENCY_TIMER_DEFAULT_VALUE 0xFF00
+
+//Constants for the CONFIG_BASE_IO_ADDRESS register
+
+#define DC21X4_IO_SPACE ((ULONG)(0x00000001))
+#define DC21X4_BASE_IO_ADDRESS ((ULONG)(0xFFFFFF80))
+
+//Constants for the CONFIG_INTERRUPT register
+
+#define DC21X4_CFIT_INTERRUPT_LINE ((ULONG)(0x000000FF))
+
+//Constants for the CONFIG_DRIVER_AREA register
+
+#define DC21X4_REGISTRED ((ULONG)(0x00000100))
+
+#define CFDA_SNOOZE_MODE 0x40000000
+
+
+//Constants for the BUS_MODE register
+
+#define DC21X4_SW_RESET ((ULONG)(0x00000001))
+#define DC21X4_BUS_ARBITRATION ((ULONG)(0x00000002))
+#define DC21X4_SKIP_LENGTH ((ULONG)(0x0000003C))
+#define DC21X4_ENDIAN ((ULONG)(0x00000080))
+#define DC21X4_BURST_LENGTH ((ULONG)(0x00003F00))
+#define DC21X4_CACHE_ALIGNMENT ((ULONG)(0x0000C000))
+#define DC21X4_AUTO_POLLING ((ULONG)(0x00070000))
+
+#define BUS_ARBITRATION_BIT_NUMBER 1
+#define BURST_LENGTH_BIT_NUMBER 8
+#define AUTO_POLLING_BIT_NUMBER 16
+
+#define DC21X4_BURST_LENGTH_DEFAULT_VALUE 16
+
+#define DC21X4_SKIP_64 ((ULONG)(0x00000030))
+#define DC21X4_SKIP_128 ((ULONG)(0x00000070))
+
+#define DC21X4_ALIGN_32 ((ULONG)(0x00004000))
+#define DC21X4_ALIGN_64 ((ULONG)(0x00008000))
+#define DC21X4_ALIGN_128 ((ULONG)(0x0000C000))
+
+//Constants for the TXM_POLL_DEMAND & RCV_POLL_DEMAND
+
+#define DC21X4_POLL_DEMAND ((ULONG)(0x00000001))
+
+
+//Constants for the STATUS register (CSR5)
+
+#define DC21X4_TXM_INTERRUPT ((ULONG)(0x00000001))
+#define DC21X4_TXM_STOPPED ((ULONG)(0x00000002))
+#define DC21X4_TXM_BUFFER_UNAVAILABLE ((ULONG)(0x00000004))
+#define DC21X4_TXM_JABBER_TIMEOUT ((ULONG)(0x00000008))
+#define DC21X4_LINK_PASS ((ULONG)(0x00000010))
+#define DC21X4_TXM_UNDERRUN ((ULONG)(0x00000020))
+#define DC21X4_RCV_INTERRUPT ((ULONG)(0x00000040))
+#define DC21X4_RCV_BUFFER_UNAVAILABLE ((ULONG)(0x00000080))
+#define DC21X4_RCV_STOPPED ((ULONG)(0x00000100))
+#define DC21X4_RCV_WATCHDOG_TIMEOUT ((ULONG)(0x00000200))
+#define DC21X4_10B5_10BT_SWITCH ((ULONG)(0x00000400))
+#define DC21X4_FULL_DUPLEX_SHORT_FRAME ((ULONG)(0x00000800))
+#define DC21X4_LINK_FAIL ((ULONG)(0x00001000))
+#define DC21X4_SYSTEM_ERROR ((ULONG)(0x00002000))
+#define DC21X4_ABNORMAL_INTERRUPT ((ULONG)(0x00008000))
+#define DC21X4_NORMAL_INTERRUPT ((ULONG)(0x00010000))
+#define DC21X4_RCV_PROCESS_STATE ((ULONG)(0x000E0000))
+#define DC21X4_TXM_PROCESS_STATE ((ULONG)(0x00700000))
+#define DC21X4_ERROR_BITS ((ULONG)(0x03800000))
+#define DC21X4_GEP_INTERRUPT ((ULONG)(0x04000000))
+
+#define DC21X4_TXM_PROCESS_SUSPENDED ((ULONG)(0x00600000))
+
+#define DC21X4_STATUS_INTERRUPTS ((ULONG)(0x0001BFFF))
+
+//Constants for the OPERATION_MODE register (CSR6)
+
+#define DC21X4_RCV_HASH_FILTER_MODE ((ULONG)(0x00000001))
+#define DC21X4_RCV_START ((ULONG)(0x00000002))
+#define DC21X4_PASS_BAD_FRAMES ((ULONG)(0x00000008))
+#define DC21X4_INVERSE_FILTERING ((ULONG)(0x00000010))
+#define DC21X4_STOP_BACKOFF_COUNTER ((ULONG)(0x00000020))
+#define DC21X4_PROMISCUOUS_MODE ((ULONG)(0x00000040))
+#define DC21X4_PASS_ALL_MULTICAST ((ULONG)(0x00000080))
+#define DC21X4_FLAKY_OSC_DISABLE ((ULONG)(0x00000100))
+#define DC21X4_FULL_DUPLEX_MODE ((ULONG)(0x00000200))
+#define DC21X4_OPERATING_MODE ((ULONG)(0x00000C00))
+#define DC21X4_FORCE_COLLISION_MODE ((ULONG)(0x00001000))
+#define DC21X4_TXM_START ((ULONG)(0x00002000))
+#define DC21X4_TXM_THRESHOLD ((ULONG)(0x0000C000))
+#define DC21X4_BACK_PRESSURE ((ULONG)(0x00010000))
+#define DC21X4_CAPTURE_EFFECT ((ULONG)(0x00020000))
+#define DC21X4_PORT_SELECT ((ULONG)(0x00040000))
+#define DC21X4_HEARTBEAT_DISABLE ((ULONG)(0x00080000))
+#define DC21X4_STORE_AND_FORWARD ((ULONG)(0x00200000))
+#define DC21X4_TXM_THRESHOLD_MODE ((ULONG)(0x00400000))
+#define DC21X4_CS_MODE ((ULONG)(0x00800000))
+#define DC21X4_SCRAMBLER ((ULONG)(0x01000000))
+#define DC21X4_LINK_HYSTERESIS ((ULONG)(0x02000000))
+
+#define DC21X4_INTERNAL_LOOPBACK_MODE ((ULONG)(0x00000400))
+#define DC21X4_EXTERNAL_LOOPBACK_MODE ((ULONG)(0x00000800))
+
+#define DC21X4_TXM10_THRESHOLD_72 ((ULONG)(0x00000000))
+#define DC21X4_TXM10_THRESHOLD_96 ((ULONG)(0x00004000))
+#define DC21X4_TXM10_THRESHOLD_128 ((ULONG)(0x00008000))
+#define DC21X4_TXM10_THRESHOLD_160 ((ULONG)(0x0000C000))
+
+#define DC21X4_TXM100_THRESHOLD_128 ((ULONG)(0x00000000))
+#define DC21X4_TXM100_THRESHOLD_256 ((ULONG)(0x00004000))
+#define DC21X4_TXM100_THRESHOLD_512 ((ULONG)(0x00008000))
+#define DC21X4_TXM100_THRESHOLD_1024 ((ULONG)(0x0000C000))
+
+#define DC21X4_DEFAULT_THRESHOLD_10MBPS DC21X4_TXM10_THRESHOLD_96
+#define DC21X4_DEFAULT_THRESHOLD_100MBPS DC21X4_TXM100_THRESHOLD_512
+
+#define DC21X4_MODE_MASK ((ULONG)( \
+ DC21X4_TXM_THRESHOLD_MODE \
+ | DC21X4_FULL_DUPLEX_MODE \
+ | DC21X4_STORE_AND_FORWARD \
+ ))
+
+#define DC21X4_MEDIUM_MASK ((ULONG)( \
+ DC21X4_TXM_THRESHOLD \
+ | DC21X4_PORT_SELECT \
+ | DC21X4_HEARTBEAT_DISABLE \
+ | DC21X4_FULL_DUPLEX_MODE \
+ | DC21X4_TXM_THRESHOLD_MODE \
+ | DC21X4_CS_MODE \
+ | DC21X4_SCRAMBLER \
+ | DC21X4_LINK_HYSTERESIS \
+ ))
+
+//initial values
+
+#define DC21X4_OPMODE_100BTX ((ULONG)( \
+ DC21X4_HEARTBEAT_DISABLE \
+ | DC21X4_LINK_HYSTERESIS \
+ ))
+
+//Constants for the INTERRUPT_MASK register (CSR7)
+
+#define DC21X4_MSK_TXM_INTERRUPT ((ULONG)(0x00000001))
+#define DC21X4_MSK_TXM_STOPPED ((ULONG)(0x00000002))
+#define DC21X4_MSK_TXM_BUFFER_UNAVAILABLE ((ULONG)(0x00000004))
+#define DC21X4_MSK_TXM_JABBER_TIMEOUT ((ULONG)(0x00000008))
+#define DC21X4_MSK_LINK_PASS ((ULONG)(0x00000010))
+#define DC21X4_MSK_TXM_UNDERRUN ((ULONG)(0x00000020))
+
+#define DC21X4_MSK_RCV_INTERRUPT ((ULONG)(0x00000040))
+#define DC21X4_MSK_RCV_BUFFER_UNAVAILABLE ((ULONG)(0x00000080))
+#define DC21X4_MSK_RCV_STOPPED ((ULONG)(0x00000100))
+#define DC21X4_MSK_RCV_WATCHDOG_TIMEOUT ((ULONG)(0x00000200))
+#define DC21X4_MSK_10B5_10BT_SWITCH ((ULONG)(0x00000400))
+#define DC21X4_MSK_TIMER_EXPIRED ((ULONG)(0x00000800))
+#define DC21X4_MSK_FULL_DUPLEX ((ULONG)(0x00000800))
+#define DC21X4_MSK_LINK_FAIL ((ULONG)(0x00001000))
+#define DC21X4_MSK_SYSTEM_ERROR ((ULONG)(0x00002000))
+#define DC21X4_MSK_EARLY_INTERRUPT ((ULONG)(0x00004000))
+#define DC21X4_MSK_ABNORMAL_INTERRUPT ((ULONG)(0x00008000))
+#define DC21X4_MSK_NORMAL_INTERRUPT ((ULONG)(0x00010000))
+#define DC21X4_MSK_GEP_INTERRUPT ((ULONG)(0x04000000))
+
+
+//initial value
+
+#define DC21X4_TXM_INTERRUPTS ((ULONG)( \
+ DC21X4_MSK_TXM_INTERRUPT \
+ | DC21X4_MSK_TXM_STOPPED \
+ | DC21X4_MSK_TXM_JABBER_TIMEOUT \
+ ))
+
+#define DC21X4_RCV_INTERRUPTS ((ULONG)( \
+ DC21X4_MSK_TXM_STOPPED \
+ | DC21X4_MSK_RCV_INTERRUPT \
+ ))
+
+#define DC21X4_MSK_MSK_DEFAULT_VALUE ((ULONG)( \
+ DC21X4_TXM_INTERRUPTS \
+ | DC21X4_RCV_INTERRUPTS \
+ | DC21X4_MSK_LINK_PASS \
+ | DC21X4_MSK_LINK_FAIL \
+ | DC21X4_MSK_TIMER_EXPIRED \
+ | DC21X4_MSK_SYSTEM_ERROR \
+ | DC21X4_MSK_ABNORMAL_INTERRUPT \
+ | DC21X4_MSK_NORMAL_INTERRUPT \
+ ))
+
+//Constants for the MISSED_FRAME/OVERFLOW register
+
+#define DC21X4_MISSED_FRAME_COUNTER ((ULONG)(0x0000FFFF))
+
+#define DC21X4_OVERFLOW_COUNTER ((ULONG)(0x00001FFF))
+#define DC21X4_OVERFLOW_COUNTER_SHIFT 16
+
+// Constants for the SERIAL ROM register
+
+#define DC21X4_IDPROM_DATA_UNVALID ((ULONG)(0x80000000))
+#define DC21X4_IDPROM_DATA ((ULONG)(0x000000FF))
+
+// Constants for the TIMER register
+
+#define DC21X4_TIMER_CON_MODE ((ULONG)(0x00010000))
+
+
+//Constants for the DC2104 SIA_STATUS register (CSR12)
+
+#define DC21X4_10B5_10BT_INDICATION ((ULONG)(0x00000001))
+#define DC21X4_NETWORK_CONNECTION_ERROR ((ULONG)(0x00000002))
+#define DC21X4_LINKFAIL_10 ((ULONG)(0x00000004))
+#define DC21X4_AUTO_POLARITY_STATE ((ULONG)(0x00000008))
+#define DC21X4_DPLL_SELF_TEST_DONE ((ULONG)(0x00000010))
+#define DC21X4_DPLL_SELF_TEST_PASS ((ULONG)(0x00000020))
+#define DC21X4_DPLL_ALL_ZERO ((ULONG)(0x00000040))
+#define DC21X4_DPLL_ALL_ONE ((ULONG)(0x00000080))
+#define DC21X4_SELECTED_PORT_ACTIVE ((ULONG)(0x00000100))
+#define DC21X4_NON_SELECTED_PORT_ACTIVE ((ULONG)(0x00000200))
+#define DC21X4_AUTO_NEGOTIATION_STATE ((ULONG)(0x00007000))
+#define DC21X4_LINK_PARTNER_NEGOTIABLE ((ULONG)(0x00008000))
+
+#define DC21X4_SELECTED_FIELD_MASK ((ULONG)(0x001F0000))
+#define DC21X4_SELECTED_FIELD ((ULONG)(0x00010000))
+
+#define DC21X4_LINK_PARTNER_10BT ((ULONG)(0x00200000))
+#define DC21X4_LINK_PARTNER_10BT_FD ((ULONG)(0x00400000))
+
+#define DC21X4_RESTART_AUTO_NEGOTIATION ((ULONG)(0x00001000))
+
+//Constants for the AutoNegotation states
+
+#define ANS_ACKNOWLEDGE_DETECTED ((ULONG)(0x00003000))
+#define ANS_ACKNOWLEDGE_COMPLETED ((ULONG)(0x00004000))
+#define ANS_AUTO_NEGOTIATION_COMPLETED ((ULONG)(0x00005000))
+
+#define DC21X4_LINK_PASS_MASK ((ULONG)( \
+ DC21X4_LINKFAIL_10 \
+ | DC21X4_AUTO_NEGOTIATION_STATE \
+ ))
+
+#define DC21X4_LINK_PASS_STATUS ((ULONG)( \
+ ANS_AUTO_NEGOTIATION_COMPLETED \
+ ))
+
+//Constants for the SIA_MODE_0 registers (CSR13)
+
+#define DC21X4_SIA_RST ((ULONG)(0x00000001))
+#define DC21X4_10B5_10BT_SELECTION ((ULONG)(0x00000002))
+#define DC21X4_CSR_AUTO_CONFIGURATION ((ULONG)(0x00000004))
+#define DC21X4_10B5_MODE ((ULONG)(0x00000008))
+
+#define DC21X4_AUTOSENSE_FLG ((ULONG)(0x80000005))
+#define DC21X4_FULL_DUPLEX_FLG ((ULONG)(0x40000005))
+#define DC21X4_LINK_DISABLE_FLG ((ULONG)(0x10000005))
+#define DC21X4_10B5_FLG ((ULONG)(0x0000000D))
+#define DC21X4_10B2_FLG ((ULONG)(0x2000000D))
+
+#define DC21X4_RESET_SIA ((ULONG)(0x00000000))
+
+
+//Constants for the SIA_MODE_1 registers (CSR14)
+
+
+#define DC21X4_AUTO_NEGOTIATION_ENABLE ((ULONG)(0x00000080))
+
+
+//Constants for the SIA_MODE_2 registers (CSR15)
+#define DC21142_SIA2_MASK ((ULONG)(0x0000FFFF))
+#define DC21142_GEP_MASK ((ULONG)(0xFFFF0000))
+
+#define DC21142_GEP_SHIFT 16
+
+
+//DC21040:
+
+//Constants for SIA TP mode
+
+#define DC21040_SIA0_10BT ((ULONG)(0x00008F01))
+#define DC21040_SIA1_10BT ((ULONG)(0x0000FFFF))
+#define DC21040_SIA1_10BT_FULL_DUPLEX ((ULONG)(0x0000FFFD))
+#define DC21040_SIA1_10BT_LINK_DISABLE ((ULONG)(0x0000CFFF))
+#define DC21040_SIA2_10BT ((ULONG)(0x00000000))
+
+//Constants for SIA BNC Thinwire mode
+
+#define DC21040_SIA0_10B2 ((ULONG)(0x0000EF09))
+#define DC21040_SIA1_10B2 ((ULONG)(0x00000705))
+#define DC21040_SIA2_10B2 ((ULONG)(0x00000006))
+
+//Constants for SIA AUI Thickwire mode
+
+#define DC21040_SIA0_10B5 ((ULONG)(0x00008F09))
+#define DC21040_SIA1_10B5 ((ULONG)(0x00000705))
+#define DC21040_SIA2_10B5 ((ULONG)(0x00000006))
+
+
+//DC21041:
+
+//Constants for SIA TP mode
+
+#define DC21041_SIA0_10BT ((ULONG)(0x0000EF01))
+#define DC21041_SIA1_10BT ((ULONG)(0x0000FF3F))
+#define DC21041_SIA1_10BT_FULL_DUPLEX ((ULONG)(0x00007F3D))
+#define DC21041_SIA1_10BT_LINK_DISABLE ((ULONG)(0x00004F3F))
+#define DC21041_SIA2_10BT ((ULONG)(0x00000008))
+
+//Constants for SIA BNC
+
+#define DC21041_SIA0_10B2 ((ULONG)(0x0000EF09))
+#define DC21041_SIA1_10B2 ((ULONG)(0x00000705))
+#define DC21041_SIA2_10B2 ((ULONG)(0x00000006))
+
+//Constants for SIA AUI mode
+
+#define DC21041_SIA0_10B5 ((ULONG)(0x0000EF09))
+#define DC21041_SIA1_10B5 ((ULONG)(0x00000705))
+#define DC21041_SIA2_10B5 ((ULONG)(0x0000000E))
+
+#define DC21041_LINK_TEST_ENABLED ((ULONG)(0x0000F038))
+
+
+//DC21142:
+
+//Constants for SIA TP mode
+
+#define DC21142_SIA0_10BT ((ULONG)(0x00000001))
+#define DC21142_SIA1_10BT ((ULONG)(0x00007F3F))
+#define DC21142_SIA1_10BT_FULL_DUPLEX ((ULONG)(0x00007F3D))
+#define DC21142_SIA1_10BT_LINK_DISABLE ((ULONG)(0x00004F3F))
+#define DC21142_SIA2_10BT ((ULONG)(0x00000008)) // turn off the BNC transceiver
+
+//Constants for SIA BNC
+
+#define DC21142_SIA0_10B2 ((ULONG)(0x00000009))
+#define DC21142_SIA1_10B2 ((ULONG)(0x00000705))
+#define DC21142_SIA2_10B2 ((ULONG)(0x00000006))
+
+//Constants for SIA AUI mode
+
+#define DC21142_SIA0_10B5 ((ULONG)(0x00000009))
+#define DC21142_SIA1_10B5 ((ULONG)(0x00000705))
+#define DC21142_SIA2_10B5 ((ULONG)(0x0000000E))
+
+//Constant for MII mode
+
+#define DC21142_SIA1_MII_HALF_DUPLEX ((ULONG)(0x00007F3F))
+#define DC21142_SIA1_MII_FULL_DUPLEX ((ULONG)(0x00007F3D))
+
+#define DC21142_GPR_BIT_SHIFT 16
+
+#define DC21X4_GEP_INTERRUPT_BIT_SHIFT 29
+
+#define DC21142_LINK_TEST_ENABLED ((ULONG)(0x0000F038)) //while in BNC or AUI mode
+
+
+#define DC21X4_NWAY_ENABLED ((ULONG)(0x000000C0))
+
+//Constants for the RCV descriptor RDES
+
+#define DC21X4_RDES_OVERFLOW ((ULONG)(0x00000001))
+#define DC21X4_RDES_CRC_ERROR ((ULONG)(0x00000002))
+#define DC21X4_RDES_DRIBBLING_BIT ((ULONG)(0x00000004))
+#define DC21X4_RDES_RCV_WATCHDOG_TIMEOUT ((ULONG)(0x00000010))
+#define DC21X4_RDES_FRAME_TYPE ((ULONG)(0x00000020))
+#define DC21X4_RDES_COLLISION_SEEN ((ULONG)(0x00000040))
+#define DC21X4_RDES_FRAME_TOO_LONG ((ULONG)(0x00000080))
+#define DC21X4_RDES_LAST_DESCRIPTOR ((ULONG)(0x00000100))
+#define DC21X4_RDES_FIRST_DESCRIPTOR ((ULONG)(0x00000200))
+#define DC21X4_RDES_MULTICAST_FRAME ((ULONG)(0x00000400))
+#define DC21X4_RDES_RUNT_FRAME ((ULONG)(0x00000800))
+#define DC21X4_RDES_DATA_TYPE ((ULONG)(0x00003000))
+#define DC21X4_RDES_LENGTH_ERROR ((ULONG)(0x00004000))
+#define DC21X4_RDES_ERROR_SUMMARY ((ULONG)(0x00008000))
+#define DC21X4_RDES_FRAME_LENGTH ((ULONG)(0x7FFF0000))
+#define DC21X4_RDES_OWN_BIT ((ULONG)(0x80000000))
+
+#define DC21X4_RDES_FIRST_BUFFER_SIZE ((ULONG)(0x000007FF))
+#define DC21X4_RDES_SECOND_BUFFER_SIZE ((ULONG)(0x003FF800))
+#define DC21X4_RDES_SECOND_ADDR_CHAINED ((ULONG)(0x01000000))
+#define DC21X4_RDES_END_OF_RING ((ULONG)(0x02000000))
+
+#define RDES_FRAME_LENGTH_BIT_NUMBER 16
+
+
+//Constants for the TXM descriptor TDES
+
+#define DC21X4_TDES_DEFERRED ((ULONG)(0x00000001))
+#define DC21X4_TDES_UNDERRUN_ERROR ((ULONG)(0x00000002))
+#define DC21X4_TDES_LINK_FAIL ((ULONG)(0x00000004))
+#define DC21X4_TDES_COLLISION_COUNT ((ULONG)(0x00000078))
+#define DC21X4_TDES_HEARTBEAT_FAIL ((ULONG)(0x00000080))
+#define DC21X4_TDES_EXCESSIVE_COLLISIONS ((ULONG)(0x00000100))
+#define DC21X4_TDES_LATE_COLLISION ((ULONG)(0x00000200))
+#define DC21X4_TDES_NO_CARRIER ((ULONG)(0x00000400))
+#define DC21X4_TDES_LOSS_OF_CARRIER ((ULONG)(0x00000800))
+#define DC21X4_TDES_TXM_JABBER_TIMEOUT ((ULONG)(0x00004000))
+#define DC21X4_TDES_ERROR_SUMMARY ((ULONG)(0x00008000))
+#define DC21X4_TDES_OWN_BIT ((ULONG)(0x80000000))
+
+#define DC21X4_TDES_ERROR_MASK ((ULONG)( \
+ DC21X4_TDES_UNDERRUN_ERROR \
+ | DC21X4_TDES_EXCESSIVE_COLLISIONS \
+ | DC21X4_TDES_LATE_COLLISION \
+ | DC21X4_TDES_NO_CARRIER \
+ | DC21X4_TDES_LOSS_OF_CARRIER \
+ | DC21X4_TDES_TXM_JABBER_TIMEOUT \
+ ))
+
+#define DC21X4_TDES_FIRST_BUFFER_SIZE ((ULONG)(0x000007FF))
+#define DC21X4_TDES_SECOND_BUFFER_SIZE ((ULONG)(0x003FF800))
+#define DC21X4_TDES_HASH_FILTERING ((ULONG)(0x00400000))
+#define DC21X4_TDES_DISABLE_PADDING ((ULONG)(0x00800000))
+#define DC21X4_TDES_SECOND_ADDR_CHAINED ((ULONG)(0x01000000))
+#define DC21X4_TDES_END_OF_RING ((ULONG)(0x02000000))
+#define DC21X4_TDES_ADD_CRC_DISABLE ((ULONG)(0x04000000))
+#define DC21X4_TDES_SETUP_PACKET ((ULONG)(0x08000000))
+#define DC21X4_TDES_INVERSE_FILTERING ((ULONG)(0x10000000))
+#define DC21X4_TDES_FIRST_SEGMENT ((ULONG)(0x20000000))
+#define DC21X4_TDES_LAST_SEGMENT ((ULONG)(0x40000000))
+#define DC21X4_TDES_INTERRUPT_ON_COMPLETION ((ULONG)(0x80000000))
+
+#define TDES_SECOND_BUFFER_SIZE_BIT_NUMBER 11
+#define TDES_COLLISION_COUNT_BIT_NUMBER 3
+
+
+//Ownership of descriptors.
+
+#define DESC_OWNED_BY_SYSTEM ((ULONG)(0x00000000))
+#define DESC_OWNED_BY_DC21X4 ((ULONG)(0x80000000))
+
+//Size of the Ethernet frame header
+
+#define ETH_HEADER_SIZE 14
+
+//Size of the frame CRC field
+
+#define ETH_CRC_SIZE 4
+
+//Number of buffer segments per DC21X4 descriptor
+
+#define NUMBER_OF_SEGMENT_PER_DESC 2
+
+//Maximum buffer size
+
+#define DC21X4_MAX_BUFFER_SIZE 1536 // 12*128(=max cache line size)
+
+//Maximum LookAhead is the size maximum of the frame
+
+#define DC21X4_MAX_FRAME_SIZE 1514
+#define DC21X4_MAX_LOOKAHEAD 1514
+
+//Maximum number of physical segments DC21X4 accepts
+//in a single Ndis buffer. Above this threshold, the packet
+//is copied into a single physically contiguous buffer
+
+#define DC21X4_MAX_SEGMENTS 8
+
+//Minimal size of a Txm packet to be directly mapped
+//into the Transmit Ring.Under this threshold, the packet
+//is copied into a preallocated Txm buffer to avoid
+//the (expensive) physical mapping translation
+
+#define DC21X4_MIN_TXM_SIZE 256
+
+
+//Number of descriptors reserved for Txm packets
+//into the Txm desc ring
+
+#define DC21X4_NUMBER_OF_TRANSMIT_DESCRIPTORS 64
+
+//Number of descriptors reserved for setup processing
+//into the Txm desc ring
+
+#define DC21X4_NUMBER_OF_SETUP_DESCRIPTORS 2
+
+//Size of the Transmit descriptor ring
+
+#define TRANSMIT_RING_SIZE (DC21X4_NUMBER_OF_TRANSMIT_DESCRIPTORS+DC21X4_NUMBER_OF_SETUP_DESCRIPTORS+1)
+
+//Number and size of allocated Txm buffers;
+//Nbr of Txm buffers MUST BE A POWER OF 2
+
+#define DC21X4_NUMBER_OF_MAX_TRANSMIT_BUFFERS 4
+#define DC21X4_MAX_TRANSMIT_BUFFER_SIZE DC21X4_MAX_BUFFER_SIZE
+
+#define DC21X4_NUMBER_OF_MIN_TRANSMIT_BUFFERS 16
+#define DC21X4_MIN_TRANSMIT_BUFFER_SIZE DC21X4_MIN_TXM_SIZE
+
+
+//Number and size of allocated setup buffers
+
+#define DC21X4_NUMBER_OF_SETUP_BUFFERS 1
+#define DC21X4_SETUP_BUFFER_SIZE 192
+
+//Physical mapping registers allocated to the adapter
+
+#if _ALPHA_
+#define DEFAULT_MAP_REGISTERS 64
+#else
+#define DEFAULT_MAP_REGISTERS 32
+#endif
+
+
+#define DC21X4_MIN_MAP_REGISTERS 4
+#define DC21X4_MAX_MAP_REGISTERS 64
+
+//Size of the Receive descriptor ring
+
+#define DC21X4_MIN_RECEIVE_RING_SIZE 8
+#define DC21X4_MAX_RECEIVE_RING_SIZE 64
+
+#define DC21X4_RECEIVE_RING_SIZE 16
+
+#define DC21X4_RECEIVE_PACKETS 100
+
+//Size of allocated receive buffers:
+
+#define DC21X4_RECEIVE_BUFFER_SIZE DC21X4_MAX_BUFFER_SIZE
+
+
+//No_carrier & ExecessCollisions counter threshold
+
+#define NO_CARRIER_THRESHOLD 4
+#define EXCESS_COLLISIONS_THRESHOLD 4
+
+
+//Transmit Underrun Threshold and Max retries
+
+#define DC21X4_UNDERRUN_THRESHOLD 10
+#define DC21X4_UNDERRUN_MAX_RETRIES 2
+
+
+
+
+//Interrupt and frame thresholds for interrupt moderation
+
+#define DC21X4_MSK_THRESHOLD_DEFAULT_VALUE 500 //interrupt/second
+#define DC21X4_FRAME_THRESHOLD_DEFAULT_VALUE 400 //frames/second
+
+//NdisStallExecution (in microseconds)
+
+#define MILLISECOND 1000
+
+//Timer (in milliseconds)
+
+#define DC21X4_ANC_TIMEOUT 3000 // 3 s
+#define DC21X4_SPA_TICK 2000 // 2 s
+#define DC21X4_MII_TICK 5000 // 5 s
+#define DC21X4_LINK_DELAY 1000 // 1 s
+#define DC21X4_POLL_DELAY 100 // 100 ms
+#define DC21X4_ANC_DELAY 500 // 500 ms
+
+#define POLL_COUNT_TIMEOUT 40 // *DC21X4_POLL_DELAY = 4s
+
+#define MAX_LINK_CHECK 10
+#define LINK_CHECK_PERIOD 1000 // 1s
+
+#define INT_MONITOR_PERIOD 500 // 500ms
+
+// Built_in timer for MII100 (81.9 us tick)
+
+#define ONE_MILLISECOND_TICK 12 // 12 * 81.9 us
+
+//Loop timeout (*10 milliseconds)
+
+#define DC21X4_SETUP_TIMEOUT 50 // *10ms
+#define DC21X4_TXM_TIMEOUT 50 // *10ms
+#define DC21X4_RVC_TIMEOUT 50 // *10ms
+
+//Line speed (* 100 bps)
+
+#define TEN_MBPS 100000 // * 100bps
+#define ONE_HUNDRED_MBPS 1000000 // * 100bps
+
+
+
+
+
+
+
diff --git a/private/ntos/ndis/dc21x4/d21x4oid.h b/private/ntos/ndis/dc21x4/d21x4oid.h
new file mode 100644
index 000000000..1b13ef953
--- /dev/null
+++ b/private/ntos/ndis/dc21x4/d21x4oid.h
@@ -0,0 +1,102 @@
+/*+
+ * file: d21x4oid.h
+ *
+ * Copyright (C) 1992-1995 by
+ * Digital Equipment Corporation, Maynard, Massachusetts.
+ * All rights reserved.
+ *
+ * This software is furnished under a license and may be used and copied
+ * only in accordance of the terms of such license and with the
+ * inclusion of the above copyright notice. This software or any other
+ * copies thereof may not be provided or otherwise made available to any
+ * other person. No title to and ownership of the software is hereby
+ * transferred.
+ *
+ * The information in this software is subject to change without notice
+ * and should not be construed as a commitment by digital equipment
+ * corporation.
+ *
+ * Digital assumes no responsibility for the use or reliability of its
+ * software on equipment which is not supplied by digital.
+ *
+ *
+ * Abstract: This file contains the Object Identifiers (OIDs) supported by
+ * the NDIS 4.0 miniport driver for DEC's DC21X4 Ethernet Adapter
+ * family
+ *
+ * Author: Philippe Klein
+ *
+ * Revision History:
+ *
+ * phk 28-aug-1994 Initial entry
+ *
+-*/
+
+
+
+
+
+
+static const UCHAR DC21040EisaDescriptor[] = "DEC DC21040 EISA Ethernet Adapter";
+static const UCHAR DC21040PciDescriptor[] = "DEC DC21040 PCI Ethernet Adapter";
+static const UCHAR DC21041PciDescriptor[] = "DEC DC21041 PCI Ethernet Adapter";
+static const UCHAR DC21140PciDescriptor[] = "DEC DC21140 PCI Fast Ethernet Adapter";
+static const UCHAR DC21142PciDescriptor[] = "DEC DC21142 PCI Fast Ethernet Adapter";
+
+static const NDIS_OID DC21X4GlobalOids[] = {
+ OID_GEN_SUPPORTED_LIST,
+ OID_GEN_HARDWARE_STATUS,
+ OID_GEN_MEDIA_SUPPORTED,
+ OID_GEN_MEDIA_IN_USE,
+ OID_GEN_MEDIA_CONNECT_STATUS,
+ OID_GEN_MAXIMUM_LOOKAHEAD,
+ OID_GEN_MAXIMUM_FRAME_SIZE,
+ OID_GEN_MAXIMUM_TOTAL_SIZE,
+ OID_GEN_MAC_OPTIONS,
+ OID_GEN_PROTOCOL_OPTIONS,
+ OID_GEN_LINK_SPEED,
+ OID_GEN_TRANSMIT_BUFFER_SPACE,
+ OID_GEN_RECEIVE_BUFFER_SPACE,
+ OID_GEN_TRANSMIT_BLOCK_SIZE,
+ OID_GEN_RECEIVE_BLOCK_SIZE,
+ OID_GEN_VENDOR_ID,
+ OID_GEN_VENDOR_DESCRIPTION,
+ OID_GEN_CURRENT_PACKET_FILTER,
+ OID_GEN_CURRENT_LOOKAHEAD,
+ OID_GEN_DRIVER_VERSION,
+ OID_GEN_XMIT_OK,
+ OID_GEN_RCV_OK,
+ OID_GEN_XMIT_ERROR,
+ OID_GEN_RCV_ERROR,
+ OID_GEN_RCV_NO_BUFFER,
+ OID_GEN_DIRECTED_BYTES_XMIT,
+ OID_GEN_DIRECTED_FRAMES_XMIT,
+ OID_GEN_MULTICAST_BYTES_XMIT,
+ OID_GEN_MULTICAST_FRAMES_XMIT,
+ OID_GEN_BROADCAST_BYTES_XMIT,
+ OID_GEN_BROADCAST_FRAMES_XMIT,
+ OID_GEN_DIRECTED_BYTES_RCV,
+ OID_GEN_DIRECTED_FRAMES_RCV,
+ OID_GEN_MULTICAST_BYTES_RCV,
+ OID_GEN_MULTICAST_FRAMES_RCV,
+ OID_GEN_BROADCAST_BYTES_RCV,
+ OID_GEN_BROADCAST_FRAMES_RCV,
+ OID_GEN_RCV_CRC_ERROR,
+ OID_GEN_TRANSMIT_QUEUE_LENGTH,
+ OID_802_3_PERMANENT_ADDRESS,
+ OID_802_3_CURRENT_ADDRESS,
+ OID_802_3_MULTICAST_LIST,
+ OID_802_3_MAXIMUM_LIST_SIZE,
+ OID_802_3_RCV_ERROR_ALIGNMENT,
+ OID_802_3_XMIT_ONE_COLLISION,
+ OID_802_3_XMIT_MORE_COLLISIONS,
+ OID_802_3_XMIT_DEFERRED,
+ OID_802_3_XMIT_MAX_COLLISIONS,
+ OID_802_3_RCV_OVERRUN,
+ OID_802_3_XMIT_UNDERRUN,
+ OID_802_3_XMIT_HEARTBEAT_FAILURE,
+ OID_802_3_XMIT_TIMES_CRS_LOST,
+ OID_802_3_XMIT_LATE_COLLISIONS
+ };
+
+
diff --git a/private/ntos/ndis/dc21x4/d21x4rgs.h b/private/ntos/ndis/dc21x4/d21x4rgs.h
new file mode 100644
index 000000000..d4adf9918
--- /dev/null
+++ b/private/ntos/ndis/dc21x4/d21x4rgs.h
@@ -0,0 +1,140 @@
+/*+
+ * file: d21x4rgs.h
+ *
+ * Copyright (C) 1992-1995 by
+ * Digital Equipment Corporation, Maynard, Massachusetts.
+ * All rights reserved.
+ *
+ * This software is furnished under a license and may be used and copied
+ * only in accordance of the terms of such license and with the
+ * inclusion of the above copyright notice. This software or any other
+ * copies thereof may not be provided or otherwise made available to any
+ * other person. No title to and ownership of the software is hereby
+ * transferred.
+ *
+ * The information in this software is subject to change without notice
+ * and should not be construed as a commitment by digital equipment
+ * corporation.
+ *
+ * Digital assumes no responsibility for the use or reliability of its
+ * software on equipment which is not supplied by digital.
+ *
+ *
+ * Abstract: This file contains the string definitions of the
+ * Registry keys for the NDIS 4.0 miniport driver for
+ * DEC's DC21X4 Ethernet Adapter family.
+ *
+ * Author: Philippe Klein
+ *
+ * Revision History:
+ *
+ * phk 28-Aug-1994 Initial entry
+ * phk 12-Mar-1995 Add ConnectionType table
+ *
+-*/
+
+
+
+
+
+
+// Registry keys
+
+typedef enum DC21X4_REGISTRY_KEY {
+ RGS_ADPT = 0, // AdapterType
+ RGS_BUSN, // BusNumber
+ RGS_DEVN, // SlotNumber
+ RGS_FCTN, // FunctionNumber
+ RGS_CFID, // AdapterCfid
+ RGS_CFCS, // PciCommand
+ RGS_CFLT, // PciLatencyTimer
+ RGS_BLEN, // BurstLen
+ RGS_FARB, // FifoArbitration
+ RGS_THRS, // TransmitThreshold
+ RGS_THRS100, // TransmitThreshold100
+ RGS_BKOC, // BackoffCounter
+ RGS_BKPR, // BackPressure
+ RGS_CPTE, // CaptureEffect
+ RGS_TI, // TiPeriod
+ RGS_SCRC, // SoftwareCRC
+ RGS_ESIA, // ExternalSia
+ RGS_SIA0, // SiaRegister0
+ RGS_SIA1, // SiaRegister1
+ RGS_SIA2, // SiaRegister2
+ RGS_TRNS, // TransceiverDelay
+ RGS_CLSZ, // CacheLineSize
+ RGS_PLDM, // AutomaticPolling
+ RGS_RCVR, // ReceiveBuffers
+ RGS_STFD, // StoreAndForward
+ RGS_MAPR, // MapRegisters
+ RGS_ITMG, // InterruptMitigation
+ RGS_ITHR, // InterruptThreshold
+ RGS_FTHR, // FrameThreshold
+ RGS_UTHR, // UnderrunThreshold
+ RGS_UNDR, // UnderrunRetry
+ RGS_SNOO, // SnoozeMode
+ RGS_NWAY, // NwayProtocol
+ RGS_RCV_BUFS, // ExtraReceiveBuffers
+ RGS_RCV_PKTS, // ExtraReceivePackets
+ RGS_CNCT, // ConnectionType
+ MAX_RGS
+} DC21X4_REGISTRY_KEY;
+
+NDIS_STRING DC21X4ConfigString[] = {
+
+ NDIS_STRING_CONST("AdapterType"),
+ NDIS_STRING_CONST("BusNumber"),
+ NDIS_STRING_CONST("SlotNumber"),
+ NDIS_STRING_CONST("FunctionNumber"),
+ NDIS_STRING_CONST("AdapterCfid"),
+ NDIS_STRING_CONST("PciCommand"),
+ NDIS_STRING_CONST("PciLatencyTimer"),
+ NDIS_STRING_CONST("BurstLength"),
+ NDIS_STRING_CONST("FifoArbitration"),
+ NDIS_STRING_CONST("TransmitThreshold"),
+ NDIS_STRING_CONST("TransmitThreshold100"),
+ NDIS_STRING_CONST("BackoffCounter"),
+ NDIS_STRING_CONST("BackPressure"),
+ NDIS_STRING_CONST("CaptureEffect"),
+ NDIS_STRING_CONST("TiPeriod"),
+ NDIS_STRING_CONST("SoftwareCRC"),
+ NDIS_STRING_CONST("ExternalSia"),
+ NDIS_STRING_CONST("SiaRegister0"),
+ NDIS_STRING_CONST("SiaRegister1"),
+ NDIS_STRING_CONST("SiaRegister2"),
+ NDIS_STRING_CONST("TransceiverDelay"),
+ NDIS_STRING_CONST("CacheLineSize"),
+ NDIS_STRING_CONST("AutomaticPolling"),
+ NDIS_STRING_CONST("ReceiveBuffers"),
+ NDIS_STRING_CONST("StoreAndForward"),
+ NDIS_STRING_CONST("MapRegisters"),
+ NDIS_STRING_CONST("InterruptMitigation"),
+ NDIS_STRING_CONST("InterruptThreshold"),
+ NDIS_STRING_CONST("FrameThreshold"),
+ NDIS_STRING_CONST("UnderrunThreshold"),
+ NDIS_STRING_CONST("UnderrunRetry"),
+ NDIS_STRING_CONST("SnoozeMode"),
+ NDIS_STRING_CONST("NwayProtocol"),
+ NDIS_STRING_CONST("ExtraReceiveBuffers"),
+ NDIS_STRING_CONST("ExtraReceivePackets"),
+ NDIS_STRING_CONST("ConnectionType")
+};
+
+static const ULONG ConnectionType[]= {
+ 0x900, // 0 = AutoDetect , AutoSense
+ 0x001, // 1 = 10Base2 (BNC)
+ 0x000, // 2 = 10BaseT (TP)
+ 0x204, // 3 = 10BaseT Full_Duplex
+ 0x400, // 4 = 10BaseT No_Link_Test
+ 0x002, // 5 = 10Base5 (AUI)
+ 0x800, // 6 = AutoSense No_Nway
+ 0x900, // 7 = Reserved
+ 0x003, // 8 = 100BaseTx
+ 0x205, // 9 = 100BaseTx Full_Duplex
+ 0x006, //10 = 100BaseT4
+ 0x007, //11 = 100BaseFx
+ 0x208 //12 = 100BaseFx Full_Duplex
+};
+
+#define MAX_MEDIA 13
+
diff --git a/private/ntos/ndis/dc21x4/dc21x4.c b/private/ntos/ndis/dc21x4/dc21x4.c
new file mode 100644
index 000000000..1356686f2
--- /dev/null
+++ b/private/ntos/ndis/dc21x4/dc21x4.c
@@ -0,0 +1,134 @@
+/*+
+ * file: DC21X4.c
+ *
+ * Copyright (C) 1992-1995 by
+ * Digital Equipment Corporation, Maynard, Massachusetts.
+ * All rights reserved.
+ *
+ * This software is furnished under a license and may be used and copied
+ * only in accordance of the terms of such license and with the
+ * inclusion of the above copyright notice. This software or any other
+ * copies thereof may not be provided or otherwise made available to any
+ * other person. No title to and ownership of the software is hereby
+ * transferred.
+ *
+ * The information in this software is subject to change without notice
+ * and should not be construed as a commitment by digital equipment
+ * corporation.
+ *
+ * Digital assumes no responsibility for the use or reliability of its
+ * software on equipment which is not supplied by digital.
+ *
+ *
+ * Abstract: This file is the main file of the NDIS 4.0 miniport driver
+ * for DEC's 21X4 Ethernet Adapter family.
+ *
+ * Author: Philippe Klein
+ *
+ * Revision History:
+ *
+ * phk 30-Jul-1994 Initial entry
+ *
+-*/
+
+#include <precomp.h>
+
+#if __DBG
+#include "version.h"
+#endif
+
+
+
+
+
+
+
+
+#pragma NDIS_INIT_FUNCTION(DriverEntry)
+
+/*+
+ * DriverEntry
+ *
+ * Routine description:
+ *
+ * Driver Entry is the initial entry point of the DC21X4 driver called
+ * by the operating system.
+ *
+-*/
+
+
+// This is the NT-specific driver entry point.
+
+NTSTATUS
+DriverEntry(
+ IN PDRIVER_OBJECT DriverObject,
+ IN PUNICODE_STRING RegistryPath
+ )
+
+
+{
+ NDIS_STATUS NdisStatus;
+ NDIS_HANDLE DC21X4WrapperHandle;
+ NDIS_MINIPORT_CHARACTERISTICS DC21X4Char;
+
+#if __DBG
+ DbgPrint("\n\n DC21X4 NDIS4.0 miniport driver %s - Built %s %s\n\n",
+ DRIVER_VERSION_STR,__DATE__,__TIME__);
+#endif
+
+ // Initialize the wrapper.
+#if __DBG
+ DbgPrint("NdisMInitializeWrapper\n");
+#endif
+
+ NdisMInitializeWrapper(
+ &DC21X4WrapperHandle,
+ DriverObject,
+ RegistryPath,
+ NULL
+ );
+
+#if _DBG
+ DbgPrint(" NdisMrapperHandle = %x\n",DC21X4WrapperHandle);
+#endif
+
+ // Initialize the characteristics before registering the MAC
+
+ DC21X4Char.MajorNdisVersion = DC21X4_NDIS_MAJOR_VERSION;
+ DC21X4Char.MinorNdisVersion = DC21X4_NDIS_MINOR_VERSION;
+ DC21X4Char.CheckForHangHandler = DC21X4CheckforHang;
+ DC21X4Char.DisableInterruptHandler = DC21X4DisableInterrupt;
+ DC21X4Char.EnableInterruptHandler = DC21X4EnableInterrupt;
+ DC21X4Char.HaltHandler = DC21X4Halt;
+ DC21X4Char.HandleInterruptHandler = DC21X4HandleInterrupt;
+ DC21X4Char.InitializeHandler = DC21X4Initialize;
+ DC21X4Char.ISRHandler = DC21X4Isr;
+ DC21X4Char.QueryInformationHandler = DC21X4QueryInformation;
+ DC21X4Char.ReconfigureHandler = NULL;
+ DC21X4Char.ResetHandler = DC21X4Reset;
+ DC21X4Char.SendHandler = DC21X4Send;
+ DC21X4Char.SetInformationHandler = DC21X4SetInformation;
+ DC21X4Char.TransferDataHandler = NULL;
+ DC21X4Char.ReturnPacketHandler = DC21X4ReturnPacket;
+ DC21X4Char.SendPacketsHandler = NULL; //DC21X4SendPackets;
+ DC21X4Char.AllocateCompleteHandler = DC21X4AllocateComplete;
+#if __DBG
+ DbgPrint("NdisMRegisterMiniport\n");
+#endif
+
+ NdisStatus = NdisMRegisterMiniport(
+ DC21X4WrapperHandle,
+ &DC21X4Char,
+ sizeof(DC21X4Char)
+ );
+
+ if (NdisStatus != NDIS_STATUS_SUCCESS) {
+ // Mac Registration completes on failure
+#if __DBG
+ DbgPrint(" NdisMRegisterMiniport failed: Status = %x\n",NdisStatus);
+#endif
+ NdisTerminateWrapper(DC21X4WrapperHandle, NULL);
+ }
+ return NdisStatus;
+}
+
diff --git a/private/ntos/ndis/dc21x4/dc21x4.hlp b/private/ntos/ndis/dc21x4/dc21x4.hlp
new file mode 100644
index 000000000..b0a38d700
--- /dev/null
+++ b/private/ntos/ndis/dc21x4/dc21x4.hlp
Binary files differ
diff --git a/private/ntos/ndis/dc21x4/dc21x4.hpj b/private/ntos/ndis/dc21x4/dc21x4.hpj
new file mode 100644
index 000000000..9d9ef063f
--- /dev/null
+++ b/private/ntos/ndis/dc21x4/dc21x4.hpj
@@ -0,0 +1,47 @@
+[OPTIONS]
+TITLE=Windows NT Setup
+CONTENTS=ALL
+ERRORLOG=dc21x4.err
+COMPRESS=0
+WARNING=3
+COPYRIGHT=Digital Equipment Corporation
+
+[FILES]
+dc21x4.rtf
+
+[MAP]
+ALL 1
+DC21040_TITLE 10
+DC21041_TITLE 20
+DC21140_TITLE 30
+DC21142_TITLE 40
+DC21143_TITLE 50
+EB40_TITLE 100
+EB41_TITLE 110
+EB140_TITLE 120
+EB142_TITLE 130
+EB143_TITLE 140
+MULTIA_TITLE 200
+DE434_TITLE 210
+DE435_TITLE 220
+DE436_TITLE 230
+DE450_TITLE 240
+DE500_TITLE 250
+
+AUTODETECT 1000
+AUTOSENSE 1010
+AUTOSENSE_NW 1020
+10BT 1030
+10BT_FD 1040
+10BT_NLT 1050
+10B2 1060
+10B5 1070
+100BTX 1080
+100BTX_FD 1090
+100BT4 1100
+100BFX 1110
+
+[WINDOWS]
+main=,(400,100,500,600),0,,,
+
+
diff --git a/private/ntos/ndis/dc21x4/dc21x4.rc b/private/ntos/ndis/dc21x4/dc21x4.rc
new file mode 100644
index 000000000..8e966c908
--- /dev/null
+++ b/private/ntos/ndis/dc21x4/dc21x4.rc
@@ -0,0 +1,66 @@
+#include "version.h"
+#include <windows.h>
+
+#ifdef RC_INVOKED
+
+#define VER_LEGALCOPYRIGHT_YEARS "1992-1996"
+
+#define VER_LEGALCOPYRIGHT_STR "Copyright\251 Digital Equip. Corp." VER_LEGALCOPYRIGHT_YEARS
+
+#define VER_FILETYPE VFT_DRV
+
+#define VER_FILESUBTYPE FT2_DRV_NETWORK
+
+#define VER_PRODUCTVERSION DRIVER_VERSION
+
+#define VER_PRODUCTVERSION_STR DRIVER_VERSION_STR
+
+
+#define VER_FILEDESCRIPTION_STR "NDIS 4.0 DC21X4 miniport driver"
+
+#define VER_INTERNALNAME_STR "DC21X4.SYS"
+
+#define VER_PRODUCTNAME_STR "Digital Semiconductor\256 21X4 PCI Ethernet controllers"
+
+#define VER_COMPANYNAME_STR "Digital Semiconductor - Digital Equipment Corporation."
+
+
+
+#define VER_ORIGINALFILENAME_STR VER_INTERNALNAME_STR
+
+#define VER_FILEVERSION VER_PRODUCTVERSION
+
+#define VER_FILEVERSION_STR VER_PRODUCTVERSION_STR
+
+
+VS_VERSION_INFO VERSIONINFO
+FILEVERSION VER_FILEVERSION
+PRODUCTVERSION VER_PRODUCTVERSION
+
+
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904B0" /* LANG_ENGLISH/SUBLANG_ENGLISH_US, Unicode CP */
+ BEGIN
+ VALUE "CompanyName", VER_COMPANYNAME_STR
+ VALUE "FileDescription", VER_FILEDESCRIPTION_STR
+ VALUE "FileVersion", VER_FILEVERSION_STR
+ VALUE "InternalName", VER_INTERNALNAME_STR
+ VALUE "LegalCopyright", VER_LEGALCOPYRIGHT_STR
+ VALUE "OriginalFilename",VER_ORIGINALFILENAME_STR
+ VALUE "ProductName", VER_PRODUCTNAME_STR
+ VALUE "ProductVersion", VER_PRODUCTVERSION_STR
+ END
+
+ END
+
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x040904B0L
+ END
+END
+#endif
+
+
+
diff --git a/private/ntos/ndis/dc21x4/dc21x4.rtf b/private/ntos/ndis/dc21x4/dc21x4.rtf
new file mode 100644
index 000000000..94e9e0972
--- /dev/null
+++ b/private/ntos/ndis/dc21x4/dc21x4.rtf
@@ -0,0 +1,199 @@
+{\rtf1\ansi\deff31
+{\fonttbl
+\f0\fswiss System;
+\f1\fmodern Fixedsys;
+\f2\fmodern 8514oem;
+\f3\fmodern Modern;
+\f4\fscript Script;
+\f5\froman Roman;
+\f6\fswiss Small Fonts;
+\f7\froman MS Serif;
+\f8\fmodern Courier;
+\f9\fswiss MS Sans Serif;
+\f10\fswiss V1 Lucida Sans;
+\f11\fswiss V1 Lucida Sans Bold;
+\f12\fswiss V1 Lucida Sans Italic;
+\f13\fswiss V2 Lucida Sans;
+\f14\fswiss V2 Lucida Sans Bold;
+\f15\fswiss V2 Lucida Sans Italic;
+\f16\fswiss V3 Lucida Sans;
+\f17\fswiss V3 Lucida Sans Bold;
+\f18\fswiss V3 Lucida Sans Italic;
+\f19\fswiss V4 Lucida Sans;
+\f20\fswiss V4 Lucida Sans Bold;
+\f21\fswiss V4 Lucida Sans Italic;
+\f22\fswiss V5 Lucida Sans;
+\f23\fswiss V6 Lucida Sans;
+\f24\fswiss V7 Lucida Sans;
+\f25\fswiss V7 Lucida Sans Bold;
+\f26\fswiss V7 Lucida Sans Italic;
+\f29\fnil Simple Latin;
+\f30\froman HM Phonetic;
+\f31\fswiss Arial;
+\f32\fmodern Courier New;
+\f33\froman Times New Roman;
+\f34\fnil Wingdings;
+\f35\froman Book Antiqua;
+\f36\fswiss Arial Narrow;
+\f37\froman Bookman Old Style;
+\f38\fswiss Century Gothic;
+\f39\fscript Monotype Corsiva;
+\f40\fnil Monotype Sorts;
+\f41\froman Century Schoolbook;
+\f42\froman MT Extra;
+\f43\fmodern MS LineDraw;
+\f44\fdecor Algerian;
+\f45\fswiss Arial Rounded MT Bold;
+\f46\fdecor Braggadocio;
+\f47\fswiss Britannic Bold;
+\f48\fscript Brush Script MT;
+\f49\fdecor Colonna MT;
+\f50\fdecor Desdemona;
+\f51\froman Footlight MT Light;
+\f52\fswiss Impact;
+\f53\fdecor Kino MT;
+\f54\froman Wide Latin;
+\f55\fscript Matura MT Script Capitals;
+\f56\fdecor Playbill;
+\f57\froman Symbol;
+\f58\fswiss Lucida Sans;
+\f59\fscript Lucida Blackletter;
+\f60\fscript Lucida Handwriting;
+\f61\fdecor Stencil;
+\f79\fnil MF Graffiti;
+\f84\fnil MS Reference 1;
+\f85\fnil MS Reference 2;
+}
+{\colortbl;
+\red0\green0\blue0;
+\red128\green0\blue0;
+\red0\green128\blue0;
+\red128\green128\blue0;
+\red0\green0\blue128;
+\red128\green0\blue128;
+\red0\green128\blue128;
+\red128\green128\blue128;
+\red192\green192\blue192;
+\red255\green0\blue0;
+\red0\green255\blue0;
+\red255\green255\blue0;
+\red0\green0\blue255;
+\red255\green0\blue255;
+\red0\green255\blue255;
+\red255\green255\blue255;
+}
+${\footnote $ D21x4 Family}
+#{\footnote # ALL}
++{\footnote + 00001}
+\keepn \f9 \fs24 \cf0 Digital Semiconductor's 21X4 PCI Ethernet Controller Family\par\pard\fs20\cf0 \par \uldb 21040\uldb0 \v DC21040_TITLE\v0 \par\uldb 21041\uldb0 \v DC21041_TITLE\v0 \par\uldb 21140\uldb0 \v DC21140_TITLE\v0 \par\uldb 21142\uldb0 \v DC21142_TITLE\v0 \par\uldb 21143\uldb0 \v DC21143_TITLE\v0 \par\uldb EB40\uldb0 \v EB40_TITLE\v0 \par\uldb EB41\uldb0 \v EB41_TITLE\v0 \par\uldb EB140\uldb0 \v EB140_TITLE\v0 \par\uldb EB142\uldb0 \v EB142_TITLE\v0 \par\uldb EB143\uldb0 \v EB143_TITLE\v0 \par\uldb MULTIA\uldb0 \v MULTIA_TITLE\v0 \par\page
+${\footnote $ Digital Semiconductor's 21040 PCI Ethernet Controller}
+#{\footnote # DC21040_TITLE}
++{\footnote + 00002}
+\keepn \f9 \fs24 \cf0 Digital Semiconductor's 21040 PCI Ethernet Controller \par \pard \f9 \fs24 \pard \fs20 \cf0 Use this dialog box to setup the medium connection for Digital Equipment Corporation's Digital Semiconductor's 21040 based Adapter.\par \par \ul AutoDetect\ul0 \v AUTODETECT\v0 \par \ul Twisted_Pair (10BaseT)\ul0 \v 10BT\v0 \par \ul Twisted_Pair Full_Duplex\ul0 \v 10BT_FD\v0 \par \ul Twisted_Pair No_Link_Test\ul0 \v 10BT_NLT\v0 \par \ul BNC (10Base2)\ul0 \v 10B2\v0 \par \ul AUI (10Base5)\ul0 \v 10B5\v0 \par \page
+${\footnote $ Digital Semiconductor's 21041 PCI Ethernet Controller}
+#{\footnote # DC21041_TITLE}
++{\footnote + 00003}
+\keepn \f9 \fs24 \cf0 Digital Semiconductor's 21041 PCI Ethernet Controller \par \pard \f9 \fs24 \pard \fs20 \cf0 Use this dialog box to setup the medium connection for Digital Equipment Corporation's Digital Semiconductor's 21041 based Adapter.\par \par \ul AutoSense\ul0 \v AUTOSENSE\v0 \par \ul AutoSense No_Nway\ul0 \v AUTOSENSE_NW\v0 \par \ul Twisted_Pair (10BaseT)\ul0 \v 10BT\v0 \par \ul Twisted_Pair Full_Duplex\ul0 \v 10BT_FD\v0 \par \ul Twisted_Pair No_Link_Test\ul0 \v 10BT_NLT\v0 \par \ul BNC (10Base2)\ul0 \v 10B2\v0 \par \ul AUI (10Base5)\ul0 \v 10B5\v0 \par \page
+${\footnote $ Digital Semiconductor's 21140 PCI Fast Ethernet Controller}
+#{\footnote # DC21140_TITLE}
++{\footnote + 00004}
+\keepn \f9 \fs24 \cf0 Digital Semiconductor's 21140 PCI Fast Ethernet Controller \par \pard \f9 \fs24 \pard \fs20 \cf0 Use this dialog box to setup the medium connection for Digital Equipment Corporation's Digital Semiconductor's 21140 based Adapter.\par \par \ul AutoSense\ul0 \v AUTOSENSE\v0 \par \ul AutoSense No_Nway\ul0 \v AUTOSENSE_NW\v0 \par \ul 100BaseTx\ul0 \v 100BTX\v0 \par \ul 100BaseTx Full_Duplex\ul0 \v 100BTX_FD\v0 \par \ul 100BaseT4\ul0 \v 100BT4\v0 \par \ul 100BaseFx\ul0 \v 100BFX\v0 \par \ul 10BaseT\ul0 \v 10BT\v0 \par \ul 10BaseT Full_Duplex\ul0 \v 10BT_FD\v0 \par \page
+${\footnote $ Digital Semiconductor's DC21142 PCI Ethernet Controller}
+#{\footnote # DC21142_TITLE}
++{\footnote + 00005}
+\keepn \f9 \fs24 \cf0 Digital Semiconductor's 21142 PCI Ethernet Controller \par \pard \f9 \fs24 \pard \fs20 \cf0 Use this dialog box to setup the medium connection for Digital Equipment Corporation's Digital Semiconductor's 21142 based Adapter.\par \par \ul AutoSense\ul0 \v AUTOSENSE\v0 \par \ul 100BaseTx\ul0 \v 100BTX\v0 \par \ul 100BaseTx Full_Duplex\ul0 \v 100BTX_FD\v0 \par \ul 100BaseT4\ul0 \v 100BT4\v0 \par \ul 100BaseFx\ul0 \v 100BFX\v0 \par \ul 10BaseT\ul0 \v 10BT\v0 \par \ul 10BaseT Full_Duplex\ul0 \v 10BT_FD\v0 \par \ul 10BaseT No_Link_Test\ul0 \v 10BT_NLT\v0 \par \ul 10Base2 (BNC)\ul0 \v 10B2\v0 \par \ul 10Base5 (AUI)\ul0 \v 10B5\v0 \par \page
+${\footnote $ Digital Semiconductor's DC21143 PCI Ethernet Controller}
+#{\footnote # DC21143_TITLE}
++{\footnote + 00006}
+\keepn \f9 \fs24 \cf0 Digital Semiconductor's 21143 PCI Ethernet Controller \par \pard \f9 \fs24 \pard \fs20 \cf0 Use this dialog box to setup the medium connection for Digital Equipment Corporation's Digital Semiconductor's 21143 based Adapter.\par \par \ul AutoSense\ul0 \v AUTOSENSE\v0 \par \ul 100BaseTx\ul0 \v 100BTX\v0 \par \ul 100BaseTx Full_Duplex\ul0 \v 100BTX_FD\v0 \par \ul 100BaseT4\ul0 \v 100BT4\v0 \par \ul 100BaseFx\ul0 \v 100BFX\v0 \par \ul 10BaseT\ul0 \v 10BT\v0 \par \ul 10BaseT Full_Duplex\ul0 \v 10BT_FD\v0 \par \ul 10BaseT No_Link_Test\ul0 \v 10BT_NLT\v0 \par \ul 10Base2 (BNC)\ul0 \v 10B2\v0 \par \ul 10Base5 (AUI)\ul0 \v 10B5\v0 \par \page
+${\footnote $ EB40 - Digital Semiconductor's 21040 Evaluation Board}
+#{\footnote # EB40_TITLE}
++{\footnote + 00007}
+\keepn \f9 \fs24 \cf0 EB40 - Digital Semiconductor's 21040's Evaluation Board\par \pard \f9 \fs24 \pard \fs20 \cf0 Use this dialog box to setup the medium connection for Digital Equipment Corporation's EB40 Evaluation Board.\par \par \ul Twisted_Pair (10BaseT)\ul0 \v 10BT\v0 \par \ul Twisted_Pair Full_Duplex\ul0 \v 10BT_FD\v0 \par \ul Twisted_Pair No_Link_Test\ul0 \v 10BT_NLT\v0 \par \page
+${\footnote $ EB41 - Digital Semiconductor's 21041 Evaluation Board}
+#{\footnote # EB41_TITLE}
++{\footnote + 00008}
+\keepn \f9 \fs24 \cf0 EB41 - Digital Semiconductor's 21041's Evaluation Board\par \pard \f9 \fs24 \pard \fs20 \cf0 Use this dialog box to setup the medium connection for Digital Equipment Corporation's EB41 Evaluation Board.\par \par \ul AutoSense\ul0 \v AUTOSENSE\v0 \par \ul AutoSense No_Nway \ul0 \v AUTOSENSE_NW\v0 \par \ul Twisted_Pair (10BaseT)\ul0 \v 10BT\v0 \par \ul Twisted_Pair Full_Duplex\ul0 \v 10BT_FD\v0 \par \ul Twisted_Pair No_Link_Test\ul0 \v 10BT_NLT\v0 \par \ul BNC (10Base2)\ul0 \v 10B2\v0 \par \ul AUI (10Base5)\ul0 \v 10B5\v0 \par \page
+${\footnote $ EB140 - Digital Semiconductor's 21140 Evaluation Board}
+#{\footnote # EB140_TITLE}
++{\footnote + 00009}
+\keepn \f9 \fs24 \cf0 EB140 - Digital Semiconductor's 21140's Evaluation Board\par \pard \f9 \fs24 \pard \fs20 \cf0 Use this dialog box to setup the medium connection for Digital Equipment Corporation's EB140 Evaluation Board.\par \par \ul AutoSense\ul0 \v AUTOSENSE\v0 \par \ul 100BaseTx\ul0 \v 100BTX\v0 \par \ul 100BaseTx Full_Duplex\ul0 \v 10BT_FD\v0 \par \ul 10BaseT\ul0 \v 10BT\v0 \par \ul 10BaseT Full_Duplex\ul0 \v 10BT_FD\v0 \par \page
+#{\footnote # EB142_TITLE}
++{\footnote + 00010}
+\keepn \f9 \fs24 \cf0 EB142 - Digital Semiconductor's 21142's Evaluation Board\par \pard \f9 \fs24 \pard \fs20 \cf0 Use this dialog box to setup the medium connection for Digital Equipment Corporation's EB142 Evaluation Board.\par \par \ul AutoSense\ul0 \v AUTOSENSE\v0 \par \ul 100BaseTx\ul0 \v 100BTX\v0 \par \ul 100BaseTx Full_Duplex\ul0 \v 100BTX_FD\v0 \par \ul 100BaseT4\ul0 \v 100BT4\v0 \par \ul 100BaseFx\ul0 \v 100BFX\v0 \par \ul 10BaseT\ul0 \v 10BT\v0 \par \ul 10BaseT Full_Duplex\ul0 \v 10BT_FD\v0 \par \ul 10BaseT No_Link_Test\ul0 \v 10BT_NLT\v0 \par \ul 10Base2 (BNC)\ul0 \v 10B2\v0 \par \page
+#{\footnote # EB143_TITLE}
++{\footnote + 00011}
+\keepn \f9 \fs24 \cf0 EB143 - Digital Semiconductor's 21143's Evaluation Board\par \pard \f9 \fs24 \pard \fs20 \cf0 Use this dialog box to setup the medium connection for Digital Equipment Corporation's EB143 Evaluation Board.\par \par \ul AutoSense\ul0 \v AUTOSENSE\v0 \par \ul 100BaseTx\ul0 \v 100BTX\v0 \par \ul 100BaseTx Full_Duplex\ul0 \v 100BTX_FD\v0 \par \ul 100BaseT4\ul0 \v 100BT4\v0 \par \ul 100BaseFx\ul0 \v 100BFX\v0 \par \ul 10BaseT\ul0 \v 10BT\v0 \par \ul 10BaseT Full_Duplex\ul0 \v 10BT_FD\v0 \par \ul 10BaseT No_Link_Test\ul0 \v 10BT_NLT\v0 \par \ul 10Base2 (BNC)\ul0 \v 10B2\v0 \par \page
+${\footnote $ DEC multia's Ethernet Controller}
+#{\footnote # MULTIA_TITLE}
++{\footnote + 00012}
+\keepn \f9 \fs24 \cf0 DEC multia's Ethernet Controller \par \pard \f9 \fs24 \pard \fs20 \cf0 Use this dialog box to setup the medium connection for Digital Equipment Corporation multia's Ethernet Controller.\par \par\ul AutoDetect\ul0 \v AUTODETECT\v0 \par \ul Twisted_Pair (10BaseT)\ul0 \v 10BT\v0 \par \ul Twisted_Pair Full_Duplex\ul0 \v 10BT_FD\v0 \par \ul Twisted_Pair No_Link_Test\ul0 \v 10BT_NLT\v0 \par \ul BNC (10Base2)\ul0 \v 10B2\v0 \par \ul AUI (10Base5)\ul0 \v 10B5\v0 \par \page
+${\footnote $ DEC DE434 EtherWORKS Turbo PCI TP Adapter}
+#{\footnote # DE434_TITLE}
++{\footnote + 00013}
+\keepn \f9 \fs24 \cf0 DEC DE434 EtherWORKS Turbo PCI TP Adapter\par \pard \f9 \fs24 \pard \fs20 \cf0 Use this dialog box to setup the medium connection for Digital Equipment Corporation's DE434 EtherWORKS Turbo PCI TP Adapter.\par \par \ul AutoDetect\ul0 \v AUTODETECT\v0 \par \ul Twisted_Pair (10BaseT)\ul0 \v 10BT\v0 \par \ul Twisted_Pair Full_Duplex\ul0 \v 10BT_FD\v0 \par \ul Twisted_Pair No_Link_Test\ul0 \v 10BT_NLT\v0 \par \page
+${\footnote $ DEC DE435 EtherWORKS Turbo PCI Adapter}
+#{\footnote # DE435_TITLE}
++{\footnote + 00014}
+\keepn \f9 \fs24 \cf0 DEC DE435 EtherWORKS Turbo PCI Adapter\par \pard \f9 \fs24 \pard \fs20 \cf0 Use this dialog box to setup the medium connection for Digital Equipment Corporation's DE435 EtherWORKS Turbo PCI Adapter.\par \par \ul AutoDetect\ul0 \v AUTODETECT\v0 \par \ul Twisted_Pair (10BaseT)\ul0 \v 10BT\v0 \par \ul Twisted_Pair Full_Duplex\ul0 \v 10BT_FD\v0 \par \ul Twisted_Pair No_Link_Test\ul0 \v 10BT_NLT\v0 \par \ul BNC (10Base2)\ul0 \v 10B2\v0 \par \ul AUI (10Base5)\ul0 \v 10B5\v0 \par \page
+${\footnote $ DEC DE436 EtherWORKS Turbo PCI Quad Adapter}
+#{\footnote # DE436_TITLE}
++{\footnote + 00015}
+\keepn \f9 \fs24 \cf0 DEC DE436 EtherWORKS Turbo PCI Quad Adapter\par \pard \f9 \fs24 \pard \fs20 \cf0 Use this dialog box to setup the medium connection for Digital Equipment Corporation's DE436 EtherWORKS Turbo PCI Quad Adapter.\par \par \ul AutoDetect\ul0 \v AUTODETECT\v0 \par \ul Twisted_Pair (10BaseT)\ul0 \v 10BT\v0 \par \ul Twisted_Pair Full_Duplex\ul0 \v 10BT_FD\v0 \par \ul Twisted_Pair No_Link_Test\ul0 \v 10BT_NLT\v0 \par \page
+${\footnote $ DEC DE435 EtherWORKS Turbo PCI Adapter}
+#{\footnote # DE450_TITLE}
++{\footnote + 00016}
+\keepn \f9 \fs24 \cf0 DEC DE450 EtherWORKS Turbo PCI Adapter\par \pard \f9 \fs24 \pard \fs20 \cf0 Use this dialog box to setup the medium connection for Digital Equipment Corporation's DE450 EtherWORKS Turbo PCI Adapter.\par \par \ul AutoDetect\ul0 \v AUTODETECT\v0 \par \ul Twisted_Pair (10BaseT)\ul0 \v 10BT\v0 \par \ul Twisted_Pair Full_Duplex\ul0 \v 10BT_FD\v0 \par \ul Twisted_Pair No_Link_Test\ul0 \v 10BT_NLT\v0 \par \ul BNC (10Base2)\ul0 \v 10B2\v0 \par \ul AUI (10Base5)\ul0 \v 10B5\v0 \par \page
+${\footnote $ DEC DE500 FastEtherWORKS Turbo PCI Adapter}
+#{\footnote # DE500_TITLE}
++{\footnote + 00017}
+\keepn \f9 \fs24 \cf0 DEC DE500 FastEtherWORKS Turbo PCI Adapter\par \pard \f9 \fs24 \pard \fs20 \cf0 Use this dialog box to setup the medium connection for Digital Equipment Corporation's DE500 FastEtherWORKS Turbo PCI Adapter.\par \par \ul AutoSense\ul0 \v AUTOSENSE\v0 \par \ul 100BaseTx\ul0 \v 100BTX\v0 \par \ul 100BaseTx Full_Duplex\ul0 \v 10BT_FD\v0 \par \ul 10BaseT\ul0 \v 10BT\v0 \par \ul 10BaseT Full_Duplex\ul0 \v 10BT_FD\v0 \par \page
+${\footnote $ AutoDetect}
+#{\footnote # AUTODETECT}
++{\footnote + 00018}
+\f9 \fs24 \pard \fs20 \cf0 Check once the 10BaseT (TP), 10Base2 (BNC) and 10Base5 (AUI) media ports and select the first live media. \par This detection takes place during driver initialization: the wire should be connected \b before\b0 the system boots and media \b cannot \b0 be switched during run time.\par AutoDectect does\cf10 \cf1 \b not\b0 check 10BaseT's Full_Duplex and No_Link_Test modes.\par \fs24 \page
+${\footnote $ AutoSense}
+#{\footnote # AUTOSENSE}
++{\footnote + 00019}
+\f9 \fs24 \pard \fs20 \cf0 Autosense the media ports supported by the Adapter and dynamically switch to the live media.\par (AutoSense does \b not \b0 sense 10BaseT's No_Link_Test mode.)\par \fs24 \page
+${\footnote $ AutoSense - No_Nway}
+#{\footnote # AUTOSENSE_NW}
++{\footnote + 00020}
+\f9 \fs24 \pard \fs20 \cf0 Autosense the media ports supported by the Adapter and dynamically switch to the live media.\par Nway's negociation is\b disabled\b0 .\par (AutoSense no_Nway does \b not \b0 sense 10BaseT's No_Link_Test mode.)\par \page
+${\footnote $ 10BaseT}
+#{\footnote # 10BT}
++{\footnote + 00021}
+\f9 \fs24 \pard \fs20 \cf0 Select the 10BaseT medium connection (RJ connector).\par \fs24 \page
+${\footnote $ 10BaseT - Full_Duplex}
+#{\footnote # 10BT_FD}
++{\footnote + 00022}
+\f9 \fs24 \pard \fs20 \cf0 Select the 10BaseT Full_Duplex medium connection (RJ connector).\par \page
+${\footnote $ 10BaseT No_Link_Test}
+#{\footnote # 10BT_NLT}
++{\footnote + 00023}
+\f9 \fs24 \pard \fs20 \cf0 Select the 10BaseT medium connection (RJ connector) with no Link Integrity Test.\par Choose this option if the Adapter is connected to a hub which does \b not\b0 generate link pulses to check the link integrity.\par \fs24 \page
+${\footnote $ 10Base2 - BNC}
+#{\footnote # 10B2}
++{\footnote + 00024}
+\f9 \fs24 \pard \fs20 \cf0 Select the 10Base2 medium connection (BNC connector).\par \fs24 \page
+${\footnote $ 10Base5 - AUI}
+#{\footnote # 10B5}
++{\footnote + 00025}
+\f9 \fs24 \pard \fs20 \cf0 Select the 10Base5 medium connection (AUI 15_pin connector).\par \fs24 \page
+${\footnote $ 100BaseTx}
+#{\footnote # 100BTX}
++{\footnote + 00026}
+\f9 \fs24 \pard \fs20 \cf0 Select the Fast Ethernet 100BaseTx medium connection (RJ connector).\par \fs24 \page
+${\footnote $ 100BaseTx Full_Duplex}
+#{\footnote # 100BTX_FD}
++{\footnote + 00027}
+\f9 \fs24 \pard \fs20 \cf0 Select the Fast Ethernet 100BaseTx Full_Duplex medium connection (RJ connector).\par \page
+${\footnote $ 100BaseT4}
+#{\footnote # 100BT4}
++{\footnote + 00028}
+\f9 \fs24 \pard \fs20 \cf0 Select the Fast Ethernet 100BaseT4 medium connection (RJ connector).\par \fs24 \page
+${\footnote $ 100BaseFx}
+#{\footnote # 100BFX}
++{\footnote + 00029}
+\f9 \fs24 \pard \fs20 \cf0 Select the Fast Ethernet 100BaseFx medium connection.\par \fs24 \page
+}
diff --git a/private/ntos/ndis/dc21x4/filter.c b/private/ntos/ndis/dc21x4/filter.c
new file mode 100644
index 000000000..d358f5d35
--- /dev/null
+++ b/private/ntos/ndis/dc21x4/filter.c
@@ -0,0 +1,758 @@
+/*+
+ * file: filter.c
+ *
+ * Copyright (C) 1992-1995 by
+ * Digital Equipment Corporation, Maynard, Massachusetts.
+ * All rights reserved.
+ *
+ * This software is furnished under a license and may be used and copied
+ * only in accordance of the terms of such license and with the
+ * inclusion of the above copyright notice. This software or any other
+ * copies thereof may not be provided or otherwise made available to any
+ * other person. No title to and ownership of the software is hereby
+ * transferred.
+ *
+ * The information in this software is subject to change without notice
+ * and should not be construed as a commitment by digital equipment
+ * corporation.
+ *
+ * Digital assumes no responsibility for the use or reliability of its
+ * software on equipment which is not supplied by digital.
+ *
+ *
+ * Abstract: This file is part of the NDIS 4.0 miniport driver for DEC's
+ * DC21X4 Ethernet adapter family.
+ *
+ * Author: Philippe Klein
+ *
+ * Revision History:
+ *
+ * phk 31-Jul-94 Creation date
+ *
+ * phk 18-dec-94 Add a dummy descriptor in front of the setup
+ * descriptor to cover the underrun before
+ * setup descriptor case.
+ *
+-*/
+
+#include <precomp.h>
+
+
+
+
+#pragma NDIS_PAGABLE_FUNCTION(DC21X4InitializeCam)
+
+/*+
+ *
+ * DC21X4InitializeCam
+ *
+ * Routine Description:
+ *
+ * Initialize the DC21X4 CAM
+ *
+-*/
+extern
+VOID
+DC21X4InitializeCam (
+ IN PDC21X4_ADAPTER Adapter,
+ IN PUSHORT Address
+ )
+{
+
+ UINT i;
+ PDC21X4_SETUP_BUFFER SetupBuffer;
+
+ SetupBuffer = (PDC21X4_SETUP_BUFFER)Adapter->SetupBufferVa;
+
+ // Perfect Filtering Setup Buffer
+
+ Adapter->FilteringMode = DC21X4_PERFECT_FILTERING;
+
+ // Copy Address into the first entry
+
+ for (i=0; i<3; i++) {
+
+ (USHORT)(SetupBuffer->Perfect.PhysicalAddress[0][i]) = *Address++;
+ }
+
+ // Duplicate the first entry in all the remaining
+ // entries of the filter
+
+ for (i = 1; i < DC21X4_SETUP_PERFECT_ENTRIES; i++) {
+
+ MOVE_MEMORY(
+ SetupBuffer->Perfect.PhysicalAddress[i],
+ SetupBuffer->Perfect.PhysicalAddress[0],
+ sizeof(ULONG)*3
+ );
+ }
+
+ return;
+}
+
+
+
+
+
+
+
+
+
+
+/*+
+ *
+ * DC21X4LoadCam
+ *
+ * Routine Description:
+ *
+ * Load the Setup Buffer into DC21X4's CAM
+ *
+ * Arguments:
+ *
+ * Adapter - the Adapter for the hardware
+ * InterruptMode - Synchronize the Setup Buffer completion on interrupt
+ *
+-*/
+extern
+BOOLEAN
+DC21X4LoadCam (
+ IN PDC21X4_ADAPTER Adapter,
+ IN BOOLEAN InterruptMode
+ )
+{
+ PDC21X4_TRANSMIT_DESCRIPTOR SetupDescriptor;
+ PDC21X4_TRANSMIT_DESCRIPTOR DummyDescriptor;
+ UINT Time = DC21X4_SETUP_TIMEOUT;
+ ULONG DC21X4Status;
+ ULONG DC21X4Command;
+
+#if _DBG
+ PULONG t;
+ UINT i;
+ DbgPrint("DC21X4LoadCam\n");
+#endif
+
+
+ if (!InterruptMode) {
+
+ // Mask the interrupts
+ DC21X4_WRITE_PORT(
+ DC21X4_INTERRUPT_MASK,
+ 0
+ );
+ }
+
+
+ if (Adapter->FullDuplex) {
+ NdisDprAcquireSpinLock(&Adapter->EnqueueSpinLock);
+ }
+
+ DummyDescriptor = Adapter->EnqueueTransmitDescriptor;
+ Adapter->EnqueueTransmitDescriptor = (Adapter->EnqueueTransmitDescriptor)->Next;
+
+ SetupDescriptor = Adapter->EnqueueTransmitDescriptor;
+ Adapter->EnqueueTransmitDescriptor = (Adapter->EnqueueTransmitDescriptor)->Next;
+
+ if (Adapter->FullDuplex) {
+ NdisDprReleaseSpinLock(&Adapter->EnqueueSpinLock);
+ NdisDprAcquireSpinLock(&Adapter->FullDuplexSpinLock);
+ }
+
+ Adapter->FreeTransmitDescriptorCount -= 2;
+
+ if (Adapter->FullDuplex) {
+ NdisDprReleaseSpinLock(&Adapter->FullDuplexSpinLock);
+ }
+
+ // Initialize the Dummy descriptor
+
+ DummyDescriptor->Control &= DC21X4_TDES_SECOND_ADDR_CHAINED;
+ DummyDescriptor->FirstBufferAddress = 0;
+ DummyDescriptor->Status = DESC_OWNED_BY_DC21X4;
+
+ // Initialize the Setup descriptor
+
+ SetupDescriptor->Control &= DC21X4_TDES_SECOND_ADDR_CHAINED;
+ SetupDescriptor->Control |=
+ (DC21X4_TDES_SETUP_PACKET | DC21X4_TDES_INTERRUPT_ON_COMPLETION
+ | DC21X4_SETUP_BUFFER_SIZE);
+
+ if (Adapter->FilteringMode != DC21X4_PERFECT_FILTERING) {
+ SetupDescriptor->Control |= DC21X4_TDES_HASH_FILTERING;
+ }
+
+ SetupDescriptor->FirstBufferAddress = Adapter->SetupBufferPa;
+ SetupDescriptor->Status = DESC_OWNED_BY_DC21X4;
+
+#if _DBG
+ DbgPrint("Setup Descriptor: %08x\n %08x\n %08x\n %08x\n %08x\n",
+ SetupDescriptor,
+ SetupDescriptor->Status,
+ SetupDescriptor->Control,
+ SetupDescriptor->FirstBufferAddress,
+ SetupDescriptor->SecondBufferAddress);
+
+ t = (PULONG)Adapter->SetupBufferVa;
+ DbgPrint("Setup buffer:\n");
+ for (i = 0; i < 16; i++, t+=3) {
+ DbgPrint(" [%08x] %08x %08x %08x\n",t,*t,*(t+1),*(t+2));
+ }
+#endif
+
+
+ // Start or Poll the Transmitter to process the Setup Frame
+
+ if ((Adapter->DeviceId == DC21040_CFID) &&
+ (Adapter->RevisionNumber == DC21040_REV1)) {
+
+ // Txm hang workaround : Disable the SIA before
+ // writing the Operation Mode register
+ // SFD workaround : Disable the Receiver before processing
+ // the setup packet
+
+ DC21X4_WRITE_PORT(
+ DC21X4_SIA_MODE_0,
+ DC21X4_RESET_SIA
+ );
+
+ NdisStallExecution(1*MILLISECOND); // Wait 1 ms
+
+ DC21X4_WRITE_PORT(
+ DC21X4_OPERATION_MODE,
+ (Adapter->OperationMode & ~DC21X4_RCV_START)
+ );
+ }
+
+ DC21X4_READ_PORT(
+ DC21X4_OPERATION_MODE,
+ &DC21X4Command
+ );
+
+ if (DC21X4Command & DC21X4_TXM_START) {
+
+ DC21X4_WRITE_PORT(
+ DC21X4_OPERATION_MODE,
+ Adapter->OperationMode
+ );
+
+ if (!Adapter->DisableTransmitPolling) {
+
+#if _DBG
+ DbgPrint(" Txm Poll_demand\n");
+#endif
+ DC21X4_WRITE_PORT(
+ DC21X4_TXM_POLL_DEMAND,
+ 1
+ );
+ }
+
+ }
+ else {
+#if _DBG
+ DbgPrint(" Start Txm\n");
+#endif
+ Adapter->OperationMode |= DC21X4_TXM_START;
+ DC21X4_WRITE_PORT(
+ DC21X4_OPERATION_MODE,
+ Adapter->OperationMode
+ );
+ }
+
+ if (InterruptMode) {
+ return TRUE;
+ }
+ else {
+
+ // Poll for completion
+
+ while (Time--) {
+
+ NdisStallExecution(5*MILLISECOND); //wait 5 ms
+
+ DC21X4_READ_PORT(
+ DC21X4_STATUS,
+ &DC21X4Status
+ );
+
+ if (DC21X4Status & DC21X4_TXM_BUFFER_UNAVAILABLE) {
+
+ DC21X4_WRITE_PORT(
+ DC21X4_STATUS,
+ DC21X4_TXM_INTERRUPTS
+ );
+ break;
+ }
+
+ }
+
+ Adapter->DequeueTransmitDescriptor =
+ ((Adapter->DequeueTransmitDescriptor)->Next)->Next;
+
+ if (Adapter->FullDuplex) {
+ NdisDprAcquireSpinLock(&Adapter->FullDuplexSpinLock);
+ }
+
+ Adapter->FreeTransmitDescriptorCount += 2;
+
+ if (Adapter->FullDuplex) {
+ NdisDprReleaseSpinLock(&Adapter->FullDuplexSpinLock);
+ }
+
+ if ((Adapter->DeviceId == DC21040_CFID) &&
+ (Adapter->RevisionNumber == DC21040_REV1)) {
+
+ //Restart the Receiver and Enable the SIA
+
+ DC21X4_WRITE_PORT(
+ DC21X4_OPERATION_MODE,
+ Adapter->OperationMode
+ );
+
+ DC21X4_WRITE_PORT(
+ DC21X4_SIA_MODE_0,
+ Adapter->Media[Adapter->SelectedMedium].SiaRegister[0]
+ );
+ }
+
+ if (Time > 0) {
+
+ //Restore the interrupt mask
+ DC21X4_WRITE_PORT(
+ DC21X4_INTERRUPT_MASK,
+ Adapter->InterruptMask
+ );
+
+ return TRUE;
+ }
+ else {
+ return FALSE;
+ }
+
+ }
+
+}
+
+
+
+
+
+
+
+
+
+
+
+
+/*++
+ *
+ * DC21X4ChangeFilter
+ *
+ * Routine Description:
+ *
+ * Action routine called when a filter class is modified
+ *
+-*/
+extern
+NDIS_STATUS
+DC21X4ChangeFilter (
+ IN PDC21X4_ADAPTER Adapter,
+ IN ULONG NewFilterClass
+ )
+{
+
+ ULONG Command;
+ ULONG PrevFilterClass;
+
+#if _DBG
+ DbgPrint("DC21X4ChangeClasses NewClass= %x\n",NewFilterClass);
+#endif
+
+ PrevFilterClass = Adapter->FilterClass;
+ Adapter->FilterClass = NewFilterClass;
+
+ Command = Adapter->OperationMode &
+ ~(DC21X4_PROMISCUOUS_MODE | DC21X4_PASS_ALL_MULTICAST);
+
+ if (NewFilterClass & NDIS_PACKET_TYPE_PROMISCUOUS) {
+#if _DBG
+ DbgPrint(" Promiscuous Mode\n");
+#endif
+ Command |= DC21X4_PROMISCUOUS_MODE;
+ }
+
+ else if (NewFilterClass & NDIS_PACKET_TYPE_ALL_MULTICAST) {
+#if _DBG
+ DbgPrint(" All_Multicast Mode\n");
+#endif
+ Command |= DC21X4_PASS_ALL_MULTICAST;
+ }
+
+ if (NewFilterClass & NDIS_PACKET_TYPE_BROADCAST) {
+
+#if _DBG
+ DbgPrint(" Broadcast Mode\n");
+#endif
+ // If broadcast was not previously enabled an entry for the
+ // broadcast address should be added into the CAM
+
+ if (!(PrevFilterClass & NDIS_PACKET_TYPE_BROADCAST)) {
+
+ AddBroadcastToSetup (
+ Adapter
+ );
+ Adapter->OperationMode = Command;
+
+ DC21X4LoadCam(
+ Adapter,
+ TRUE
+ );
+
+ return NDIS_STATUS_PENDING;
+ }
+ }
+
+ else if (PrevFilterClass & NDIS_PACKET_TYPE_BROADCAST) {
+
+ // Broadcast was previously enabled and should be
+ // disabled now by removing the braodcast address entry
+ // from to CAM
+
+ RemoveBroadcastFromSetup (
+ Adapter
+ );
+ Adapter->OperationMode = Command;
+
+ DC21X4LoadCam(
+ Adapter,
+ TRUE
+ );
+
+ return NDIS_STATUS_PENDING;
+ }
+
+ if (Command != Adapter->OperationMode) {
+
+ // Modify the DC21X4 Serial Command Register
+
+ Adapter->OperationMode = Command;
+
+ switch (Adapter->DeviceId) {
+
+ case DC21040_CFID:
+
+ if (Adapter->RevisionNumber == DC21040_REV1) {
+
+ // Txm hang workaround : Disable the SIA before
+ // writing the Operation Mode register
+
+ DC21X4_WRITE_PORT(
+ DC21X4_SIA_MODE_0,
+ DC21X4_RESET_SIA
+ );
+
+ NdisStallExecution(1*MILLISECOND); // Wait 1 ms
+
+
+ DC21X4_WRITE_PORT(
+ DC21X4_OPERATION_MODE,
+ Adapter->OperationMode
+ );
+
+ DC21X4_WRITE_PORT(
+ DC21X4_SIA_MODE_0,
+ Adapter->Media[Adapter->SelectedMedium].SiaRegister[0]
+ );
+ break;
+ }
+
+ default:
+
+ DC21X4_WRITE_PORT(
+ DC21X4_OPERATION_MODE,
+ Adapter->OperationMode
+ );
+ }
+
+ }
+
+ return NDIS_STATUS_SUCCESS;
+}
+
+
+
+
+
+
+
+
+
+
+/*+
+ *
+ * AddBroadcastToSetup (Adapter);
+ *
+ * Routine Description:
+ *
+ * Add the Broadcast address to the DC21X4 Setup Buffer
+ *
+-*/
+
+VOID
+AddBroadcastToSetup (
+ IN PDC21X4_ADAPTER Adapter
+ )
+
+{
+
+ PDC21X4_SETUP_BUFFER SetupBuffer;
+ UINT i;
+
+#if _DBG
+ PULONG t;
+ DbgPrint("AddBroadcastToSetup\n");
+#endif
+
+ SetupBuffer = (PDC21X4_SETUP_BUFFER)Adapter->SetupBufferVa;
+
+ if (Adapter->FilteringMode == DC21X4_PERFECT_FILTERING) {
+
+ // Load the broadcast address in the second entry
+ // of the Setup Buffer
+
+ for (i=0; i<3; i++) {
+
+ SetupBuffer->Perfect.PhysicalAddress[1][i] = 0x0000ffff;
+ }
+
+ }
+ else {
+
+ // Add the Broadcast hit to the Hash Filter
+ // (HashIndex(Broadcast_address) = 255)
+
+ SetupBuffer->Hash.Filter[15] |= 0x8000;
+ }
+
+}
+
+
+
+
+
+
+
+
+
+
+/*+
+ *
+ * RemoveBroadcastFromSetup (Adapter);
+ *
+ * Routine Description:
+ *
+ * Remove the Broadcast address from the DC21X4 Setup Buffer
+ *
+-*/
+
+VOID
+RemoveBroadcastFromSetup (
+ IN PDC21X4_ADAPTER Adapter
+ )
+{
+
+ PDC21X4_SETUP_BUFFER SetupBuffer;
+
+#if _DBG
+ DbgPrint("RemoveBroadcastFromSetup\n");
+#endif
+
+ SetupBuffer = (PDC21X4_SETUP_BUFFER)Adapter->SetupBufferVa;
+
+ if (Adapter->FilteringMode == DC21X4_PERFECT_FILTERING) {
+
+ // Duplicate the Adapter entry (1st entry) into the
+ // broadcast entry (2nd entry)
+
+ MOVE_MEMORY (
+ SetupBuffer->Perfect.PhysicalAddress[1],
+ SetupBuffer->Perfect.PhysicalAddress[0],
+ sizeof(ULONG)*3
+ );
+ }
+ else {
+
+ // Remove the Broadcast hit from the Hash Filter
+ // (HashIndex(Broadcast_address) = 255)
+
+ SetupBuffer->Hash.Filter[15] &= ~0x8000;
+ }
+}
+
+
+
+
+
+
+
+
+
+
+/*+
+ *
+ * DC21X4ChangeAddresses
+ *
+ * Routine Description:
+ *
+ * Load a new Multicast Addresse list into the adapter's CAM
+ *
+-*/
+extern
+NDIS_STATUS
+DC21X4ChangeMulticastAddresses(
+ IN PDC21X4_ADAPTER Adapter,
+ IN PVOID MulticastAddresses,
+ IN UINT AddressCount
+ )
+
+{
+ PDC21X4_SETUP_BUFFER SetupBuffer;
+
+ PUSHORT AsUShort;
+ PUCHAR MultAddr;
+ PULONG Buffer;
+ UINT HashIndex;
+ UINT i;
+
+#if _DBG
+ DbgPrint("DC21X4ChangeMulticastAddresses\n");
+#endif
+
+ if (AddressCount > Adapter->MaxMulticastAddresses) {
+ return NDIS_STATUS_MULTICAST_FULL;
+ }
+
+ SetupBuffer = (PDC21X4_SETUP_BUFFER)Adapter->SetupBufferVa;
+
+ // Reinitialize the Setup Buffer and load the DC21X4's CAM
+
+ if (AddressCount <= DC21X4_MAX_MULTICAST_PERFECT) {
+
+#if _DBG
+ DbgPrint("Perfect Filtering\n");
+#endif
+ // Perfect Filtering
+
+ //The first entry is the Adapter address
+
+ AsUShort = (PUSHORT)Adapter->CurrentNetworkAddress;
+
+ for (i=0; i<3; i++,AsUShort++) {
+
+ (USHORT)(SetupBuffer->Perfect.PhysicalAddress[0][i]) = *AsUShort;
+ }
+
+ //The second entry is a broadcast address if Broadcast_Enable
+ //otherwise it is a duplicate of the first entry
+
+ if ( Adapter->FilterClass & NDIS_PACKET_TYPE_BROADCAST) {
+
+ for (i=0; i<3; i++) {
+
+ SetupBuffer->Perfect.PhysicalAddress[1][i] = 0x0000ffff;
+ }
+ }
+ else {
+ MOVE_MEMORY (
+ SetupBuffer->Perfect.PhysicalAddress[1],
+ SetupBuffer->Perfect.PhysicalAddress[0],
+ sizeof(ULONG)*3
+ );
+ }
+
+ // Load the new multicast list;
+
+ AsUShort = (PUSHORT)MulticastAddresses;
+ Buffer = (PULONG)SetupBuffer->Perfect.PhysicalAddress[2];
+
+ for (i=0; i< AddressCount * 3; i++,AsUShort++) {
+ *(PUSHORT)Buffer = *AsUShort;
+ Buffer++;
+ }
+
+ // Duplicate the Adapter adress in the remaining entries
+ // of the buffer
+
+ for (i=AddressCount+2; i< DC21X4_SETUP_PERFECT_ENTRIES; i++ ) {
+
+ MOVE_MEMORY(
+ SetupBuffer->Perfect.PhysicalAddress[i],
+ SetupBuffer->Perfect.PhysicalAddress[0],
+ sizeof(ULONG)*3
+ );
+ }
+
+ Adapter->FilteringMode = DC21X4_PERFECT_FILTERING;
+
+ }
+
+ else {
+
+
+#if _DBG
+ DbgPrint("Hashing\n");
+#endif
+ //Hashing
+
+ // Initialize the SetupBuffer
+
+ NdisZeroMemory (
+ (PVOID)(SetupBuffer->Hash.Filter),
+ (ULONG)(sizeof(SetupBuffer->Hash))
+ );
+
+ // Load the hash filter
+
+ MultAddr = (PUCHAR)MulticastAddresses;
+ for (i=0; i < AddressCount; i++, MultAddr += ETH_LENGTH_OF_ADDRESS) {
+
+ if (IS_MULTICAST(MultAddr)) {
+
+ HashIndex = ~CRC32(MultAddr,ETH_LENGTH_OF_ADDRESS) & 0x1FF;
+ SetupBuffer->Hash.Filter[HashIndex/16] |= (1 << (HashIndex % 16));
+#if _DBG
+ DbgPrint(" >>HashIndex = %d [%d]bit=%d\n",HashIndex,(HashIndex/16),(HashIndex%16));
+#endif
+ }
+
+ }
+
+
+ if (Adapter->FilterClass & NDIS_PACKET_TYPE_BROADCAST) {
+
+ // Add the Broadcast entry to the Hash Filter
+ // (Hash_Index(Broadcast_address) = 255)
+
+ SetupBuffer->Hash.Filter[15] |= 0x80000;
+ }
+
+ // Load the Adapter Address
+
+ AsUShort = (PUSHORT)Adapter->CurrentNetworkAddress;
+ for (i=0; i<3; i++, AsUShort++) {
+
+ (USHORT)(SetupBuffer->Hash.PhysicalAddress[i]) = *AsUShort;
+ }
+
+ Adapter->FilteringMode = DC21X4_HASH_FILTERING;
+ }
+
+ DC21X4LoadCam(
+ Adapter,
+ TRUE
+ );
+
+ return NDIS_STATUS_PENDING;
+
+}
+
+
diff --git a/private/ntos/ndis/dc21x4/init.c b/private/ntos/ndis/dc21x4/init.c
new file mode 100644
index 000000000..915a085fc
--- /dev/null
+++ b/private/ntos/ndis/dc21x4/init.c
@@ -0,0 +1,881 @@
+/*+
+ * file: init.c
+ *
+ * Copyright (C) 1992-1995 by
+ * Digital Equipment Corporation, Maynard, Massachusetts.
+ * All rights reserved.
+ *
+ * This software is furnished under a license and may be used and copied
+ * only in accordance of the terms of such license and with the
+ * inclusion of the above copyright notice. This software or any other
+ * copies thereof may not be provided or otherwise made available to any
+ * other person. No title to and ownership of the software is hereby
+ * transferred.
+ *
+ * The information in this software is subject to change without notice
+ * and should not be construed as a commitment by digital equipment
+ * corporation.
+ *
+ * Digital assumes no responsibility for the use or reliability of its
+ * software on equipment which is not supplied by digital.
+ *
+ *
+ * Abstract: This file is part of the NDIS 4.0 miniport driver for
+ * DEC's DC21X4 Ethernet Adapter family.
+ * It contains the adapter's register initialization routines
+ *
+ * Author: Philippe Klein
+ *
+ * Revision History:
+ *
+ * phk 28-Aug-1992 Initial entry
+ *
+-*/
+
+#include <precomp.h>
+
+
+
+
+
+
+
+
+
+
+/*+
+ *
+ * DC21X4InitPciConfigurationRegisters
+ *
+ * Routine Description:
+ *
+ * This routine initialize the DC21X4 PCI Configuration
+ * Registers
+ *
+ * Arguments:
+ *
+ * Adapter - The adapter whose hardware is to be initialized.
+ *
+ * Return Value:
+ *
+ * NONE
+ *
+-*/
+extern
+VOID
+DC21X4InitPciConfigurationRegisters(
+ IN PDC21X4_ADAPTER Adapter
+ )
+{
+
+ ULONG Value;
+ BOOLEAN SetTimer = FALSE;
+
+#if _DBG
+ DbgPrint("DC21X4InitPciConfigurationRegisters\n");
+#endif
+
+ switch (Adapter->AdapterType) {
+
+ case NdisInterfacePci:
+
+ //initialize the Command Register
+
+ NdisWritePciSlotInformation(
+ Adapter->MiniportAdapterHandle,
+ Adapter->SlotNumber,
+ PCI_CFCS_OFFSET,
+ &Adapter->PciCommand,
+ sizeof(Adapter->PciCommand)
+ );
+
+ //initialize the latency timer if not initialized already
+ //or if a latency value has been stored in the Registry
+
+ if (Adapter->PciLatencyTimer) {
+ SetTimer = TRUE;
+ }
+ else {
+ NdisReadPciSlotInformation(
+ Adapter->MiniportAdapterHandle,
+ Adapter->SlotNumber,
+ PCI_CFLT_OFFSET,
+ &Adapter->PciLatencyTimer,
+ sizeof(Adapter->PciLatencyTimer)
+ );
+
+ if (Adapter->PciLatencyTimer == 0) {
+ Adapter->PciLatencyTimer =
+ DC21X4_PCI_LATENCY_TIMER_DEFAULT_VALUE;
+ SetTimer = TRUE;
+ }
+ }
+
+ if (SetTimer) {
+
+ NdisWritePciSlotInformation(
+ Adapter->MiniportAdapterHandle,
+ Adapter->SlotNumber,
+ PCI_CFLT_OFFSET,
+ &Adapter->PciLatencyTimer,
+ sizeof(Adapter->PciLatencyTimer)
+ );
+ }
+
+ // Initialize the CFDA Register
+
+ NdisWritePciSlotInformation(
+ Adapter->MiniportAdapterHandle,
+ Adapter->SlotNumber,
+ PCI_CFDA_OFFSET,
+ &Adapter->PciDriverArea,
+ sizeof(Adapter->PciDriverArea)
+ );
+
+#if __DBG
+ NdisReadPciSlotInformation(
+ Adapter->MiniportAdapterHandle,
+ Adapter->SlotNumber,
+ PCI_CFCS_OFFSET,
+ &Value,
+ sizeof(Value)
+ );
+
+ DbgPrint("CFCS = %08x\n",Value);
+
+ NdisReadPciSlotInformation(
+ Adapter->MiniportAdapterHandle,
+ Adapter->SlotNumber,
+ PCI_CFLT_OFFSET,
+ &Value,
+ sizeof(Value)
+ );
+
+ DbgPrint("CFLT = %08x\n",Value);
+
+
+ NdisReadPciSlotInformation(
+ Adapter->MiniportAdapterHandle,
+ Adapter->SlotNumber,
+ PCI_CBIO_OFFSET,
+ &Value,
+ sizeof(Value)
+ );
+
+ DbgPrint("CBIO = %08x\n",Value);
+
+ NdisReadPciSlotInformation(
+ Adapter->MiniportAdapterHandle,
+ Adapter->SlotNumber,
+ PCI_CFDA_OFFSET,
+ &Value,
+ sizeof(Value)
+ );
+
+ DbgPrint("CFDA = %08x\n",Value);
+
+#endif
+
+ break;
+
+ case NdisInterfaceEisa:
+
+ DC21X4_WRITE_PCI_REGISTER(
+ DC21X4_PCI_COMMAND,
+ Adapter->PciCommand
+ );
+
+ DC21X4_WRITE_PCI_REGISTER(
+ DC21X4_PCI_LATENCY_TIMER,
+ DC21X4_PCI_LATENCY_TIMER_DEFAULT_VALUE
+ );
+
+ DC21X4_WRITE_PCI_REGISTER(
+ DC21X4_PCI_BASE_IO_ADDRESS,
+ (Adapter->IOBaseAddress | DC21X4_IO_SPACE)
+ );
+ }
+
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+/*+
+ *
+ * DC21X4InitializeRegisters
+ *
+ * Routine Description:
+ *
+ * This routine initialize the DC21X4 CSRs
+ *
+ * Arguments:
+ *
+ * Adapter - The adapter whose hardware is to be initialized.
+ *
+ * Return Value:
+ *
+ * NONE
+ *
+-*/
+extern
+VOID
+DC21X4InitializeRegisters(
+ IN PDC21X4_ADAPTER Adapter
+ )
+{
+
+ UINT i;
+
+ PDC21X4_TRANSMIT_DESCRIPTOR TransmitDescriptor;
+ PDC21X4_RECEIVE_DESCRIPTOR ReceiveDescriptor;
+
+ // Reset DC21X4
+
+ DC21X4StopAdapter(Adapter);
+
+ switch (Adapter->AdapterType) {
+
+ case NdisInterfaceEisa:
+
+ DC21X4InitPciConfigurationRegisters (Adapter);
+ break;
+
+ case NdisInterfacePci:
+
+ switch (Adapter->DeviceId) {
+
+ case DC21040_CFID :
+
+ if (Adapter->RevisionNumber == DC21040_REV1) {
+
+ // The PCI configuration registers should
+ // be reinitialized after reset
+
+ DC21X4InitPciConfigurationRegisters (Adapter);
+ }
+ break;
+
+ case DC21140_CFID :
+
+ //Initialize PortSelect and reset the chip
+ DC21X4_WRITE_PORT(
+ DC21X4_OPERATION_MODE,
+ Adapter->OperationMode & ~(DC21X4_RCV_START | DC21X4_TXM_START)
+ );
+
+ DC21X4StopAdapter(Adapter);
+
+ break;
+ }
+ }
+
+ // Initialize the descriptor ownership in the
+ // Transmit and Receive descriptor rings
+
+ for (i=0,
+ TransmitDescriptor = (PDC21X4_TRANSMIT_DESCRIPTOR)Adapter->TransmitDescriptorRingVa;
+ i < TRANSMIT_RING_SIZE;
+ i++) {
+ TransmitDescriptor->Status = DESC_OWNED_BY_SYSTEM;
+ TransmitDescriptor = TransmitDescriptor->Next;
+ }
+
+ for (i=0,
+ ReceiveDescriptor = (PDC21X4_RECEIVE_DESCRIPTOR)Adapter->ReceiveDescriptorRingVa;
+ i < Adapter->ReceiveRingSize;
+ i++) {
+ ReceiveDescriptor->Status = DESC_OWNED_BY_DC21X4;
+ ReceiveDescriptor = ReceiveDescriptor->Next;
+ }
+
+ // Initialize the DC21X4 CSRs
+
+#if _DBG
+ DbgPrint(" Init DC21X4 CSRs\n");
+#endif
+
+#if __DBG
+ DbgPrint(" CSR0 (bus mode): %08x\n",
+ Adapter->BusMode);
+#endif
+ DC21X4_WRITE_PORT(
+ DC21X4_BUS_MODE,
+ Adapter->BusMode
+ );
+
+#if __DBG
+ DbgPrint(" CSR3 (Rx desc Ring): %08x\n",
+ Adapter->ReceiveDescriptorRingPa);
+#endif
+ DC21X4_WRITE_PORT(
+ DC21X4_RCV_DESC_RING,
+ Adapter->ReceiveDescriptorRingPa
+ );
+#if _DBG
+ DbgPrint(" CSR4 (Tx desc Ring): %08x\n",
+ Adapter->TransmitDescriptorRingPa);
+#endif
+ DC21X4_WRITE_PORT(
+ DC21X4_TXM_DESC_RING,
+ Adapter->TransmitDescriptorRingPa
+ );
+
+
+ switch (Adapter->DeviceId) {
+
+ case DC21040_CFID :
+
+ DC21X4_WRITE_PORT(
+ DC21X4_RESERVED,
+ 0
+ );
+
+ }
+
+}
+
+
+
+
+
+
+
+
+
+
+/*+
+ *
+ * DC21X4StopAdapter
+ *
+ *
+ * Routine Description:
+ *
+ * This routine stops the DC21X4 by resetting
+ * the chip.
+ *
+ * NOTE: This is not a gracefull stop.
+ *
+ * Arguments:
+ *
+ * Adapter - The adapter for the DC21X4 to stop.
+ *
+ * Return Value:
+ *
+ * None.
+ *
+-*/
+extern
+VOID
+DC21X4StopAdapter(
+ IN PDC21X4_ADAPTER Adapter
+ )
+{
+
+#if __DBG
+ DbgPrint("DC21X4StopAdapter\n");
+#endif
+
+ DC21X4IndicateMediaStatus(Adapter,LinkFail);
+
+ switch (Adapter->AdapterType) {
+
+ case NdisInterfaceEisa:
+
+ // Use HW reset instead of SW reset
+
+#if _DBG
+ DbgPrint(" HW reset\n");
+#endif
+
+ NdisRawWritePortUchar (
+ Adapter->PortOffset + EISA_REG1_OFFSET,
+ 0x01
+ );
+
+ NdisRawWritePortUchar (
+ Adapter->PortOffset + EISA_REG1_OFFSET,
+ 0
+ );
+
+ break;
+
+ default:
+
+ // Set the SW Reset bit in BUS_MODE register
+
+#if _DBG
+ DbgPrint(" SW reset\n");
+#endif
+
+ DC21X4_WRITE_PORT(
+ DC21X4_BUS_MODE,
+ DC21X4_SW_RESET);
+ }
+
+ // Wait 50 PCI bus cycles to wait for reset completion
+
+ NdisStallExecution(2*MILLISECOND); // Wait for 2 ms
+
+}
+
+
+
+
+
+
+
+
+
+
+/*+
+ *
+ * DC21X4StartAdapter
+ *
+ *
+ * Routine Description:
+ *
+ * This routine starts DC21X4's Txm & Rcv processes.
+ *
+ * At this point The Txm descriptor ring should be empty
+ * and the TxM process should enter the SUSPENDED state
+ *
+ * The 1st Rxm descriptor of the Rcv ring should available
+ * and the RxM process should enter the RUNNING state
+ *
+ * Note:
+ *
+ * This routine assume that only a single thread of
+ * execution is working with this particular adapter.
+ *
+ * Arguments:
+ *
+ * Adapter - The adapter for the DC21X4 to stop.
+ *
+ * Return Value:
+ *
+ * None.
+ *
+-*/
+extern
+VOID
+DC21X4StartAdapter(
+ IN PDC21X4_ADAPTER Adapter
+ )
+{
+
+#if __DBG
+ DbgPrint("DC21X4StartAdapter\n");
+#endif
+
+ // Set the RCV_START and TXM_START bits in
+ // the OPERATION_MODE register
+
+ Adapter->OperationMode |= (DC21X4_RCV_START | DC21X4_TXM_START );
+
+ switch (Adapter->DeviceId) {
+
+ case DC21040_CFID :
+
+ if (Adapter->RevisionNumber == DC21040_REV1) {
+
+ // Txm hang workaround : Disable the SIA before
+ // writing the Operation Mode register
+
+ DC21X4_WRITE_PORT(
+ DC21X4_SIA_MODE_0,
+ DC21X4_RESET_SIA
+ );
+
+ NdisStallExecution(1*MILLISECOND); // Wait 1 ms
+
+ DC21X4_WRITE_PORT(
+ DC21X4_OPERATION_MODE,
+ Adapter->OperationMode
+ );
+
+ DC21X4_WRITE_PORT(
+ DC21X4_SIA_MODE_0,
+ Adapter->Media[Adapter->SelectedMedium].SiaRegister[0]
+ );
+
+ break;
+
+ }
+
+ default:
+
+ DC21X4_WRITE_PORT(
+ DC21X4_OPERATION_MODE,
+ Adapter->OperationMode
+ );
+ }
+
+}
+
+
+
+/*+
+ *
+ * DC21X4WriteGepRegister
+ *
+ *
+ * Routine Description:
+ *
+ * Write the DC21X4 General Purpose Register
+ *
+ *
+ * Arguments:
+ *
+ * Adapter
+ * Data
+ *
+ * Return Value:
+ *
+ * None.
+ *
+-*/
+extern
+VOID
+DC21X4WriteGepRegister(
+ IN PDC21X4_ADAPTER Adapter,
+ IN ULONG Data
+ )
+{
+
+ switch (Adapter->DeviceId) {
+
+ case DC21142_CFID:
+
+ Adapter->Gep_Sia2 = (Data << DC21142_GEP_SHIFT)
+ | (Adapter->Gep_Sia2 & DC21142_SIA2_MASK);
+
+ DC21X4_WRITE_PORT(
+ DC21X4_SIA_MODE_2,
+ Adapter->Gep_Sia2
+ );
+ break;
+
+ default:
+
+ DC21X4_WRITE_PORT(
+ DC21X4_GEN_PURPOSE,
+ Data
+ );
+
+ }
+}
+
+
+
+/*+
+ *
+ * DC21X4InitializeGepRegisters
+ *
+ *
+ * Routine Description:
+ *
+ * This routine initializes the GEP registers of the DC21140 adapters
+ *
+ *
+ * Arguments:
+ *
+ * Adapter - The adapter for the DC21X4 to initialize
+ *
+ * Return Value:
+ *
+ * None.
+ *
+-*/
+extern
+VOID
+DC21X4InitializeGepRegisters(
+ IN PDC21X4_ADAPTER Adapter,
+ IN BOOLEAN Phy
+ )
+{
+
+ INT Seq;
+
+#if __DBG
+ DbgPrint("InitializeGepRegisters\n");
+#endif
+
+
+ if (Phy) {
+
+ // Write the Gen Purpose register with the PHY's required sequence:
+ // Control,Data_1,...,Data_n
+
+#if __DBG
+ DbgPrint("InitializeGepRegisters: Control=%08x\n",
+ Adapter->Phy[Adapter->PhyNumber].GeneralPurposeCtrl);
+#endif
+ DC21X4WriteGepRegister(
+ Adapter,
+ (ULONG)Adapter->Phy[Adapter->PhyNumber].GeneralPurposeCtrl
+ );
+
+ for (Seq=0; Seq < Adapter->Phy[Adapter->PhyNumber].GepSequenceLength; Seq++) {
+#if __DBG
+ DbgPrint("InitializeGepRegisters: DATA[%d]=%04x\n",
+ Seq, Adapter->Phy[Adapter->PhyNumber].GepSequence[Seq]);
+#endif
+ DC21X4WriteGepRegister(
+ Adapter,
+ (ULONG)Adapter->Phy[Adapter->PhyNumber].GepSequence[Seq]
+ );
+ }
+ }
+ else {
+
+#if __DBG
+ DbgPrint("InitializeGepRegisters:\n");
+ DbgPrint(" GeneralPurpose Ctrl : %08x\n",
+ Adapter->Media[Adapter->SelectedMedium].GeneralPurposeCtrl);
+ DbgPrint(" GeneralPurpose Data : %08x\n",
+ Adapter->Media[Adapter->SelectedMedium].GeneralPurposeData);
+#endif
+
+ DC21X4WriteGepRegister(
+ Adapter,
+ (ULONG)Adapter->Media[Adapter->SelectedMedium].GeneralPurposeCtrl
+ );
+
+ DC21X4WriteGepRegister(
+ Adapter,
+ (ULONG)Adapter->Media[Adapter->SelectedMedium].GeneralPurposeData
+ );
+ }
+
+}
+
+
+
+/*+
+ * DC21X4InitializeMediaRegisters
+ *
+ * Routine Description:
+ *
+ * Initialize the DC21X4 Media (GEP &internal SIA) registers
+ *
+ *
+ * Arguments:
+ *
+ * Adapter
+ *
+ *
+ * Return Value:
+ *
+ * None.
+ *
+-*/
+extern
+VOID
+DC21X4InitializeMediaRegisters(
+ IN PDC21X4_ADAPTER Adapter,
+ IN BOOLEAN Phy
+ )
+{
+#if __DBG
+ DbgPrint("InitializeMediaRegisters\n");
+#endif
+
+ switch (Adapter->DeviceId) {
+
+ case DC21040_CFID :
+ case DC21041_CFID :
+
+ DC2104InitializeSiaRegisters(Adapter);
+ break;
+
+ case DC21140_CFID :
+
+ DC21X4InitializeGepRegisters(Adapter,Phy);
+ break;
+
+ case DC21142_CFID :
+
+ DC21X4InitializeGepRegisters(Adapter,Phy);
+ DC2104InitializeSiaRegisters(Adapter);
+ break;
+
+ }
+}
+
+
+
+
+
+
+
+
+
+/*+
+ *
+ * DC2104InitializeSiaRegisters
+ *
+ *
+ * Routine Description:
+ *
+ * This routine initializes the SIA register of the DC2104x adapters
+ *
+ *
+ * Arguments:
+ *
+ * Adapter - The adapter for the DC21X4 to initialize
+ *
+ * Return Value:
+ *
+ * None.
+ *
+-*/
+extern
+VOID
+DC2104InitializeSiaRegisters(
+ IN PDC21X4_ADAPTER Adapter
+ )
+
+{
+ UINT i;
+
+#if __DBG
+ DbgPrint("DC2104InitializeSiaRegisters\n");
+#endif
+
+ DC21X4_WRITE_PORT(
+ DC21X4_SIA_MODE_0,
+ DC21X4_RESET_SIA
+ );
+
+ for (i=0;i<2;i++) {
+ NdisStallExecution(5*MILLISECOND);
+ }
+
+#if __DBG
+ DbgPrint(" CSR15: %08x\n",Adapter->Media[Adapter->SelectedMedium].SiaRegister[2]);
+ DbgPrint(" CSR14: %08x\n",Adapter->Media[Adapter->SelectedMedium].SiaRegister[1]);
+ DbgPrint(" CSR13: %08x\n",Adapter->Media[Adapter->SelectedMedium].SiaRegister[0]);
+
+#endif
+
+ switch (Adapter->DeviceId) {
+
+ case DC21142_CFID:
+
+ Adapter->Gep_Sia2 =
+ (Adapter->Media[Adapter->SelectedMedium].SiaRegister[2] & DC21142_SIA2_MASK)
+ | (Adapter->Gep_Sia2 & DC21142_GEP_MASK);
+
+ DC21X4_WRITE_PORT(
+ DC21X4_SIA_MODE_2,
+ Adapter->Gep_Sia2
+ );
+
+ break;
+
+ default:
+
+ DC21X4_WRITE_PORT(
+ DC21X4_SIA_MODE_2,
+ Adapter->Media[Adapter->SelectedMedium].SiaRegister[2]
+ );
+ }
+
+ DC21X4_WRITE_PORT(
+ DC21X4_SIA_MODE_1,
+ Adapter->Media[Adapter->SelectedMedium].SiaRegister[1]
+ );
+
+ DC21X4_WRITE_PORT(
+ DC21X4_SIA_MODE_0,
+ Adapter->Media[Adapter->SelectedMedium].SiaRegister[0]
+ );
+
+#if 0
+ //Restart the Receiver and Transmitter
+ DC21X4_WRITE_PORT(
+ DC21X4_OPERATION_MODE,
+ Adapter->OperationMode
+ );
+#endif
+
+}
+
+
+
+
+
+
+
+
+
+
+
+/*+
+ *
+ * DC21X4StopReceiverAndTransmitter
+ *
+ *
+ * Routine Description:
+ *
+ * Gracefull stop the Receiver and Transmitter and
+ * synchronize on completion
+ *
+ *
+ * Arguments:
+ *
+ * Adapter - The adapter for the DC21X4 to initialize
+ *
+ * Return Value:
+ *
+ * None.
+ *
+-*/
+extern
+VOID
+DC21X4StopReceiverAndTransmitter(
+ IN PDC21X4_ADAPTER Adapter
+ )
+
+{
+
+ ULONG Status;
+ UINT Time=50;
+
+ //Request the Receiver and Transmitter to stop
+
+ DC21X4_WRITE_PORT(
+ DC21X4_OPERATION_MODE,
+ 0
+ );
+
+ //Wait for completion
+
+ while (Time--) {
+
+ DC21X4_READ_PORT(
+ DC21X4_STATUS,
+ &Status
+ );
+
+ if (Status & (DC21X4_RCV_PROCESS_STATE
+ | DC21X4_TXM_PROCESS_STATE) == 0) {
+ break;
+ }
+
+ NdisStallExecution(2*MILLISECOND);
+ }
+
+ return;
+
+}
diff --git a/private/ntos/ndis/dc21x4/interrup.c b/private/ntos/ndis/dc21x4/interrup.c
new file mode 100644
index 000000000..9de60bc52
--- /dev/null
+++ b/private/ntos/ndis/dc21x4/interrup.c
@@ -0,0 +1,1726 @@
+/*+
+ * file: interrup.c
+ *
+ * Copyright (C) 1992-1995 by
+ * Digital Equipment Corporation, Maynard, Massachusetts.
+ * All rights reserved.
+ *
+ * This software is furnished under a license and may be used and copied
+ * only in accordance of the terms of such license and with the
+ * inclusion of the above copyright notice. This software or any other
+ * copies thereof may not be provided or otherwise made available to any
+ * other person. No title to and ownership of the software is hereby
+ * transferred.
+ *
+ * The information in this software is subject to change without notice
+ * and should not be construed as a commitment by digital equipment
+ * corporation.
+ *
+ * Digital assumes no responsibility for the use or reliability of its
+ * software on equipment which is not supplied by digital.
+ *
+ *
+ * Abstract: This file contains the interrupt handling routines for
+ * the NDIS 4.0 miniport driver for DEC's DC21X4 Ethernet
+ * controller family .
+ *
+ * Author: Philippe Klein
+ *
+ * Revision History:
+ *
+ * phk 09-Aug-1994 Initial entry
+ * phk 09-Feb-1995 V2.0
+ *
+-*/
+
+#include <precomp.h>
+
+
+
+
+
+
+
+
+
+
+
+
+// Logging code to keep track of receive buffers and packets.
+
+#if DBG
+#define PACKET_LOG_SIZE 1024
+
+typedef struct _PACKET_LOG {
+
+ PNDIS_PACKET Packet;
+ PRCV_HEADER RcvHeader;
+ ULONG Ident1;
+ ULONG Ident2;
+
+}PACKET_LOG,*PPACKET_LOG;
+
+
+UINT dc21x4CurrentLogEntry = (PACKET_LOG_SIZE - 1);
+PPACKET_LOG dc21x4PacketLogHead = NULL;
+PACKET_LOG dc21x4PacketLog[PACKET_LOG_SIZE] = {0};
+
+VOID DC21X4LogPacket(PNDIS_PACKET Packet, PRCV_HEADER RcvHeader, UINT Ident1, UINT Ident2) {
+
+ dc21x4PacketLogHead = &dc21x4PacketLog[dc21x4CurrentLogEntry];
+
+ dc21x4PacketLogHead->Packet = Packet;
+ dc21x4PacketLogHead->RcvHeader = RcvHeader;
+ dc21x4PacketLogHead->Ident1 = Ident1;
+ dc21x4PacketLogHead->Ident2 = Ident2;
+
+ if (dc21x4CurrentLogEntry-- == 0) {
+ dc21x4CurrentLogEntry = (PACKET_LOG_SIZE - 1);
+ }
+}
+#else
+
+#define DC21X4LogPacket(Packet, RcvHeader, Ident1, Ident2)
+
+#endif
+
+
+
+
+
+
+
+
+
+
+
+
+/*+
+ *
+ * DC21X4Isr
+ *
+ * Routine Description:
+ *
+ * Interrupt service routine.
+ * Get the value of ISR and clear the adapter's interrupt status
+ *
+-*/
+
+extern
+VOID
+DC21X4Isr(
+ OUT PBOOLEAN InterruptRecognized,
+ OUT PBOOLEAN QueueMiniportHandleInterrupt,
+ IN NDIS_HANDLE MiniportAdapterContext
+ )
+{
+
+ PDC21X4_ADAPTER Adapter;
+ ULONG Status;
+ ULONG IsrStatus;
+
+#if _DBG
+ DbgPrint("DC21X4Isr\n");
+#endif
+
+ Adapter = (PDC21X4_ADAPTER)MiniportAdapterContext;
+
+ // Read the interrupt field of the adapter's Status CSR
+
+ DC21X4_READ_PORT(
+ DC21X4_STATUS,
+ &Status
+ );
+
+ IsrStatus = Status & DC21X4_STATUS_INTERRUPTS;
+
+#if _DBG
+ DbgPrint("ISR[%08x] Interrupt Status = %08x\n",Adapter,IsrStatus);
+#endif
+
+ // Check if the shared interrupt is recognized by the adapter
+
+ if (IsrStatus == 0) {
+
+ *InterruptRecognized = FALSE;
+ *QueueMiniportHandleInterrupt = FALSE;
+ return;
+ }
+
+ *InterruptRecognized = TRUE;
+
+ //Mask the interrupts
+ //(shared interrupts should be disabled in the ISR).
+
+ DC21X4_WRITE_PORT(
+ DC21X4_INTERRUPT_MASK,
+ 0
+ );
+
+ //Clear the interrupts
+
+ DC21X4_WRITE_PORT(
+ DC21X4_STATUS,
+ Status
+ );
+
+ if (IsrStatus & DC21X4_SYSTEM_ERROR) {
+
+ // This is a fatal error caused by a system hardware
+ // failure: stop the DC21X4 chip
+#if __DBG
+ DbgPrint("\n\nDC21X4_SYSTEM_ERROR!!!\n\n");
+#endif
+ Adapter->ParityError = TRUE;
+
+ DC21X4StopAdapter(Adapter);
+
+ *QueueMiniportHandleInterrupt = FALSE;
+ return;
+ }
+
+#if __DBG
+ if (IsrStatus & DC21X4_LINK_FAIL) {
+ DbgPrint("ISR: LinkFail interrupt\n");
+ }
+ else if (IsrStatus & DC21X4_LINK_PASS) {
+ DbgPrint("ISR: LinkPass interrupt\n");
+ }
+#endif
+
+ // count the number of Rcv & Txm interrupts
+
+ if ( (IsrStatus & Adapter->InterruptMask)
+ & (DC21X4_RCV_INTERRUPTS | DC21X4_TXM_INTERRUPTS)) {
+ Adapter->InterruptCount++;
+ }
+
+ Adapter->InterruptStatus |= IsrStatus;
+ *QueueMiniportHandleInterrupt = TRUE;
+ return;
+
+}
+
+
+
+
+
+
+
+
+
+
+
+
+/*++
+ *
+ * DC21X4SynchClearIsr
+ *
+ * Routine Description:
+ *
+ * This routine is used by the interrupt handler to synchronize
+ * with the interrupt service routine while accessing the shared
+ * ISR value.
+ *
+ * The routine clears the Adapter's Interrupt Status CSR
+ *
+ * Arguments:
+ *
+ * SyncContext - A pointer to a structure storing a pointer to the
+ * adapter and the ISR Status value.
+ *
+ * Return Value:
+ *
+ * None
+ *
+-*/
+
+VOID
+DC21X4SynchClearIsr(
+ IN PDC21X4_SYNCH_CONTEXT SyncContext
+ )
+{
+ PDC21X4_ADAPTER Adapter = SyncContext->Adapter;
+
+#if _DBG
+ DbgPrint("DC21X4SynchClearIsr [%08x]\n",
+ ( DC21X4_RCV_INTERRUPTS
+ | DC21X4_TXM_INTERRUPTS
+ | SyncContext->IsrStatus));
+#endif
+
+ //Clear the interrupt status
+
+ DC21X4_WRITE_PORT(
+ DC21X4_STATUS,
+ ( DC21X4_RCV_INTERRUPTS
+ | DC21X4_TXM_INTERRUPTS
+ | SyncContext->IsrStatus)
+ );
+
+}
+
+
+
+
+
+
+
+
+
+
+
+
+/*++
+ *
+ * DC21X4HandleInterrupt
+ *
+ * Routine Description:
+ *
+ * This routine is queued by the interrupt service routine and
+ * handle the routines associated with the interrupts
+ *
+-*/
+
+extern
+VOID
+DC21X4HandleInterrupt(
+ IN NDIS_HANDLE MiniportAdapterContext
+ )
+
+{
+
+ PDC21X4_ADAPTER Adapter;
+ PDC21X4_RECEIVE_DESCRIPTOR ReceiveDescriptor;
+ PDC21X4_TRANSMIT_DESCRIPTOR TransmitDescriptor;
+
+ DC21X4_SYNCH_CONTEXT SyncContext;
+
+ ULONG Status;
+ ULONG IsrStatus;
+
+#if _DBG
+ DbgPrint("DC21X4HandleInterrupt\n");
+#endif
+
+ Adapter = (PDC21X4_ADAPTER)MiniportAdapterContext;
+ SyncContext.Adapter = Adapter;
+
+ while (TRUE) {
+
+ IsrStatus = Adapter->InterruptStatus;
+ SyncContext.IsrStatus = IsrStatus;
+
+ if (IsrStatus & ( DC21X4_LINK_FAIL
+ | DC21X4_LINK_PASS
+ | DC21X4_GEP_INTERRUPT
+ )
+ ) {
+
+ if (IsrStatus & DC21X4_GEP_INTERRUPT) {
+ HandleGepInterrupt(Adapter);
+ }
+ if (IsrStatus & DC21X4_LINK_FAIL) {
+ HandleLinkFailInterrupt(Adapter,&IsrStatus);
+ }
+ if (IsrStatus & DC21X4_LINK_PASS) {
+ HandleLinkPassInterrupt(Adapter,&IsrStatus);
+ }
+ }
+
+ // Clear the Interrupt Status CSR
+
+
+ NdisMSynchronizeWithInterrupt(
+ &Adapter->Interrupt,
+ DC21X4SynchClearIsr,
+ &SyncContext
+ );
+
+ if (Adapter->ResetInProgress) {
+ return;
+ }
+
+ // Check the Receive and Transmit Descriptor
+ // rings to process any pending packet
+
+ ReceiveDescriptor =
+ ProcessReceiveDescRing (Adapter);
+
+ TransmitDescriptor =
+ ProcessTransmitDescRing (Adapter);
+
+
+ // Check if there is more work to do
+
+ DC21X4_READ_PORT(
+ DC21X4_STATUS,
+ &Status
+ );
+
+ Adapter->InterruptStatus =
+ Status & DC21X4_STATUS_INTERRUPTS;
+
+ if (Adapter->InterruptStatus) {
+ continue;
+ }
+
+#if _DBG
+ DbgPrint("Rcv Status %08x\n",ReceiveDescriptor->Status);
+#endif
+ if ((ReceiveDescriptor->Status & DC21X4_RDES_OWN_BIT) == DESC_OWNED_BY_SYSTEM) {
+ // More Receive frames should be processed
+ continue;
+ }
+
+#if _DBG
+ DbgPrint("Txm Status %08x\n",TransmitDescriptor->Status);
+#endif
+ if (Adapter->DequeueTransmitDescriptor == Adapter->EnqueueTransmitDescriptor) {
+ break;
+ }
+
+ else if ((TransmitDescriptor->Status & DC21X4_TDES_OWN_BIT) == DESC_OWNED_BY_DC21X4) {
+
+ // The transmit ring contains Txm descriptor(s): Poll_transmit
+ // the adapter
+ // (if Txm is running (expected case), this is a no_op
+ // if Txm is suspendend (abnormal case caused by Motorola
+ // Eagle chip set's cache coherency problem) the transmission
+ // will resume)
+ DC21X4_WRITE_PORT(
+ DC21X4_TXM_POLL_DEMAND,
+ 1
+ );
+ break;
+ }
+ }
+
+ if (Adapter->Polling) {
+
+ //Restart the monitor timer
+
+ DC21X4_WRITE_PORT(
+ DC21X4_TIMER,
+ Adapter->Polling
+ );
+ }
+
+#if _DBG
+ DbgPrint("Interrupt Handler completed\n");
+#endif
+
+}
+
+
+
+
+/*+
+ *
+ * HandleGepInterrupt
+ *
+ * Routine Description:
+ *
+ * Handle the GEP interrupt
+ *
+ * Arguments:
+ *
+ * Adapter - The adapter to indicate to.
+ *
+ * Return Value:
+ *
+ * None.
+ *
+-*/
+VOID
+HandleGepInterrupt(
+ IN PDC21X4_ADAPTER Adapter
+ )
+{
+ ULONG Gep;
+#if __DBG
+ DbgPrint("Handle GEP interrupt\n");
+#endif
+
+ //Read the GEP register
+
+ DC21X4_READ_PORT(
+ DC21X4_SIA_MODE_2,
+ &Gep
+ );
+
+ if ( (Gep & Adapter->Phy[Adapter->PhyNumber].GepInterruptMask)
+ && (Adapter->PhyMediumInSrom)
+ ) {
+
+#if __DBG
+ DbgPrint("GEP Interrupt:\n");
+#endif
+ // A MII card was plugged in: Initialize the PHY
+
+ DC21X4IndicateMediaStatus(Adapter,LinkFail);
+
+#if __DBG
+ DbgPrint("Init the PHY...\n");
+#endif
+ Adapter->PhyPresent = DC21X4PhyInit(Adapter);
+#if __DBG
+ DbgPrint("Adapter->PhyPresent=%d\n",Adapter->PhyPresent);
+#endif
+
+ if (Adapter->PhyPresent) {
+
+ DC21X4SetPhyConnection(
+ Adapter
+ );
+
+ if ( (Adapter->PhyNwayCapable)
+ && (Adapter->MediaType & MEDIA_NWAY)
+ ) {
+ //PHY is Nway capable: disable DC21X4's Nway
+ DC21X4DisableNway (Adapter);
+ }
+
+ // Start the AutoSense timer
+ DC21X4StartAutoSenseTimer(
+ Adapter,
+ (UINT)0
+ );
+ }
+ }
+
+}
+
+
+
+
+
+/*+
+ *
+ * HandleLinkFailInterrupt
+ *
+ * Routine Description:
+ *
+ * Handle the Link_Fail interrupt
+ *
+ * Arguments:
+ *
+ * Adapter - The adapter to indicate to.
+ * IsrStatus - Interrupt status
+ * Return Value:
+ *
+ * None.
+ *
+-*/
+VOID
+HandleLinkFailInterrupt(
+ IN PDC21X4_ADAPTER Adapter,
+ IN OUT PULONG IsrStatus
+ )
+{
+
+#if __DBG
+ DbgPrint("Handle Link Fail interrupt\n");
+#endif
+
+ if (Adapter->SelectedMedium != Medium10BaseT) {
+ return;
+ }
+
+ if (Adapter->PhyPresent) {
+
+ DC21X4SetPhyControl(
+ Adapter,
+ MiiGenAdminRelease10
+ );
+
+ }
+
+ switch (Adapter->DeviceId) {
+
+ case DC21040_CFID:
+
+ DC21X4IndicateMediaStatus(Adapter,LinkFail);
+ *IsrStatus &= ~(
+ DC21X4_LINK_PASS
+ );
+
+ //21040 does not provide a Link_pass interrupt:
+ //Start the AutoSense timer to poll on Link Pass
+
+ DC21X4StartAutoSenseTimer(
+ Adapter,
+ DC21X4_SPA_TICK
+ );
+ return;
+
+ case DC21142_CFID:
+
+ Adapter->Indicate10BTLink = FALSE;
+
+ case DC21041_CFID:
+
+ switch (Adapter->LinkHandlerMode) {
+
+ case NwayWorkAround:
+
+ DC21X4IndicateMediaStatus(Adapter,LinkFail);
+ *IsrStatus &= ~(
+ DC21X4_LINK_PASS
+ );
+
+ if ((!Adapter->NwayEnabled) && (Adapter->MediaNway)) {
+
+ SwitchMediumToTpNway(Adapter);
+
+ }
+ break;
+
+ case Nway:
+
+ DC21X4IndicateMediaStatus(Adapter,LinkFail);
+ *IsrStatus &= ~(
+ DC21X4_LINK_PASS
+ );
+
+ if ((Adapter->MediaType & MEDIA_AUTOSENSE)
+ ||(Adapter->MediaNway)
+ ){
+
+ //Stop the Link Timer if active
+ if (Adapter->TimerFlag != NoTimer) {
+ DC21X4StopAutoSenseTimer(Adapter);
+ }
+
+ //Start the Anc Timer to timeout if the
+ //Nway autonegotiation does not complete
+
+ Adapter->TimerFlag=AncTimeout;
+
+ NdisMSetTimer(
+ &Adapter->Timer,
+ DC21X4_ANC_TIMEOUT
+ );
+ }
+ break;
+
+
+ default:
+
+ DC21X4IndicateMediaStatus(Adapter,LinkFail);
+ *IsrStatus &= ~(
+ DC21X4_LINK_PASS
+ );
+
+ if (Adapter->MediaType & MEDIA_AUTOSENSE) {
+
+ DC21X4SwitchMedia(
+ Adapter,
+ Medium10Base2_5
+ );
+ }
+ else if (Adapter->MediaType & MEDIA_NWAY) {
+
+ //Stop the Link Timer if active
+ if (Adapter->TimerFlag != NoTimer) {
+ DC21X4StopAutoSenseTimer(Adapter);
+ }
+
+ //Start the Anc Timer to timeout if the
+ //Nway autonegotiation does not complete
+
+ Adapter->TimerFlag=AncTimeout;
+
+ NdisMSetTimer(
+ &Adapter->Timer,
+ DC21X4_ANC_TIMEOUT
+ );
+ }
+ break;
+ }
+ }
+
+}
+
+
+
+
+/*+
+ *
+ * HandleLinkPassInterrupt
+ *
+ * Routine Description:
+ *
+ * Handle the LinkPass/ANC interrupt
+ *
+ * Arguments:
+ *
+ * Adapter - The adapter to indicate to.
+ * IsrStatus - Interrupt status
+ * Return Value:
+ *
+ * None.
+ *
+-*/
+VOID
+HandleLinkPassInterrupt(
+ IN PDC21X4_ADAPTER Adapter,
+ IN OUT PULONG IsrStatus
+ )
+{
+
+ INT i;
+
+#if __DBG
+ DbgPrint("Handle Link Pass interrupt\n");
+#endif
+
+
+ switch (Adapter->DeviceId) {
+
+ case DC21041_CFID:
+ case DC21142_CFID:
+ switch (Adapter->LinkHandlerMode) {
+
+ case NwayWorkAround:
+
+ if (Adapter->TimerFlag==AncPolling){
+ return;
+ }
+ else if ( (Adapter->SelectedMedium != Medium10BaseT)
+ || (Adapter->FirstAncInterrupt)) {
+
+ SwitchMediumToTpNway(Adapter);
+ }
+
+ else {
+ DC21X4IndicateMediaStatus(Adapter,LinkPass);
+ }
+
+ Adapter->FirstAncInterrupt = FALSE;
+ return;
+
+ case Nway:
+
+ if (Adapter->MediaNway) {
+
+ //NWAY enabled: Auto_Negotiation_Completed interrupt
+#if __DBG
+ DbgPrint("AutoNegotiation Completed\n");
+#endif
+ //Stop the Anc or Spa timer if active
+ if (Adapter->TimerFlag != NoTimer) {
+ DC21X4StopAutoSenseTimer(Adapter);
+ }
+
+ //Start the Link timer to defer the
+ //Link Status check
+ Adapter->TimerFlag=DeferredLinkCheck;
+ NdisMSetTimer(
+ &Adapter->Timer,
+ DC21X4_LINK_DELAY
+ );
+
+ return;
+ }
+
+ default:
+
+ //No NWAY: Link Pass interrupt
+
+ if (Adapter->SelectedMedium != Medium10BaseT) {
+
+ if (Adapter->MediaType & MEDIA_AUTOSENSE) {
+
+ if ( (Adapter->TimerFlag != NoTimer)
+ && (!Adapter->PhyPresent) ){
+
+ DC21X4StopAutoSenseTimer(Adapter);
+ }
+
+ //Switch to 10BaseT
+ DC21X4SwitchMedia(
+ Adapter,
+ Medium10BaseT
+ );
+ }
+ }
+ else {
+
+ if (Adapter->PhyPresent) {
+
+ // Deferred the indicaton of the 10BT link
+ // to poll first the PHY Link status
+ // to check if the link interrupt
+ // is not a false 10BT link generated by
+ // 100BTx pulses.
+
+ Adapter->Indicate10BTLink = TRUE;
+ return;
+
+ }
+ DC21X4IndicateMediaStatus(Adapter,LinkPass);
+
+ }
+ return;
+
+
+ }
+ break;
+
+ default:
+
+ DC21X4IndicateMediaStatus(Adapter,LinkPass);
+ }
+
+}
+
+
+
+/*+
+ *
+ * SwitchMediumToTpNway
+ *
+ * Routine Description:
+ *
+ * Switch Medium to 10BaseT with Nway enabled
+ *
+ * Arguments:
+ *
+ * Adapter - The adapter to indicate to.
+ *
+ * Return Value:
+ *
+ * None.
+ *
+-*/
+VOID
+SwitchMediumToTpNway(
+ IN PDC21X4_ADAPTER Adapter
+ )
+{
+
+ //Stop the Spa timer if active
+
+ if (Adapter->TimerFlag != NoTimer) {
+ DC21X4StopAutoSenseTimer(Adapter);
+ }
+
+ //Switch medium to TP with Nway enabled :
+
+ DC21X4SwitchMedia(
+ Adapter,
+ Medium10BaseTNway
+ );
+
+ Adapter->AutoNegotiationCount = 0;
+
+ //Initialize the Poll timeout counter
+ Adapter->PollCount= POLL_COUNT_TIMEOUT;
+
+ //Start the Poll timer to
+ //poll the AutoNegotiation State
+
+ Adapter->TimerFlag=AncPolling;
+ NdisMSetTimer(
+ &Adapter->Timer,
+ DC21X4_POLL_DELAY
+ );
+
+}
+
+
+
+
+
+/*+
+ *
+ * ProcessReceiveDescRing
+ *
+ * Routine Description:
+ *
+ * Process the packets that have finished receiving.
+ *
+ * Arguments:
+ *
+ * Adapter - The adapter to indicate to.
+ *
+ * Return Value:
+ *
+ * None.
+ *
+-*/
+PDC21X4_RECEIVE_DESCRIPTOR
+ProcessReceiveDescRing(
+ IN PDC21X4_ADAPTER Adapter
+ )
+{
+
+ // Walk down the receive descriptors ring starting at the
+ // last known descriptor owned by the adapter
+ //
+ // Examine each receive ring descriptor for errors.
+ //
+ // When we have the entire packet (and error processing doesn't
+ // prevent us from indicating it), we give the routine that
+ // processes the packet through the filter, the buffers virtual
+ // address (which is always the lookahead size) and as the
+ // MAC context the address of the first data byte.
+
+ PDC21X4_RECEIVE_DESCRIPTOR CurrentDescriptor;
+
+ PVOID FrameVa;
+ USHORT FrameType;
+
+ UINT FrameSize;
+ UINT LookAheadSize;
+
+ BOOLEAN fStopReceiveProcessing = FALSE;
+
+ PRCV_HEADER RcvHeader;
+ PNDIS_PACKET Packet;
+ PPNDIS_PACKET pPktArray;
+ PNDIS_BUFFER Buffer;
+ ULONG Length;
+ UINT Index;
+ UINT Count;
+ UINT i;
+ PDC21X4_RECEIVE_DESCRIPTOR DescriptorMark;
+ ULONG Status;
+ ULONG Register;
+ INT Timeout;
+ ULONG OverflowCount;
+ ULONG MissedFrames;
+
+ NDIS_PHYSICAL_ADDRESS Pa;
+
+#if _DBG
+ DbgPrint("ProcessReceiveInterrupts\n");
+#endif
+
+ NdisSetPhysicalAddressHigh(Pa,0);
+ DescriptorMark = Adapter->DequeueReceiveDescriptor;
+
+ while (!fStopReceiveProcessing) {
+
+ // Grab a max of MAX_PACKET_ARRAY packets at a time.
+
+ for (Count = 0, pPktArray = Adapter->PacketArray; Count < MAX_PACKET_ARRAY;) {
+
+ // Get the current receive descriptor.
+
+ CurrentDescriptor = Adapter->DequeueReceiveDescriptor;
+#if _DBG
+ DbgPrint("RcvDesc [%08x]\n",CurrentDescriptor);
+#endif
+
+ // If the descriptor is not owned by the system, we are done.
+
+ if ((CurrentDescriptor->Status & DC21X4_RDES_OWN_BIT) != DESC_OWNED_BY_SYSTEM) {
+ fStopReceiveProcessing = TRUE;
+ break;
+ }
+
+ if (Adapter->OverflowWorkAround) {
+
+ if (CurrentDescriptor==DescriptorMark) {
+
+ // Mark the next descriptor not owned by the system into the ring
+
+ do {
+ DescriptorMark = DescriptorMark->Next;
+ }
+ while (
+ ((DescriptorMark->Status & DC21X4_RDES_OWN_BIT) != DESC_OWNED_BY_DC21X4)
+ && (DescriptorMark != Adapter->DequeueReceiveDescriptor)
+ );
+
+ if (!Adapter->IndicateOverflow) {
+
+ //Check if an overflow occured for at least one
+ // of the packets currently queued into the Rcv ring
+
+ DC21X4_READ_PORT(
+ DC21X4_MISSED_FRAME,
+ &Register
+ );
+
+ MissedFrames = Register & DC21X4_MISSED_FRAME_COUNTER;
+ if (MissedFrames) {
+ Adapter->GeneralMandatory[GM_MISSED_FRAMES] += MissedFrames;
+ }
+ OverflowCount = (Register >> DC21X4_OVERFLOW_COUNTER_SHIFT)
+ & DC21X4_OVERFLOW_COUNTER;
+ if (OverflowCount) {
+ Adapter->IndicateOverflow = TRUE;
+ Adapter->MediaOptional[MO_RECEIVE_OVERFLOW]+= OverflowCount;
+ }
+
+ }
+
+ if (Adapter->IndicateOverflow) {
+
+ //Stop the Receiver
+ DC21X4_WRITE_PORT(
+ DC21X4_OPERATION_MODE,
+ Adapter->OperationMode & ~(DC21X4_RCV_START)
+ );
+
+ // Discard the packets queued into the ring:
+ // Reclaim all the descriptors owned by the system
+
+
+ while (((Adapter->DequeueReceiveDescriptor)->Status & DC21X4_RDES_OWN_BIT)
+ == DESC_OWNED_BY_SYSTEM
+ ) {
+
+ (Adapter->DequeueReceiveDescriptor)->Status = DESC_OWNED_BY_DC21X4;
+ Adapter->MediaOptional[MO_RECEIVE_OVERFLOW]++;
+ Adapter->DequeueReceiveDescriptor = (Adapter->DequeueReceiveDescriptor)->Next;
+ }
+
+ Adapter->IndicateOverflow = FALSE;
+
+ // Wait for the Receiver to stop
+ Timeout = DC21X4_RVC_TIMEOUT;
+
+ while (Timeout--) {
+
+ DC21X4_READ_PORT(
+ DC21X4_STATUS,
+ &Status
+ );
+
+ if ((Status & (DC21X4_RCV_PROCESS_STATE)) == 0) {
+ break;
+ }
+ NdisStallExecution(2*MILLISECOND);
+ }
+
+ // Once the Receiver is stopped reclaim the descriptors
+ // owned by the system (this happends if a reception was
+ // in progress when tyhe stop_receive command was issued
+
+ while (((Adapter->DequeueReceiveDescriptor)->Status & DC21X4_RDES_OWN_BIT)
+ == DESC_OWNED_BY_SYSTEM
+ ) {
+
+ (Adapter->DequeueReceiveDescriptor)->Status = DESC_OWNED_BY_DC21X4;
+ Adapter->MediaOptional[MO_RECEIVE_OVERFLOW]++;
+ Adapter->DequeueReceiveDescriptor = (Adapter->DequeueReceiveDescriptor)->Next;
+ }
+
+ // Restart the Receiver
+ DC21X4_WRITE_PORT(
+ DC21X4_OPERATION_MODE,
+ Adapter->OperationMode
+ );
+
+ DescriptorMark = Adapter->DequeueReceiveDescriptor;
+ //leave the "for Count" loop back to the "while" loop
+ break;
+ }
+
+ }
+
+ }
+
+ Adapter->DequeueReceiveDescriptor = CurrentDescriptor->Next;
+
+ if (!(CurrentDescriptor->Status & DC21X4_RDES_ERROR_SUMMARY)) {
+
+ // The frame was received correctly
+
+ FrameSize = ((CurrentDescriptor->Status & DC21X4_RDES_FRAME_LENGTH) >> RDES_FRAME_LENGTH_BIT_NUMBER)
+ - ETH_CRC_SIZE;
+
+ // Get a pointer to the receive buffer header.
+
+ RcvHeader = CurrentDescriptor->RcvHeader;
+ ASSERT(RcvHeader->Signature == 'dHxR');
+
+ FrameVa = (PVOID)(RcvHeader->Va);
+
+ NdisFlushBuffer(
+ RcvHeader->FlushBuffer,
+ FALSE
+ );
+
+ NdisSetPhysicalAddressLow(Pa,RcvHeader->Pa);
+
+ NdisMUpdateSharedMemory(
+ Adapter->MiniportAdapterHandle,
+ RcvHeader->Size,
+ (PVOID)RcvHeader->Va,
+ Pa
+ );
+
+ // Adjust the length of the flush buffer to the
+ // length of the packet.
+
+ NdisAdjustBufferLength(
+ RcvHeader->FlushBuffer,
+ FrameSize
+ );
+
+
+ // Save the packet in the packet array.
+
+ Packet = RcvHeader->Packet;
+ *pPktArray = Packet;
+
+ // Log the packet.
+
+ DC21X4LogPacket(Packet, RcvHeader, '-', Count);
+ // Update the statistics based on Receive status;
+#if _DBG
+ DbgPrint("Receive ok\n");
+#endif
+ Adapter->GeneralMandatory[GM_RECEIVE_OK]++;
+
+ // DC21X4 flags Rcv Multicast address but does not
+ // support a specific flag for Rcv Broadcast address
+
+ if (CurrentDescriptor->Status & DC21X4_RDES_MULTICAST_FRAME) {
+ FrameType = (IS_BROADCAST (FrameVa)) ? RCV_BROADCAST_FRAME: RCV_MULTICAST_FRAME;
+ }
+ else {
+ FrameType = RCV_DIRECTED_FRAME;
+ }
+#if _DBG
+ DbgPrint("FrameType = %d\n",FrameType);
+#endif
+ Adapter->GeneralOptionalCount[FrameType].FrameCount++;
+
+ ADD_ULONG_TO_LARGE_INTEGER(
+ Adapter->GeneralOptionalCount[FrameType].ByteCount,
+ FrameSize
+ );
+ // Can the binding keep the packet?
+
+ if (Adapter->FreeRcvList != NULL) {
+
+ NDIS_SET_PACKET_STATUS(*pPktArray, NDIS_STATUS_SUCCESS);
+
+ // Remove the receive buffer from the ring
+ // and replace it with an extra one.
+
+ RcvHeader = Adapter->FreeRcvList;
+ Adapter->FreeRcvList = RcvHeader->Next;
+
+ Adapter->CurrentReceiveBufferCount--;
+
+ // Setup a new receive buffer for the current descriptor.
+
+ CurrentDescriptor->RcvHeader = RcvHeader;
+ CurrentDescriptor->FirstBufferAddress = RcvHeader->Pa;
+ CurrentDescriptor->Status = DESC_OWNED_BY_DC21X4;
+ }
+ else {
+
+ // Mark the packet as copy only...
+
+ NDIS_SET_PACKET_STATUS(*pPktArray, NDIS_STATUS_RESOURCES);
+
+ Adapter->NeededReceiveBuffers++;
+ RCV_RESERVED(Packet)->Descriptor = CurrentDescriptor;
+ }
+
+ Count ++;
+ pPktArray ++;
+ }
+ else {
+
+ // The frame was received with errors:
+ // Update the statistics based on the Receive status.
+#if _DBG
+ DbgPrint("Receive_error: DescStatus = %08x\n",CurrentDescriptor->Status);
+#endif
+ Adapter->GeneralMandatory[GM_RECEIVE_ERROR]++;
+
+ if (CurrentDescriptor->Status & DC21X4_RDES_DRIBBLING_BIT) {
+#if _DBG
+ DbgPrint(" Rcv Alignment Error\n");
+#endif
+ Adapter->MediaMandatory[MM_RECEIVE_ALIGNMENT_ERROR]++;
+ }
+ else if (CurrentDescriptor->Status & DC21X4_RDES_CRC_ERROR) {
+#if _DBG
+ DbgPrint(" Rcv CRC Error\n");
+#endif
+ Adapter->GeneralOptional[GO_RECEIVE_CRC_ERROR]++;
+ }
+
+ if (CurrentDescriptor->Status & DC21X4_RDES_OVERFLOW) {
+#if _DBG
+ DbgPrint(" Rcv Overflow\n");
+#endif
+ Adapter->MediaOptional[MO_RECEIVE_OVERFLOW]++;
+ }
+
+ CurrentDescriptor->Status = DESC_OWNED_BY_DC21X4;
+ }
+
+ }
+
+ // Did we get any packets to indicate up?
+
+ if (Count != 0) {
+
+
+ // Indicate the packets up to the filter library.
+
+ NdisMIndicateReceivePacket(Adapter->MiniportAdapterHandle,
+ Adapter->PacketArray,
+ Count);
+
+
+ // Determine which packets were kept and which ones
+ // were not.
+
+ for (i = 0, pPktArray = Adapter->PacketArray;
+ i < Count;
+ i++, pPktArray ++) {
+
+ // If the status code for the packet is not
+ // status pending then we can place the resources back
+ // on the free lists.
+
+ if (NDIS_GET_PACKET_STATUS(*pPktArray) != NDIS_STATUS_PENDING) {
+
+ // Get a pointer to the receive header.
+
+ RcvHeader = RCV_RESERVED(*pPktArray)->RcvHeader;
+ ASSERT(RcvHeader->Signature == 'dHxR');
+
+ DC21X4LogPacket(*pPktArray, RcvHeader, '+', i);
+
+ // Adjust the buffer length.
+
+ NdisAdjustBufferLength(
+ RcvHeader->FlushBuffer,
+ DC21X4_MAX_FRAME_SIZE
+ );
+
+ // If we indicated to the binding that it couldn't
+ // keep this packet then don't place it back on the
+ // list!!!
+
+ if (NDIS_GET_PACKET_STATUS(*pPktArray) == NDIS_STATUS_RESOURCES) {
+ RCV_RESERVED(*pPktArray)->Descriptor->Status = DESC_OWNED_BY_DC21X4;
+ }
+ else {
+
+ // Place the buffer back on the free queue.
+
+ RcvHeader->Next = Adapter->FreeRcvList;
+ Adapter->FreeRcvList = RcvHeader;
+ }
+ }
+ }
+ }
+ }
+ return CurrentDescriptor;
+
+}
+
+
+
+
+
+
+
+
+
+
+/*+
+ *
+ * ProcessTransmitDescRing
+ *
+ * Routine Description:
+ *
+ * Process the packets that have finished transmitting
+ *
+ * Arguments:
+ *
+ * Adapter - The adapter to indicate to.
+ *
+ * Return Value:
+ *
+ * None.
+ *
+-*/
+
+
+PDC21X4_TRANSMIT_DESCRIPTOR
+ProcessTransmitDescRing(
+ IN PDC21X4_ADAPTER Adapter
+ )
+{
+
+ PDC21X4_TRANSMIT_DESCRIPTOR CurrentDescriptor;
+ PDC21X4_TRANSMIT_DESCRIPTOR Descptr;
+ UINT Collisions;
+ NDIS_STATUS NdisStatus;
+ UINT MapPtr;
+ ULONG ProcessStatus;
+ ULONG DescOwnership;
+
+ ULONG TxmDescriptorCount = 0;
+ ULONG MapRegistersCount = 0;
+ ULONG MaxTransmitBufferCount = 0;
+ ULONG MinTransmitBufferCount = 0;
+ ULONG GoTransmitCount = 0;
+
+#if _DBG
+ DbgPrint("ProcessTransmitInterrupts\n");
+#endif
+
+ // If the Transmit descriptor ring is not empty,
+ // walk the ring from the last known descriptor owned by the adapter
+
+ while (Adapter->DequeueTransmitDescriptor != Adapter->EnqueueTransmitDescriptor) {
+
+ CurrentDescriptor = Adapter->DequeueTransmitDescriptor;
+
+ // If the current descriptor is not owned by the system, we are done.
+
+ if ((CurrentDescriptor->Status & DC21X4_TDES_OWN_BIT) != DESC_OWNED_BY_SYSTEM) {
+ break;
+ }
+
+ if (CurrentDescriptor->Control & DC21X4_TDES_SETUP_PACKET) {
+
+#if _DBG
+ DbgPrint("Int: TxmDesc %08x - Setup desc.\n",CurrentDescriptor);
+#endif
+ // Setup buffer
+ // Complete the pended Set Information request
+ // which originated the CAM load
+
+#if _DBG
+ DbgPrint("Complete Set Information\n");
+#endif
+ NdisMSetInformationComplete (
+ Adapter->MiniportAdapterHandle,
+ NDIS_STATUS_SUCCESS
+ );
+
+ if ( (Adapter->DeviceId == DC21040_CFID)
+ && (Adapter->RevisionNumber == DC21040_REV1)) {
+
+ // SFD bug workaround :
+ // Restart the Receiver and Enable the Sia
+
+ DC21X4_WRITE_PORT(
+ DC21X4_OPERATION_MODE,
+ Adapter->OperationMode
+ );
+
+ DC21X4_WRITE_PORT(
+ DC21X4_SIA_MODE_0,
+ Adapter->Media[Adapter->SelectedMedium].SiaRegister[0]
+ );
+ }
+
+ TxmDescriptorCount++;
+ Adapter->DequeueTransmitDescriptor = CurrentDescriptor->Next;
+
+ }
+
+ else if (CurrentDescriptor->Control & DC21X4_TDES_LAST_SEGMENT) {
+
+#if _DBG
+ DbgPrint("Int: TxmDesc %08x - Last segment desc.\n",CurrentDescriptor);
+#endif
+ // if Underrun check if the packet should be requeued
+ if ( (CurrentDescriptor->Status & DC21X4_TDES_UNDERRUN_ERROR)
+ && (Adapter->UnderrunRetryCount < Adapter->UnderrunMaxRetries)
+ ) {
+
+ // The Txm packet can only be requeued
+ // if the Txm process has not been restarted
+ // by a Txm Poll demand
+
+ Adapter->DisableTransmitPolling = TRUE;
+
+ DC21X4_READ_PORT(
+ DC21X4_STATUS,
+ &ProcessStatus
+ );
+
+ ProcessStatus &= DC21X4_TXM_PROCESS_STATE;
+
+ DescOwnership = (CurrentDescriptor->Next != Adapter->EnqueueTransmitDescriptor) ?
+ (CurrentDescriptor->Next)->Status & DC21X4_TDES_OWN_BIT :
+ DESC_OWNED_BY_DC21X4;
+
+ if ((ProcessStatus == DC21X4_TXM_PROCESS_SUSPENDED) && (DescOwnership == DESC_OWNED_BY_DC21X4)) {
+
+ // Requeue the Txm packet
+#if __DBG
+ DbgPrint(" Txm Underrun: Retry = %d\n",Adapter->UnderrunRetryCount);
+#endif
+ //Stop the transmitter
+
+ DC21X4_WRITE_PORT(
+ DC21X4_OPERATION_MODE,
+ Adapter->OperationMode & ~(DC21X4_TXM_START)
+ );
+
+ //Reinitialize the descriptor's ownership bits
+
+ //First segment descriptor
+ Descptr = CurrentDescriptor->DescPointer;
+
+ DC21X4_WRITE_PORT(
+ DC21X4_TXM_DESC_RING,
+ Descptr->DescriptorPa
+ );
+
+ while (TRUE) {
+
+ Descptr->Status = DESC_OWNED_BY_DC21X4;
+ if (Descptr == CurrentDescriptor) {
+ break;
+ }
+ else {
+ Descptr = Descptr->Next;
+ }
+ }
+
+ Adapter->DisableTransmitPolling = FALSE;
+
+ //Restart the transmitter
+
+ DC21X4_WRITE_PORT(
+ DC21X4_OPERATION_MODE,
+ Adapter->OperationMode
+ );
+
+ Adapter->UnderrunRetryCount++;
+
+ return CurrentDescriptor;
+ }
+ else {
+ Adapter->DisableTransmitPolling = FALSE;
+
+ }
+
+ }
+
+ Adapter->UnderrunRetryCount = 0 ;
+
+ // Point to the first segment descriptor and walk down the descriptors
+ // mapping the current frame to free the physical mapping table
+
+ Descptr = CurrentDescriptor->DescPointer;
+
+ while (TRUE) {
+
+ // If this descriptor points the first segment of a Ndis Buffer, free the
+ // Physical Mapping table of this buffer
+
+ for (MapPtr = Descptr->MapTableIndex;
+ MapPtr < Descptr->MapTableIndex + NUMBER_OF_SEGMENT_PER_DESC;
+ MapPtr++) {
+
+ if (Adapter->PhysicalMapping[MapPtr].Valid) {
+#if _DBG
+ DbgPrint(" NdisMCompleteBufferPhysicalMapping (%d)\n",MapPtr);
+#endif
+ NdisMCompleteBufferPhysicalMapping(
+ Adapter->MiniportAdapterHandle,
+ Adapter->PhysicalMapping[MapPtr].Buffer,
+ Adapter->PhysicalMapping[MapPtr].Register
+ );
+
+ Adapter->PhysicalMapping[MapPtr].Valid = FALSE;
+ MapRegistersCount++;
+ }
+ }
+
+ if (Descptr == CurrentDescriptor) {
+ break;
+ }
+ else {
+ TxmDescriptorCount++;
+ Descptr = Descptr->Next;
+ }
+
+ }
+
+ // If this packet was copied into a preallocated Txm Buffer,
+ // free the resources
+
+ if (CurrentDescriptor->SendStatus == CopyMaxBuffer) {
+ MaxTransmitBufferCount++;
+ }
+ else if (CurrentDescriptor->SendStatus == CopyMinBuffer) {
+ MinTransmitBufferCount++;
+ }
+
+ // Update the statistics based on the Transmit status
+
+ if (!(CurrentDescriptor->Status & Adapter->TransmitDescriptorErrorMask)) {
+
+ // The frame was transmitted correctly
+
+ Collisions = (CurrentDescriptor->Status & DC21X4_TDES_COLLISION_COUNT)
+ >> TDES_COLLISION_COUNT_BIT_NUMBER;
+
+ if (Collisions == 1) {
+ Adapter->MediaMandatory[MM_TRANSMIT_ONE_COLLISION]++;
+ }
+ else if (Collisions > 1) {
+ Adapter->MediaMandatory[MM_TRANSMIT_MULT_COLLISIONS]++;
+ }
+ if (CurrentDescriptor->Status & DC21X4_TDES_DEFERRED) {
+ Adapter->MediaOptional[MO_TRANSMIT_DEFERRED]++;
+ }
+ if (CurrentDescriptor->Status & DC21X4_TDES_HEARTBEAT_FAIL) {
+ Adapter->MediaOptional[MO_TRANSMIT_HEARTBEAT_FAILURE]++;
+ }
+
+ Adapter->GeneralOptionalCount[CurrentDescriptor->PacketType].FrameCount++;
+ ADD_ULONG_TO_LARGE_INTEGER(
+ Adapter->GeneralOptionalCount[CurrentDescriptor->PacketType].ByteCount,
+ CurrentDescriptor->PacketSize
+ );
+
+ Adapter->GeneralMandatory[GM_TRANSMIT_OK]++;
+ NdisStatus = NDIS_STATUS_SUCCESS;
+ }
+
+ else {
+
+#if _DBG
+ DbgPrint("Transmit_error: DescStatus = %08x\n",CurrentDescriptor->Status);
+#endif
+ if (CurrentDescriptor->Status & DC21X4_TDES_TXM_JABBER_TIMEOUT) {
+
+ // This indicates a severe SIA hardware error. Stop the adapter
+ // to avoid generating noise on the net
+#if __DBG
+ DbgPrint("DC21X4 TXM JABBER TIMEOUT!!!\n");
+#endif
+ DC21X4StopAdapter(Adapter);
+
+ NdisWriteErrorLogEntry(
+ Adapter->MiniportAdapterHandle,
+ NDIS_ERROR_CODE_HARDWARE_FAILURE,
+ 1,
+ DC21X4_ERRMSG_TXM_JABBER_TIMEOUT
+ );
+ }
+
+ if (CurrentDescriptor->Status & DC21X4_TDES_EXCESSIVE_COLLISIONS) {
+#if _DBG
+ DbgPrint(" Txm Excess Collisions\n");
+#endif
+ Adapter->MediaOptional[MO_TRANSMIT_EXC_COLLISIONS]++;
+ Adapter->ExcessCollisionsCount++;
+ }
+ else {
+ Adapter->ExcessCollisionsCount=0;
+ }
+
+ if (CurrentDescriptor->Status & DC21X4_TDES_UNDERRUN_ERROR) {
+
+ Adapter->MediaOptional[MO_TRANSMIT_UNDERRUN]++;
+#if __DBG
+ DbgPrint(" Txm Underrun [UnderrunCount=%d]\n",Adapter->MediaOptional[MO_TRANSMIT_UNDERRUN]);
+#endif
+
+ if ( (Adapter->MediaOptional[MO_TRANSMIT_UNDERRUN] >= Adapter->UnderrunThreshold)
+ && !(Adapter->OperationMode & DC21X4_STORE_AND_FORWARD)
+ ) {
+
+ //Force StoreAndForward mode
+#if __DBG
+ DbgPrint("UnderrunCount=%d : Force StoreAnd Forward mode\n",
+ Adapter->MediaOptional[MO_TRANSMIT_UNDERRUN]);
+#endif
+ DC21X4StopReceiverAndTransmitter(Adapter);
+
+ Adapter->OperationMode |= DC21X4_STORE_AND_FORWARD;
+
+ DC21X4_WRITE_PORT(
+ DC21X4_OPERATION_MODE,
+ Adapter->OperationMode
+ );
+ }
+
+ }
+ else if (CurrentDescriptor->Status & DC21X4_TDES_LATE_COLLISION) {
+#if _DBG
+ DbgPrint(" Txm Late Collision\n");
+#endif
+ Adapter->MediaOptional[MO_TRANSMIT_LATE_COLLISION]++;
+ }
+ if (CurrentDescriptor->Status & DC21X4_TDES_NO_CARRIER) {
+#if _DBG
+ DbgPrint(" Txm No Carrier\n");
+#endif
+ Adapter->NoCarrierCount++;
+ }
+ else {
+ Adapter->NoCarrierCount=0;
+ }
+
+ Adapter->GeneralMandatory[GM_TRANSMIT_ERROR]++;
+ NdisStatus = NDIS_STATUS_FAILURE;
+
+ }
+
+ GoTransmitCount++;
+
+// if (CurrentDescriptor->SendStatus == MappedBuffer) {
+#if _DBG
+ DbgPrint(" Signal Tx Completion desc= %08x\n", CurrentDescriptor);
+#endif
+ NdisMSendComplete(
+ Adapter->MiniportAdapterHandle,
+ CurrentDescriptor->Packet,
+ NdisStatus
+ );
+
+// }
+
+ TxmDescriptorCount++;
+ Adapter->DequeueTransmitDescriptor = CurrentDescriptor->Next;
+ }
+
+ else if (CurrentDescriptor->Control & DC21X4_TDES_FIRST_SEGMENT) {
+
+#if _DBG
+ DbgPrint("Int: TxmDesc %08x - First segment desc.\n",CurrentDescriptor);
+#endif
+ Adapter->DequeueTransmitDescriptor = CurrentDescriptor->DescPointer;
+
+ }
+
+ else {
+
+ TxmDescriptorCount++;
+ Adapter->DequeueTransmitDescriptor = CurrentDescriptor->Next;
+ }
+
+ }
+
+ if (Adapter->FullDuplex) {
+ NdisDprAcquireSpinLock(&Adapter->FullDuplexSpinLock);
+ }
+
+ Adapter->FreeTransmitDescriptorCount += TxmDescriptorCount;
+
+ Adapter->FreeMapRegisters += MapRegistersCount;
+
+ Adapter->MaxTransmitBufferInUse -= MaxTransmitBufferCount;
+
+ Adapter->MinTransmitBufferInUse -= MinTransmitBufferCount;
+
+ Adapter->GeneralOptional[GO_TRANSMIT_QUEUE_LENGTH] -= GoTransmitCount;
+
+ if (Adapter->FullDuplex) {
+ NdisDprReleaseSpinLock(&Adapter->FullDuplexSpinLock);
+ }
+
+ return Adapter->DequeueTransmitDescriptor;
+
+}
+
+/*+
+ *
+ * DC21X4EnableInterrupt
+ *
+-*/
+extern
+VOID
+DC21X4EnableInterrupt(
+ IN NDIS_HANDLE MiniportAdapterContext
+ )
+{
+ PDC21X4_ADAPTER Adapter;
+
+ Adapter = (PDC21X4_ADAPTER)MiniportAdapterContext;
+
+ DC21X4_WRITE_PORT(
+ DC21X4_INTERRUPT_MASK,
+ Adapter->InterruptMask
+ );
+ return;
+}
+
+/*+
+ *
+ * DC21X4DisableInterrupt
+ *
+-*/
+extern
+VOID
+DC21X4DisableInterrupt(
+ IN NDIS_HANDLE MiniportAdapterContext
+ )
+{
+ PDC21X4_ADAPTER Adapter;
+
+ Adapter = (PDC21X4_ADAPTER)MiniportAdapterContext;
+
+ DC21X4_WRITE_PORT(
+ DC21X4_INTERRUPT_MASK,
+ 0
+ );
+ return;
+}
+
+
+/*+
+ *
+ *DC21X4ReturnPacket
+ *
+ * Routine Description:
+ *
+ * Place a buufer released by the binding back into its free list
+ *
+ * Arguments:
+ *
+ * Return Value:
+ *
+-*/
+NDIS_STATUS
+DC21X4ReturnPacket(
+ IN NDIS_HANDLE MiniportAdapterContext,
+ IN PNDIS_PACKET Packet
+ )
+
+{
+
+ PDC21X4_ADAPTER Adapter = (PDC21X4_ADAPTER)MiniportAdapterContext;
+ PRCV_HEADER RcvHeader;
+
+
+ // Get a pointer to the receive header.
+
+ RcvHeader = RCV_RESERVED(Packet)->RcvHeader;
+ ASSERT(RcvHeader->Signature == 'dHxR');
+
+ DC21X4LogPacket(Packet, RcvHeader, '+', (ULONG)-1);
+
+
+ // Adjust the buffer length.
+
+ NdisAdjustBufferLength(
+ RcvHeader->FlushBuffer,
+ DC21X4_RECEIVE_BUFFER_SIZE
+ );
+
+ // Place the buffer back on the free queue.
+
+ RcvHeader->Next = Adapter->FreeRcvList;
+ Adapter->FreeRcvList = RcvHeader;
+
+ return NDIS_STATUS_SUCCESS;
+
+}
+
diff --git a/private/ntos/ndis/dc21x4/mactophy.c b/private/ntos/ndis/dc21x4/mactophy.c
new file mode 100644
index 000000000..e8ac6cde0
--- /dev/null
+++ b/private/ntos/ndis/dc21x4/mactophy.c
@@ -0,0 +1,701 @@
+/*+
+ * file: mactophy.c
+ *
+ * Copyright (C) 1992-1995 by
+ * Digital Equipment Corporation, Maynard, Massachusetts.
+ * All rights reserved.
+ *
+ * This software is furnished under a license and may be used and copied
+ * only in accordance of the terms of such license and with the
+ * inclusion of the above copyright notice. This software or any other
+ * copies thereof may not be provided or otherwise made available to any
+ * other person. No title to and ownership of the software is hereby
+ * transferred.
+ *
+ * The information in this software is subject to change without notice
+ * and should not be construed as a commitment by digital equipment
+ * corporation.
+ *
+ * Digital assumes no responsibility for the use or reliability of its
+ * software on equipment which is not supplied by digital.
+ *
+ *
+ * Abstract: This file contains the code to access the MII PHY device
+ * (initialization, set the connections, and sensing of the
+ * link.
+ *
+ * Author: Claudio Hazan
+ *
+ * Revision History:
+ *
+ * 15-Oct-95 ch Creation
+ * 20-Dec-95 phk Cleanup, add support for DC21142
+ *
+-*/
+
+#include <precomp.h>
+
+#define LINK_PASS_MAX_LOOP 350
+#define LINK_PASS_DELAY (10*MILLISECOND)
+
+#if MII_DBG
+PUCHAR MiiMediumString[] = {
+ "","","","","","","","","",
+ "Mii10BaseT",
+ "Mii10BaseT_FD",
+ "Mii10Base2",
+ "Mii10Base5",
+ "Mii100BaseTx",
+ "Mii100BaseTx_FD",
+ "Mii100BaseT4",
+ "Mii100BaseFx",
+ "Mii100BaseFx_FD"
+};
+#endif
+
+/*+
+ * DC21X4PhyInit
+ *
+ * Routine Description:
+ *
+ * This routine initializes each PHY present in the SROM; Reset each Phy
+ * if there is a Reset sequence specified there, Initializes the Phys and
+ * updates the Capabilities tables from the values contained in the SROM
+ * with the values supported by the Phys.
+ *
+ * Arguments:
+ *
+ * Adapter - Pointer to the Data Structure
+ *
+ * Return Value:
+ *
+ * True if any PHY was succesfully initialized.
+ *
+-*/
+extern
+BOOLEAN
+DC21X4PhyInit(
+ IN PDC21X4_ADAPTER Adapter
+ )
+{
+ BOOLEAN PhyPresent;
+ BOOLEAN ConnectionPresent=FALSE;
+ USHORT Capabilities;
+ INT PhyNumber;
+ INT Seq;
+
+ ULONG Data;
+
+#if MII_DBG
+ DbgPrint("DC21X4PhyInit\n");
+#endif
+ // Reset all the phys using its reset sequence.
+
+ if (!Adapter->PhyMediumInSrom) {
+#if __DBG
+ DbgPrint("No PHY Media in SROM\n");
+#endif
+ return FALSE;
+ }
+
+#if __DBG
+ DbgPrint("PHY Reset\n");
+#endif
+
+ Adapter->Force10 = FALSE;
+
+ for (PhyNumber=0; PhyNumber < MAX_PHY_TABLE; PhyNumber++) {
+
+ if (Adapter->Phy[Adapter->PhyNumber].ResetSequenceLength != 0) {
+
+ DC21X4WriteGepRegister(
+ Adapter,
+ (ULONG)Adapter->Phy[Adapter->PhyNumber].GeneralPurposeCtrl
+ );
+
+ for (Seq=0; Seq < Adapter->Phy[Adapter->PhyNumber].ResetSequenceLength; Seq++) {
+#if MII_DBG
+ DbgPrint("Sequence[%d]=%04x\n", Seq, Adapter->Phy[PhyNumber].ResetSequence[Seq]);
+#endif
+ DELAY (5); // 5 microseconds
+
+ DC21X4WriteGepRegister(
+ Adapter,
+ (ULONG)Adapter->Phy[Adapter->PhyNumber].ResetSequence[Seq]
+ );
+ }
+ }
+ }
+
+ Adapter->PhyNumber = 0;
+ PhyPresent = MiiGenInit(Adapter);
+
+ if (PhyPresent) {
+#if __DBG
+ DbgPrint("Phy: Initialization OK\n");
+#endif
+
+ Capabilities = MiiGenGetCapabilities(Adapter);
+
+ // Convert the MediaType to the MiiMediaType values
+
+ Adapter->MiiMediaType =
+ ConvertMediaTypeToMiiType[Adapter->MediaType & MEDIA_MASK]
+ | (Adapter->MediaType & CONTROL_MASK);
+
+#if MII_DBG
+ DbgPrint("Translate MediaType %x to MiiMediaType %x\n",
+ Adapter->MediaType,Adapter->MiiMediaType);
+#endif
+
+ Adapter->PhyNwayCapable = ( ((Adapter->MiiMediaType & MEDIA_NWAY) != 0)
+ && ((Capabilities & MiiPhyNwayCapable) != 0)
+ );
+
+ // Merge the PHY Capabilities with the medium stored in SROM
+
+ for (PhyNumber=0; PhyNumber < MAX_PHY_TABLE; PhyNumber++) {
+
+ Adapter->Phy[PhyNumber].MediaCapabilities &= Capabilities;
+
+
+ Adapter->Phy[PhyNumber].MediaCapabilities |= (Capabilities & MiiPhyNwayCapable);
+#if MII_DBG
+ DbgPrint("Merged Capabilities (SROM&PHY)= %04x\n", Adapter->Phy[PhyNumber].MediaCapabilities);
+#endif
+ Adapter->MiiGen.Phys[PhyNumber]->PhyCapabilities = Adapter->Phy[PhyNumber].MediaCapabilities;
+ }
+ }
+ if (PhyPresent) {
+#if MII_DBG
+ DbgPrint("Check if Connection is supported\n");
+#endif
+ // Now check the Connection.
+ ConnectionPresent = MiiGenCheckConnection(
+ Adapter,
+ (USHORT)Adapter->MiiMediaType
+ );
+
+ if (!ConnectionPresent) {
+ //Force the Phy to 10
+ DC21X4SetPhyControl(
+ Adapter,
+ MiiGenAdminForce10
+ );
+ }
+ }
+
+ return (PhyPresent && ConnectionPresent);
+}
+
+
+/*+
+ * DC21X4SetPhyConnection
+ *
+ * Routine Description:
+ *
+ * This function first resets the MAC (which could reset the PHY) and
+ * initialize CSR6 and CSR12 registers. Then sets the PHY to
+ * the required medium.
+ *
+ * Arguments:
+ *
+ * Adapter - Pointer to the Data Structure
+ *
+ * Return Value:
+ *
+ * True if the requested Medium is supported by the Phy.
+ *
+-*/
+extern
+BOOLEAN
+DC21X4SetPhyConnection(
+ IN PDC21X4_ADAPTER Adapter
+ )
+{
+ BOOLEAN MediaSupported;
+
+ // First set Mac Connection.
+#if MII_DBG
+ DbgPrint("DC21X4SetPhyConnection\n");
+#endif
+ SetMacConnection(Adapter);
+
+ // Now set the PHY Connection.
+ MediaSupported = MiiGenSetConnection(
+ Adapter,
+ Adapter->MiiMediaType,
+ Adapter->Phy[Adapter->PhyNumber].NwayAdvertisement
+ );
+ return MediaSupported;
+
+}
+
+
+
+/*+
+ * SetMacConnection
+ *
+ * Routine Description:
+ *
+ * This function initialize the CSR6 and CSR12 registers according to the
+ * values present in the SROM for the Selected Medium.
+ *
+ * Arguments:
+ *
+ * Adapter - Pointer to the Data Structure
+ *
+ * Return Value:
+ *
+ *
+-*/
+
+void
+SetMacConnection(
+ IN PDC21X4_ADAPTER Adapter
+ )
+{
+
+ USHORT MediaPositionMask;
+ ULONG OperationMode;
+
+#if MII_DBG
+ DbgPrint("SetMacConnection\n");
+#endif
+ // First of all find the media type.
+
+ MediaPositionMask = MediaBitTable[(Adapter->MiiMediaType & MEDIA_MASK)];
+#if MII_DBG
+ DbgPrint(" MiiMediaType %04x Bitmap %04x\n",
+ Adapter->MiiMediaType,MediaPositionMask);
+#endif
+
+ // If unknown media, just return.
+ if (MediaPositionMask == 0) {
+#if __DBG
+ DbgPrint("UNKNOWN Phy Medium %x!!!\n",Adapter->MiiMediaType);
+#endif
+ return;
+ }
+
+ // select Port_Select MII (disable HEARTBEAT in MII mode).
+ OperationMode = Adapter->OperationMode | (DC21X4_PORT_SELECT | DC21X4_HEARTBEAT_DISABLE);
+
+ if (Adapter->Phy[Adapter->PhyNumber].MediaCapabilities & MediaPositionMask) {
+
+ if (Adapter->Phy[Adapter->PhyNumber].FullDuplexBits & MediaPositionMask) {
+ // Set FullDuplex bit
+ OperationMode |= DC21X4_FULL_DUPLEX_MODE;
+ }
+ else {
+ //Reset FullDuplex bit
+ OperationMode &= ~DC21X4_FULL_DUPLEX_MODE;
+ }
+ if (Adapter->Phy[Adapter->PhyNumber].TxThresholdModeBits & MediaPositionMask) {
+ // Set TTM bit
+ OperationMode &= ~(Adapter->Threshold100Mbps);
+ OperationMode |= (DC21X4_TXM_THRESHOLD_MODE | Adapter->Threshold10Mbps);
+ }
+ else {
+ // Reset TTM bit
+ OperationMode &= ~(DC21X4_TXM_THRESHOLD_MODE | Adapter->Threshold10Mbps);
+ OperationMode |= Adapter->Threshold100Mbps;
+ }
+
+#if __DBG
+ DbgPrint("SetMacConnection:%s FullDuplex & %s TTM bits in CSR6\n",
+ OperationMode & DC21X4_FULL_DUPLEX_MODE ? "Set" : "Reset",
+ OperationMode & DC21X4_TXM_THRESHOLD_MODE ? "Set" : "Reset");
+#endif
+
+ }
+
+ // Switch Medium:
+
+ DC21X4IndicateMediaStatus(
+ Adapter,
+ LinkFail
+ );
+
+ // if TTM or FDX setting has changed, stop the TXM and RCV process before modifying
+ // these modes
+
+ if ((OperationMode & DC21X4_MODE_MASK) != (Adapter->OperationMode & DC21X4_MODE_MASK) ) {
+#if MII_DBG
+ DbgPrint("FDX or TTM setting has changed: stop RCV and TXM\n");
+#endif
+ DC21X4StopReceiverAndTransmitter(Adapter);
+ }
+
+ switch (Adapter->DeviceId) {
+
+ case DC21142_CFID:
+
+ //Initialize the Sia Registers for MII operation
+ // Reset Sia (CSR13)
+ // Turn off the BNC transceiver (CSR15)
+ // Disable Autonegotiation (CSR14)
+
+ DC21X4_WRITE_PORT(
+ DC21X4_SIA_MODE_0,
+ DC21X4_RESET_SIA
+ );
+
+ Adapter->Gep_Sia2 =
+ (DC21142_SIA2_10BT & DC21142_SIA2_MASK)
+ | (Adapter->Gep_Sia2 & DC21142_GEP_MASK);
+
+ DC21X4_WRITE_PORT(
+ DC21X4_SIA_MODE_2,
+ Adapter->Gep_Sia2
+ );
+
+ DC21X4_WRITE_PORT(
+ DC21X4_SIA_MODE_1,
+ 0
+ );
+
+ break;
+ }
+
+
+ // Init the Command Register.
+
+ Adapter->OperationMode = OperationMode;
+
+#if __DBG
+ DbgPrint("SetMacConnection: Write CSR6=%08x\n", OperationMode);
+#endif
+ DC21X4_WRITE_PORT(
+ DC21X4_OPERATION_MODE,
+ Adapter->OperationMode
+ );
+ DELAY(5);
+
+ DC21X4InitializeGepRegisters(Adapter,TRUE);
+
+}
+
+/*+
+ * DC21X4MiiAutoDetect
+ *
+ * Routine Description:
+ *
+ * This function contains the power up autosensing for PHYs.
+ *
+ * Arguments:
+ *
+ * Adapter - Pointer to the Data Structure
+ *
+ * Return Value:
+ *
+ * Link status
+ *
+-*/
+extern
+BOOLEAN
+DC21X4MiiAutoDetect(
+ IN PDC21X4_ADAPTER Adapter
+ )
+{
+ ULONG OperationMode;
+ INT Loop;
+ USHORT ConnectionStatus;
+ USHORT TmpMedia;
+ BOOLEAN Link;
+#if MII_DBG
+ ULONG Status;
+#endif
+
+ Link = MiiGenGetConnectionStatus(
+ Adapter,
+ &ConnectionStatus
+ );
+ DC21X4IndicateMediaStatus(
+ Adapter,
+ Link ? MiiLinkPass : LinkFail
+ );
+
+ // If no link available while still negotiating, continue to
+ // check the link up to 3s.
+
+ if (!Link) {
+#if MII_DBG
+ Loop = 30;
+#else
+ Loop = LINK_PASS_MAX_LOOP;
+#endif
+ while (!Link && Loop--) {
+#if MII_DBG
+ DbgPrint("LinkPass=FALSE: wait up to 3 seconds %d\n", Loop);
+#endif
+ DELAY(LINK_PASS_DELAY);
+ Link = MiiGenGetConnectionStatus(
+ Adapter,
+ &ConnectionStatus
+ );
+ }
+ DC21X4IndicateMediaStatus(
+ Adapter,
+ Link ? MiiLinkPass : LinkFail
+ );
+ }
+
+#if MII_DBG
+ DC21X4_READ_PORT(
+ DC21X4_OPERATION_MODE,
+ &Status
+ );
+ DbgPrint("CSR6= %08x, OperationMode=%08x\n", Status, Adapter->OperationMode);
+#endif
+
+ // In AutoSense mode, we must know which media has been chosen to set the MAC.
+ // otherwise the MAC has been already set.
+
+ if (Adapter->MiiMediaType & MEDIA_AUTOSENSE){
+#if MII_DBG
+ DbgPrint("AutoSense to check which Medium was chosen\n");
+#endif
+ Link = MiiGenGetConnection(
+ Adapter,
+ &TmpMedia
+ );
+ DC21X4IndicateMediaStatus(
+ Adapter,
+ Link ? MiiLinkPass : LinkFail
+ );
+
+ if (Link){
+#if MII_DBG
+ DbgPrint("LinkPass= TRUE; Medium = %s\n",
+ MiiMediumString[TmpMedia&MEDIA_MASK]);
+#endif
+ Adapter->MiiMediaType = (TmpMedia | MEDIA_AUTOSENSE);
+ SetMacConnection(Adapter);
+ }
+ }
+
+ if ( !Link
+ && (Adapter->MediaCapable)
+ && (Adapter->MiiMediaType & MEDIA_AUTOSENSE)
+ ) {
+
+ //Switch back to the non_MII port
+
+ SelectNonMiiPort(Adapter);
+
+ }
+
+ return Link;
+
+}
+
+
+/*+
+ * DC21X4DynamicMiiAutoSense
+ *
+ * Routine Description:
+ *
+ * This function performs the PHY Dynamic Autosense
+ *
+ * Arguments:
+ *
+ * Adapter - Pointer to the Data Structure
+ *
+ * Return Value:
+ *
+ * Link status
+ *
+-*/
+extern
+BOOLEAN
+DC21X4MiiAutoSense(
+ IN PDC21X4_ADAPTER Adapter
+ )
+
+{
+ ULONG OperationMode;
+ USHORT CurrentMedia;
+ USHORT ConnectionStatus;
+ BOOLEAN Link;
+ BOOLEAN SwitchPort=FALSE;
+
+#if MII_DBG
+ DbgPrint("DC21X4MiiAutoSense\n");
+#endif
+
+ Link = MiiGenGetConnectionStatus(
+ Adapter,
+ &ConnectionStatus
+ );
+
+#if MII_DBG
+ DbgPrint("MiiMediaType = %04x, ConnectionStatus = %04x\n",
+ Adapter->MiiMediaType, ConnectionStatus);
+#endif
+
+ if (Adapter->MiiMediaType & MEDIA_AUTOSENSE) {
+
+ if (Link &&
+ ((ConnectionStatus & MEDIA_STATUS_MASK) == MEDIA_LINK_PASS_WITH_PF)){
+
+ // There was a link failure
+ // Check the current medium
+
+ Link = MiiGenGetConnection(
+ Adapter,
+ &CurrentMedia
+ );
+
+ if ( Link
+ && ( (Adapter->MiiMediaType != CurrentMedia)
+ || (Adapter->LinkStatus != MiiLinkPass)
+ )
+ ){
+
+ //The link is up but the medium has changed
+#if MII_DBG
+ DbgPrint("Mii Medium has changed: New Mii Medium = %s \n",
+ MiiMediumString[CurrentMedia&MEDIA_MASK]);
+#endif
+ Adapter->MiiMediaType = (CurrentMedia | MEDIA_AUTOSENSE);
+ SetMacConnection(Adapter);
+ }
+ }
+ }
+
+ // do not indicate the Mii Link down transition
+ // if the non_Mii link is up.
+ // In any other case indicate the transition
+
+ if (Link || (Adapter->LinkStatus != LinkPass)) {
+
+ DC21X4IndicateMediaStatus(
+ Adapter,
+ Link ? MiiLinkPass : LinkFail
+ );
+ }
+
+ if ( !Link
+ && (Adapter->MediaCapable)
+ && (Adapter->MiiMediaType & MEDIA_AUTOSENSE)
+ ) {
+
+ if ((ConnectionStatus & MEDIA_STATUS_MASK) == MEDIA_READ_REGISTER_FAILED){
+
+ //PHY is not connected anymore
+
+ Adapter->PhyPresent=FALSE;
+
+ if (Adapter->MediaType & MEDIA_NWAY) {
+
+ //Enable Nway Negotiation
+ DC21X4EnableNway (Adapter);
+
+ SwitchPort=TRUE;
+ }
+ }
+ else if (Adapter->OperationMode & DC21X4_PORT_SELECT){
+
+ // Mii link is down,current port is Mii,
+ // at least one non Mii port is populated:
+ //Switch Port_Select to enable the non MII ports
+ SwitchPort = TRUE;
+ }
+
+ if (SwitchPort) {
+
+ SelectNonMiiPort(Adapter);
+
+ }
+
+ }
+
+ return Link;
+
+}
+
+/*+
+ * SelectNonMiiPort
+ *
+ * Routine Description:
+ *
+ * This function selects the DC21X4 non_MII port
+ *
+ * Arguments:
+ *
+ * Adapter - Pointer to the Data Structure
+ *
+ * Return Value:
+ *
+ * None
+ *
+-*/
+extern
+VOID
+SelectNonMiiPort(
+ IN PDC21X4_ADAPTER Adapter
+ )
+
+{
+
+ ULONG OperationMode;
+
+ OperationMode = Adapter->OperationMode & ~(DC21X4_MEDIUM_MASK);
+ OperationMode |= Adapter->Media[Adapter->SelectedMedium].Mode;
+
+ if ((OperationMode & DC21X4_MODE_MASK) != (Adapter->OperationMode & DC21X4_MODE_MASK)) {
+ DC21X4StopReceiverAndTransmitter(Adapter);
+ }
+
+ Adapter->OperationMode = OperationMode;
+
+ DC21X4_WRITE_PORT(
+ DC21X4_OPERATION_MODE,
+ Adapter->OperationMode
+ );
+
+ DC21X4InitializeMediaRegisters(Adapter,FALSE);
+
+ switch (Adapter->SelectedMedium) {
+
+ case Medium10Base2:
+ case Medium10Base5:
+
+ DC21X4IndicateMediaStatus(Adapter,LinkPass);
+ break;
+ }
+
+}
+
+
+/*+
+ * DC21X4SetPhyControl
+ *
+ * Routine Description:
+ *
+ * This function modifies the PHY Control register.
+ *
+ * Arguments:
+ *
+ * Adapter - Pointer to the Data Structure
+ * Control - The Control to perform
+ *
+ * Return Value:
+ *
+ * none
+-*/
+extern
+VOID
+DC21X4SetPhyControl(
+ PDC21X4_ADAPTER Adapter,
+ USHORT AdminControl
+ )
+{
+
+ MiiGenAdminControl(Adapter, AdminControl);
+ return;
+
+}
+
+
diff --git a/private/ntos/ndis/dc21x4/makefile b/private/ntos/ndis/dc21x4/makefile
new file mode 100644
index 000000000..58189757d
--- /dev/null
+++ b/private/ntos/ndis/dc21x4/makefile
@@ -0,0 +1,7 @@
+#
+# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source
+# file to this component. This file merely indirects to the real make file
+# that is shared by all the driver components of the Windows NT DDK
+#
+
+!INCLUDE $(NTMAKEENV)\makefile.def
diff --git a/private/ntos/ndis/dc21x4/makefile.inc b/private/ntos/ndis/dc21x4/makefile.inc
new file mode 100644
index 000000000..0b46b8d78
--- /dev/null
+++ b/private/ntos/ndis/dc21x4/makefile.inc
@@ -0,0 +1,5 @@
+dc21x4.hlp: $(TARGETEXEFILES)
+ chmode -r dc21x4.hlp
+ binplace dc21x4.hlp
+ touch dc21x4.hlp
+ chmode +r dc21x4.hlp
diff --git a/private/ntos/ndis/dc21x4/media.c b/private/ntos/ndis/dc21x4/media.c
new file mode 100644
index 000000000..745b34085
--- /dev/null
+++ b/private/ntos/ndis/dc21x4/media.c
@@ -0,0 +1,2047 @@
+/*+
+ * file: media.c
+ *
+ * Copyright (C) 1992-1995 by
+ * Digital Equipment Corporation, Maynard, Massachusetts.
+ * All rights reserved.
+ *
+ * This software is furnished under a license and may be used and copied
+ * only in accordance of the terms of such license and with the
+ * inclusion of the above copyright notice. This software or any other
+ * copies thereof may not be provided or otherwise made available to any
+ * other person. No title to and ownership of the software is hereby
+ * transferred.
+ *
+ * The information in this software is subject to change without notice
+ * and should not be construed as a commitment by digital equipment
+ * corporation.
+ *
+ * Digital assumes no responsibility for the use or reliability of its
+ * software on equipment which is not supplied by digital.
+ *
+ *
+ * Abstract: This file contains the Media detection code of the
+ * NDIS 4.0 miniport driver for DEC's DC21X4 Ethernet Adapter
+ * family.
+ *
+ * Author: Philippe Klein
+ *
+ * Revision History:
+ *
+ * phk 01-Dec-1994 Initial entry
+ * phk 31-Jan-1994 Add Polarity support
+ * phk 26-Apr-1995 Modify the DC21140 MediaDetect and
+ * AutoSense routines
+ *
+-*/
+
+#include <precomp.h>
+
+#define MII100_TICK 30 // 2.5ms (81.9 us/tick)
+#define EXT10_TICK 12 // 2.5ms (204.8 us/tick)
+#define MII10_TICK 3 // 2.5ms (819.2 us/tick)
+
+#define ONE_SECOND_DELAY 400 // * 2.5 ms
+#define FIVE_MILLISECONDS_DELAY 2 // * 2.5 ms
+
+#define MAX_RETRY 4
+
+#define GEP_READ_DELAY 200 // milliseconds
+
+#define DC21X4_LINK_STATUS(_status,_adapter,_medium) \
+ (BOOLEAN) ( ( ( (_status) ^ (_adapter)->Media[(_medium)].Polarity) \
+ & (_adapter)->Media[(_medium)].SenseMask ) != 0)
+
+#if __DBG
+PUCHAR MediumString[] = {
+ "10BaseT",
+ "10Base2",
+ "10Base5",
+ "100BaseTx",
+ "10BaseT_FD",
+ "100BaseTx_FD",
+ "100BaseT4",
+ "100BaseFx",
+ "100BaseFx_FD",
+ "Mii10BaseT",
+ "Mii10BaseT_FD",
+ "Mii10Base2",
+ "Mii10Base5",
+ "Mii100BaseTx",
+ "Mii100BaseTx_FD",
+ "Mii100BaseT4",
+ "Mii100BaseFx",
+ "Mii100BaseFx_FD"
+};
+
+#endif
+
+/*+
+ * DC21X4MediaDetect
+ *
+ * Routine Description:
+ *
+ * DC21X4MediaDetect:
+ *
+ * checks the DC2104x media ports in the following order:
+ * 10BaseT -> 10Base2 -> 10Base5
+ *
+ * checks the DC21140 link status
+ *
+ * Arguments:
+ *
+ * Adapter
+ *
+ * Return Value:
+ *
+ * TRUE if the Autosense timer should be fired
+ *
+-*/
+
+extern
+BOOLEAN
+DC21X4MediaDetect(
+ IN PDC21X4_ADAPTER Adapter
+ )
+{
+
+ PDC21X4_TRANSMIT_DESCRIPTOR TxmDescriptor;
+ ULONG Status;
+ UINT PacketSize = 64;
+ INT Time;
+ INT CurrentMedium=0;
+ INT i;
+ INT j;
+
+ BOOLEAN Link=FALSE;
+ BOOLEAN Sensed=FALSE;
+#if __DBG
+ DbgPrint("DC21X4MediaDetect\n");
+#endif
+
+ switch (Adapter->DeviceId) {
+
+ case DC21140_CFID:
+
+ if (Adapter->MediaType & MEDIA_AUTOSENSE) {
+
+ //AutoSense mode:
+
+ //Initialize the General Purpose Control register
+
+ CurrentMedium = Adapter->MediaPrecedence[0];
+
+ DC21X4_WRITE_PORT(
+ DC21X4_GEN_PURPOSE,
+ Adapter->Media[CurrentMedium].GeneralPurposeCtrl
+ );
+
+ //Check the link status of each medium supported
+ //by the adapter until afirst link is detected up.
+
+ for (i=Adapter->MediaCount; i>0; i--) {
+
+ CurrentMedium = Adapter->MediaPrecedence[i-1];
+#if __DBG
+ DbgPrint("DC21X4MediaDetect: %d - Check medium %x \n",
+ i,CurrentMedium);
+#endif
+
+ if (( (CurrentMedium == Medium100BaseTx)
+ ||(CurrentMedium == Medium10BaseT)
+ )
+ && (!Sensed)
+ ) {
+
+ // 100BaseTx or 10BaseT medium:
+ // Check the 100BaseTx & the 10BaseT link
+
+ Link = DC2114Sense100BaseTxLink(Adapter);
+ Sensed = TRUE;
+#if __DBG
+ DbgPrint(" Link[%x]=%d\n",
+ (Link?Adapter->SelectedMedium:CurrentMedium),Link);
+#endif
+ if (Link) {
+ // a link was detected up
+ break;
+ }
+ }
+ else {
+
+ //Medium is not 100BaseTx or 10BaseT:
+ //Initialize the Mode and GEP registers
+ //and check the link status
+
+ DC21X4_WRITE_PORT(
+ DC21X4_OPERATION_MODE,
+ ((Adapter->OperationMode & ~(DC21X4_MEDIUM_MASK))
+ | Adapter->Media[CurrentMedium].Mode)
+ );
+
+ DC21X4_WRITE_PORT(
+ DC21X4_GEN_PURPOSE,
+ Adapter->Media[CurrentMedium].GeneralPurposeData
+ );
+
+ for (j=0;j<(GEP_READ_DELAY/5);j++) {
+ NdisStallExecution(5*MILLISECOND);
+ }
+
+ DC21X4_READ_PORT(
+ DC21X4_GEN_PURPOSE,
+ &Status
+ );
+
+ Link = DC21X4_LINK_STATUS(Status,Adapter,CurrentMedium);
+#if __DBG
+ DbgPrint(" Link[%x]=%d\n",CurrentMedium,Link);
+#endif
+ if (Link) {
+
+ // The link was detected up:
+ // select the current medium
+
+ Adapter->SelectedMedium = CurrentMedium;
+ Adapter->OperationMode &= ~(DC21X4_MEDIUM_MASK);
+ Adapter->OperationMode |= Adapter->Media[CurrentMedium].Mode;
+ break;
+ }
+
+ }
+
+ }
+
+ DC21X4IndicateMediaStatus(
+ Adapter,
+ Link ? LinkPass : LinkFail
+ );
+
+ if (!Link) {
+
+ //No link detected: select the default medium
+#if __DBG
+ DbgPrint("MediaDetect: No link - Select the default Medium (%x)\n",
+ Adapter->DefaultMedium);
+#endif
+ Adapter->SelectedMedium = Adapter->DefaultMedium;
+
+ Adapter->OperationMode &= ~(DC21X4_MEDIUM_MASK);
+ Adapter->OperationMode |= Adapter->Media[Adapter->SelectedMedium].Mode;
+
+ DC21X4_WRITE_PORT(
+ DC21X4_OPERATION_MODE,
+ Adapter->OperationMode
+ );
+
+ DC21X4_WRITE_PORT(
+ DC21X4_GEN_PURPOSE,
+ Adapter->Media[Adapter->SelectedMedium].GeneralPurposeData
+ );
+ }
+
+ }
+ else {
+
+ // Not AutoSense mode
+
+ if (Adapter->Media[Adapter->SelectedMedium].SenseMask) {
+
+ //Check the link status of the select medium
+
+ DC21X4_READ_PORT(
+ DC21X4_GEN_PURPOSE,
+ &Status
+ );
+
+ Link = DC21X4_LINK_STATUS(Status,Adapter,Adapter->SelectedMedium);
+ DC21X4IndicateMediaStatus(
+ Adapter,
+ Link ? LinkPass : LinkFail
+ );
+ }
+ else {
+
+ //There is no link status reported in the
+ //General Purpose Register for the selected medium:
+ //Set the LinkPass flag but do not start AutoSense
+
+ if (!Adapter->PhyPresent) {
+ DC21X4IndicateMediaStatus(Adapter,LinkPass);
+ }
+ return Adapter->PhyPresent;
+ }
+ }
+
+ // if DynamicAutoSense mode is disabled clear
+ // the AutoSense flag in MediaType to disable
+ // the medium link dynamic check but fire the
+ // Spa timer anyway to check the link status
+ // of the selected medium
+
+ if (!Adapter->DynamicAutoSense) {
+ Adapter->MediaType &= ~(MEDIA_AUTOSENSE);
+ }
+
+ return TRUE;
+
+
+ case DC21041_CFID:
+ case DC21142_CFID:
+
+ if (!(Adapter->MediaType & MEDIA_AUTOSENSE)) {
+ return Adapter->PhyPresent;
+ }
+ if (Adapter->SelectedMedium != Medium10BaseT) {
+
+ // Selected medium is 10Base2 or 10Base5
+
+ DC21X4IndicateMediaStatus(Adapter,LinkPass);
+
+ return TRUE;
+ }
+ return Adapter->PhyPresent;
+
+ case DC21040_CFID:
+
+ if (Adapter->SelectedMedium != Medium10BaseT) {
+
+ DC21X4IndicateMediaStatus(Adapter,LinkPass);
+ return FALSE;
+ }
+
+ // Selected Medium = 10BaseT:
+ // Check the TP Link status
+
+ do {
+
+ // Read the SIA satus
+
+ DC21X4_READ_PORT(
+ DC21X4_SIA_STATUS,
+ &Status
+ );
+
+#if __DBG
+ DbgPrint("Sia Status = %08x\n",Status);
+#endif
+
+ if (!(Status & DC21X4_LINKFAIL_10)) {
+#if __DBG
+ DbgPrint("MediaDetect: TP Link established\n");
+#endif
+ DC21X4IndicateMediaStatus(Adapter,LinkPass);
+ return FALSE;
+ }
+
+ if (Status & DC21X4_NETWORK_CONNECTION_ERROR) {
+#if __DBG
+ DbgPrint("MediaDetect: TP Link failure\n");
+#endif
+ break;
+ }
+
+ }
+ while ((Status & DC21X4_LINKFAIL_10)
+ && !(Status & DC21X4_NETWORK_CONNECTION_ERROR));
+
+ if (!(Adapter->MediaType & MEDIA_AUTOSENSE)) {
+
+ DC21X4IndicateMediaStatus(Adapter,LinkFail);
+ return FALSE;
+ }
+
+ // AutoSense mode: Link Pass failure
+
+#if __DBG
+ DbgPrint(" 10BaseT link failure: switch to 10Base2 \n");
+#endif
+ Adapter->SelectedMedium = Medium10Base2;
+ DC2104InitializeSiaRegisters(
+ Adapter
+ );
+
+ // wait at least 300ms for the 10Base2 transceivers
+ // to stabilize
+
+ for (i=0; i< max(Adapter->TransceiverDelay,30); i++) {
+ for (j=0;j<2;j++) {
+ NdisStallExecution(5*MILLISECOND);
+ }
+ }
+
+ //Send a minimal size packet (with an false CRC) to check
+ //the carrier status
+
+ ZERO_MEMORY (
+ Adapter->MaxTransmitBuffer[Adapter->MaxTransmitBufferIndex].Va,
+ PacketSize
+ );
+
+ MOVE_MEMORY (
+ Adapter->MaxTransmitBuffer[Adapter->MaxTransmitBufferIndex].Va,
+ Adapter->CurrentNetworkAddress,
+ ETH_LENGTH_OF_ADDRESS
+ );
+
+ MOVE_MEMORY (
+ Adapter->MaxTransmitBuffer[Adapter->MaxTransmitBufferIndex].Va + ETH_LENGTH_OF_ADDRESS,
+ Adapter->CurrentNetworkAddress,
+ ETH_LENGTH_OF_ADDRESS
+ );
+
+ TxmDescriptor = Adapter->EnqueueTransmitDescriptor;
+ Adapter->EnqueueTransmitDescriptor = (Adapter->EnqueueTransmitDescriptor)->Next;
+ Adapter->DequeueTransmitDescriptor = Adapter->EnqueueTransmitDescriptor;
+
+ // Initialize the descriptor
+
+ TxmDescriptor->Control &= DC21X4_TDES_SECOND_ADDR_CHAINED;
+ TxmDescriptor->Control |=
+ ( DC21X4_TDES_FIRST_SEGMENT | DC21X4_TDES_LAST_SEGMENT
+ | DC21X4_TDES_ADD_CRC_DISABLE | PacketSize );
+
+ TxmDescriptor->FirstBufferAddress =
+ Adapter->MaxTransmitBuffer[Adapter->MaxTransmitBufferIndex].Pa;
+
+ TxmDescriptor->Status = DESC_OWNED_BY_DC21X4;
+
+ // Mask the interrupts
+ DC21X4_WRITE_PORT(
+ DC21X4_INTERRUPT_MASK,
+ 0
+ );
+
+#if __DBG
+ DbgPrint(" send a test packet\n");
+#endif
+ DC21X4_WRITE_PORT(
+ DC21X4_TXM_POLL_DEMAND,
+ 1
+ );
+
+ // Poll for completion
+
+ Time = DC21X4_TXM_TIMEOUT;
+
+ while (--Time) {
+
+ for (j=0;j<2;j++) {
+ NdisStallExecution(5*MILLISECOND);
+ }
+
+ DC21X4_READ_PORT(
+ DC21X4_STATUS,
+ &Status
+ );
+#if __DBG
+ DbgPrint(" CSR5 = %08x Time = %d\n",Status,Time);
+#endif
+ if (Status & DC21X4_TXM_BUFFER_UNAVAILABLE) {
+ break;
+ }
+
+ }
+#if __DBG
+ DbgPrint(" Desc status = %08x Time = %d \n",TxmDescriptor->Status,Time);
+#endif
+
+ //Check if Status_Error or Timeout
+
+ if (TxmDescriptor->Status & DC21X4_TDES_ERROR_SUMMARY || (Time <= 0) ) {
+
+ //switch to AUI Port
+#if __DBG
+ DbgPrint(" 10Base2 failure: switch to 10Base5\n");
+#endif
+
+ Adapter->SelectedMedium = Medium10Base5;
+
+ //Reset the adapter to clean up the Txm path
+
+ DC21X4InitializeRegisters(
+ Adapter
+ );
+ DC2104InitializeSiaRegisters(
+ Adapter
+ );
+
+ Adapter->DequeueReceiveDescriptor =
+ (PDC21X4_RECEIVE_DESCRIPTOR)Adapter->ReceiveDescriptorRingVa;
+ Adapter->EnqueueTransmitDescriptor =
+ (PDC21X4_TRANSMIT_DESCRIPTOR)Adapter->TransmitDescriptorRingVa;
+ Adapter->DequeueTransmitDescriptor =
+ Adapter->EnqueueTransmitDescriptor;
+
+ DC21X4StartAdapter(Adapter);
+
+ }
+ else {
+
+ //Clear Txm interrupts
+
+ DC21X4_WRITE_PORT(
+ DC21X4_STATUS,
+ Status
+ );
+
+ }
+
+ //Restore the interrupt mask
+
+ DC21X4_WRITE_PORT(
+ DC21X4_INTERRUPT_MASK,
+ Adapter->InterruptMask
+ );
+
+ DC21X4IndicateMediaStatus(Adapter,LinkPass);
+ return FALSE;
+ }
+
+ return FALSE;
+}
+
+
+
+
+
+/*+
+ *
+ *DC2114Sense100BaseTxLink
+ *
+ * Routine Description:
+ *
+ * Sense the DC2114X 100BaseTx and 10BaseT link status
+ *
+ * Arguments:
+ *
+ * Adapter
+ *
+ * Return Value:
+ *
+ * Link Status
+ *
+-*/
+extern
+BOOLEAN
+DC2114Sense100BaseTxLink(
+ IN PDC21X4_ADAPTER Adapter
+ )
+
+{
+
+ ULONG Status;
+ ULONG Mode100Tx;
+ ULONG CFDA_Data;
+ INT Loop;
+ INT Retry = MAX_RETRY;
+ INT AssertionTime;
+ INT CurrentTime;
+ INT AssertionThreshold;
+ INT Timeout;
+ INT Medium10Tick;
+ INT i;
+
+ BOOLEAN Link = FALSE;
+ BOOLEAN Scrambler;
+
+#if __DBG
+ DbgPrint("Sense100BaseTxLink\n");
+#endif
+
+ // If the adapter is in Snooze mode,
+ // switch to regular mode to enable the
+ // built-in timer
+
+ if (Adapter->PciDriverArea & CFDA_SNOOZE_MODE) {
+
+ CFDA_Data = Adapter->PciDriverArea & ~CFDA_SNOOZE_MODE;
+
+ NdisWritePciSlotInformation(
+ Adapter->MiniportAdapterHandle,
+ Adapter->SlotNumber,
+ PCI_CFDA_OFFSET,
+ &CFDA_Data,
+ sizeof(CFDA_Data)
+ );
+ }
+
+ //Mask the Timer_Expired interrupt
+
+ DC21X4_WRITE_PORT(
+ DC21X4_INTERRUPT_MASK,
+ Adapter->InterruptMask & ~(DC21X4_MSK_TIMER_EXPIRED)
+ );
+
+ //Sense the 100BaseTx & 10BaseT link
+
+ Mode100Tx =
+ ( (Adapter->OperationMode & ~(DC21X4_MEDIUM_MASK))
+ | Adapter->Media[Medium100BaseTx].Mode
+ )
+ & ~(DC21X4_SCRAMBLER);
+
+ // Set the 10 Mbps timer tick
+ Medium10Tick =
+ (Adapter->Media[Medium10BaseT].Mode & DC21X4_PORT_SELECT) ?
+ MII10_TICK : EXT10_TICK;
+
+ while (Retry-- && !Link) {
+
+ //if DC21140 Rev1.1 disable the scrambler
+ Scrambler = (Adapter->RevisionNumber != DC21140_REV1_1);
+
+ Loop=2;
+ while(Loop-- && !Link) {
+
+ AssertionThreshold =
+ Scrambler? FIVE_MILLISECONDS_DELAY : ONE_SECOND_DELAY;
+
+ Timeout = (3 * AssertionThreshold);
+
+ if (Adapter->MediaCapable & MEDIUM_100BTX) {
+
+ //Select 100BaseTx
+
+ DC21X4_WRITE_PORT(
+ DC21X4_OPERATION_MODE,
+ Mode100Tx
+ | ( Scrambler ? DC21X4_SCRAMBLER : 0 )
+ );
+
+ DC21X4_WRITE_PORT(
+ DC21X4_GEN_PURPOSE,
+ Adapter->Media[Medium100BaseTx].GeneralPurposeData
+ );
+
+ // Check 100BaseTx Symbol Link for a
+ // continuous assertion of 'AssertionThreshold'
+
+ AssertionTime = 0;
+ CurrentTime = 0;
+
+ //Start the built_in timer in cyclic mode of
+ //2.5 ms ticks
+ DC21X4_WRITE_PORT(
+ DC21X4_TIMER,
+ MII100_TICK | DC21X4_TIMER_CON_MODE
+ );
+
+ while ((CurrentTime < (Timeout+1)) && !Link) {
+
+ DC21X4_READ_PORT(
+ DC21X4_STATUS,
+ &Status
+ );
+
+ if (Status & DC21X4_MSK_TIMER_EXPIRED) {
+
+ DC21X4_WRITE_PORT(
+ DC21X4_STATUS,
+ DC21X4_MSK_TIMER_EXPIRED
+ );
+ CurrentTime++;
+ }
+
+ DC21X4_READ_PORT(
+ DC21X4_GEN_PURPOSE,
+ &Status
+ );
+
+ if (DC21X4_LINK_STATUS(Status,Adapter,Medium100BaseTx)) {
+
+ // Link is asserted
+ if (AssertionTime == 0 ) {
+ //First assertion
+ AssertionTime = CurrentTime+1;
+ }
+ else {
+ Link = ((CurrentTime - AssertionTime) >= AssertionThreshold);
+ }
+ }
+ else {
+ // No link
+ AssertionTime = 0;
+ }
+ }
+
+ //Stop the built_in timer
+
+ DC21X4_WRITE_PORT(
+ DC21X4_TIMER,
+ 0
+ );
+
+ DC21X4_WRITE_PORT(
+ DC21X4_STATUS,
+ DC21X4_MSK_TIMER_EXPIRED
+ );
+
+ if (Link) {
+
+ // 100BaseTx link detected: Select 100BaseTx
+
+ Adapter->SelectedMedium = Medium100BaseTx;
+
+ Adapter->OperationMode &= ~(DC21X4_MEDIUM_MASK);
+ Adapter->OperationMode |= Adapter->Media[Medium100BaseTx].Mode;
+
+ if (!Scrambler) {
+
+ //Turn the scrambler on
+
+ DC21X4_WRITE_PORT(
+ DC21X4_OPERATION_MODE,
+ Adapter->OperationMode
+ );
+ }
+
+ break;
+
+ }
+
+ }
+
+ // No 100BaseTx link detected:
+
+ if (Adapter->MediaCapable & MEDIUM_10BT) {
+
+ // Switch to 10BaseT
+
+ DC21X4_WRITE_PORT(
+ DC21X4_OPERATION_MODE,
+ (Adapter->OperationMode &~(DC21X4_MEDIUM_MASK))
+ | Adapter->Media[Medium10BaseT].Mode
+ );
+
+ DC21X4_WRITE_PORT(
+ DC21X4_GEN_PURPOSE,
+ Adapter->Media[Medium10BaseT].GeneralPurposeData
+ );
+
+ //Check the 10BaseT link status
+
+ // Start the built_in timer for
+ // half the 100BaseTx timeout
+
+ DC21X4_WRITE_PORT(
+ DC21X4_TIMER,
+ (Timeout/2) * Medium10Tick
+ );
+
+ while (!Link) {
+
+ //Check the 10BaseT link
+
+ for (i=0,Link=TRUE; i<2; i++) {
+
+ DC21X4_READ_PORT(
+ DC21X4_GEN_PURPOSE,
+ &Status
+ );
+ Link = Link && DC21X4_LINK_STATUS(Status,Adapter,Medium10BaseT);
+ }
+
+ DC21X4_READ_PORT(
+ DC21X4_STATUS,
+ &Status
+ );
+
+ if (Status & DC21X4_MSK_TIMER_EXPIRED) {
+ break;
+ }
+ }
+
+ }
+
+ if (Link) {
+
+ // 10BaseT link detected:
+
+ //Stop the timer
+
+ DC21X4_WRITE_PORT(
+ DC21X4_TIMER,
+ 0
+ );
+
+ DC21X4_WRITE_PORT(
+ DC21X4_STATUS,
+ DC21X4_MSK_TIMER_EXPIRED
+ );
+
+ if (Loop) {
+
+ // first detection of 10BT link:
+ // check the 100BaseTx link again to reject
+ // a 'false' 10BT link link induced by the 100BTX
+ Link = FALSE;
+ }
+ else {
+
+ // 10BT link detected twice:
+ // select Medium10BaseT
+
+ Adapter->SelectedMedium = Medium10BaseT;
+
+ Adapter->OperationMode &= ~(DC21X4_MEDIUM_MASK);
+ Adapter->OperationMode |= Adapter->Media[Medium10BaseT].Mode;
+ }
+ }
+ else if (Loop) {
+
+ if (Scrambler) {
+
+ //Disable the scrambler and restart the
+ //link check
+ Scrambler = FALSE;
+ Loop = 2;
+ }
+ else {
+
+ // First loop & Scrambler disbled:
+ // leave the loop and select the default medium
+ Retry = 0;
+ break;
+ }
+ }
+
+ } // endwhile Loop
+
+ } //endwhile Retry
+
+
+ //Demask the Timer_Expired interrupt
+
+ DC21X4_WRITE_PORT(
+ DC21X4_STATUS,
+ DC21X4_MSK_TIMER_EXPIRED
+ );
+
+ DC21X4_WRITE_PORT(
+ DC21X4_INTERRUPT_MASK,
+ Adapter->InterruptMask
+ );
+
+ if (Adapter->PciDriverArea & CFDA_SNOOZE_MODE) {
+
+ //set to the initial snooze mode
+
+ NdisWritePciSlotInformation(
+ Adapter->MiniportAdapterHandle,
+ Adapter->SlotNumber,
+ PCI_CFDA_OFFSET,
+ &Adapter->PciDriverArea,
+ sizeof(Adapter->PciDriverArea)
+ );
+ }
+
+#if __DBG
+ if (Link)
+ DbgPrint("Sense: SelectMedium = %s\n",
+ Adapter->SelectedMedium==Medium100BaseTx?"100BaseTx":"10BaseT");
+#endif
+
+ return Link;
+
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+/*+
+ * DC21X4DynamicAutoSense
+ *
+ * Routine Description:
+ *
+ * Autosense between the PHY's Autosense routine and the
+ * other media autosense's routine
+ *
+ * Arguments:
+ *
+ * Adapter
+ *
+-*/
+extern
+VOID
+DC21X4DynamicAutoSense (
+ IN PVOID Systemspecific1,
+ IN PDC21X4_ADAPTER Adapter,
+ IN PVOID Systemspecific2,
+ IN PVOID Systemspecific3
+ )
+{
+
+ BOOLEAN LinkStatus=FALSE;
+ BOOLEAN StartTimer=TRUE;
+ BOOLEAN LoopbackMode;
+
+#if _DBG
+ DbgPrint("DC21X4DynamicAutoSense\n");
+#endif
+
+ if ( (Adapter->PhyPresent)
+ && (!Adapter->Force10)
+ ){
+ LinkStatus = DC21X4MiiAutoSense(Adapter);
+ }
+
+ if (Adapter->Indicate10BTLink) {
+
+ Adapter->Indicate10BTLink = FALSE;
+
+ if (!LinkStatus) {
+
+ // The current link is a 10BaseT link
+
+#if 0
+ DC21X4SetPhyControl(
+ Adapter,
+ (USHORT)MiiGenAdminIsolate
+ );
+#endif
+
+ DC21X4SetPhyControl(
+ Adapter,
+ (USHORT)((Adapter->OperationMode & DC21X4_FULL_DUPLEX_MODE) ?
+ MiiGenAdminForce10Fd : MiiGenAdminForce10)
+ );
+
+ DC21X4IndicateMediaStatus(Adapter,LinkPass);
+ }
+ }
+
+ if ( !LinkStatus
+ && (Adapter->MediaCapable)
+ ) {
+ StartTimer = DC21X4AutoSense(Adapter);
+ }
+
+ // Restart the Autosense timer
+
+ if (StartTimer) {
+
+ DC21X4StartAutoSenseTimer(
+ Adapter,
+ (UINT)((Adapter->PhyPresent) ? DC21X4_MII_TICK : DC21X4_SPA_TICK)
+ );
+
+ }
+
+}
+
+
+/*+
+ * DC21X4AutoSense
+ *
+ * Routine Description:
+ *
+ * Autosense the DC21041 10Base2/10Base5 port
+ * Autosense the DC21140 100BaseTx/10BaseT link
+ *
+ * Arguments:
+ *
+ * Adapter
+ *
+ * Return:
+ *
+ * TRUE if AutoSense Timer should be fired
+ *
+-*/
+extern
+BOOLEAN
+DC21X4AutoSense (
+ IN PDC21X4_ADAPTER Adapter
+ )
+{
+ ULONG Status;
+ BOOLEAN SelectedPortActive;
+ BOOLEAN SwitchMedium;
+ BOOLEAN FullDuplex;
+
+ INT CurrentMedium=0;
+ INT NextMedium;
+ INT index;
+
+#if _DBG
+ DbgPrint("Autosense routine\n");
+#endif
+
+ switch (Adapter->DeviceId) {
+
+ case DC21040_CFID:
+
+ if (Adapter->LinkStatus != LinkFail) {
+ return FALSE;
+ }
+
+ //DC21040 supports Link_Fail interrupt
+ //but does not support Link_Pass
+ //Check the Link status:
+ //If link is up wait for Link_Fail interrupt
+ //otherwhise poll the link status
+
+ DC21X4_READ_PORT(
+ DC21X4_SIA_STATUS,
+ &Status
+ );
+
+ if ((Status & DC21X4_LINKFAIL_10) == 0) {
+ DC21X4IndicateMediaStatus(Adapter,LinkPass);
+ return FALSE;
+ }
+ break;
+
+ case DC21041_CFID:
+ case DC21142_CFID:
+ if (!(Adapter->MediaType & MEDIA_AUTOSENSE)) {
+ return Adapter->PhyPresent;
+ }
+
+ if (Adapter->IgnoreTimer) {
+ Adapter->IgnoreTimer = FALSE;
+ return FALSE;
+ }
+
+ switch (Adapter->TimerFlag) {
+
+ case AncPolling:
+
+ if (Adapter->PollCount--) {
+
+ //Read the SIA Status
+
+ DC21X4_READ_PORT(
+ DC21X4_SIA_STATUS,
+ &Status
+ );
+
+ //check the AutoNegotation State
+
+ switch (Status & DC21X4_AUTO_NEGOTIATION_STATE) {
+
+ case ANS_ACKNOWLEDGE_DETECTED:
+ case ANS_ACKNOWLEDGE_COMPLETED:
+
+ //store the Sia status snapshot
+ Adapter->SiaStatus = Status;
+
+ default:
+
+ // Restart the Poll timer
+ NdisMSetTimer(
+ &Adapter->Timer,
+ DC21X4_POLL_DELAY
+ );
+ return FALSE;
+
+ case ANS_AUTO_NEGOTIATION_COMPLETED:
+
+ //Check the Link Partner capabilities
+
+ // LPN SF 10BT_FD 10BT Link_Partner Medium
+ // 0 xx x x not_negotiable 10BT
+ // 1 01 1 x 10BT_FD capable 10BT_FD
+ // 1 01 0 1 10BT_HD capable 10BT
+ // 1 01 0 0 no_common_mode 10B2/5
+ // 1 !01 x x no_common_mode 10B2/5
+
+ if (!(Status & DC21X4_LINK_PARTNER_NEGOTIABLE)) {
+#if __DBG
+ DbgPrint("Link Partner not negotiable\n");
+#endif
+ if (++Adapter->AutoNegotiationCount < 2) {
+
+
+ //Fire the Restart AutoNegotation Timer
+ // to defer the restart of the auto_negotiation
+
+ Adapter->TimerFlag=DeferredAnc;
+ NdisMSetTimer(
+ &Adapter->Timer,
+ DC21X4_ANC_DELAY
+ );
+
+ return FALSE;
+
+ }
+ else {
+ NextMedium = Medium10BaseT;
+ FullDuplex=FALSE;
+ }
+ }
+
+ else {
+
+ // Link Partner negotiable
+
+ if (!Adapter->SiaStatus) {
+
+ //Restart the AutoNegotiation
+
+ //Reinitialize the Poll timeout counter
+ Adapter->PollCount= POLL_COUNT_TIMEOUT;
+
+ DC21X4_WRITE_PORT(
+ DC21X4_SIA_STATUS,
+ DC21X4_RESTART_AUTO_NEGOTIATION
+ );
+
+ //Restart the Poll timer to
+ //poll on AutoNegotiation State
+
+ Adapter->TimerFlag=AncPolling;
+ NdisMSetTimer(
+ &Adapter->Timer,
+ DC21X4_POLL_DELAY
+ );
+
+ return FALSE;
+
+ }
+ else if ((Adapter->SiaStatus & DC21X4_SELECTED_FIELD_MASK) != DC21X4_SELECTED_FIELD) {
+ NextMedium=Medium10Base2_5;
+ FullDuplex=FALSE;
+ }
+ else if (Adapter->SiaStatus & DC21X4_LINK_PARTNER_10BT_FD) {
+ //10BT Full Duplex capable
+ NextMedium=Medium10BaseT;
+ FullDuplex=TRUE;
+ }
+ else if (Adapter->SiaStatus & DC21X4_LINK_PARTNER_10BT) {
+ //10BT Half Duplex capable
+ NextMedium=Medium10BaseT;
+ FullDuplex=FALSE;
+ }
+ else {
+ //no common mode
+ NextMedium=Medium10Base2_5;
+ FullDuplex=FALSE;
+ }
+ }
+ }
+ }
+ else {
+ //poll timeout
+ NextMedium = Medium10Base2_5;
+ FullDuplex=FALSE;
+ }
+
+ Adapter->TimerFlag = NoTimer;
+
+ //Reinitialize the Sia status snapshot
+ Adapter->SiaStatus = 0;
+
+ if (!FullDuplex) {
+ // Stop the Receiver and Transmitter to
+ // reset the Full_duplex mode
+ DC21X4StopReceiverAndTransmitter(
+ Adapter
+ );
+
+ Adapter->OperationMode &= ~(DC21X4_FULL_DUPLEX_MODE);
+ }
+
+
+ // Switch to the selected medium
+
+ Adapter->NwayEnabled=FALSE;
+
+ if (NextMedium == Medium10Base2_5) {
+
+ DC21X4SwitchMedia(
+ Adapter,
+ Medium10Base2_5
+ );
+ }
+ else {
+
+ //10BaseT: Disable NWAY
+
+ DC21X4_WRITE_PORT(
+ DC21X4_SIA_MODE_1,
+ Adapter->Media[Medium10BaseT].SiaRegister[1]
+ );
+
+ DC21X4IndicateMediaStatus(Adapter,LinkPass);
+
+ }
+
+ if (!FullDuplex) {
+
+ //Restart the Receiver and Transmitter
+ DC21X4_WRITE_PORT(
+ DC21X4_OPERATION_MODE,
+ Adapter->OperationMode
+ );
+ }
+ return FALSE;
+
+ case DeferredAnc:
+
+ //Restart the AutoNegotiation
+
+ //Reinitialize the Poll timeout counter
+ Adapter->PollCount= POLL_COUNT_TIMEOUT;
+ Adapter->SiaStatus = 0;
+
+
+ DC21X4_WRITE_PORT(
+ DC21X4_SIA_STATUS,
+ DC21X4_RESTART_AUTO_NEGOTIATION
+ );
+
+ //Restart the Poll timer to
+ //poll on AutoNegotiation State
+
+ Adapter->TimerFlag=AncPolling;
+ NdisMSetTimer(
+ &Adapter->Timer,
+ DC21X4_POLL_DELAY
+ );
+
+ return FALSE;
+
+
+ case AncTimeout:
+
+ // AutoNegotiation timeout:
+ Adapter->TimerFlag = NoTimer;
+
+ if (Adapter->MediaType & MEDIA_AUTOSENSE) {
+
+ // Switch medium from 10BaseT
+ DC21X4SwitchMedia(
+ Adapter,
+ Medium10Base2_5
+ );
+ }
+ return FALSE;
+
+
+ case DeferredLinkCheck:
+
+ Adapter->TimerFlag = NoTimer;
+
+ //Check the 10BaseT Link Status
+
+ DC21X4_READ_PORT(
+ DC21X4_SIA_STATUS,
+ &Status
+ );
+
+ if ((Status & DC21X4_LINK_PASS_MASK) == DC21X4_LINK_PASS_STATUS) {
+
+ //Link Pass:
+
+ if (Adapter->SelectedMedium == Medium10BaseT) {
+
+ //10BaseT link is up
+ DC21X4IndicateMediaStatus(Adapter,LinkPass);
+ return Adapter->PhyPresent;
+ }
+ else {
+
+ //Switch the medium to 10BaseT and start the
+ //Anc Timer to timeout if the Nway Autonegotiation
+ //does not complete
+ Adapter->TimerFlag = AncTimeout;
+ NdisMSetTimer(
+ &Adapter->Timer,
+ DC21X4_ANC_TIMEOUT
+ );
+ DC21X4SwitchMedia(
+ Adapter,
+ Medium10BaseT
+ );
+ return FALSE;
+ }
+ }
+ else {
+
+ // No 10baseT link:
+ // If the current Medium is not 10BaseT,
+ //ignore this state and enters the Selected_Port_Active check
+ //instead
+ if (Adapter->SelectedMedium == Medium10BaseT) {
+
+ if (Adapter->MediaType & MEDIA_AUTOSENSE) {
+
+ // Switch medium from 10BaseT
+ DC21X4SwitchMedia(
+ Adapter,
+ Medium10Base2_5
+ );
+ }
+ return FALSE;
+ }
+ }
+
+ case SpaTimer:
+
+ //Selected_Port_Active (10Base2/10Base5 media) periodic check
+
+ if (Adapter->SelectedMedium == Medium10BaseT) {
+ break;
+ }
+
+ if ((Adapter->MediaCapable & (MEDIUM_10B2 | MEDIUM_10B5)) !=
+ (MEDIUM_10B2 | MEDIUM_10B5)) {
+
+ //The board does not support both 10Base2 & 10Base5 ports
+ break;
+ }
+
+ // Read the Selected_Port_Active Status
+
+ DC21X4_READ_PORT(
+ DC21X4_SIA_STATUS,
+ &Status
+ );
+
+ SelectedPortActive = ((Status & DC21X4_SELECTED_PORT_ACTIVE) != 0);
+
+#if __DBG
+ DbgPrint("Autosense: SelectePortActive=%d Nocarrier=%d ExcessColl=%d\n",
+ SelectedPortActive,
+ Adapter->NoCarrierCount,
+ Adapter->ExcessCollisionsCount);
+#endif
+ if ( (!SelectedPortActive)
+ || (Adapter->NoCarrierCount >= NO_CARRIER_THRESHOLD)
+ || (Adapter->ExcessCollisionsCount >= EXCESS_COLLISIONS_THRESHOLD)
+ ) {
+
+ //Switch medium port
+ Adapter->SelectedMedium = (Adapter->SelectedMedium == Medium10Base2) ?
+ Medium10Base5 : Medium10Base2;
+#if __DBG
+ DbgPrint("Autosense: Switch Media to %s\n",
+ MediumString[Adapter->SelectedMedium]);
+#endif
+ DC21X4_WRITE_PORT(
+ DC21X4_SIA_MODE_2,
+ Adapter->Media[Adapter->SelectedMedium].SiaRegister[2]
+ );
+
+ //reset the NoCarrier and ExcessCollisions counters
+
+ Adapter->NoCarrierCount = 0;
+ Adapter->ExcessCollisionsCount = 0;
+ }
+
+ // clear the SPA flag into the Sia Status register:
+
+ DC21X4_WRITE_PORT(
+ DC21X4_SIA_STATUS,
+ DC21X4_SELECTED_PORT_ACTIVE
+ );
+
+ break;
+
+ case NoTimer:
+
+ return FALSE;
+
+ }
+ break;
+
+ case DC21140_CFID:
+
+ if (!Adapter->Media[Adapter->SelectedMedium].SenseMask) {
+ DC21X4IndicateMediaStatus(Adapter,LinkPass);
+ return Adapter->PhyPresent;
+ }
+
+ if ( (!(Adapter->MediaType & MEDIA_AUTOSENSE))
+ && (Adapter->PhyPresent)
+ ) {
+ return TRUE;
+ }
+
+ //Check the Link status
+
+ DC21X4_READ_PORT(
+ DC21X4_GEN_PURPOSE,
+ &Status
+ );
+
+ DC21X4IndicateMediaStatus(
+ Adapter,
+ DC21X4_LINK_STATUS(Status,Adapter,Adapter->SelectedMedium) ?
+ LinkPass : LinkFail
+ );
+
+ if (Adapter->MediaType & MEDIA_AUTOSENSE) {
+
+ //Check the link status of every medium supported
+ //by the adapter
+
+ for (index=Adapter->MediaCount; index>0; index--) {
+
+ CurrentMedium = Adapter->MediaPrecedence[index-1];
+
+ if (DC21X4_LINK_STATUS(Status,Adapter,CurrentMedium)) {
+ break;
+ }
+ }
+
+ if (index > 0) {
+
+ // A link was detected,switch to this medium if:
+ // current > selected (a medium link of higher precedence is up
+ // current < selected (selected medium link is down)
+
+ SwitchMedium = (CurrentMedium != Adapter->SelectedMedium);
+ }
+ else {
+
+ // no link detected:
+ // switch to the default medium if defined and different
+ // of the selected medium
+ // otherwise stay with the selected medium
+
+ CurrentMedium = Adapter->DefaultMedium;
+ SwitchMedium = Adapter->DefaultMediumFlag
+ && (Adapter->SelectedMedium != Adapter->DefaultMedium);
+
+ }
+
+ if (SwitchMedium) {
+#if __DBG
+ DbgPrint("Autosense: 21140 - Switch Medium to %s\n",
+ MediumString[CurrentMedium]);
+#endif
+
+ DC21X4SwitchMedia(
+ Adapter,
+ CurrentMedium
+ );
+
+ DC21X4_READ_PORT(
+ DC21X4_GEN_PURPOSE,
+ &Status
+ );
+#if __DBG
+ DbgPrint("Autosense 21140: Link=%s\n",
+ Adapter->LinkStatus ? "UP":"DOWN");
+#endif
+ }
+
+ }
+ break;
+ }
+
+ return TRUE;
+
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+/*++
+ *
+ * DC21X4SwitchMedia
+ *
+ * Routine Description:
+ *
+ * This routine switches DC21X4's media ports
+ *
+ * Arguments:
+ *
+ * Adapter
+ * NewMedium : the new medium to switch to
+ *
+ * Return Value:
+ *
+ * None
+ *
+-*/
+extern
+VOID
+DC21X4SwitchMedia(
+ IN PDC21X4_ADAPTER Adapter,
+ IN LONG NewMedium
+ )
+{
+
+ ULONG Status;
+ BOOLEAN SpaTimer=FALSE;
+ ULONG FullDuplex=0;
+ UINT j;
+
+#if __DBG
+ DbgPrint("DC21X4SwitchMedia [->%x]\n",NewMedium);
+#endif
+
+ DC21X4IndicateMediaStatus(Adapter,LinkFail);
+
+ switch (Adapter->DeviceId) {
+
+
+
+ case DC21142_CFID:
+ case DC21041_CFID:
+
+ switch (NewMedium) {
+
+
+ case Medium10BaseT:
+#if __DBG
+ DbgPrint("Medium = %s %s \n",
+ MediumString[NewMedium],
+ FullDuplex ? "Full_Duplex" : "");
+#endif
+ Adapter->SelectedMedium = NewMedium;
+ DC2104InitializeSiaRegisters(Adapter);
+ return;
+
+ case Medium10BaseTNway:
+#if __DBG
+ DbgPrint("Medium = 10BaseT - Nway enabled\n");
+#endif
+ NewMedium &= MEDIA_MASK;
+ Adapter->SelectedMedium = NewMedium;
+ Adapter->NwayEnabled=TRUE;
+
+ //Stop the Receiver and the Transmitter
+ DC21X4StopReceiverAndTransmitter(Adapter);
+
+ //enable Nway
+ Adapter->Media[Medium10BaseT].SiaRegister[1] |= DC21X4_NWAY_ENABLED;
+
+ DC2104InitializeSiaRegisters(Adapter);
+
+ Adapter->Media[Medium10BaseT].SiaRegister[1] &= ~(DC21X4_NWAY_ENABLED);
+
+ //Restart the Receiver and Transmitter in Full Duplex mode
+ Adapter->OperationMode |= DC21X4_FULL_DUPLEX_MODE;
+
+ DC21X4_WRITE_PORT(
+ DC21X4_OPERATION_MODE,
+ Adapter->OperationMode
+ );
+
+ return;
+
+ case Medium10Base2:
+
+ //switch medium to 10Base2
+ SpaTimer = (Adapter->MediaCapable & MEDIUM_10B5);
+ break;
+
+ case Medium10Base5:
+
+ //switch medium to 10Base5
+ SpaTimer = (Adapter->MediaCapable & MEDIUM_10B2);
+ break;
+
+ case Medium10Base2_5:
+
+ switch (Adapter->MediaCapable & (MEDIUM_10B2 | MEDIUM_10B5)) {
+
+ case (MEDIUM_10B2 | MEDIUM_10B5) :
+
+ // 10Base2 & 10Base5 ports are both populated:
+ // if Non_Selected_Port_Active select 10Base5
+ // otherwise select 10Base2
+
+ DC21X4_READ_PORT(
+ DC21X4_SIA_STATUS,
+ &Status
+ );
+
+ NewMedium = (Status & DC21X4_NON_SELECTED_PORT_ACTIVE) ?
+ Medium10Base5 : Medium10Base2;
+
+ SpaTimer = TRUE;
+ break;
+
+ case MEDIUM_10B2 :
+
+ // 10Base2 port only is populated:
+ NewMedium = Medium10Base2;
+ break;
+
+ case MEDIUM_10B5 :
+
+ // 10Base5 port only is populated
+ NewMedium = Medium10Base5;
+ break;
+
+ default:
+
+ if (Adapter->PhyPresent) {
+
+ //Start the AutoSense Timer to poll the PHY Link
+ DC21X4StartAutoSenseTimer(
+ Adapter,
+ (UINT)DC21X4_MII_TICK
+ );
+ }
+ return;
+
+ }
+
+ }
+
+#if __DBG
+ DbgPrint("Medium = %s %s\n",
+ MediumString[NewMedium],
+ Adapter->Media[NewMedium].SiaRegister[1] & DC21X4_AUTO_NEGOTIATION_ENABLE ?
+ "- NWAY Enabled" : "");
+#endif
+
+ Adapter->SelectedMedium=NewMedium;
+
+ DC2104InitializeSiaRegisters(Adapter);
+ DC21X4IndicateMediaStatus(Adapter,LinkPass);
+
+ if (SpaTimer || Adapter->PhyPresent) {
+#if __DBG
+ DbgPrint("Start the AutoSense timer\n");
+#endif
+ //Reset the NoCarrier and ExcessCollisions counters
+
+ Adapter->NoCarrierCount = 0;
+ Adapter->ExcessCollisionsCount = 0;
+
+ //Start the AutoSense Timer
+ DC21X4StartAutoSenseTimer(
+ Adapter,
+ (UINT)((Adapter->PhyPresent) ? DC21X4_MII_TICK : DC21X4_SPA_TICK)
+ );
+
+ }
+ break;
+
+
+ case DC21140_CFID:
+
+ // Switch medium:
+ // Reload GEP and OperationMode registers
+
+ Adapter->OperationMode &= ~(DC21X4_MEDIUM_MASK);
+ Adapter->OperationMode |= Adapter->Media[NewMedium].Mode;
+
+ Adapter->SelectedMedium = NewMedium;
+
+ DC21X4_WRITE_PORT(
+ DC21X4_GEN_PURPOSE,
+ Adapter->Media[NewMedium].GeneralPurposeData
+ );
+
+ DC21X4_WRITE_PORT(
+ DC21X4_OPERATION_MODE,
+ Adapter->OperationMode
+ );
+
+ for (j=0;j<(GEP_READ_DELAY/5);j++) {
+ NdisStallExecution(5*MILLISECOND);
+ }
+
+ DC21X4_READ_PORT(
+ DC21X4_GEN_PURPOSE,
+ &Status
+ );
+
+ DC21X4IndicateMediaStatus(
+ Adapter,
+ DC21X4_LINK_STATUS(Status,Adapter,Adapter->SelectedMedium) ?
+ LinkPass : LinkFail
+ );
+
+ return;
+
+ }
+
+}
+ /*++
+ *
+ * DC21X4StartAutoSenseTimer
+ *
+ * Routine Description:
+ *
+ * Start the AutoSense Timer
+ *
+ * Arguments:
+ *
+ * Adapter
+ *
+ * Return Value:
+ *
+ * None
+ *
+-*/
+extern
+VOID
+DC21X4StartAutoSenseTimer(
+ IN PDC21X4_ADAPTER Adapter,
+ IN UINT Value
+ )
+{
+
+
+ Adapter->TimerFlag=SpaTimer;
+
+ NdisMSetTimer(
+ &Adapter->Timer,
+ Value
+ );
+
+}
+
+/*++
+ *
+ * DC21X4StopAutoSenseTimer
+ *
+ * Routine Description:
+ *
+ * Stop the AutoSense Timer
+ *
+ * Arguments:
+ *
+ * Adapter
+ *
+ * Return Value:
+ *
+ * None
+ *
+-*/
+extern
+VOID
+DC21X4StopAutoSenseTimer(
+ IN PDC21X4_ADAPTER Adapter
+ )
+{
+ BOOLEAN Canceled;
+
+ Adapter->TimerFlag = NoTimer;
+
+ NdisMCancelTimer(
+ &Adapter->Timer,
+ &Canceled
+ );
+
+ Adapter->IgnoreTimer = !Canceled;
+
+}
+
+
+
+/*+
+ * DC21X4EnableNway
+ *
+ * Routine Description:
+ *
+ * Enable the Nway Negotiation
+ *
+ * Arguments:
+ *
+ * Adapter - The adapter in question.
+ *
+ * Return Value:
+ *
+ * None
+ *
+-*/
+extern
+VOID
+DC21X4EnableNway(
+ IN PDC21X4_ADAPTER Adapter
+ )
+{
+
+ULONG Mask;
+
+#if __DBG
+ DbgPrint("Enable Nway Negotiation\n");
+#endif
+
+ switch (Adapter->DeviceId) {
+
+ case DC21041_CFID:
+
+ switch (Adapter->RevisionNumber) {
+
+ case DC21041_REV2_0:
+ if (Adapter->NwayProtocol) {
+ Adapter->MediaNway = TRUE;
+ Adapter->LinkHandlerMode=NwayWorkAround;
+ break;
+ }
+ case DC21041_REV1_1:
+ case DC21041_REV1_0:
+
+ Adapter->MediaNway = FALSE;
+ Adapter->LinkHandlerMode=NoNway;
+ break;
+
+ default:
+
+ Adapter->MediaNway = TRUE;
+ Adapter->LinkHandlerMode=Nway;
+
+ Adapter->Media[Medium10BaseT].SiaRegister[1] |= DC21X4_NWAY_ENABLED;
+ Adapter->Media[Medium10Base2].SiaRegister[1] |= DC21X4_NWAY_ENABLED;
+ Adapter->Media[Medium10Base5].SiaRegister[1] |= DC21X4_NWAY_ENABLED;
+
+ Adapter->Media[Medium10BaseT].Mode |= DC21X4_FULL_DUPLEX_MODE;
+ Adapter->Media[Medium10Base2].Mode |= DC21X4_FULL_DUPLEX_MODE;
+ Adapter->Media[Medium10Base5].Mode |= DC21X4_FULL_DUPLEX_MODE;
+ }
+ break;
+
+ case DC21142_CFID:
+
+ switch (Adapter->RevisionNumber) {
+
+ case DC21142_REV1_0:
+ case DC21142_REV1_1:
+
+ if (Adapter->NwayProtocol) {
+ Adapter->MediaNway = TRUE;
+ Adapter->LinkHandlerMode=NwayWorkAround;
+ }
+ else {
+ Adapter->MediaNway = FALSE;
+ Adapter->LinkHandlerMode=NoNway;
+ }
+ break;
+
+ default:
+
+ Adapter->MediaNway = TRUE;
+ Adapter->LinkHandlerMode=Nway;
+
+ Adapter->Media[Medium10BaseT].SiaRegister[1] |= DC21X4_NWAY_ENABLED;
+ Adapter->Media[Medium10Base2].SiaRegister[1] |= DC21X4_NWAY_ENABLED;
+ Adapter->Media[Medium10Base5].SiaRegister[1] |= DC21X4_NWAY_ENABLED;
+
+ Adapter->Media[Medium10BaseT].Mode |= DC21X4_FULL_DUPLEX_MODE;
+ Adapter->Media[Medium10Base2].Mode |= DC21X4_FULL_DUPLEX_MODE;
+ Adapter->Media[Medium10Base5].Mode |= DC21X4_FULL_DUPLEX_MODE;
+
+ }
+
+ break;
+
+
+ }
+
+}
+
+
+/*+
+ * DC21X4DisableNway
+ *
+ * Routine Description:
+ *
+ * Disable the Nway Negotiation
+ *
+ * Arguments:
+ *
+ * Adapter - The adapter in question.
+ *
+ * Return Value:
+ *
+ * None
+ *
+-*/
+extern
+VOID
+DC21X4DisableNway(
+ IN PDC21X4_ADAPTER Adapter
+ )
+{
+
+#if __DBG
+ DbgPrint("Disable Nway Negotiation\n");
+#endif
+
+ Adapter->MediaNway = FALSE;
+ Adapter->LinkHandlerMode=NoNway;
+
+ switch (Adapter->DeviceId) {
+
+ case DC21041_CFID:
+ case DC21142_CFID:
+ Adapter->Media[Medium10BaseT].SiaRegister[1] &= ~DC21X4_NWAY_ENABLED;
+ Adapter->Media[Medium10Base2].SiaRegister[1] &= ~DC21X4_NWAY_ENABLED;
+ Adapter->Media[Medium10Base5].SiaRegister[1] &= ~DC21X4_NWAY_ENABLED;
+
+ Adapter->Media[Medium10BaseT].Mode &= ~DC21X4_FULL_DUPLEX_MODE;
+ Adapter->Media[Medium10Base2].Mode &= ~DC21X4_FULL_DUPLEX_MODE;
+ Adapter->Media[Medium10Base5].Mode &= ~DC21X4_FULL_DUPLEX_MODE;
+
+ break;
+
+
+ }
+
+}
+
+
+
+/*++
+ *
+ * DC21X4IndicateMediaStatus
+ *
+ * Routine Description:
+ *
+ * Indicate the media status
+ *
+ * Arguments:
+ *
+ * Adapter
+ *
+ * Return Value:
+ *
+ * None
+ *
+-*/
+extern
+VOID
+DC21X4IndicateMediaStatus(
+ IN PDC21X4_ADAPTER Adapter,
+ IN UINT Status
+ )
+{
+
+ ULONG LinkPartner;
+
+ Adapter->LinkStatus=Status;
+
+ if (Status != Adapter->PreviousLinkStatus) {
+
+ switch (Adapter->LinkStatus) {
+
+#if __DBG
+ case LinkFail:
+ DbgPrint("IndicateMediaStatus: Link FAIL\n");
+ break;
+#endif
+
+ case LinkPass:
+
+ switch (Adapter->SelectedMedium) {
+
+ case Medium100BaseTx:
+ case Medium100BaseT4:
+ case Medium100BaseFx:
+
+ Adapter->LinkSpeed = ONE_HUNDRED_MBPS;
+ break;
+
+ default:
+
+ Adapter->LinkSpeed = TEN_MBPS;
+ break;
+ }
+
+ if (Adapter->MediaNway) {
+
+ //Nway: read the Link Partner Ability to check
+ // Half/Full Duplex link mode
+
+ DC21X4_READ_PORT(
+ DC21X4_SIA_STATUS,
+ &LinkPartner
+ );
+
+ Adapter->FullDuplexLink =
+ LinkPartner & (DC21X4_LINK_PARTNER_10BT_FD) ?
+ TRUE : FALSE ;
+ }
+ else {
+ Adapter->FullDuplexLink =
+ (Adapter->MediaType & MEDIA_FULL_DUPLEX) != 0;
+ }
+
+#if __DBG
+ DbgPrint("IndicateMediaStatus: %s%s Link PASS\n",
+ MediumString[Adapter->SelectedMedium],
+ Adapter->FullDuplexLink ? " Full_Duplex" : "");
+#endif
+ break;
+
+ case MiiLinkPass:
+
+ Adapter->LinkSpeed = TEN_MBPS;
+ Adapter->FullDuplexLink = FALSE;
+
+ switch (Adapter->MiiMediaType & MEDIA_MASK) {
+
+ case MediumMii10BaseTFd:
+
+ Adapter->FullDuplexLink = TRUE;
+ break;
+
+ case MediumMii100BaseTxFd:
+ case MediumMii100BaseFxFd:
+
+ Adapter->FullDuplexLink = TRUE;
+
+ case MediumMii100BaseTx:
+ case MediumMii100BaseT4:
+ case MediumMii100BaseFx:
+
+ Adapter->LinkSpeed = ONE_HUNDRED_MBPS;
+ break;
+ }
+#if __DBG
+ DbgPrint("IndicateMediaStatus: %s%s MiiLink PASS\n",
+ MediumString[Adapter->MiiMediaType & MEDIA_MASK],
+ Adapter->FullDuplexLink ? " Full_Duplex" : "");
+#endif
+ break;
+ }
+
+ if (Adapter->FullDuplexLink) {
+ Adapter->TransmitDescriptorErrorMask &=
+ ~(DC21X4_TDES_NO_CARRIER | DC21X4_TDES_LOSS_OF_CARRIER);
+ }
+ else {
+ Adapter->TransmitDescriptorErrorMask =
+ Adapter->TransmitDefaultDescriptorErrorMask;
+ }
+
+ if (!Adapter->Initializing) {
+ NdisMIndicateStatus (
+ Adapter->MiniportAdapterHandle,
+ (Status == LinkFail ? NDIS_STATUS_MEDIA_DISCONNECT : NDIS_STATUS_MEDIA_CONNECT),
+ NULL,
+ 0
+ );
+ }
+
+ Adapter->PreviousLinkStatus = Status;
+
+ }
+
+}
+
+
diff --git a/private/ntos/ndis/dc21x4/mii.h b/private/ntos/ndis/dc21x4/mii.h
new file mode 100644
index 000000000..aae0f7b9f
--- /dev/null
+++ b/private/ntos/ndis/dc21x4/mii.h
@@ -0,0 +1,453 @@
+/*+
+ * file: mii.h
+ *
+ * Copyright (C) 1992-1995 by
+ * Digital Equipment Corporation, Maynard, Massachusetts.
+ * All rights reserved.
+ *
+ * This software is furnished under a license and may be used and copied
+ * only in accordance of the terms of such license and with the
+ * inclusion of the above copyright notice. This software or any other
+ * copies thereof may not be provided or otherwise made available to any
+ * other person. No title to and ownership of the software is hereby
+ * transferred.
+ *
+ * The information in this software is subject to change without notice
+ * and should not be construed as a commitment by digital equipment
+ * corporation.
+ *
+ * Digital assumes no responsibility for the use or reliability of its
+ * software on equipment which is not supplied by digital.
+ *
+ *
+ * Abstract: This file contains the definition of the MII protocol
+ * This file is part of the DEC's DC21X4 Ethernet Controller
+ * driver
+ *
+ * Author: Claudio Hazan
+ *
+ * Revision History:
+ *
+ * 20-Nov-95 ch Initial version
+ * 20-Dec-95 phk Modified
+ *
+-*/
+
+
+#define PHY_ADDR_ALIGN 23 // shift
+#define REG_ADDR_ALIGN 18 // shift
+
+#define MII_MDO_BIT_POSITION 17
+#define MII_MDI_BIT_POSITION 19
+#define MII_DELAY 1 // uS
+
+
+#define MII_WRITE ((ULONG) (0x00002000))
+#define MII_CLK ((ULONG) (0x00010000))
+#define MII_MDO_MASK ((ULONG) (0x00020000))
+#define MII_MDI_MASK ((ULONG) (0x00080000))
+
+#define PRE ((ULONG) (0xFFFFFFFF))
+#define MII_READ_FRAME ((ULONG) (0x60000000))
+#define MII_WRITE_FRAME ((ULONG) (0x50020000))
+
+#define TEST_PATTERN 0xAA5500FF
+
+#define CSR_READ 0x4000
+#define SEL_SROM 0x0800
+
+#define RESET_DELAY 10000
+
+// MII related bits in CSR9
+
+#define MII_READ ((ULONG) 0x00044000)
+#define MII_WRITE_TS ((ULONG) 0x00042000)
+#define MII_DATA_1 ((ULONG) 0x00020000) // MDO = 1
+#define MII_DATA_0 ((ULONG) 0x00000000) // MDO = 0
+
+#define MII_10BITS_TO_MDO_SHIFT 5 // number of left shifts needed to
+ // put MSB of MII_PhyAddr packed
+ // with MII_RegNumber in the MDO
+ // bit position at CSR9
+#define MII_16BITS_TO_MDO_SHIFT 2 // number of left shifts needed to
+ // put MSB of MII write data in
+ // the MDO bit position at CSR9
+
+#define MII_READ_DATA_MASK MII_MDI_MASK // MDI bit mask
+
+#define MAX_PHYADD 32
+
+//PHY Types
+
+#define PHY_NUMBER 0 // No Multiple PHYs support yet
+#define MAX_PHY_TABLE (PHY_NUMBER+1)
+#define MAX_GPR_SEQUENCE 5
+#define MAX_RESET_SEQUENCE 5
+
+#define NO_SELECTED_PHY 0x00FF
+
+
+#define MiiPhyCtrlReset ((USHORT) 0x8000)
+#define MiiPhyCtrlLoopBack ((USHORT) 0x4000)
+#define MiiPhyCtrlSpeed100 ((USHORT) 0x2000)
+#define MiiPhyCtrlEnableNway ((USHORT) 0x1000)
+#define MiiPhyCtrlPowerDown ((USHORT) 0x0800)
+#define MiiPhyCtrlIsolate ((USHORT) 0x0400)
+#define MiiPhyCtrlRestartNway ((USHORT) 0x0200)
+#define MiiPhyCtrlDuplexMode ((USHORT) 0x0100)
+#define MiiPhyCtrlCollisionTest ((USHORT) 0x0080)
+#define MiiPhyCtrlReservedBitsMask ((USHORT) 0x007F)
+#define MiiPhyCtrlForce10 ((USHORT) 0xCEFF)
+
+
+#define MiiPhy100BaseT4 ((USHORT) 0x8000)
+#define MiiPhy100BaseTxFD ((USHORT) 0x4000)
+#define MiiPhy100BaseTx ((USHORT) 0x2000)
+#define MiiPhy10BaseTFD ((USHORT) 0x1000)
+#define MiiPhy10BaseT ((USHORT) 0x0800)
+#define MiiPhyStatReservedBitsMask ((USHORT) 0x07C0)
+#define MiiPhyNwayComplete ((USHORT) 0x0020)
+#define MiiPhyRemoteFault ((USHORT) 0x0010)
+#define MiiPhyNwayCapable ((USHORT) 0x0008)
+#define MiiPhyLinkStatus ((USHORT) 0x0004)
+#define MiiPhyJabberDetect ((USHORT) 0x0002)
+#define MiiPhyExtendedCapabilities ((USHORT) 0x0001)
+
+#define MiiPhyMediaCapabilitiesMask (MiiPhy100BaseT4 | \
+ MiiPhy100BaseTxFD | \
+ MiiPhy100BaseTx | \
+ MiiPhy10BaseTFD | \
+ MiiPhy10BaseT)
+
+#define MiiPhyCapabilitiesMask (MiiPhyMediaCapabilitiesMask | \
+ MiiPhyNwayCapable)
+
+// Vendors' PHY IDs
+
+//National
+
+#define DP83840_0 ((ULONG) 0x20005C00)
+
+//Broadcom
+
+#define BCM5000_0 ((ULONG) 0x03E00000)
+#define MII_BROADCOM_EXTENDED_REG_ADDRESS 16
+
+#define BROADCOM_EXT_REG_FORCE_FAIL_EN_MASK 0x100
+#define BROADCOM_EXT_REG_SPEED_MASK 0x2
+
+//Generic
+
+#define GENERIC_PHY ((ULONG) 0xFFFFFFFF)
+
+// Useful masks
+
+#define VENDOR_ID_MASK ((ULONG) 0xFFFFFC00)
+#define VENDOR_ID_RIGHT_JUSTIFY 10
+
+#define VENDOR_MODEL_MASK ((USHORT) 0x03F0)
+#define VENDOR_MODEL_RIGHT_JUSTIFY 4
+
+#define VENDOR_Rev_MASK ((USHORT) 0x000F)
+
+#define MiiPhyNwayNextPageAble ((USHORT) 0x8000)
+#define MiiPhyNwayACK ((USHORT) 0x4000)
+#define MiiPhyNwayRemoteFault ((USHORT) 0x2000)
+#define MiiPhyNwayReservedBitsMask ((USHORT) 0x1C00)
+#define MiiPhyNway100BaseT4 ((USHORT) 0x0200)
+#define MiiPhyNway100BaseTxFD ((USHORT) 0x0100)
+#define MiiPhyNway100BaseTx ((USHORT) 0x0080)
+#define MiiPhyNway10BaseTFD ((USHORT) 0x0040)
+#define MiiPhyNway10BaseT ((USHORT) 0x0020)
+#define MiiPhyNwaySelectorMask ((USHORT) 0x001F)
+
+// MiiPhyNwayCapabilitiesMask - 0x03E0
+
+#define MiiPhyNwayCapabilitiesMask (MiiPhyNway100BaseT4 | \
+ MiiPhyNway100BaseTxFD | \
+ MiiPhyNway100BaseTx | \
+ MiiPhyNway10BaseTFD | \
+ MiiPhyNway10BaseT)
+
+#define NWAY_802_3_Selector 1
+
+#define MiiPhyNwayExpReservedBitsMask ((USHORT) 0xFFE0)
+#define MiiPhyNwayExpMultipleLinkFault ((USHORT) 0x0010)
+#define MiiPhyNwayExpLinkPartnerNextPageAble ((USHORT) 0x0008)
+#define MiiPhyNwayExpNextPageAble ((USHORT) 0x0004)
+#define MiiPhyNwayExpReceivedLinkCodePage ((USHORT) 0x0002)
+#define MiiPhyNwayExpLinkPartnerNwayAble ((USHORT) 0x0001)
+
+
+// MII PHY Register's
+
+#define PhyControlReg 0
+#define PhyStatusReg 1
+#define PhyId_1 2
+#define PhyId_2 3
+#define PhyNwayAdvertisement 4
+#define PhyNwayLinkPartnerAbility 5
+#define PhyNwayExpansion 6
+#define PhyNwayNextPageTransmit 7
+#define PhyReserved 8 // 8-15 are PHY's reserved
+#define PhyVendorSpecific 16 // 16-31 are Vendor's Specific
+#define NatPhyParRegister 25
+#define MAX_PHY_REGS 32
+
+#define DELAY(_time) NdisStallExecution(_time)
+
+//National Phy PAR Register
+#define PAR_SPEED_10 ((USHORT)0x0040)
+
+
+// MAC connection capabilities
+
+#define MAC_CONN_UNKNOWN ((USHORT) 0xFFFF)
+
+
+//PHY Type Values
+
+#define PHY_TYPE_UNKNOWN ((UCHAR) 0xFF) // Initializing, true state or type not known
+#define PHY_TYPE_SIA 0 // 10MB/s Manchester
+#define PHY_TYPE_MII 1 // MII PHY
+
+//PHY Operation Modes
+
+#define PHY_OM_UNKNOWN ((UCHAR) 0xFF)
+
+//PHY_OM_AUTOSENSE
+
+#define PHY_OM_NWAY MiiPhyNwayCapable
+#define PHY_NO_SPECIAL_OM 0
+
+//Media Attachment Interface Status
+
+#define MAI_UNKNOWN ((UCHAR) 0xFF)
+#define MAI_Absent 0
+#define MAI_Present 1
+#define MAI_PresentConnected 3
+
+// MAU list
+
+#define MAU_UNKNOWN 0
+#define MAU_10BaseT MiiPhy10BaseT
+#define MAU_10BaseTFD MiiPhy10BaseTFD
+//MAU_BNC
+//MAU_AUI
+#define MAU_100BaseT4 MiiPhy100BaseT4
+#define MAU_100BaseTX MiiPhy100BaseTx
+#define MAU_100BaseFX MiiPhy100BaseTx
+#define MAU_100BaseTXFD MiiPhy100BaseTxFD
+#define MAU_100BaseFXFD MiiPhy100BaseTxFD
+//MAU_10BaseFX
+
+#define NWAY_10BaseT MiiPhyNway10BaseT
+#define NWAY_100BaseT4 MiiPhyNway100BaseT4
+#define NWAY_100BaseTX MiiPhyNway100BaseTx
+#define NWAY_10BaseTFD MiiPhyNway10BaseTFD
+#define NWAY_100BaseTXFD MiiPhyNway100BaseTxFD
+
+// define Media status
+
+#define MEDIA_STATE_UNKNOWN 0x00FF
+#define MEDIA_STATE_UNDEFINED 0x00FE
+#define MEDIA_READ_REGISTER_FAILED 0x00FD
+#define MEDIA_LINK_FAIL 0x0000
+#define MEDIA_LINK_PASS 0x0001
+#define MEDIA_LINK_PASS_WITH_PF 0x0002
+
+#define MEDIA_STATUS_MASK 0x00FF
+
+// define NWAY Availability & status
+
+#define NWAY_UNKNOWN 0xFF00 //PHY is still initializing
+#define NWAY_NOT_SUPPORTED 0x0000 //No NWAY in this Phy
+#define NWAY_SUPPORTED 0x0100 //NWAY supported
+#define NWAY_DISABLED 0x0200 //NWAY present but disabled
+#define NWAY_CONFIGURING 0x0300 //NWAY still configuring
+#define NWAY_COMPLETE 0x0400 //NWAY negotiation is done
+
+#define NWAY_STATUS_MASK 0xFF00
+
+typedef enum _MII_STATUS {
+ MiiGenAdminReset,
+ MiiGenAdminOperational,
+ MiiGenAdminStandBy,
+ MiiGenAdminPowerDown,
+ MiiGenAdminForce10,
+ MiiGenAdminForce10Fd,
+ MiiGenAdminRelease10
+} MII_STATUS, *PMII_STATUS;
+
+typedef USHORT CAPABILITY, *PCAPABILITY;
+
+typedef struct _PHY_EXT_ROUTINES_ENTRIES {
+
+ BOOLEAN (*PhyInit)(PDC21X4_ADAPTER,PMII_PHY_INFO);
+ void (*PhyGetCapabilities)(PMII_PHY_INFO,PCAPABILITY);
+ BOOLEAN (*PhySetConnectionType)(PDC21X4_ADAPTER,PMII_PHY_INFO,USHORT,USHORT);
+ BOOLEAN (*PhyGetConnectionType)(PDC21X4_ADAPTER,PMII_PHY_INFO,PUSHORT);
+ BOOLEAN (*PhyGetConnectionStatus)(PDC21X4_ADAPTER,PMII_PHY_INFO,PUSHORT);
+ void (*PhyAdminStatus)(PDC21X4_ADAPTER,PMII_PHY_INFO,PMII_STATUS);
+ void (*PhyAdminControl)(PDC21X4_ADAPTER,PMII_PHY_INFO,PMII_STATUS);
+
+}PHY_EXT_ROUTINES_ENTRIES;
+
+typedef struct _PHY_INT_ROUTINES_ENTRIES {
+
+ BOOLEAN (*PhyReadRegister)(PDC21X4_ADAPTER,PMII_PHY_INFO,USHORT,PUSHORT);
+ BOOLEAN (*PhyWriteRegister)(PDC21X4_ADAPTER,PMII_PHY_INFO,USHORT,PUSHORT);
+ void (*PhyNwayGetLocalAbility)(PDC21X4_ADAPTER,PMII_PHY_INFO,PCAPABILITY);
+ void (*PhyNwaySetLocalAbility)(PDC21X4_ADAPTER,PMII_PHY_INFO,USHORT);
+ void (*PhyNwayGetPartnerAbility)(PDC21X4_ADAPTER,PMII_PHY_INFO,PCAPABILITY);
+
+}PHY_INT_ROUTINES_ENTRIES;
+
+
+typedef struct _MII_PHY_INFO {
+
+ BOOLEAN StructValid;
+ USHORT PhyAddress;
+ ULONG PhyId;
+ USHORT PhyCapabilities;
+ USHORT PhyMediaAdvertisement;
+ USHORT PhyRegs[MAX_PHY_REGS];
+ USHORT PreviousControl;
+ PHY_EXT_ROUTINES_ENTRIES PhyExtRoutines;
+ PHY_INT_ROUTINES_ENTRIES PhyIntRoutines;
+
+} MII_PHY_INFO, *PMII_PHY_INFO;
+
+
+typedef struct _MII_GEN_INFO {
+
+ USHORT NumOfPhys;
+ USHORT PhysCapabilities;
+ USHORT SelectedPhy; // 0 means that all phys are isolated
+ PMII_PHY_INFO Phys[MAX_PHY_TABLE];
+
+} MII_GEN_INFO, *PMII_GEN_INFO;
+
+
+//Data Structure holding PHY's registers mask
+
+static const USHORT PhyRegsReservedBitsMasks[] = {
+
+ MiiPhyCtrlReservedBitsMask, // Control reg reserved bits mask
+ MiiPhyStatReservedBitsMask, // Status reg reserved bits PhyID reserved bits mask
+ 0, // PhyID reserved bits mask
+ 0, // PhyID reserved bits mask
+ MiiPhyNwayReservedBitsMask, // Nway Local ability reserved bits mask
+ MiiPhyNwayReservedBitsMask, // Nway Partner ability reserved bits mask
+ MiiPhyNwayExpReservedBitsMask, // Nway Expansion
+ 0,0,0,0,0,0,0,0,0,0,0,0,0, // Other regs
+ 0,0,0,0,0,0,0,0,0,0,0,0 // Other regs
+ };
+
+static const UINT AdminControlConversionTable[] = {
+ MiiPhyCtrlReset, // Reset
+ 0x0, // Operational
+ MiiPhyCtrlIsolate, // StandBy / Isolate
+ MiiPhyCtrlPowerDown, // Powerdown
+ 0x0, // Force10
+ MiiPhyCtrlDuplexMode, // Force10Fd
+ 0x0 // Release10
+ };
+
+
+static const USHORT MediaBitTable[] = {
+ 0x0000, // TP
+ 0x0000, // BNC
+ 0x0000, // AUI
+ 0x0000, // 100BaseTx/SymScr
+ 0x0000, // TP-FD
+ 0x0000, // 100BaseTx-FD/SymScr-FD
+ 0x0000, // 100BaseT4
+ 0x0000, // 100BaseFx
+ 0x0000, // 100BaseFx-FD
+ 0x0800, // MediaMiiTP
+ 0x1000, // MediaMiiTpFD
+ 0x0000, // MediaMiiBNC
+ 0x0000, // MediaMiiAUI
+ 0x2000, // MediaMii100BaseTX
+ 0x4000, // MediaMii100BaseTxFD
+ 0x8000, // MediaMii100BaseT4
+ 0x0000, // MediaMii100BaseFX
+ 0x0000 // MediaMii100BaseFxFD
+};
+
+static const USHORT ConvertMediaTypeToMiiType[] = {
+ 0x0009, // TP -> MII TP
+ 0x000B, // BNC -> MII BNC
+ 0x000C, // AUI -> MII AUI
+ 0x000D, // 100BaseTx -> MII 100BaseTx
+ 0x020A, // TP-FD -> MII TP-FD
+ 0x020E, // 100BaseTx-FD -> MII 100BaseTxFD
+ 0x000F, // 100BaseT4 -> MII 100BaseT4
+ 0x0010, // 100BaseFx -> MII 100BaseFx
+ 0x0211 // 100BaseFx-FD -> MII 100BaseFxFD
+};
+
+static const USHORT MediaToCommandConversionTable[] = {
+ 0x0000, // TP
+ 0x0000, // BNC
+ 0x0000, // AUI
+ 0x2000, // 100BaseTx/SymScr
+ 0x0100, // TP-FD
+ 0x2100, // 100BaseTx-FD/SymScr-FD
+ 0x2000, // 100BaseT4
+ 0x2000, // 100BaseFx
+ 0x2100, // 100BaseFx-FD
+ 0x0000, // MediaMiiTP
+ 0x0100, // MediaMiiTpFD
+ 0x0000, // MediaMiiBNC
+ 0x0000, // MediaMiiAUI
+ 0x2000, // MediaMii100BaseTX
+ 0x2100, // MediaMii100BaseTxFD
+ 0x2000, // MediaMii100BaseT4
+ 0x2000, // MediaMii100BaseFX
+ 0x2100 // MediaMii100BaseFxFD
+};
+
+static const USHORT MediaToNwayConversionTable[] = {
+ 0x0020, // TP
+ 0x0000, // BNC
+ 0x0000, // AUI
+ 0x0080, // 100BaseTx/SymScr
+ 0x0040, // TP-FD
+ 0x0100, // 100BaseTx-FD/SymScr-FD
+ 0x0200, // 100BaseT4
+ 0x0080, // 100BaseFx
+ 0x0100, // 100BaseFx-FD
+ 0x0020, // MediaMiiTP
+ 0x0040, // MediaMiiTpFD
+ 0x0000, // MediaMiiBNC
+ 0x0000, // MediaMiiAUI
+ 0x0080, // MediaMii100BaseTX
+ 0x0100, // MediaMii100BaseTxFD
+ 0x0200, // MediaMii100BaseT4
+ 0x0080, // MediaMii100BaseFX
+ 0x0100 // MediaMii100BaseFxFD
+};
+
+static const USHORT MediaToStatusConversionTable[] = {
+ 0x0800, // TP
+ 0x0000, // BNC
+ 0x0000, // AUI
+ 0x2000, // 100BaseTx/SymScr
+ 0x1000, // TP-FD
+ 0x4000, // 100BaseTx-FD/SymScr-FD
+ 0x8000, // 100BaseT4
+ 0x2000, // 100BaseFx
+ 0x4000, // 100BaseFx-FD
+ 0x0800, // MediaMiiTP
+ 0x1000, // MediaMiiTpFD
+ 0x0000, // MediaMiiBNC
+ 0x0000, // MediaMiiAUI
+ 0x2000, // MediaMii100BaseTX
+ 0x4000, // MediaMii100BaseTxFD
+ 0x8000, // MediaMii100BaseT4
+ 0x2000, // MediaMii100BaseFX
+ 0x4000 // MediaMii100BaseFxFD
+ };
+
diff --git a/private/ntos/ndis/dc21x4/miigen.c b/private/ntos/ndis/dc21x4/miigen.c
new file mode 100644
index 000000000..d1d7d4333
--- /dev/null
+++ b/private/ntos/ndis/dc21x4/miigen.c
@@ -0,0 +1,524 @@
+/*+
+ * file: miigen.c
+ *
+ * Copyright (C) 1992-1995 by
+ * Digital Equipment Corporation, Maynard, Massachusetts.
+ * All rights reserved.
+ *
+ * This software is furnished under a license and may be used and copied
+ * only in accordance of the terms of such license and with the
+ * inclusion of the above copyright notice. This software or any other
+ * copies thereof may not be provided or otherwise made available to any
+ * other person. No title to and ownership of the software is hereby
+ * transferred.
+ *
+ * The information in this software is subject to change without notice
+ * and should not be construed as a commitment by digital equipment
+ * corporation.
+ *
+ * Digital assumes no responsibility for the use or reliability of its
+ * software on equipment which is not supplied by digital.
+ *
+ *
+ * Abstract: This file contains the code needed to support the
+ * generic PHY chip through MII connection
+ *
+ * Author: Claudio Hazan
+ *
+ * Revision History:
+ *
+ * 20-Nov-95 as Initial version
+ * 20-Dec-95 phk Cleanup
+ *
+-*/
+
+
+#include <precomp.h>
+
+
+
+/*+
+ *
+ *MiiGenInit(Adapter)
+ *
+ *Description:
+ * This Routine is called to initialize the module:
+ * - Initializes its internal structures.
+ * - Calls FindMiiPhysProc to find the first PHY on the adapter card
+ * - If a PHY is found then
+ * - Calls the PHY's init routine.
+ * - Gets the PHY's capabilities and saves them
+ * as the generic PHY capabilities.
+ *
+ *On Entry:
+ *
+ *Returns: FALSE - no PHY was found.
+ * TRUE - a PHY was found.
+ *
+-*/
+extern
+BOOLEAN
+MiiGenInit(
+ PDC21X4_ADAPTER Adapter
+ )
+{
+
+ CAPABILITY Cap;
+ UINT Loop;
+ UINT Retry=2;
+ UINT Count;
+ ULONG Status;
+
+#if MII_DBG
+ DbgPrint("MiiGenInit\n");
+#endif
+
+ //Find the first PHY connected
+
+ if (!FindAndInitMiiPhys(Adapter)) {
+#if MII_DBG
+ DbgPrint("***MiiGenInit: No PHY was found\n");
+#endif
+ return FALSE;
+ }
+
+ // Set Generic PHY capabilities
+
+ (Adapter->MiiGen.Phys[Adapter->PhyNumber])->PhyExtRoutines.PhyGetCapabilities(
+ Adapter->MiiGen.Phys[Adapter->PhyNumber],
+ &Cap
+ );
+ // Update General Phys' capabilities
+
+ Adapter->MiiGen.PhysCapabilities |= Cap;
+#if MII_DBG
+ DbgPrint("MiiGenInit: PHY Capabilities= %04x\n", Cap);
+#endif
+
+ // Selected PHY number
+ Adapter->MiiGen.SelectedPhy = Adapter->PhyNumber;
+
+ return TRUE;
+}
+
+
+
+
+/*+
+ *
+ * MiiGenGetCapabilities (Adapter)
+ *
+ *
+ * Description:
+ *
+ * Returns the Generic Phy capabilities
+ *
+ * Returns:
+ *
+ * Phys capabilities
+ *
+-*/
+extern
+USHORT
+MiiGenGetCapabilities(
+ PDC21X4_ADAPTER Adapter
+ )
+{
+#if __DBG
+ DbgPrint("MiiGenGetCapabilities\n");
+#endif
+ return(Adapter->MiiGen.PhysCapabilities);
+}
+
+
+/*+
+ *
+ *MiiGenCheckConnection
+ *
+ *Description:
+ * Checks if the desired connection is supported by the PHY.
+ *
+ *On Entry:
+ * Connection - the desired connection.
+ *
+ *Returns
+ * FALSE - upon failing to support connection.
+ * TRUE - on success.
+ *
+-*/
+
+extern
+BOOLEAN
+MiiGenCheckConnection(
+ PDC21X4_ADAPTER Adapter,
+ USHORT Connection
+ )
+{
+ // Check PHY's connection
+#if MII_DBG
+ DbgPrint("MiiGenCheckConnection\n");
+#endif
+
+ return CheckConnectionSupport(
+ Adapter->MiiGen.Phys[Adapter->PhyNumber],
+ Connection
+ );
+}
+
+
+/*+
+ *
+ *MiiGenSetConnection
+ *
+ *Description:
+ * Sets PHY's connection to the desired connection and advertised
+ *
+ * (PHY will remain Isolated and selecting one of them will
+ * be done via the Admin control procedure).
+ *
+ *On Entry:
+ * Connection - the desired connection.
+ * NWAYAdvertisement (if =0 -> use PHY's defaults)
+ *
+ *Returns
+ * FALES - upon failing to set connection.
+ * TRUE - on success.
+ *
+-*/
+
+extern
+BOOLEAN
+MiiGenSetConnection(
+ PDC21X4_ADAPTER Adapter,
+ UINT Connection,
+ USHORT NwayAdvertisement
+ )
+{
+ // Set PHY's connection
+#if MII_DBG
+ DbgPrint("MiiGenSetConnection\n");
+#endif
+
+ return (Adapter->MiiGen.Phys[Adapter->PhyNumber])->PhyExtRoutines.PhySetConnectionType(
+ Adapter,
+ Adapter->MiiGen.Phys[Adapter->PhyNumber],
+ Connection,
+ NwayAdvertisement
+ );
+}
+
+/*+
+ *
+ *MiiGenGetConnectionStatus
+ *
+ *Description:
+ * Returns the connection status of the Phy
+ *
+ *On Entry:
+ *
+ *On Return:
+ * ConnectionStatus - hold connection status
+ *
+ *Return: FALSE: Upon Status "error" (Nway configuring or Link-Fail)
+ * TRUE: No error
+ *
+-*/
+extern
+BOOLEAN
+MiiGenGetConnectionStatus (
+ PDC21X4_ADAPTER Adapter,
+ PUSHORT ConnectionStatus
+ )
+{
+#if MII_DBG
+ DbgPrint("MiiGenGetConnectionStatus\n");
+#endif
+ return Adapter->MiiGen.Phys[Adapter->PhyNumber]->PhyExtRoutines.PhyGetConnectionStatus(
+ Adapter,
+ Adapter->MiiGen.Phys[Adapter->PhyNumber],
+ ConnectionStatus
+ );
+}
+
+
+
+/*+
+ *
+ *MiiGenGetConnection
+ *
+ *Description:
+ * Returns the connection type of the PHY if possible (PHY Nway
+ * is either disabled or completed).
+ *
+ *
+ *On Return:
+ * Connection - Phys connection.
+ *
+ *Returns; FALSE - set Upon error (Connection = MAC_CONN_UNKNOWN)
+ * TRUE - valid connection type.
+ *
+-*/
+extern
+BOOLEAN
+MiiGenGetConnection(
+ PDC21X4_ADAPTER Adapter,
+ PUSHORT Connection
+ )
+{
+
+ // Is the PHY in a "stable" state ?
+
+#if MII_DBG
+ DbgPrint("MiiGenGetConnection\n");
+#endif
+ if (Adapter->MiiGen.Phys[Adapter->PhyNumber]->PhyExtRoutines.PhyGetConnectionStatus(
+ Adapter,
+ Adapter->MiiGen.Phys[Adapter->PhyNumber],
+ Connection
+ )
+ ) {
+
+ // PHY is in a stable state - get Connection
+
+ return Adapter->MiiGen.Phys[Adapter->PhyNumber]->PhyExtRoutines.PhyGetConnectionType(
+ Adapter,
+ Adapter->MiiGen.Phys[Adapter->PhyNumber],
+ Connection
+ );
+ }
+ else {
+
+ // NWAY Not in stable state or Link_Fail.
+ *Connection = MAC_CONN_UNKNOWN;
+#if MII_DBG
+ DbgPrint("***MiiGenGetConnection: Connection= %04x Unknown by the PHY or status not stable\n", *Connection);
+#endif
+ return FALSE;
+ }
+
+}
+
+
+
+
+
+
+/*+
+ *
+ *MiiGenAdminStatus
+ *
+ *Description:
+ * Returnes the Admin status of the PHY.
+ *
+ *On Return:
+ * AdminStatus
+ *
+ *Returns:
+ * None
+ *
+-*/
+extern
+void
+MiiGenAdminStatus(
+ PDC21X4_ADAPTER Adapter,
+ PUSHORT AdminStatus
+ )
+{
+
+ // Get PHY Status
+#if MII_DBG
+ DbgPrint("MiiGenAdminStatus\n");
+#endif
+
+ Adapter->MiiGen.Phys[Adapter->PhyNumber]->PhyExtRoutines.PhyAdminStatus(
+ Adapter,
+ Adapter->MiiGen.Phys[Adapter->PhyNumber],
+ AdminStatus
+ );
+
+}
+
+
+
+
+
+
+
+/*+
+ *
+ *MiiGenAdminControl
+ *
+ *Description:
+ * Performs the requested Admin control on the Phy.
+ *
+ *On Entry:
+ * AdminControl
+ *
+ *Returns:
+ * FALSE - upon Failure.
+ * TRUE - Perform Admin control OK.
+ *
+-*/
+extern
+BOOLEAN
+MiiGenAdminControl(
+ PDC21X4_ADAPTER Adapter,
+ USHORT AdminControl
+ )
+{
+ // Perform the operation on the Phy
+#if MII_DBG
+ DbgPrint("MiiGenAdminControl: %s\n",
+ AdminControl == MiiGenAdminReset? "Reset" :
+ AdminControl == MiiGenAdminOperational? "Operational" :
+ AdminControl == MiiGenAdminForce10? "Force10" :
+ AdminControl == MiiGenAdminForce10Fd? "Force10Fd" :
+ AdminControl == MiiGenAdminRelease10? "Release10" :
+ AdminControl == MiiGenAdminStandBy? "StandBy" :
+ AdminControl == MiiGenAdminPowerDown? "PowerDown" :
+ "Unknown Command!!!!"
+ );
+#endif
+
+ Adapter->MiiGen.Phys[Adapter->PhyNumber]->PhyExtRoutines.PhyAdminControl(
+ Adapter,
+ Adapter->MiiGen.Phys[Adapter->PhyNumber],
+ AdminControl
+ );
+
+ // Perform Generic PHY operations related to the specified command
+
+ switch (AdminControl) {
+
+ case MiiGenAdminReset:
+ case MiiGenAdminOperational:
+ case MiiGenAdminForce10:
+ case MiiGenAdminForce10Fd:
+ case MiiGenAdminRelease10:
+
+ Adapter->MiiGen.SelectedPhy = Adapter->PhyNumber;
+ break;
+
+ case MiiGenAdminStandBy:
+ case MiiGenAdminPowerDown:
+
+ Adapter->MiiGen.SelectedPhy = NO_SELECTED_PHY;
+ break;
+
+
+ default:
+ // If reached this point Unknown command
+ return FALSE;
+ }
+ return TRUE;
+}
+
+
+
+
+
+
+
+/*+
+ *
+ *FindAndInitMiiPhysProc
+ *
+ *Description:
+ * This Routine Scans the entire Nic's Phys address space and
+ * for a PHY and Initializes each PHY found .
+ *
+ *On Return:
+ *
+ * Note: The driver currently supports only 1 single PHY per
+ * adapter
+ *
+ *Returns:
+ *
+ * TRUE if a PHY was found and initialized successfully
+-*/
+BOOLEAN
+FindAndInitMiiPhys(
+ PDC21X4_ADAPTER Adapter
+ )
+{
+ INT PhysCount = 0; // Start from address 0
+ NDIS_STATUS NdisStatus;
+
+#if MII_DBG
+ DbgPrint("FindAndInitMiiPhys\n");
+#endif
+
+ if (!Adapter->MiiGen.Phys[Adapter->PhyNumber]) {
+
+ ALLOC_MEMORY(
+ &NdisStatus,
+ &(Adapter->MiiGen.Phys[Adapter->PhyNumber]),
+ sizeof(MII_PHY_INFO)
+ );
+
+ if (NdisStatus != NDIS_STATUS_SUCCESS) {
+ return FALSE;
+ }
+
+ }
+
+ // Init the routine's structure.
+ InitPhyInfoEntries(
+ Adapter->MiiGen.Phys[Adapter->PhyNumber]
+ );
+
+ while (PhysCount < MAX_PHYADD) {
+
+ // did we pass the legal address range ?
+ // Is there a PHY in this address?
+
+ Adapter->MiiGen.Phys[Adapter->PhyNumber]->PhyAddress = PhysCount;
+#if MII_DBG
+ DbgPrint("Adapter->MiiGen.Phys[Adapter->PhyNumber]->PhyAddress=%02x\n",Adapter->MiiGen.Phys[Adapter->PhyNumber]->PhyAddress);
+#endif
+ if (MiiPhyInit(
+ Adapter,
+ Adapter->MiiGen.Phys[Adapter->PhyNumber]
+ ) ) {
+ // Found a PHY - Handle it
+#if MII_DBG
+ DbgPrint("FindAndInitMiiPhys: A PHY was found at address= %d\n", PhysCount);
+#endif
+ Adapter->MiiGen.NumOfPhys++; // inc # of phys found
+ return TRUE;
+ }
+ PhysCount++; // Look at next PHY address.
+ }
+
+ FREE_MEMORY(
+ Adapter->MiiGen.Phys[Adapter->PhyNumber],
+ sizeof(MII_PHY_INFO)
+ );
+ Adapter->MiiGen.Phys[Adapter->PhyNumber] = (PMII_PHY_INFO)NULL;
+
+ return FALSE;
+}
+
+
+/*+
+ *
+ * MiiFreeResources
+ *
+ *Description:
+ * Free the resources allocated to Mii
+ *
+-*/
+void
+MiiFreeResources(
+ PDC21X4_ADAPTER Adapter
+ )
+
+{
+ if (Adapter->MiiGen.Phys[Adapter->PhyNumber]) {
+ FREE_MEMORY(
+ Adapter->MiiGen.Phys[Adapter->PhyNumber],
+ sizeof(MII_PHY_INFO)
+ );
+ Adapter->MiiGen.Phys[Adapter->PhyNumber] = (PMII_PHY_INFO)NULL;
+ }
+}
diff --git a/private/ntos/ndis/dc21x4/miiphy.c b/private/ntos/ndis/dc21x4/miiphy.c
new file mode 100644
index 000000000..e06d02195
--- /dev/null
+++ b/private/ntos/ndis/dc21x4/miiphy.c
@@ -0,0 +1,1913 @@
+/*+
+ * file: miiphy.c
+ *
+ * Copyright (C) 1992-1995 by
+ * Digital Equipment Corporation, Maynard, Massachusetts.
+ * All rights reserved.
+ *
+ * This software is furnished under a license and may be used and copied
+ * only in accordance of the terms of such license and with the
+ * inclusion of the above copyright notice. This software or any other
+ * copies thereof may not be provided or otherwise made available to any
+ * other person. No title to and ownership of the software is hereby
+ * transferred.
+ *
+ * The information in this software is subject to change without notice
+ * and should not be construed as a commitment by digital equipment
+ * corporation.
+ *
+ * Digital assumes no responsibility for the use or reliability of its
+ * software on equipment which is not supplied by digital.
+ *
+ *
+ * Abstract: This file contains the code to support the MII protocol
+ * to access the PHY chip.
+ * This file is part of the DEC's DC21X4 Ethernet Controller
+ * driver
+ *
+ * Author: Claudio Hazan
+ *
+ * Revision History:
+ *
+ * 20-Nov-95 ch Initial version
+ * 20-Dec-95 phk Cleanup
+ *
+-*/
+
+#include <precomp.h>
+
+
+/*+
+ *
+ * MiiPhyInit
+ *
+ * Description : Initializes Mii PHY entry variables.
+ * Searches for PHY in given address, initializes it if found.
+ *
+ * Input parameters:
+ *
+ * PDC21X4_ADAPTER - Adapter The Adapter's DS
+ * PhyInfoPtr - PMII_PHY_INFO pointer to struct with PHY info
+ *
+ * Output parameters:
+ *
+ * None.
+-*/
+extern
+BOOLEAN
+MiiPhyInit(
+ PDC21X4_ADAPTER Adapter,
+ PMII_PHY_INFO PhyInfoPtr
+ )
+{
+
+ USHORT i;
+
+#if MII_DBG
+ DbgPrint("MiiPhyInit\n");
+#endif
+
+ if ( !(FindMiiPhyDevice(Adapter, PhyInfoPtr)) ) {
+ return FALSE;
+ }
+
+#if MII_DBG
+ DbgPrint("MiiPhyDevice FOUND!\n");
+#endif
+
+ // Reset the PHY to return it to his default values
+ PhyInfoPtr->PhyExtRoutines.PhyAdminControl(
+ Adapter,
+ PhyInfoPtr,
+ MiiGenAdminReset
+ );
+
+ // Once the PHY is reset, read the values of its
+ // whole registers
+
+ if ( !(FindMiiPhyDevice(Adapter, PhyInfoPtr)) ) {
+ return FALSE;
+ }
+
+ // get and save PHY capabilities
+ PhyInfoPtr->PhyCapabilities =
+ PhyInfoPtr->PhyRegs[PhyStatusReg] & MiiPhyCapabilitiesMask;
+
+ switch (PhyInfoPtr->PhyId) {
+
+ case BCM5000_0:
+
+#if MII_DBG
+ DbgPrint("Broadcom PHY...\n");
+#endif
+ // allow Autosense
+ PhyInfoPtr->PhyCapabilities |= MiiPhyNwayCapable;
+ break;
+ }
+#if MII_DBG
+ DbgPrint("PhyCapabilities = %04x\n", PhyInfoPtr->PhyCapabilities);
+#endif
+
+ // get and save PHY's NWAY Advertisement
+ PhyInfoPtr->PhyIntRoutines.PhyNwayGetLocalAbility(
+ Adapter,
+ PhyInfoPtr,
+ &(PhyInfoPtr->PhyMediaAdvertisement)
+ );
+#if MII_DBG
+ DbgPrint("PhyMediaAdvertisement = %04x\n", PhyInfoPtr->PhyMediaAdvertisement);
+#endif
+
+ // put the PHY in operational mode
+ PhyInfoPtr->PhyExtRoutines.PhyAdminControl(
+ Adapter,
+ PhyInfoPtr,
+ MiiGenAdminOperational
+ );
+
+ /* mark that PHY entry is valid */
+ PhyInfoPtr->StructValid = TRUE;
+
+#if MII_DBG
+ DbgPrint("MiiPhyInit Done\n");
+#endif
+ return TRUE;
+
+}
+
+
+/*+
+ *
+ * MiiPhyGetCapabilities
+ *
+ * Description : Returns the PHY capabilities.
+
+ * Input parameters:
+ *
+ * PhyInfoPtr - PMII_PHY_INFO pointer to struct with PHY info
+ *
+ * Output parameters:
+ *
+ * Capabilities - CAPABILITY
+ *
+ *
+-*/
+extern
+void
+MiiPhyGetCapabilities(
+ PMII_PHY_INFO PhyInfoPtr,
+ CAPABILITY *Capabilities
+ )
+{
+#if MII_DBG
+ DbgPrint("MiiPhyGetCapabilities\n");
+#endif
+ *Capabilities = PhyInfoPtr->PhyCapabilities;
+ return;
+}
+
+
+
+
+/*+
+ *
+ * MiiPhySetConnectionType
+ *
+ * Description:
+ *
+ * if (Connection == NWAY) then
+ * if (Advertisement != 0 )
+ * Change LocalAdvertisement
+ * and Set RestartNway bit
+ * set NWAy bit On in CTRL register
+ * else
+ * Translate Media to appropriate control bits
+ * write CTRL reg
+ * and return success
+ *
+ * Input parameters:
+ *
+ * PhyInfoPtr - PMII_PHY_INFO pointer to struct with PHY info
+ * Connection - USHORT
+ * Advertisement - USHORT
+ *
+ * Output parameters:
+ *
+ * None.
+ *
+ * On return - FALSE if PHY does not support Connection, TRUE otherwise.
+ *
+-*/
+extern
+BOOLEAN
+MiiPhySetConnectionType(
+ PDC21X4_ADAPTER Adapter,
+ PMII_PHY_INFO PhyInfoPtr,
+ USHORT Connection,
+ USHORT Advertisement
+ )
+{
+#if MII_DBG
+ DbgPrint("MiiPhySetConnectionType\n");
+#endif
+ // Check if the PHY supports this connection ?
+ if(!CheckConnectionSupport(
+ PhyInfoPtr,
+ Connection
+ )){
+#if MII_DBG
+ DbgPrint("***The Connection %04x is not supported by the Phy\n", Connection);
+#endif
+ return FALSE;
+ }
+
+ // Convert Connection type to Control_word
+ ConvertConnectionToControl(
+ PhyInfoPtr,
+ &Connection
+ );
+
+ // Clear Previous Connection bits from Control_word
+ // (Leave only Isolate and Power-down bits)
+ PhyInfoPtr->PhyRegs[PhyControlReg] &=
+ (MiiPhyCtrlIsolate | MiiPhyCtrlPowerDown);
+
+ // Create the new Control_word
+ PhyInfoPtr->PhyRegs[PhyControlReg] |= Connection;
+
+ // If operation mode is NWAY - set its parameters
+ if (Connection & MiiPhyCtrlEnableNway) {
+ PhyInfoPtr->PhyIntRoutines.PhyNwaySetLocalAbility(
+ Adapter,
+ PhyInfoPtr,
+ Advertisement
+ );
+ }
+
+ // write the new control word
+#if MII_DBG
+ DbgPrint("New Control_word= %04x\n", PhyInfoPtr->PhyRegs[PhyControlReg]);
+#endif
+ PhyInfoPtr ->PhyIntRoutines.PhyWriteRegister(
+ Adapter,
+ PhyInfoPtr ,
+ PhyControlReg,
+ PhyInfoPtr->PhyRegs[PhyControlReg]
+ );
+
+ // Don't save RestartNway bit !
+ PhyInfoPtr ->PhyRegs[PhyControlReg] &= ~MiiPhyCtrlRestartNway;
+
+ switch (PhyInfoPtr ->PhyId) {
+
+ case BCM5000_0:
+
+ // Need to be reset between 10Base to 100Base transitions
+#if MII_DBG
+ DbgPrint("Broadcom - 10B to 100B transition\n");
+#endif
+ HandleBroadcomMediaChangeFrom10To100(
+ Adapter,
+ PhyInfoPtr
+ );
+ break;
+ }
+
+ return TRUE;
+}
+
+/*+
+ *
+ * MiiPhyGetConnectionType
+ *
+ * Description:
+ *
+ * Returns selected connection of the PHY.
+ * If PHY connection is not yet resolved and wait is required,
+ * waits for connection resolution and returns it.
+ * If not - returns error status.
+ *
+ * Input parameters:
+ *
+ * PhyInfoPtr - PMII_PHY_INFO pointer to struct with PHY info
+ *
+ * Output parameters:
+ *
+ * ConnectionStatus - Status
+ *
+ * On Return
+ * Upon error - FALSE
+ * ConnectionStatus - error status
+ *
+ * Upon success - TRUE
+ * ConnectionStatus - selected connection.
+ *
+ *Remarks:
+ *
+ * We use the NWAY capable bit in the PHY capabilities field to
+ * overcome Broadcom's AutoSense issue.
+ *
+-*/
+extern
+BOOLEAN
+MiiPhyGetConnectionType(
+ PDC21X4_ADAPTER Adapter,
+ PMII_PHY_INFO PhyInfoPtr,
+ PUSHORT ConnectionStatus
+ )
+{
+
+ CAPABILITY LocalAbility;
+ CAPABILITY PartnerAbility;
+ CAPABILITY Ability;
+ USHORT Register;
+
+#if MII_DBG
+ DbgPrint("MiiPhyGetConnectionType\n");
+#endif
+ switch (PhyInfoPtr->PhyId) {
+
+ case BCM5000_0:
+
+ if (!GetBroadcomPhyConnectionType(
+ Adapter,
+ PhyInfoPtr,
+ ConnectionStatus
+ )
+ ) {
+
+#if MII_DBG
+ DbgPrint("***Connection not supported by Broadcom's Phy\n");
+#endif
+ *ConnectionStatus = MAC_CONN_UNKNOWN;
+ return FALSE;
+ }
+ else {
+ HandleBroadcomMediaChangeFrom10To100(
+ Adapter,
+ PhyInfoPtr
+ );
+ return TRUE;
+ }
+ break;
+
+ default:
+
+ if (PhyInfoPtr->PhyRegs[PhyControlReg] & MiiPhyCtrlEnableNway) {
+
+ // NWAY selected:
+ // get partner and local abilities,
+ // use them to retrieve the selected connection type
+#if MII_DBG
+ DbgPrint("Not Broadcom PHY: enable NWAY\n");
+#endif
+ PhyInfoPtr->PhyIntRoutines.PhyNwayGetLocalAbility(
+ Adapter,
+ PhyInfoPtr,
+ &LocalAbility
+ );
+
+ PhyInfoPtr->PhyIntRoutines.PhyNwayGetPartnerAbility(
+ Adapter,
+ PhyInfoPtr,
+ &PartnerAbility
+ );
+
+ Ability = LocalAbility & PartnerAbility;
+#if MII_DBG
+ DbgPrint("LocalAbility : %04x\n",LocalAbility);
+ DbgPrint("PartnerAbility : %04x\n",PartnerAbility);
+#endif
+
+ if (!Ability){
+ // No common mode:
+#if MII_DBG
+ DbgPrint("No Common Mode...\n");
+#endif
+
+ if (PhyInfoPtr->PhyId == DP83840_0) {
+
+ //National's Phy Speed Sensing workaround:
+ //read the Speed_bit in the PAR register to sense
+ //the connection speed
+
+ if (PhyInfoPtr->PhyIntRoutines.PhyReadRegister(
+ Adapter,
+ PhyInfoPtr ,
+ NatPhyParRegister,
+ &Register
+ )) {
+
+ Ability = (LocalAbility &
+ ((Register & PAR_SPEED_10) ? MiiPhy10BaseT : MiiPhy100BaseTx) >>6);
+#if MII_DBG
+ DbgPrint("National: Ability : %04x\n", Ability);
+#endif
+ }
+ }
+ }
+ return (Ability ?
+ ConvertNwayToConnectionType(Ability, ConnectionStatus) : FALSE);
+ }
+ else {
+
+ // Nway not supported or not selected,
+ // connection has been selected via CommandReg
+
+ if (PhyInfoPtr->PhyRegs[PhyControlReg] & MiiPhyCtrlDuplexMode) {
+
+ // Full Duplex Medium
+
+ *ConnectionStatus =
+ (PhyInfoPtr->PhyRegs[PhyControlReg] & MiiPhyCtrlSpeed100) ?
+ MediumMii100BaseTxFullDuplex : MediumMii10BaseTFullDuplex;
+#if MII_DBG
+ DbgPrint("Full Duplex Medium; ConnectionStatus= %04x\n",*ConnectionStatus);
+#endif
+ }
+ else if (PhyInfoPtr->PhyRegs[PhyControlReg] & MiiPhyCtrlSpeed100) {
+
+ *ConnectionStatus =
+ (PhyInfoPtr->PhyRegs[PhyStatusReg] & MiiPhy100BaseTx) ?
+ MediumMii100BaseTx : MediumMii100BaseT4;
+ }
+ else{
+ *ConnectionStatus = MediumMii10BaseT;
+ }
+#if MII_DBG
+ DbgPrint("ConnectionStatus= %04x\n",*ConnectionStatus);
+#endif
+ return TRUE;
+ }
+ }
+
+}
+
+/*+
+ *
+ * MiiPhyGetConnectionStatus
+ *
+ * Description:
+ *
+ * Returns the connection status of the PHY.
+ * Rewrites the command word read from the PHY in its entry
+ * in the PhysArray.
+ *
+ * Connection status has the following attributes:
+ * NwayAdminStatus
+ * MAUStatus
+ *
+ *On Entry:
+ * PhyInfoPtr
+ *
+ *On Return:
+ * ConnectionStatus :
+ * High byte - Nwaystatus
+ * Low byte - LinkStatus
+ *
+ *On return
+ * TRUE - on success
+ * FALSE - on fail, the return Connection Status is not valid
+ *
+-*/
+extern
+BOOLEAN
+MiiPhyGetConnectionStatus (
+ PDC21X4_ADAPTER Adapter,
+ PMII_PHY_INFO PhyInfoPtr ,
+ PUSHORT ConnectionStatus
+ )
+{
+
+ //Init all Status bytes to UNKNOWN
+ CAPABILITY NwayStatus=NWAY_UNKNOWN;
+ CAPABILITY LinkStatus=MEDIA_STATE_UNKNOWN;
+
+ CAPABILITY Ability;
+ CAPABILITY LocalAbility;
+ CAPABILITY PartnerAbility;
+
+ ULONG Register;
+
+#if MII_DBG
+ DbgPrint("MiiPhyGetConnectionStatus\n");
+#endif
+ // Read and save Control Reg since the speed selection may be
+ // forced via an hardware pin causing the software selection
+ // to be ignored
+
+ if (!PhyInfoPtr->PhyIntRoutines.PhyReadRegister(
+ Adapter,
+ PhyInfoPtr ,
+ PhyControlReg,
+ &(PhyInfoPtr->PhyRegs[PhyControlReg])
+ )) {
+
+ LinkStatus = MEDIA_READ_REGISTER_FAILED;
+ *ConnectionStatus = NwayStatus | LinkStatus;
+ return FALSE;
+ }
+
+#if MII_DBG
+ DbgPrint("PHY's ControlReg = %04x\n",PhyInfoPtr->PhyRegs[PhyControlReg]);
+#endif
+
+ // Read & save Status word
+ if (!PhyInfoPtr->PhyIntRoutines.PhyReadRegister(
+ Adapter,
+ PhyInfoPtr,
+ PhyStatusReg,
+ &(PhyInfoPtr->PhyRegs[PhyStatusReg])
+ )) {
+ LinkStatus = MEDIA_READ_REGISTER_FAILED;
+ *ConnectionStatus = NwayStatus | LinkStatus;
+ return FALSE;
+ }
+#if MII_DBG
+ DbgPrint("PHY's StatusReg = %04x\n",PhyInfoPtr->PhyRegs[PhyStatusReg]);
+#endif
+ if (PhyInfoPtr->PhyRegs[PhyStatusReg] == 0){
+ LinkStatus = MEDIA_READ_REGISTER_FAILED;
+ *ConnectionStatus = NwayStatus | LinkStatus;
+ return FALSE;
+ }
+
+ // Set Nway status according to Nway complete & ability bits & enable
+
+ switch (PhyInfoPtr->PhyId) {
+
+ case BCM5000_0:
+
+ // Broadcom
+
+ if (PhyInfoPtr ->PhyRegs[PhyControlReg] & MiiPhyCtrlEnableNway) {
+
+ NwayStatus = NWAY_COMPLETE;
+ }
+ else {
+
+ NwayStatus = NWAY_DISABLED;
+ }
+ break;
+
+ default:
+
+ if (PhyInfoPtr ->PhyRegs[PhyStatusReg] & MiiPhyNwayCapable) {
+
+ if (PhyInfoPtr ->PhyRegs[PhyControlReg] & MiiPhyCtrlEnableNway) {
+
+ if (PhyInfoPtr ->PhyRegs[PhyStatusReg] & MiiPhyNwayComplete) {
+ NwayStatus = NWAY_COMPLETE;
+ }
+ else {
+ // assume configuration not done yet
+ NwayStatus = NWAY_CONFIGURING;
+ *ConnectionStatus = NwayStatus | LinkStatus;
+ return FALSE;
+ }
+ }
+ else {
+ NwayStatus = NWAY_DISABLED;
+ }
+ }
+ else {
+ NwayStatus = NWAY_NOT_SUPPORTED;
+ }
+ }
+
+ // Set link status according to link bit.
+ // Since LinkStatus bit latches Link-Fail status
+ // the link status is find as follows:
+ //
+ // If Status Reg indicate LinkPass then
+ // LinkStatus=LINK_PASS
+ // else
+ // Read Status Register
+ // If Status Reg indicate LinkPass then
+ // LinkStatus=LINK_PASS_WITH_PF
+ // else
+ // LinkStatus=LINK_FAIL
+ // endif
+ // endif
+
+
+ // Check if the Link status indicates a
+ // PHY's supported medium
+ // Only if the Phy is NWAY's Capable or NWAY is enabled
+
+ if (NwayStatus == NWAY_COMPLETE) {
+
+ PhyInfoPtr->PhyIntRoutines.PhyNwayGetLocalAbility(
+ Adapter,
+ PhyInfoPtr,
+ &LocalAbility
+ );
+
+ PhyInfoPtr->PhyIntRoutines.PhyNwayGetPartnerAbility(
+ Adapter,
+ PhyInfoPtr,
+ &PartnerAbility
+ );
+
+ if (PhyInfoPtr->PhyId == DP83840_0) {
+
+ //National's Phy Speed Sensing workaround:
+ //read the Speed_bit in the PAR register to sense
+ //the connection speed
+
+ if (PhyInfoPtr->PhyIntRoutines.PhyReadRegister(
+ Adapter,
+ PhyInfoPtr ,
+ NatPhyParRegister,
+ &Register
+ )) {
+
+ Ability = (LocalAbility &
+ ((Register & PAR_SPEED_10) ? MiiPhy10BaseT : MiiPhy100BaseTx ) >>6);
+#if MII_DBG
+ DbgPrint("National: Speed sense -> %s\n",
+ (Register & PAR_SPEED_10) ? "10Mbps" : "100Mbps" );
+#endif
+ }
+ }
+ else {
+ Ability = LocalAbility & PartnerAbility;
+ }
+
+ if (!(Ability)) {
+ LinkStatus = MEDIA_LINK_FAIL;
+ *ConnectionStatus = NwayStatus | LinkStatus;
+ return FALSE;
+ }
+ }
+
+ if (!(PhyInfoPtr->PhyRegs[PhyStatusReg] & MiiPhyLinkStatus)) {
+
+ // Link fail: Read again Status Reg
+ if (!PhyInfoPtr->PhyIntRoutines.PhyReadRegister(
+ Adapter,
+ PhyInfoPtr,
+ PhyStatusReg,
+ &(PhyInfoPtr->PhyRegs[PhyStatusReg])
+ )) {
+ return FALSE;
+ }
+
+ if (!(PhyInfoPtr->PhyRegs[PhyStatusReg] & MiiPhyLinkStatus)) {
+
+ // Link bit is still in Fail state
+ LinkStatus = MEDIA_LINK_FAIL;
+ }
+ else {
+#if MII_DBG
+ DbgPrint("LinkPass with Previous Failure\n");
+#endif
+ LinkStatus = MEDIA_LINK_PASS_WITH_PF;
+ }
+ }
+ else {
+ LinkStatus = MEDIA_LINK_PASS;
+ }
+
+ *ConnectionStatus = NwayStatus | LinkStatus;
+ return (LinkStatus != MEDIA_LINK_FAIL);
+
+}
+
+/*+
+ *
+ * MiiPhyAdminControl
+ *
+ * Description:
+ *
+ * Performs the Control command on the specified Phy.
+ * Control command can be one of the following:
+ * Reset - reset the PHY (returns it to defaults)
+ * PowerDown
+ * StandBy
+ * Operational
+ *
+ * Input parameters:
+ *
+ * PhyInfoPtr - PMII_PHY_INFO pointer to MII_PHY_INFO
+ * Control - MII_STATUS
+ *
+ * AdminControlConversionTable - used in this routine
+ *
+ * Output parameters:
+ *
+ * None.
+ *
+-*/
+extern
+void
+MiiPhyAdminControl(
+ PDC21X4_ADAPTER Adapter,
+ PMII_PHY_INFO PhyInfoPtr,
+ MII_STATUS Control
+ )
+{
+ MII_STATUS Status = MiiGenAdminReset;
+ INT i = 0;
+
+#if MII_DBG
+ DbgPrint("MiiPhyAdminControl\n");
+#endif
+
+ switch (Control) {
+
+ case MiiGenAdminForce10:
+ case MiiGenAdminForce10Fd:
+
+ PhyInfoPtr->PreviousControl = PhyInfoPtr->PhyRegs[PhyControlReg];
+ PhyInfoPtr->PhyRegs[PhyControlReg] &= MiiPhyCtrlForce10;
+ Adapter->Force10 = TRUE;
+ break;
+
+ case MiiGenAdminRelease10:
+
+ PhyInfoPtr->PhyRegs[PhyControlReg] = PhyInfoPtr->PreviousControl;
+ Adapter->Force10 = FALSE;
+ break;
+
+ default:
+ // Clear previous Control bits
+ PhyInfoPtr->PhyRegs[PhyControlReg] &= ~(MiiPhyCtrlReset |
+ MiiPhyCtrlPowerDown |
+ MiiPhyCtrlIsolate);
+ }
+
+ // Write Control register
+#if MII_DBG
+ DbgPrint("Write ControlReg = %04x\n",(PhyInfoPtr->PhyRegs[PhyControlReg]|
+ AdminControlConversionTable[Control]));
+#endif
+ PhyInfoPtr->PhyIntRoutines.PhyWriteRegister(
+ Adapter,
+ PhyInfoPtr,
+ PhyControlReg,
+ (PhyInfoPtr->PhyRegs[PhyControlReg] | AdminControlConversionTable[Control])
+ );
+
+ if (Control == MiiGenAdminReset) {
+ // Delay until reset done and chip stabilizes
+#if MII_DBG
+ DbgPrint("Control = Reset; Delay until done and chip stabilizes\n");
+#endif
+ while ( (i++) < RESET_DELAY ) {
+ PhyInfoPtr->PhyExtRoutines.PhyAdminStatus(
+ Adapter,
+ PhyInfoPtr,
+ &Status
+ );
+ if ( Status != MiiGenAdminReset ) {
+ break;
+ }
+
+ }
+#if MII_DBG
+ DbgPrint("Control = %x after Delay \n", Status);
+#endif
+ }
+
+ return;
+
+}
+
+
+/*+
+ *
+ * MiiPhyAdminStatus
+ *
+ * Description:
+ *
+ * Returns PHY admin status, which can be one of the following:
+ * Reset - reset process is in progress (not completed yet)
+ * PowerDown - Chip is in Power Down mode
+ * StandBy - Chip listening but not accessing mii data lines
+ * Operational - Chip is fully active
+ *
+ * Input parameters:
+ *
+ * PhyInfoPtr - PMII_PHY_INFO pointer to MII_PHY_INFO
+ *
+ * Output parameters:
+ *
+ * Status - MII_STATUS
+ *
+ *
+ * Note: Interrupts are disabled.
+ *
+-*/
+extern
+void
+MiiPhyAdminStatus(
+ PDC21X4_ADAPTER Adapter,
+ PMII_PHY_INFO PhyInfoPtr,
+ PMII_STATUS Status
+ )
+{
+
+ USHORT RegVal = 0;
+ SHORT i = 3;
+
+#if MII_DBG
+ DbgPrint("MiiPhyAdminStatus\n");
+#endif
+ // Reads 3 times to garanty that 0 is a real value
+ while (i--) {
+ PhyInfoPtr->PhyIntRoutines.PhyReadRegister(
+ Adapter,
+ PhyInfoPtr,
+ PhyControlReg,
+ &RegVal
+ );
+ if (RegVal) {
+ break;
+ }
+ }
+
+ switch (RegVal) {
+
+ case MiiPhyCtrlReset:
+
+ *Status = MiiGenAdminReset;
+ break;
+
+ case MiiPhyCtrlPowerDown:
+
+ *Status = MiiGenAdminPowerDown;
+ break;
+
+ case MiiPhyCtrlIsolate:
+
+ *Status = MiiGenAdminStandBy;
+ break;
+
+ default:
+
+ *Status = MiiGenAdminOperational;
+ }
+#if _DBG
+ DbgPrint("AdminStatus = %x\n", Status);
+#endif
+
+ return;
+}
+
+
+
+//***************************************************************************
+//* Mii PHY Internal Routines *
+//***************************************************************************
+/*+
+ *
+ * MiiPhyReadRegister
+ *
+ * Description:
+ *
+ * Reads contents of register RegNum into *Register.
+ *
+ * Input parameters:
+ *
+ * PDC21X4_ADAPTER - Adapter The Adapter DS.
+ * PhyInfoPtr - PMII_PHY_INFO pointer to MII_PHY_INFO
+ * RegNum - USHORT # of register to be read
+ *
+ * Output parameters:
+ *
+ * *Register - USHORT contents of RegNum
+ *
+ * On return - TRUE if reading completed successfully, FALSE otherwise.
+ *
+ *
+ *
+ * +-----------------------------------------------------------------------+
+ * | Management frame fields |
+ * +------+-------+----+----+-------+-------+----+------------------+------+
+ * | | PRE | ST | OP | PHYAD | REGAD | TA | DATA | IDLE |
+ * +------+-------+----+----+-------+-------+----+------------------+------+
+ * |Read | 1...1 | 01 | 10 | AAAAA | RRRRR | Z0 | DDDDDDDDDDDDDDDD | Z |
+ * +------+-------+----+----+-------+-------+----+------------------+------+
+ *
+ * Note: Interrupts are disabled.
+ *
+-*/
+extern
+BOOLEAN
+MiiPhyReadRegister(
+ PDC21X4_ADAPTER Adapter,
+ PMII_PHY_INFO PhyInfoPtr,
+ USHORT RegNum,
+ PUSHORT RegDat
+ )
+{
+ ULONG CommandWord;
+ ULONG Tmp = 0;
+ USHORT Data = 0;
+ INT i;
+ INT SizeOfUshort = ((sizeof(USHORT))*8);
+ BOOLEAN Succeed=TRUE;
+
+#if _DBG
+ DbgPrint("MiiPhyReadRegister\n");
+#endif
+ // Write Preamble
+ WriteMii(Adapter, PRE, 2*SizeOfUshort);
+
+ // Prepare command word
+ CommandWord = PhyInfoPtr->PhyAddress << PHY_ADDR_ALIGN;
+ CommandWord |= (RegNum << REG_ADDR_ALIGN);
+ CommandWord |= MII_READ_FRAME;
+#if _DBG
+ DbgPrint("CommandWord=%08x\n", CommandWord);
+#endif
+ WriteMii(Adapter, CommandWord, SizeOfUshort-2);
+
+ MiiOutThreeState(Adapter);
+
+ // Check that the PHY chip generated a zero bit the 2nd clock
+ DC21X4_READ_PORT(
+ DC21X4_IDPROM,
+ &Tmp
+ );
+
+ if (Tmp & MII_READ_DATA_MASK) {
+#if _DBG
+ DbgPrint("***No Zero bit generated after 3 states\n");
+#endif
+ Succeed = FALSE;
+ }
+
+ // read data WORD
+ (*RegDat) = 0;
+ for (i=0; i<SizeOfUshort; i++) {
+ DC21X4_WRITE_PORT(
+ DC21X4_IDPROM,
+ MII_READ
+ );
+ DELAY(MII_DELAY);
+ DC21X4_WRITE_PORT(
+ DC21X4_IDPROM,
+ (MII_READ | MII_CLK)
+ );
+ DELAY(MII_DELAY);
+ DC21X4_READ_PORT(
+ DC21X4_IDPROM,
+ &Tmp
+ );
+ DELAY(MII_DELAY);
+ Data = (USHORT) ((Tmp >> MII_MDI_BIT_POSITION) & 0x0001);
+ (*RegDat) = ((*RegDat) << 1) | Data;
+ }
+
+#if _DBG
+ DbgPrint("&RegData=%08x Reg[%d]=%04x\n", RegDat, RegNum, *RegDat);
+#endif
+ MiiOutThreeState(Adapter);
+
+ // clear reserved bits
+ (*RegDat) &= ~PhyRegsReservedBitsMasks[RegNum];
+#if _DBG
+ DbgPrint("After Mask, Reg[%d]=%04x\n", RegNum, *RegDat);
+#endif
+
+ return Succeed;
+}
+
+
+
+
+/*+
+ *
+ * MiiPhyWriteRegister
+ *
+ * Description:
+ *
+ * Writes contents of Register to register number RegNum.
+ *
+ * Input parameters:
+ *
+ * PhyInfoPtr - PMII_PHY_INFO pointer to MII_PHY_INFO
+ * RegNum - USHORT
+ * Register - USHORT
+ *
+ * Output parameters:
+ *
+ * None.
+ *
+ *
+ * +-----------------------------------------------------------------------+
+ * | Management frame fields |
+ * +------+-------+----+----+-------+-------+----+------------------+------+
+ * | | PRE | ST | OP | PHYAD | REGAD | TA | DATA | IDLE |
+ * +------+-------+----+----+-------+-------+----+------------------+------+
+ * |Write | 1...1 | 01 | 01 | AAAAA | RRRRR | 10 | DDDDDDDDDDDDDDDD | Z |
+ * +------+-------+----+----+-------+-------+----+------------------+------+
+ *
+ * Note: Interrupts are disabled.
+ *
+-*/
+extern
+void
+MiiPhyWriteRegister(
+ PDC21X4_ADAPTER Adapter,
+ PMII_PHY_INFO PhyInfoPtr,
+ USHORT RegNum,
+ USHORT Register
+ )
+{
+
+ ULONG CommandWord;
+ INT SizeOfUshort = ((sizeof(USHORT))*8);
+
+#if _DBG
+ DbgPrint("MiiPhyWriteRegister\n");
+#endif
+ // Clear reserved bits
+ Register &= ~PhyRegsReservedBitsMasks[RegNum];
+
+ WriteMii(Adapter, PRE, 2*SizeOfUshort);
+
+ // Prepare command word
+ CommandWord = (PhyInfoPtr->PhyAddress << PHY_ADDR_ALIGN);
+ CommandWord |= (RegNum << REG_ADDR_ALIGN);
+ CommandWord |= (MII_WRITE_FRAME | Register);
+
+#if _DBG
+ DbgPrint("CommandWord to write: %08x\n", CommandWord);
+#endif
+ WriteMii(Adapter, CommandWord, 2*SizeOfUshort);
+
+ MiiOutThreeState(Adapter);
+ return;
+}
+
+
+
+
+/*+
+ *
+ * MiiPhyNwayGetLocalAbility
+ *
+ * Description:
+ *
+ * Returns local abilities of the PHY according to the value
+ * written in Nway Local Abilities register.
+ *
+ * Input parameters:
+ *
+ * PhyInfoPtr - PMII_PHY_INFO pointer to MII_PHY_INFO
+ *
+ * Output parameters
+ *
+ * *Ability - NwayCapacity
+ *
+ *
+-*/
+extern
+void
+MiiPhyNwayGetLocalAbility(
+ PDC21X4_ADAPTER Adapter,
+ PMII_PHY_INFO PhyInfoPtr,
+ PCAPABILITY Ability
+ )
+{
+
+#if MII_DBG
+ DbgPrint("MiiPhyNwayGetLocalAbility\n");
+#endif
+
+ switch (PhyInfoPtr->PhyId) {
+
+ case BCM5000_0:
+
+ // Broadcom's PHY
+ *Ability = (PhyInfoPtr->PhyCapabilities >> 6);
+ break;
+
+ default:
+
+ if (PhyInfoPtr->PhyIntRoutines.PhyReadRegister(
+ Adapter,
+ PhyInfoPtr,
+ PhyNwayAdvertisement,
+ &(PhyInfoPtr->PhyRegs[PhyNwayAdvertisement])
+ )
+ ) {
+
+ *Ability = PhyInfoPtr->PhyRegs[PhyNwayAdvertisement] & MiiPhyNwayCapabilitiesMask;
+ }
+ else {
+ *Ability = 0;
+ }
+ }
+ return;
+
+}
+
+
+
+
+/*+
+ *
+ * MiiPhyNwaySetLocalAbility
+ *
+ * Description:
+ *
+ * Modifies the local PHY Local abilities Advertisement register value
+ * for the purpose of limiting the media connections to be negotiated
+ * (/sent) to the link partner.
+ *
+ * Input parameters:
+ *
+ * PhyInfoPtr - PMII_PHY_INFO
+ * MediaBits - USHORT
+ *
+ * Output parameters:
+ *
+ * None.
+ *
+ *
+-*/
+extern
+void
+MiiPhyNwaySetLocalAbility(
+ PDC21X4_ADAPTER Adapter,
+ PMII_PHY_INFO PhyInfoPtr,
+ USHORT MediaBits
+ )
+{
+
+#if MII_DBG
+ DbgPrint("MiiPhyNwaySetLocalAbility\n");
+#endif
+
+ if (PhyInfoPtr->PhyId != BCM5000_0){
+ PhyInfoPtr->PhyRegs[PhyNwayAdvertisement] =
+ (PhyInfoPtr->PhyMediaAdvertisement & MediaBits) |
+ NWAY_802_3_Selector;
+
+#if MII_DBG
+ DbgPrint("PhyInfoPtr->PhyRegs[PhyNwayAdvertisement] = %04x\n", PhyInfoPtr->PhyRegs[PhyNwayAdvertisement]);
+ DbgPrint("SROM Advertisement = %04x\n", MediaBits);
+#endif
+ PhyInfoPtr->PhyIntRoutines.PhyWriteRegister(
+ Adapter,
+ PhyInfoPtr,
+ PhyNwayAdvertisement,
+ PhyInfoPtr->PhyRegs[PhyNwayAdvertisement]
+ );
+ }
+ return;
+}
+
+
+
+
+
+
+/*+
+ *
+ * MiiPhyNwayGetPartnerAbility
+ *
+ * Description:
+ *
+ * Returns link partner abilities as written in the link partner
+ * abilities register (which reflects link partner's Advertisement
+ * register).
+ * Input parameters:
+ *
+ * PhyInfoPtr - PMII_PHY_INFO pointer to struct with PHY info
+ *
+ * Output parameters:
+ *
+ * *Ability - NWayAbility pointer to partner abilities
+ *
+ *
+ * A value of 0 will be returned If link partner is not Nway capable or
+ * does not support any known medium.
+ *
+-*/
+extern
+void
+MiiPhyNwayGetPartnerAbility(
+ PDC21X4_ADAPTER Adapter,
+ PMII_PHY_INFO PhyInfoPtr,
+ PCAPABILITY Ability
+ )
+{
+
+#if MII_DBG
+ DbgPrint("MiiPhyNwayGetPartnerAbility\n");
+#endif
+ if (PhyInfoPtr->PhyIntRoutines.PhyReadRegister(
+ Adapter,
+ PhyInfoPtr,
+ PhyNwayLinkPartnerAbility,
+ &(PhyInfoPtr->PhyRegs[PhyNwayLinkPartnerAbility])
+ )
+ ) {
+
+ PhyInfoPtr->PhyRegs[PhyNwayLinkPartnerAbility] &= MiiPhyNwayCapabilitiesMask;
+ *Ability = PhyInfoPtr->PhyRegs[PhyNwayLinkPartnerAbility];
+ }
+ else {
+ *Ability = 0;
+ }
+ return;
+
+}
+
+
+
+/*+
+ *
+ * FindMiiPhyDevice
+ *
+ * Description:
+ *
+ * Receives MII PHY address and checks if a PHY exists there.
+ * PhyInfotPtr->PhyAddress holds the PHY address
+ *
+ * Input parameter:
+ *
+ * PhyInfoPtr - PMII_PHY_INFO pointer to struct with PHY info
+ *
+ * Return value:
+ *
+ * FALSE - if no such PHY is found
+ * TRUE - otherwise
+ *
+ *****************************************************************************/
+extern
+BOOLEAN
+FindMiiPhyDevice(
+ PDC21X4_ADAPTER Adapter,
+ PMII_PHY_INFO PhyInfoPtr
+ )
+{
+ USHORT RegOffset;
+ USHORT RegData;
+
+#if MII_DBG
+ DbgPrint("FindMiiPhyDevice\n");
+#endif
+
+ // Read PHY's Registers
+
+ //The first two registers are mandatory
+ for (RegOffset=0; RegOffset<=PhyStatusReg; RegOffset++) {
+ if(PhyInfoPtr->PhyIntRoutines.PhyReadRegister(
+ Adapter,
+ PhyInfoPtr,
+ RegOffset,
+ &RegData
+ ) ){
+ PhyInfoPtr->PhyRegs[RegOffset] = RegData;
+ }
+ else {
+ return FALSE;
+ }
+ }
+
+ // Read the Phy's Id Registers
+ for (; RegOffset<=PhyId_2; RegOffset++) {
+ if(PhyInfoPtr->PhyIntRoutines.PhyReadRegister(
+ Adapter,
+ PhyInfoPtr,
+ RegOffset,
+ &RegData
+ ) ){
+ PhyInfoPtr->PhyRegs[RegOffset] = RegData;
+ }
+ else {
+ break;
+ }
+ }
+ if (RegOffset > PhyId_2) {
+ PhyInfoPtr->PhyId =
+ (PhyInfoPtr->PhyRegs[PhyId_1] <<16) | PhyInfoPtr->PhyRegs[PhyId_2];
+ }
+
+
+ //Read the remaining registers
+ for (RegOffset=PhyNwayAdvertisement; RegOffset<MAX_PHY_REGS; RegOffset++) {
+ if(PhyInfoPtr->PhyIntRoutines.PhyReadRegister(
+ Adapter,
+ PhyInfoPtr,
+ RegOffset,
+ &RegData
+ ) ){
+ PhyInfoPtr->PhyRegs[RegOffset] = RegData;
+ }
+ else {
+ break;
+ }
+ }
+
+ //Check if the required number of registers have been read
+ //successfully
+
+ switch (PhyInfoPtr->PhyId) {
+
+ case BCM5000_0 :
+ case DP83840_0 :
+
+ if (RegOffset < MAX_PHY_REGS) {
+ return FALSE;
+ }
+ break;
+
+ default:
+
+ if ( ( (PhyInfoPtr->PhyRegs[PhyStatusReg] | MiiPhyNwayCapable)
+ && (RegOffset <= PhyNwayLinkPartnerAbility)
+ )
+ || ( (PhyInfoPtr->PhyRegs[PhyNwayAdvertisement] | MiiPhyNwayNextPageAble)
+ && (RegOffset <= PhyNwayExpansion )
+ )
+ ){
+ return FALSE;
+ }
+ break;
+ }
+
+#if MII_DBG
+ DbgPrint("Device PhyId= %08x\n", PhyInfoPtr->PhyId);
+ DbgPrint("PhyStatusReg= %04x\n", PhyInfoPtr->PhyRegs[PhyStatusReg]);
+#endif
+
+ //return FALSE if the Status Register is all 0's
+ //otherwise return TRUE;
+
+ return (PhyInfoPtr->PhyRegs[PhyStatusReg] !=0);
+
+}
+
+
+/*+
+ *
+ * WriteMii
+ *
+ * Description:
+ *
+ * Writes the data size bits from the MiiData to the Mii control lines.
+ *
+ * Input parameters
+ * MiiData - The data to be written
+ * DataSize - The number of bits to write
+ *
+ * Output parameters
+ * None.
+ *
+ * Return Value
+ * TRUE if success, FALSE if hardware failure encountered.
+ *
+-*/
+extern
+void
+WriteMii(
+ PDC21X4_ADAPTER Adapter,
+ ULONG MiiData,
+ int DataSize
+ )
+{
+
+ INT i;
+ ULONG Dbit;
+
+#if _DBG
+ DbgPrint("WriteMii\n");
+ DbgPrint("PHY: Data to write = %08x\n", MiiData);
+#endif
+
+ // Write the data to the PHY
+
+ for (i = DataSize; i> 0; i--) {
+
+ Dbit = ((MiiData >> (31-MII_MDO_BIT_POSITION)) & MII_MDO_MASK);
+
+ DC21X4_WRITE_PORT(
+ DC21X4_IDPROM,
+ MII_WRITE | Dbit
+ );
+
+ DELAY(MII_DELAY);
+
+ DC21X4_WRITE_PORT(
+ DC21X4_IDPROM,
+ MII_WRITE | MII_CLK | Dbit
+ );
+
+ DELAY(MII_DELAY);
+
+ MiiData = MiiData << 1;
+ }
+
+
+}
+
+
+
+
+/*+**************************************************************************
+ *
+ * MiiOutThreeState
+ *
+ * Description:
+ *
+ * Puts the MDIO port in threestate for the turn around bits
+ * in MII read and at end of MII management sequence.
+ *
+ * Parameters
+ * None.
+ *
+-*/
+extern
+void
+MiiOutThreeState(
+ PDC21X4_ADAPTER Adapter
+ )
+{
+
+#if _DBG
+ DbgPrint("MiiOutThreeState\n");
+#endif
+ DC21X4_WRITE_PORT(
+ DC21X4_IDPROM,
+ MII_WRITE_TS
+ );
+ DELAY(MII_DELAY);
+ DC21X4_WRITE_PORT(
+ DC21X4_IDPROM,
+ (MII_WRITE_TS | MII_CLK)
+ );
+ DELAY(MII_DELAY);
+
+ return;
+}
+
+/*+
+ *
+ * InitPhyInfoEntries
+ *
+ * Description:
+ *
+ * Initializes the MII PHY struct by directing pointers of struct
+ * routines to routines addresses.
+ * (these addresses cannot be resolved at compile time).
+ *
+ * Parameter:
+ *
+ * PhyInfoPtr - PMII_PHY_INFO pointer to struct with PHY info
+ *
+ *
+-*/
+extern
+void
+InitPhyInfoEntries(
+ PMII_PHY_INFO PhyInfoPtr
+ )
+{
+ NDIS_STATUS NdisStatus;
+
+#if MII_DBG
+ DbgPrint("InitPhyInfoEntries\n");
+#endif
+
+ PhyInfoPtr->PhyExtRoutines.PhyInit = (void *)MiiPhyInit;
+ PhyInfoPtr->PhyExtRoutines.PhyGetCapabilities = (void *)MiiPhyGetCapabilities;
+ PhyInfoPtr->PhyExtRoutines.PhySetConnectionType = (void *)MiiPhySetConnectionType;
+ PhyInfoPtr->PhyExtRoutines.PhyGetConnectionType = (void *)MiiPhyGetConnectionType;
+ PhyInfoPtr->PhyExtRoutines.PhyGetConnectionStatus = (void *)MiiPhyGetConnectionStatus;
+ PhyInfoPtr->PhyExtRoutines.PhyAdminControl = (void *)MiiPhyAdminControl;
+ PhyInfoPtr->PhyExtRoutines.PhyAdminStatus = (void *)MiiPhyAdminStatus;
+
+ PhyInfoPtr->PhyIntRoutines.PhyReadRegister = (void *)MiiPhyReadRegister;
+ PhyInfoPtr->PhyIntRoutines.PhyWriteRegister = (void *)MiiPhyWriteRegister;
+ PhyInfoPtr->PhyIntRoutines.PhyNwayGetLocalAbility = (void *)MiiPhyNwayGetLocalAbility;
+ PhyInfoPtr->PhyIntRoutines.PhyNwaySetLocalAbility = (void *)MiiPhyNwaySetLocalAbility;
+ PhyInfoPtr->PhyIntRoutines.PhyNwayGetPartnerAbility = (void *)MiiPhyNwayGetPartnerAbility;
+
+ return;
+}
+
+/*+
+ *
+ * ConvertConnectionToControl
+ *
+ * Input parameters
+ * PhyInfoPtr - PMII_PHY_INFO pointer to struct with PHY info
+ * Connection - ConnectionType
+ *
+ * Output parameters
+ * Converted Connection - ConnectionType
+ *
+ * Note: Interrupts are disabled.
+ *
+-*/
+extern
+void
+ConvertConnectionToControl(
+ PMII_PHY_INFO PhyInfotPtr,
+ PUSHORT Connection
+ )
+{
+
+ USHORT OM_bits = ((*Connection) & CONTROL_MASK);
+
+#if MII_DBG
+ DbgPrint("ConvertConnectionToControl\n");
+ DbgPrint("Before Conversion: Connection = %04x\n", *Connection);
+#endif
+ // Convert Media Type to control bits
+
+ *Connection = MediaToCommandConversionTable[*Connection & MEDIA_MASK];
+
+ // Check if Nway bits are also needed
+
+ if (( OM_bits & (MEDIA_NWAY | MEDIA_AUTOSENSE))) {
+
+ // Autosense or Nway are required:
+
+ switch (PhyInfotPtr->PhyId) {
+
+ default:
+
+ *Connection |= MiiPhyCtrlRestartNway;
+
+ case BCM5000_0:
+
+ *Connection |= MiiPhyCtrlEnableNway;
+ }
+
+ }
+
+#if MII_DBG
+ DbgPrint("After Conversion: Connection = %04x\n", *Connection);
+#endif
+
+ return;
+
+}
+
+
+/*+
+ *
+ * ConvertMediaTypeToNwayLocalAbility
+ *
+ * Input parameters
+ * MediaType - USHORT (in SROM format)
+ *
+ * Output parameters
+ * NwayLocalAbility - CAPABILITY
+ *
+-*/
+extern
+void
+ConvertMediaTypeToNwayLocalAbility(
+ USHORT MediaType,
+ PCAPABILITY NwayLocalAbility
+ )
+{
+
+#if MII_DBG
+ DbgPrint("ConvertMediaTypeToNwayLocalAbility\n");
+ DbgPrint("MediaType = %04x\n", MediaType);
+#endif
+
+ // Convert MediaType to Nway Advertisement bits
+
+ *NwayLocalAbility = MediaToNwayConversionTable[(MediaType & MEDIA_MASK)];
+#if MII_DBG
+ DbgPrint("NwayLocalAbility = %04x\n", *NwayLocalAbility);
+#endif
+ return;
+
+}
+
+/*+
+ *
+ * ConvertNwayToConnectionType
+ *
+ * Description:
+ *
+ * Returns highest precedence media type whose bit is set in Nway
+ * word, according to the following table:
+ * +----+---------------------------+--------+
+ * |Bit | Technology |Priority|
+ * +----+---------------------------+--------+
+ * | A0 | 10Base-T (Half-Duplex) | 5(LSP) |
+ * +----+---------------------------+--------+
+ * | A1 | 10Base-T Full-Duplex | 4 |
+ * +----+---------------------------+--------+
+ * | A2 | 100Base-TX (Half-Duplex) | 3 |
+ * +----+---------------------------+--------+
+ * | A3 | 100Base-TX Full-Duplex | 1(MSP) |
+ * +----+---------------------------+--------+
+ * | A4 | 100Base-T4 | 2 |
+ * +----+---------------------------+--------+
+ *
+ *On Entry:
+ * NwayReg - Nway register bits (in Advertisement format).
+ *On Return:
+ * NwayReg - The converted ConnectionType
+ *
+ *Return Value
+ * FALSE - No Media Found
+ * TRUE - Media found and returned in NwayReg
+ *
+-*/
+extern
+BOOLEAN
+ConvertNwayToConnectionType(
+ CAPABILITY NwayReg,
+ PUSHORT Connection
+ )
+{
+
+#if MII_DBG
+ DbgPrint("ConvertNwayToConnectionType\n");
+#endif
+ if (NwayReg & MiiPhyNway100BaseTxFD) {
+ // 100BaseTx FD
+ *Connection = (MediumMii100BaseTxFullDuplex | MediaAutoSense);
+ }
+ else if (NwayReg & MiiPhyNway100BaseT4) {
+ // 100BaseT4
+ *Connection = (MediumMii100BaseT4 | MediaAutoSense);
+ }
+ else if (NwayReg & MiiPhyNway100BaseTx) {
+ // 100BaseTx
+ *Connection = (MediumMii100BaseTx | MediaAutoSense);
+ }
+ else if (NwayReg & MiiPhyNway10BaseTFD) {
+ // 10BaseT FD
+ *Connection = (MediumMii10BaseTFullDuplex | MediaAutoSense);
+ }
+ else if (NwayReg & MiiPhyNway10BaseT) {
+ // 10BaseT
+ *Connection = (MediumMii10BaseT | MediaAutoSense);
+ }
+ else {
+ // No media found
+ return FALSE;
+ }
+ return TRUE;
+}
+
+
+/*+
+ *
+ * CheckConnectionSupport
+ *
+ * Input parameters:
+ *
+ * PhyInfoPtr - PMII_PHY_INFO pointer to struct with PHY info
+ * MiiMediaCapable - Mii Media capability mask from the SROM
+ * ConCommand - Connection command bits (in SROM format)
+ *
+ * Return value:
+ *
+ * FALSE - Connection NOT supported
+ * TRUE - Connection supported
+ *
+-*/
+extern
+BOOLEAN
+CheckConnectionSupport(
+ PMII_PHY_INFO PhyInfoPtr,
+ USHORT ConCommand
+ )
+{
+ USHORT StatusBits;
+
+#if MII_DBG
+ DbgPrint("CheckConnectionSupport\n");
+#endif
+
+ if ((ConCommand & (MEDIA_NWAY | MEDIA_AUTOSENSE))){
+ //NWAY or AutoSense are required
+#if MII_DBG
+ DbgPrint("NWAY or AutoSensing\n");
+#endif
+ return ((PhyInfoPtr->PhyCapabilities & MiiPhyNwayCapable) != 0);
+ }
+
+ //Convert media to status bits
+
+ StatusBits = MediaToStatusConversionTable[(ConCommand & MEDIA_MASK)];
+#if MII_DBG
+ DbgPrint("Before Conversion: ConCommand = %04x\n", ConCommand);
+ DbgPrint("After Conversion: StatusBits = %04x\n", StatusBits);
+#endif
+
+ //Return TRUE if the requested medium is supported by the PHY
+
+ return ((StatusBits & PhyInfoPtr->PhyCapabilities) != 0);
+
+}
+
+
+
+
+
+
+
+
+
+
+//****************************************************************************
+//* Broadcom support routines *
+//****************************************************************************
+
+/*+
+ *Broadcom extended register (address 16)
+ *---------------------------------------
+ *
+ * +-----+----------------+---------------------------+-----------------------------+
+ * | Bit | Name | Description | Comments |
+ * +-----+----------------+---------------------------+-----------------------------+
+ * | 15 | JABDIS |1=Jubber Disabled | Default 0 (R/W) |
+ * | | |1=Jubber Enabled | |
+ * +-----+----------------+---------------------------+-----------------------------+
+ * | 14 | LINKDIS |1=Link test Disabled | Default 0 (R/W) |
+ * | | |0=Link test Enabled | |
+ * +-----+----------------+---------------------------+-----------------------------+
+ * |13-9 | reserved | |Write as 0, Ignore on read |
+ * +-----+----------------+---------------------------+-----------------------------+
+ * | 8 |FORCEFAIL_EN |1=Force fail enabled | Default 1 (R/W) |
+ * | | |0=Force fail disabled | |
+ * +-----+----------------+---------------------------+-----------------------------+
+ * | 7-5 |RV_CNTR |Revision control indicator | Value is 000 (RO) |
+ * +-----+----------------+---------------------------+-----------------------------+
+ * | 4-3 |HSQ:LSQ |Defines the squelch mode of|10=High squelch, 00=Normal |
+ * | | |the carrier sense mechanism|01=Low Squelch,11=Not allowed|
+ * | | | |Default 00 (R/W) |
+ * +-----+----------------+---------------------------+-----------------------------+
+ * | 2 |TXDAC power mode| |Default 0 (R/W) |
+ * +-----+----------------+---------------------------+-----------------------------+
+ * | 1 |Speed Indication|1 = 100Mbps mode |Default 0 RO |
+ * | | |0 = 10Mbps mode | |
+ * +-----+----------------+---------------------------+-----------------------------+
+ * | 0 |reserved | | |
+ * +-----+----------------+---------------------------+-----------------------------+
+-*/
+
+
+
+
+
+/*+
+ *
+ * HandleBroadcomMediaChangeFrom10To100
+ *
+ * Description:
+ *
+ * Handle Broadcom special requirements for speed change from 10 to 100 Mbps
+ *
+ * Input parameters:
+ *
+ * PhyInfoPtr - PMII_PHY_INFO pointer to struct with PHY info
+ *
+ * Output parameters:
+ *
+ * None.
+ *
+ *
+-*/
+extern
+void
+HandleBroadcomMediaChangeFrom10To100(
+ PDC21X4_ADAPTER Adapter,
+ PMII_PHY_INFO PhyInfoPtr
+ )
+{
+
+ USHORT Register;
+
+#if MII_DBG
+ DbgPrint("HandleBroadcomMediaChangeFrom10To100\n");
+#endif
+ PhyInfoPtr->PhyIntRoutines.PhyReadRegister(
+ Adapter,
+ PhyInfoPtr,
+ MII_BROADCOM_EXTENDED_REG_ADDRESS,
+ &Register
+ );
+
+ if ( (Register != PhyInfoPtr->PhyRegs[MII_BROADCOM_EXTENDED_REG_ADDRESS])
+ && (Register & BROADCOM_EXT_REG_FORCE_FAIL_EN_MASK)
+ && (Register & BROADCOM_EXT_REG_SPEED_MASK)
+ && !( PhyInfoPtr->PhyRegs[MII_BROADCOM_EXTENDED_REG_ADDRESS]
+ & BROADCOM_EXT_REG_SPEED_MASK
+ )
+ ) {
+ // Speed has changed :
+ // reset the PHY and restore the old control value
+#if MII_DBG
+ DbgPrint("Speed has changed; reset PHY and restore old ctrl value\n");
+#endif
+ PhyInfoPtr->PhyExtRoutines.PhyAdminControl(
+ Adapter,
+ PhyInfoPtr,
+ MiiGenAdminReset
+ );
+ PhyInfoPtr->PhyIntRoutines.PhyWriteRegister(
+ Adapter,
+ PhyInfoPtr,
+ PhyControlReg,
+ PhyInfoPtr->PhyRegs[PhyControlReg]
+ );
+ }
+ PhyInfoPtr->PhyRegs[MII_BROADCOM_EXTENDED_REG_ADDRESS] = Register;
+
+ return;
+}
+
+
+
+
+
+
+/*+
+ *
+ * GetBroadcomPhyConnectionType
+ *
+ * Description:
+ *
+ * Returns connection type, which may be one of the following:
+ * T4
+ * Tp
+ * TpFD
+ *
+ * Input parameters:
+ *
+ * PhyInfoPtr - PMII_PHY_INFO pointer to struct with PHY info
+ *
+ * Output parameters:
+ *
+ * Connection - ConnectionType
+ *
+ * On return
+ * Returns TRUE if
+ *
+-*/
+extern
+BOOLEAN
+GetBroadcomPhyConnectionType(
+ PDC21X4_ADAPTER Adapter,
+ PMII_PHY_INFO PhyInfoPtr,
+ PUSHORT Connection
+ )
+{
+
+ USHORT Register;
+
+#if MII_DBG
+ DbgPrint("GetBroadcomPhyConnectionType\n");
+#endif
+ if (!PhyInfoPtr->PhyIntRoutines.PhyReadRegister(
+ Adapter,
+ PhyInfoPtr,
+ MII_BROADCOM_EXTENDED_REG_ADDRESS,
+ &Register
+ )) {
+ return FALSE;
+ }
+
+ if ((Register & BROADCOM_EXT_REG_FORCE_FAIL_EN_MASK) == 0){
+ return FALSE;
+ }
+
+ if (!PhyInfoPtr->PhyIntRoutines.PhyReadRegister(
+ Adapter,
+ PhyInfoPtr,
+ PhyControlReg,
+ &(PhyInfoPtr->PhyRegs[PhyControlReg])
+ )) {
+ return FALSE;
+ }
+
+ if (Register & BROADCOM_EXT_REG_SPEED_MASK){
+ // Speed is 100Mbps
+ *Connection = MediumMii100BaseT4;
+ }
+ else {
+ // Speed is 10Mbps
+ *Connection =
+ (PhyInfoPtr->PhyRegs[PhyControlReg] & MiiPhyCtrlDuplexMode) ?
+ MediumMii10BaseTFullDuplex : MediumMii10BaseT;
+ }
+
+ if (PhyInfoPtr->PhyRegs[PhyControlReg] & MiiPhyCtrlEnableNway) {
+ *Connection |= (MEDIA_AUTOSENSE | MEDIA_NWAY);
+ }
+#if MII_DBG
+ DbgPrint("ConnectionType= %04x\n", *Connection);
+#endif
+
+ return TRUE;
+}
+
diff --git a/private/ntos/ndis/dc21x4/monitor.c b/private/ntos/ndis/dc21x4/monitor.c
new file mode 100644
index 000000000..fafb162e2
--- /dev/null
+++ b/private/ntos/ndis/dc21x4/monitor.c
@@ -0,0 +1,354 @@
+/*+
+ * file: monitor.c
+ *
+ * Copyright (C) 1992-1995 by
+ * Digital Equipment Corporation, Maynard, Massachusetts.
+ * All rights reserved.
+ *
+ * This software is furnished under a license and may be used and copied
+ * only in accordance of the terms of such license and with the
+ * inclusion of the above copyright notice. This software or any other
+ * copies thereof may not be provided or otherwise made available to any
+ * other person. No title to and ownership of the software is hereby
+ * transferred.
+ *
+ * The information in this software is subject to change without notice
+ * and should not be construed as a commitment by digital equipment
+ * corporation.
+ *
+ * Digital assumes no responsibility for the use or reliability of its
+ * software on equipment which is not supplied by digital.
+ *
+ *
+ * Abstract: This file is part of the NDIS 4.0 miniport driver for DEC's
+ * DC21X4 Ethernet adapter.
+ *
+ * Author: Philippe Klein
+ *
+ * Revision History:
+ *
+ * phk 28-Aug-1994 initial entry
+ *
+-*/
+
+#include <precomp.h>
+
+
+
+
+
+/*+
+ *
+ * DC21X4ModerateInterrupt
+ *
+ * Routine Description:
+ *
+ * Enable/Disable Rcv & Txm interrups based on the
+ * Rcv+Txm frames/second rate
+ *
+ * Arguments:
+ *
+ * Adapter
+ *
+-*/
+extern
+VOID
+DC21X4ModerateInterrupt (
+ IN PVOID Systemspecific1,
+ IN PDC21X4_ADAPTER Adapter,
+ IN PVOID Systemspecific2,
+ IN PVOID Systemspecific3
+ )
+{
+
+ INT FrameCount;
+ INT FrameRate;
+ INT InterruptRate;
+ ULONG CFDA_Data;
+
+
+ //snapshot the number of frames processed and the number of
+ // interrupt handled during the last monitor interval
+
+ FrameCount = Adapter->GeneralMandatory[GM_RECEIVE_OK]
+ + Adapter->GeneralMandatory[GM_RECEIVE_ERROR]
+ + Adapter->GeneralMandatory[GM_TRANSMIT_OK]
+ + Adapter->GeneralMandatory[GM_TRANSMIT_ERROR];
+
+ FrameRate = FrameCount - Adapter->FrameCount;
+
+ InterruptRate = Adapter->InterruptCount - Adapter->LastInterruptCount;
+
+ //save the snapshots
+
+ Adapter->FrameCount = FrameCount;
+ Adapter->LastInterruptCount = Adapter->InterruptCount;
+
+
+ if (InterruptRate > Adapter->InterruptThreshold) {
+ switch (Adapter->InterruptModeration) {
+
+ case NoInterruptMasked:
+
+ //Mask the Txm Interrupts
+ Adapter->InterruptModeration = TxmInterruptMasked;
+
+ Adapter->InterruptMask &= ~(DC21X4_TXM_INTERRUPTS);
+
+ DC21X4_WRITE_PORT(
+ DC21X4_INTERRUPT_MASK,
+ Adapter->InterruptMask
+ );
+
+ //Start the built_in timer to poll the Txm descriptor ring
+
+ // If the adapter is in Snooze mode,
+ // switch to regular mode to enable the
+ // built-in timer
+
+ if (Adapter->PciDriverArea & CFDA_SNOOZE_MODE) {
+
+ CFDA_Data = Adapter->PciDriverArea & ~CFDA_SNOOZE_MODE;
+
+ NdisWritePciSlotInformation(
+ Adapter->MiniportAdapterHandle,
+ Adapter->SlotNumber,
+ PCI_CFDA_OFFSET,
+ &CFDA_Data,
+ sizeof(CFDA_Data)
+ );
+ }
+
+ Adapter->Polling = Adapter->TxmPolling;
+ DC21X4_WRITE_PORT(
+ DC21X4_TIMER,
+ Adapter->Polling
+ );
+ break;
+
+ case TxmInterruptMasked:
+
+ //Mask the Rcv Interrupts
+ Adapter->InterruptModeration = TxmRcvInterruptMasked;
+
+ Adapter->InterruptMask &= ~(DC21X4_RCV_INTERRUPTS);
+
+ DC21X4_WRITE_PORT(
+ DC21X4_INTERRUPT_MASK,
+ Adapter->InterruptMask
+ );
+
+ //Restart the built_in timer to poll the Rcv & Txm descriptor rings
+
+ Adapter->Polling = Adapter->RcvTxmPolling;
+ DC21X4_WRITE_PORT(
+ DC21X4_TIMER,
+ Adapter->Polling
+ );
+ break;
+ }
+
+ }
+
+ else if (FrameRate < Adapter->FrameThreshold) {
+ switch (Adapter->InterruptModeration) {
+
+ case TxmRcvInterruptMasked:
+
+ //Demask the Rcv Interrupts
+
+ Adapter->InterruptModeration = TxmInterruptMasked;
+
+ Adapter->InterruptMask |= DC21X4_RCV_INTERRUPTS;
+
+ DC21X4_WRITE_PORT(
+ DC21X4_INTERRUPT_MASK,
+ Adapter->InterruptMask
+ );
+
+ //Restart the built_in timer to poll the Txm descriptor ring
+ Adapter->Polling = Adapter->TxmPolling;
+ DC21X4_WRITE_PORT(
+ DC21X4_TIMER,
+ Adapter->Polling
+ );
+ break;
+
+ case TxmInterruptMasked:
+
+ //Demask the Txm Interrupts
+ Adapter->InterruptModeration = NoInterruptMasked;
+
+ Adapter->InterruptMask |= DC21X4_TXM_INTERRUPTS;
+
+ DC21X4_WRITE_PORT(
+ DC21X4_INTERRUPT_MASK,
+ Adapter->InterruptMask
+ );
+
+ //Stop the Polling timer
+
+ Adapter->Polling = 0;
+
+ DC21X4_WRITE_PORT(
+ DC21X4_TIMER,
+ Adapter->Polling
+ );
+
+ if (Adapter->PciDriverArea & CFDA_SNOOZE_MODE) {
+
+ //set to the initial snooze mode
+
+ NdisWritePciSlotInformation(
+ Adapter->MiniportAdapterHandle,
+ Adapter->SlotNumber,
+ PCI_CFDA_OFFSET,
+ &Adapter->PciDriverArea,
+ sizeof(Adapter->PciDriverArea)
+ );
+ }
+
+ break;
+ }
+
+ }
+
+ //Restart the interrupt monitor timer
+
+ NdisMSetTimer(
+ &Adapter->MonitorTimer,
+ INT_MONITOR_PERIOD
+ );
+
+ }
+
+
+
+
+
+ /*+
+ *
+ * DC21X4CheckforHang
+ *
+ * Routine Description:
+ *
+ * The DC21X4CheckforHang routine verifies that no unprocessed descriptor
+ * are left due to the interrupt synchronization on PCI where the
+ * interrupt posted by DC21X4 can be handled before the associated
+ * descriptor has been effectively closed into memory.
+ *
+ * The algorithm is as follows:
+ *
+ * if "current" Rx descriptor is owned by the host
+ * if current Rx_frame_count == snapshoted Rx_frame_count
+ * generate an interrupt
+ * else
+ * snashots the current Rx_frame_count
+ *
+ * if "current" Tx descriptor is owned by the host
+ * if current Tx_frame_count == snapshoted Tx_frame_count
+ * generate an interrupt
+ * else
+ * snashots the current Tx_frame_count
+ *
+ * Arguments:
+ *
+ * Adapter
+ *
+ * Return Value:
+ *
+ * None
+ *
+ -*/
+ extern
+ BOOLEAN
+ DC21X4CheckforHang(
+ IN NDIS_HANDLE MiniportAdapterContext
+ )
+ {
+
+ PDC21X4_ADAPTER Adapter;
+ INT TransmitFrameCount;
+ INT ReceiveFrameCount;
+
+ PDC21X4_RECEIVE_DESCRIPTOR ReceiveDescriptor;
+ PDC21X4_TRANSMIT_DESCRIPTOR TransmitDescriptor;
+
+ BOOLEAN GenerateInterrupt = FALSE;
+
+ Adapter = (PDC21X4_ADAPTER)MiniportAdapterContext;
+
+ if (Adapter->Polling) {
+ return FALSE;
+ }
+
+ ReceiveDescriptor = Adapter->DequeueReceiveDescriptor;
+
+ if ((ReceiveDescriptor->Status & DC21X4_RDES_OWN_BIT) == DESC_OWNED_BY_SYSTEM ) {
+
+ ReceiveFrameCount = Adapter->GeneralMandatory[GM_RECEIVE_OK]
+ + Adapter->GeneralMandatory[GM_RECEIVE_ERROR];
+
+ GenerateInterrupt = (ReceiveFrameCount == Adapter->ReceiveFrameCount);
+
+ Adapter->ReceiveFrameCount = ReceiveFrameCount;
+
+ }
+
+ TransmitDescriptor = Adapter->DequeueTransmitDescriptor;
+
+ if (Adapter->GeneralOptional[GO_TRANSMIT_QUEUE_LENGTH] &&
+ ((TransmitDescriptor->Status & DC21X4_TDES_OWN_BIT) == DESC_OWNED_BY_SYSTEM)) {
+
+ TransmitFrameCount = Adapter->GeneralMandatory[GM_TRANSMIT_OK]
+ + Adapter->GeneralMandatory[GM_TRANSMIT_ERROR];
+
+ GenerateInterrupt = GenerateInterrupt ||
+ (TransmitFrameCount == Adapter->TransmitFrameCount);
+
+ Adapter->TransmitFrameCount = TransmitFrameCount;
+
+ }
+
+ if (GenerateInterrupt) {
+
+
+ switch (Adapter->DeviceId) {
+
+ case DC21040_CFID:
+
+ //Stop/start the Txm process to generate an Txm interrupt
+#if _DBG
+ DbgPrint("Stop/Start Txm\n");
+#endif
+ DC21X4_WRITE_PORT(
+ DC21X4_OPERATION_MODE,
+ Adapter->OperationMode & ~(DC21X4_TXM_START)
+ );
+
+ DC21X4_WRITE_PORT(
+ DC21X4_OPERATION_MODE,
+ Adapter->OperationMode
+ );
+ break;
+
+ default:
+
+ // Start the DC21X4 built_in timer to generate
+ // an Timer_expired interrupt
+
+ DC21X4_WRITE_PORT(
+ DC21X4_TIMER,
+ 1
+ );
+
+ }
+
+ }
+
+ return FALSE;
+
+ }
+
+
+
diff --git a/private/ntos/ndis/dc21x4/precomp.h b/private/ntos/ndis/dc21x4/precomp.h
new file mode 100644
index 000000000..147d76a53
--- /dev/null
+++ b/private/ntos/ndis/dc21x4/precomp.h
@@ -0,0 +1,9 @@
+#include <ndis.h>
+#include <efilter.h>
+#include <mii.h>
+#include <d21x4det.h>
+#include <d21x4hrd.h>
+#include <d21x4def.h>
+#include <d21x4fct.h>
+#include <d21x4oid.h>
+
diff --git a/private/ntos/ndis/dc21x4/register.c b/private/ntos/ndis/dc21x4/register.c
new file mode 100644
index 000000000..113d34b3f
--- /dev/null
+++ b/private/ntos/ndis/dc21x4/register.c
@@ -0,0 +1,2469 @@
+/*+
+ * file: register.c
+ *
+ * Copyright (C) 1992-1995 by
+ * Digital Equipment Corporation, Maynard, Massachusetts.
+ * All rights reserved.
+ *
+ * This software is furnished under a license and may be used and copied
+ * only in accordance of the terms of such license and with the
+ * inclusion of the above copyright notice. This software or any other
+ * copies thereof may not be provided or otherwise made available to any
+ * other person. No title to and ownership of the software is hereby
+ * transferred.
+ *
+ * The information in this software is subject to change without notice
+ * and should not be construed as a commitment by digital equipment
+ * corporation.
+ *
+ * Digital assumes no responsibility for the use or reliability of its
+ * software on equipment which is not supplied by digital.
+ *
+ *
+ * Abstract: This file contains the Adapter Registration code of the
+ * NDIS 4.0 miniport driver for DEC's DC21X4 Ethernet Adapter
+ * family.
+ *
+ * Author: Philippe Klein
+ *
+ * Revision History:
+ *
+ * phk 31-Jul-95 Initial entry
+ * phk 12-Jan-95 V2.0 Add DC21041
+ * Add Win95 and PowerPC fixes to the miniport
+ * phk 20-Feb-95 Add "sonic" callback for MIPS platforms
+ * phk 23-Feb-95 Fix MediaType retrieval from Eisa ECU data
+ *
+-*/
+
+#include <precomp.h>
+#include <d21x4rgs.h>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#ifdef _MIPS_
+
+// Global variables used to keep track of the
+// last multi-function adapter found.
+
+UINT MultifunctionAdapterNumber = 0;
+UINT ControllerNumber = 0;
+
+#endif
+
+#pragma NDIS_PAGABLE_FUNCTION(DC21X4Initialize)
+
+/*+
+ * DC21X4Initialize
+ *
+ * Routine Description:
+ *
+ * DC21X4Initialize is called to have the Miniport driver
+ * initialize the adapter
+ *
+-*/
+
+extern
+NDIS_STATUS
+DC21X4Initialize(
+ OUT PNDIS_STATUS OpenErrorStatus,
+ OUT PUINT SelectedMediumIndex,
+ IN PNDIS_MEDIUM MediumArray,
+ IN UINT MediumArraySize,
+ IN NDIS_HANDLE MiniportAdapterHandle,
+ IN NDIS_HANDLE WrapperConfigurationHandle
+ )
+{
+ NDIS_HANDLE ConfigurationHandle;
+ NDIS_STATUS NdisStatus;
+ PDC21X4_ADAPTER Adapter;
+
+ PNDIS_CONFIGURATION_PARAMETER Configuration;
+ PUCHAR NetworkAddress;
+ UCHAR SWNetworkAddress[6];
+ UINT NetworkAddressLength;
+ ULONG InterruptVector;
+ ULONG InterruptLevel;
+
+ UINT MapRegisterCount;
+
+ NDIS_INTERRUPT_MODE InterruptMode = NdisInterruptLevelSensitive;
+
+ NDIS_EISA_FUNCTION_INFORMATION EisaData;
+
+ DC21X4_CONFIGURATION DC21X4Configuration[MAX_RGS];
+ DC21X4_PCI_CONFIGURATION DC21X4PciConfiguration;
+
+ USHORT IntPort;
+ USHORT PciCFCSPort;
+ USHORT PciCFLTPort;
+ USHORT BusModePort;
+ USHORT SiaPort;
+
+ PUCHAR BytePtr;
+
+ UCHAR InitType;
+
+ ULONG PortValue;
+ ULONG PortAddress;
+ ULONG Mask;
+ ULONG Mode;
+
+ UCHAR PortWidth;
+ UCHAR UseMask;
+
+ UCHAR Value;
+
+ UINT Irq[4] = { 5, 9, 10, 11};
+ UINT Width[4] = {sizeof(UCHAR), sizeof(USHORT), sizeof(ULONG), 1};
+
+ UINT i;
+
+ BOOLEAN Link=FALSE;
+ BOOLEAN StartTimer=TRUE;
+
+#if __DBG
+ DbgPrint ("\nDC21X4Initialize\n");
+#endif
+
+ // Search for the 802.3 media type in the Medium Array
+
+ for (i=0; i<MediumArraySize; i++) {
+
+ if (MediumArray[i] == NdisMedium802_3)
+ break;
+ }
+
+ if (i == MediumArraySize) {
+ return NDIS_STATUS_UNSUPPORTED_MEDIA;
+ }
+
+ *SelectedMediumIndex = i;
+
+#if __DBG
+ DbgPrint("Media = 802_3\n");
+#endif
+
+
+ // Allocate and initialize the Adapter block
+
+ ALLOC_MEMORY (&NdisStatus, &Adapter, sizeof(DC21X4_ADAPTER));
+ if (NdisStatus != NDIS_STATUS_SUCCESS) {
+ // Cannot allocate the adapter
+ return NdisStatus;
+ }
+#if __DBG
+ DbgPrint("Adapter block &%08x %d bytes\n",&Adapter,sizeof(DC21X4_ADAPTER));
+#endif
+ ZERO_MEMORY (Adapter,sizeof(DC21X4_ADAPTER));
+
+ Adapter->Initializing = TRUE;
+ Adapter->MiniportAdapterHandle = MiniportAdapterHandle;
+
+ // Initialize the DC21X4 Csr Configuration array
+
+ ZERO_MEMORY (DC21X4Configuration, sizeof(DC21X4Configuration));
+
+ DC21X4Configuration[RGS_CFCS].CsrValue = DC21X4_PCI_COMMAND_DEFAULT_VALUE;
+
+ DC21X4Configuration[RGS_BLEN].RegistryValue = DC21X4_BURST_LENGTH_DEFAULT_VALUE;
+ DC21X4Configuration[RGS_RCVR].RegistryValue = DC21X4_RECEIVE_RING_SIZE;
+ DC21X4Configuration[RGS_ITHR].RegistryValue = DC21X4_MSK_THRESHOLD_DEFAULT_VALUE;
+ DC21X4Configuration[RGS_FTHR].RegistryValue = DC21X4_FRAME_THRESHOLD_DEFAULT_VALUE;
+
+ DC21X4Configuration[RGS_UTHR].RegistryValue = DC21X4_UNDERRUN_THRESHOLD;
+ DC21X4Configuration[RGS_UNDR].RegistryValue = DC21X4_UNDERRUN_MAX_RETRIES;
+
+ DC21X4Configuration[RGS_SNOO].RegistryValue = 0;
+ DC21X4Configuration[RGS_NWAY].RegistryValue = 1;
+
+ // Open the configuration info.
+
+#if __DBG
+ DbgPrint ("NdisOpenConfiguration\n");
+#endif
+
+ NdisOpenConfiguration(
+ &NdisStatus,
+ &ConfigurationHandle,
+ WrapperConfigurationHandle
+ );
+ if (NdisStatus != NDIS_STATUS_SUCCESS) {
+ FREE_MEMORY(Adapter, sizeof(DC21X4_ADAPTER));
+ return NdisStatus;
+ }
+
+ // Query the Registry
+
+ for (i=0; i < MAX_RGS; i++ ) {
+
+ NdisReadConfiguration(
+ &NdisStatus,
+ &Configuration,
+ ConfigurationHandle,
+ &DC21X4ConfigString[i],
+ NdisParameterHexInteger
+ );
+
+ if (NdisStatus == NDIS_STATUS_SUCCESS) {
+
+ DC21X4Configuration[i].Present = TRUE;
+ DC21X4Configuration[i].RegistryValue =
+ Configuration->ParameterData.IntegerData;
+#if __DBG
+ DbgPrint("Registry[%2d]=%x\n",
+ i,DC21X4Configuration[i].RegistryValue);
+#endif
+ }
+
+ }
+
+
+ // Check that our adapter type is supported.
+
+ if (DC21X4Configuration[RGS_ADPT].Present) {
+ Adapter->AdapterType = DC21X4Configuration[RGS_ADPT].RegistryValue;
+ }
+ else {
+ NdisWriteErrorLogEntry(
+ MiniportAdapterHandle,
+ NDIS_ERROR_CODE_UNSUPPORTED_CONFIGURATION,
+ 1,
+ DC21X4_ERRMSG_REGISTRY
+ );
+ FreeAdapterResources(Adapter,1);
+ return NdisStatus;
+ }
+
+ switch (Adapter->AdapterType) {
+
+ case NdisInterfacePci:
+
+ break;
+
+
+ case NdisInterfaceEisa:
+
+ // Read the EISA Slot Information block
+#if __DBG
+ DbgPrint ("ReadEisaSlotInformation\n");
+#endif
+ NdisReadEisaSlotInformation(
+ &NdisStatus,
+ WrapperConfigurationHandle,
+ &Adapter->SlotNumber,
+ &EisaData
+ );
+
+ if (NdisStatus != NDIS_STATUS_SUCCESS) {
+#if __DBG
+ DbgPrint("DC21X4: Could not read EISA Config data\n");
+#endif
+ NdisCloseConfiguration(ConfigurationHandle);
+ FREE_MEMORY(Adapter, sizeof(DC21X4_ADAPTER));
+ return NdisStatus;
+ }
+
+ // Now we walk through the Eisa Initialization Data block to
+ // read the interrupt information.
+ // Initalization Data entry format:
+ //
+ // Byte 0 : Initialization Type
+ // bit<7> = 0 - Last Entry
+ // 1 - More entries to follow
+ // bit<2> = Port Value or Mask Value
+ // 0 - write value to port
+ // 1 - use mask and value
+ // bit<1:0> = Type of access
+ // 00 byte address
+ // 01 word address
+ // 10 lword address
+ // Byte 1 = LSByte of port I/O address
+ // Byte 2 = MSByte of port I/O address
+ // if Byte_0<2> = 0 (no mask) then
+ // Byte_0<1:0> = Port width to write
+ // 00 Byte 3 = Port Value
+ // 01 Byte 3-4 = Port Value
+ // 10 Byte 3-6 = Port Value
+ // if Byte_0<2> = 1 (use mask) then
+ // Byte_0<1:0> = width of port value and mask
+ // 00 Byte 3 = Port Value
+ // Byte 4 = Port Mask
+ // 01 Byte 3-4 = Port Value
+ // Byte 5-6 = Port Mask
+ // 10 Byte 3-6 = Port Value
+ // Byte 7-10 = Port Mask
+
+ BytePtr = (PUCHAR)EisaData.InitializationData;
+ PciCFCSPort= (USHORT)(Adapter->SlotNumber << SLOT_NUMBER_OFFSET) + EISA_CFCS_OFFSET;
+ PciCFLTPort= (USHORT)(Adapter->SlotNumber << SLOT_NUMBER_OFFSET) + EISA_CFLT_OFFSET;
+ IntPort = (USHORT)(Adapter->SlotNumber << SLOT_NUMBER_OFFSET) + EISA_REG0_OFFSET;
+ BusModePort= (USHORT)(Adapter->SlotNumber << SLOT_NUMBER_OFFSET) + EISA_CFGSCR1_OFFSET;
+ SiaPort = (USHORT)(Adapter->SlotNumber << SLOT_NUMBER_OFFSET) + EISA_CFGSCR2_OFFSET;
+
+ do {
+
+#if __DBG
+ DbgPrint("BytePtr = %x \n", BytePtr);
+#endif
+ InitType = *(BytePtr++);
+
+ UseMask = InitType & 0x04;
+ PortWidth = InitType & 0x03;
+
+ PortAddress = *(UNALIGNED USHORT *)(BytePtr);
+ (ULONG)BytePtr += sizeof(USHORT);
+
+ PortValue = 0;
+ MOVE_MEMORY(&PortValue,BytePtr,Width[PortWidth]);
+ (ULONG)BytePtr += Width[PortWidth];
+
+ Mask = 0;
+ if (UseMask) {
+ MOVE_MEMORY(&Mask,BytePtr,Width[PortWidth]);
+ (ULONG)BytePtr += Width[PortWidth];
+ }
+#if __DBG
+ DbgPrint("InitType = %x PortAddress = %08x Value=%x Mask=%x\n",
+ InitType,PortAddress,PortValue,Mask);
+#endif
+ if (PortAddress == IntPort) {
+
+ Value = ((UCHAR)PortValue & ~(UCHAR)Mask);
+
+ InterruptVector = Irq[(Value & 0x06) >> IRQ_BIT_NUMBER];
+ InterruptLevel = InterruptVector;
+
+ InterruptMode = (Value & 0x01) ?
+ NdisInterruptLatched : NdisInterruptLevelSensitive;
+
+#if __DBG
+ DbgPrint("Eisa data: InterruptVector = %d\n",InterruptVector);
+ DbgPrint(" InterruptLevel = %d\n",InterruptLevel);
+ DbgPrint(" InterruptMode = %d\n",InterruptMode);
+#endif
+ }
+ else if (PortAddress == PciCFCSPort) {
+
+ if (!DC21X4Configuration[RGS_CFCS].Present) {
+ DC21X4Configuration[RGS_CFCS].CsrValue = PortValue;
+#if __DBG
+ DbgPrint("Eisa CFCS = %08x\n",DC21X4Configuration[RGS_CFCS].CsrValue);
+#endif
+ }
+
+ }
+ else if (PortAddress == PciCFLTPort) {
+
+ if (!DC21X4Configuration[RGS_CFLT].Present) {
+ DC21X4Configuration[RGS_CFLT].CsrValue = PortValue;
+#if __DBG
+ DbgPrint("Eisa CFLT = %08x\n",DC21X4Configuration[RGS_CFLT].CsrValue);
+#endif
+ }
+ }
+ else if (PortAddress == BusModePort) {
+ Adapter->BusMode = PortValue;
+#if __DBG
+ DbgPrint("Eisa CSR0 = %08x\n",PortValue);
+#endif
+ }
+ else if (PortAddress == SiaPort) {
+
+ switch (PortValue) {
+
+ default:
+ case DC21X4_AUTOSENSE_FLG:
+
+ DC21X4Configuration[RGS_CNCT].RegistryValue = 0; //AutoSense
+ break;
+
+ case DC21X4_10B2_FLG:
+
+ DC21X4Configuration[RGS_CNCT].RegistryValue = 1; //BNC
+ break;
+
+ case DC21X4_FULL_DUPLEX_FLG:
+
+ DC21X4Configuration[RGS_CNCT].RegistryValue = 3; //TpFD
+ break;
+
+ case DC21X4_LINK_DISABLE_FLG:
+
+ DC21X4Configuration[RGS_CNCT].RegistryValue = 4; //TpNLT
+ break;
+
+ case DC21X4_10B5_FLG:
+
+ DC21X4Configuration[RGS_CNCT].RegistryValue = 5; //AUI
+ break;
+
+ }
+ }
+
+ } while (InitType & 0x80);
+
+ break;
+
+ default:
+
+ // This adapter type is not supported by this driver
+#if __DBG
+ DbgPrint("DC21X4: Unsupported adapter type: %lx\n", Configuration->ParameterData.IntegerData);
+#endif
+ NdisWriteErrorLogEntry(
+ MiniportAdapterHandle,
+ NDIS_ERROR_CODE_UNSUPPORTED_CONFIGURATION,
+ 1,
+ DC21X4_ERRMSG_REGISTRY
+ );
+ NdisCloseConfiguration(ConfigurationHandle);
+ FreeAdapterResources(Adapter,1);
+ return NDIS_STATUS_FAILURE;
+ }
+
+ // Adapter CFID
+
+ if (!DC21X4Configuration[RGS_CFID].Present) {
+#if __DBG
+ DbgPrint("DC21X4: AdapterCfid is missing into the Registry\n");
+#endif
+ NdisCloseConfiguration(ConfigurationHandle);
+ FREE_MEMORY(Adapter, sizeof(DC21X4_ADAPTER));
+ return NDIS_STATUS_FAILURE;
+ }
+ Adapter->DeviceId = DC21X4Configuration[RGS_CFID].RegistryValue;
+#if __DBG
+ DbgPrint ("Registry(Cfid)=%x\n",Adapter->DeviceId);
+#endif
+
+ // PCI registers
+
+ if (DC21X4Configuration[RGS_CFCS].Present) {
+ DC21X4Configuration[RGS_CFCS].CsrValue =
+ DC21X4Configuration[RGS_CFCS].RegistryValue;
+ }
+ if (DC21X4Configuration[RGS_CFLT].Present) {
+ DC21X4Configuration[RGS_CFLT].CsrValue =
+ DC21X4Configuration[RGS_CFLT].RegistryValue;
+ }
+
+ // Bus Mode register
+
+
+ if (DC21X4Configuration[RGS_BLEN].Present) {
+
+ // Valid Burst length values are 1,2,4,8,16 & 32 (DC2114x only)
+ switch (DC21X4Configuration[RGS_BLEN].RegistryValue) {
+
+ case 1:
+ case 2:
+ case 4:
+ case 8:
+ case 16:
+
+ break;
+
+ case 32:
+
+ if ( (Adapter->DeviceId == DC21040_CFID)
+ ||(Adapter->DeviceId == DC21041_CFID)) {
+
+ //max burst limit = 16 LW
+ DC21X4Configuration[RGS_BLEN].RegistryValue = 16;
+ }
+ break;
+
+ default:
+ DC21X4Configuration[RGS_BLEN].RegistryValue = DC21X4_BURST_LENGTH_DEFAULT_VALUE;
+ }
+ }
+
+ Adapter->BusMode &= ~(DC21X4_BURST_LENGTH);
+ Adapter->BusMode |=
+ (DC21X4Configuration[RGS_BLEN].RegistryValue << BURST_LENGTH_BIT_NUMBER);
+#if __DBG
+ DbgPrint ("Burst Length = %d LW\n",DC21X4Configuration[RGS_BLEN].RegistryValue);
+#endif
+
+ if (DC21X4Configuration[RGS_FARB].Present) {
+
+ Adapter->BusMode &= ~(DC21X4_BUS_ARBITRATION);
+ Adapter->BusMode |=
+ (DC21X4Configuration[RGS_FARB].RegistryValue << BUS_ARBITRATION_BIT_NUMBER);
+#if __DBG
+ DbgPrint ("Bus Arbitration = %x\n",DC21X4Configuration[RGS_FARB].RegistryValue);
+#endif
+ }
+
+ if (DC21X4Configuration[RGS_PLDM].Present) {
+#if __DBG
+ DbgPrint ("Poll Demand = %x\n",DC21X4Configuration[RGS_PLDM].RegistryValue);
+#endif
+ // Initialize the Txm Automatic Poll Demand field
+
+ Adapter->BusMode |=
+ (DC21X4Configuration[RGS_PLDM].RegistryValue << AUTO_POLLING_BIT_NUMBER);
+ }
+
+ // Read the network address from the Registry
+#if __DBG
+ DbgPrint ("NdisReadNetworkAddress\n");
+#endif
+
+ NdisReadNetworkAddress(
+ &NdisStatus,
+ (PVOID *)&NetworkAddress,
+ &NetworkAddressLength,
+ ConfigurationHandle
+ );
+
+ // Check if we get a valid network address
+
+ if ((NdisStatus == NDIS_STATUS_SUCCESS)
+ && (NetworkAddressLength == ETH_LENGTH_OF_ADDRESS)
+ && !(IS_NULL_ADDRESS(NetworkAddress))
+ ){
+ MOVE_MEMORY(
+ &SWNetworkAddress[0],
+ NetworkAddress,
+ ETH_LENGTH_OF_ADDRESS
+ );
+ NetworkAddress = &SWNetworkAddress[0];
+#if __DBG
+ DbgPrint("Network address from registry = %.2x-%.2x-%.2x-%.2x-%.2x-%.2x\n",
+ *(NetworkAddress),*(NetworkAddress+1),*(NetworkAddress+2),
+ *(NetworkAddress+3),*(NetworkAddress+4),*(NetworkAddress+5));
+#endif
+ }
+ else {
+ // no SW configured network address available
+ NetworkAddress = NULL;
+ }
+
+ // Close the Configuration
+#if __DBG
+ DbgPrint ("NdisCloseConfiguration\n");
+#endif
+ NdisCloseConfiguration(ConfigurationHandle);
+
+
+ // Register the Adapter Type
+#if __DBG
+ DbgPrint ("NdisMSetAttributes AdapterContext =%x\n",Adapter);
+#endif
+
+ NdisMSetAttributes(
+ MiniportAdapterHandle,
+ Adapter,
+ TRUE,
+ Adapter->AdapterType
+ );
+
+
+ switch (Adapter->AdapterType) {
+
+ case NdisInterfacePci:
+
+ Adapter->SlotNumber = DC21X4Configuration[RGS_DEVN].RegistryValue;
+
+ NdisReadPciSlotInformation(
+ MiniportAdapterHandle,
+ Adapter->SlotNumber,
+ PCI_CFID_OFFSET,
+ &DC21X4PciConfiguration,
+ sizeof(ULONG)
+ );
+
+ if (DC21X4PciConfiguration.Reg[CFID] !=
+ DC21X4Configuration[RGS_CFID].RegistryValue) {
+#if __DBG
+ DbgPrint("Adapter's CFID [%x] does not match Registry's CFID [%x] !!\n",
+ DC21X4PciConfiguration.Reg[CFID],
+ DC21X4Configuration[RGS_CFID].RegistryValue);
+#endif
+ NdisWriteErrorLogEntry(
+ MiniportAdapterHandle,
+ NDIS_ERROR_CODE_ADAPTER_NOT_FOUND,
+ 0
+ );
+ FreeAdapterResources(Adapter,1);
+ return NDIS_STATUS_ADAPTER_NOT_FOUND;
+ }
+
+ NdisStatus = FindPciConfiguration(
+ MiniportAdapterHandle,
+ Adapter->SlotNumber,
+ &Adapter->IOBaseAddress,
+ &Adapter->IOSpace,
+ &InterruptLevel,
+ &InterruptVector
+ );
+
+ if (NdisStatus != NDIS_STATUS_SUCCESS) {
+ FREE_MEMORY(Adapter, sizeof(DC21X4_ADAPTER));
+ return NdisStatus;
+ }
+
+ NdisReadPciSlotInformation(
+ MiniportAdapterHandle,
+ Adapter->SlotNumber,
+ PCI_CFID_OFFSET,
+ &DC21X4PciConfiguration,
+ sizeof(DC21X4PciConfiguration)
+ );
+
+ InterruptMode = NdisInterruptLevelSensitive;
+
+#if __DBG
+ DbgPrint("SubSystem ID = %x\n", DC21X4PciConfiguration.Reg[SSID]);
+#endif
+
+ break;
+
+ case NdisInterfaceEisa:
+
+ Adapter->IOBaseAddress = (Adapter->SlotNumber << SLOT_NUMBER_OFFSET);
+
+ switch (Adapter->DeviceId) {
+
+ default:
+ case DC21040_CFID:
+
+ Adapter->IOSpace = EISA_DC21040_REGISTER_SPACE;
+ break;
+
+ case DC21140_CFID:
+
+ Adapter->IOSpace = EISA_DC21140_REGISTER_SPACE;
+ break;
+ }
+
+ }
+
+ // Register the IoPortRange
+
+#if __DBG
+ DbgPrint("NdisMRegisterIOPortRange\n");
+#endif
+ NdisStatus = NdisMRegisterIoPortRange(
+ (PVOID *)(&(Adapter->PortOffset)),
+ MiniportAdapterHandle,
+ Adapter->IOBaseAddress,
+ Adapter->IOSpace
+ );
+
+ if (NdisStatus != NDIS_STATUS_SUCCESS) {
+#if __DBG
+ DbgPrint(" Failed: Status = %x\n",NdisStatus);
+#endif
+ FREE_MEMORY(Adapter, sizeof(DC21X4_ADAPTER));
+ return NdisStatus;
+ }
+
+ //Map the adapter CSR addresses
+
+ switch (Adapter->AdapterType) {
+
+ case NdisInterfacePci:
+
+ for (i=0; i < DC21X4_MAX_CSR; i++) {
+ Adapter->CsrMap[i] = Adapter->PortOffset + (i * PCI_CSR_OFFSET);
+ }
+ break;
+
+ case NdisInterfaceEisa:
+
+ Adapter->PciRegMap[DC21X4_PCI_ID] = Adapter->PortOffset + EISA_CFID_OFFSET;
+ Adapter->PciRegMap[DC21X4_PCI_COMMAND] = Adapter->PortOffset + EISA_CFCS_OFFSET;
+ Adapter->PciRegMap[DC21X4_PCI_REVISION] = Adapter->PortOffset + EISA_CFRV_OFFSET;
+ Adapter->PciRegMap[DC21X4_PCI_LATENCY_TIMER] = Adapter->PortOffset + EISA_CFLT_OFFSET;
+ Adapter->PciRegMap[DC21X4_PCI_BASE_IO_ADDRESS] = Adapter->PortOffset + EISA_CBIO_OFFSET;
+
+ for (i=0; i < DC21X4_MAX_CSR; i++) {
+ Adapter->CsrMap[i] = Adapter->PortOffset + (i * EISA_CSR_OFFSET);
+ }
+
+ // Read DC21X4 Device_Id and Revision Number
+
+ DC21X4_READ_PCI_REGISTER(
+ DC21X4_PCI_ID,
+ &DC21X4PciConfiguration.Reg[CFID]
+ );
+#if __DBG
+ DbgPrint("PCI[Cfid]=%x\n",DC21X4PciConfiguration.Reg[CFID]);
+#endif
+
+ if (DC21X4PciConfiguration.Reg[CFID] !=
+ DC21X4Configuration[RGS_CFID].RegistryValue) {
+
+ NdisWriteErrorLogEntry(
+ MiniportAdapterHandle,
+ NDIS_ERROR_CODE_ADAPTER_NOT_FOUND,
+ 0
+ );
+
+ FreeAdapterResources(Adapter,2);
+ return NDIS_STATUS_ADAPTER_NOT_FOUND;
+ }
+
+ DC21X4_READ_PCI_REGISTER(
+ DC21X4_PCI_REVISION,
+ &DC21X4PciConfiguration.Reg[CFRV]
+ );
+
+ break;
+ }
+
+ Adapter->RevisionNumber =
+ DC21X4PciConfiguration.Reg[CFRV] & DC21X4_REVISION_ID;
+
+#if __DBG
+ DbgPrint("RevisionNumber= %x\n",Adapter->RevisionNumber);
+#endif
+
+
+
+ // Allocate the Map registers;
+ // if the number of map registers is not specified into the Registry,
+ // query the number of map registers supported by this platform
+ // and allocate 1/8th.
+ // The number of map register allocated to the adapter is casted
+ // to the range [DC21X4_MIN_MAP_REGISTERS,..,DC21X4_MAX_MAP_REGISTERS]
+
+ if (DC21X4Configuration[RGS_MAPR].Present) {
+ Adapter->AllocMapRegisters = DC21X4Configuration[RGS_MAPR].RegistryValue;
+ }
+ else {
+ NdisStatus = NdisQueryMapRegisterCount(
+ Adapter->AdapterType,
+ &MapRegisterCount
+ );
+
+ Adapter->AllocMapRegisters = (NdisStatus == NDIS_STATUS_SUCCESS) ?
+ MapRegisterCount/8 : DC21X4_MAX_MAP_REGISTERS;
+ }
+
+ Adapter->AllocMapRegisters =
+ max(min(Adapter->AllocMapRegisters,DC21X4_MAX_MAP_REGISTERS),DC21X4_MIN_MAP_REGISTERS);
+
+#if __DBG
+ DbgPrint("NdisMAllocateMapRegisters: allocate %d map registers)\n",
+ Adapter->AllocMapRegisters);
+#endif
+
+ NdisMAllocateMapRegisters(
+ MiniportAdapterHandle,
+ 0,
+ TRUE,
+ Adapter->AllocMapRegisters,
+ DC21X4_MAX_BUFFER_SIZE
+ );
+
+ Adapter->PhysicalSegmentThreshold =
+ min(Adapter->AllocMapRegisters,DC21X4_MAX_SEGMENTS);
+#if __DBG
+ DbgPrint("Txm Segment Threshold = %d\n",Adapter->PhysicalSegmentThreshold);
+#endif
+
+
+ if (DC21X4Configuration[RGS_ITMG].RegistryValue == 1) {
+
+ // normalize the Interrupt and Frame thresholds to rate/second
+
+ Adapter->InterruptThreshold =
+ max((ULONG)((DC21X4Configuration[RGS_ITHR].RegistryValue * INT_MONITOR_PERIOD) / 1000),1);
+
+ Adapter->FrameThreshold =
+ max((ULONG)((DC21X4Configuration[RGS_FTHR].RegistryValue * INT_MONITOR_PERIOD) / 1000),1);
+
+ // calculate the Rcv & Txm descriptor ring polling frequencies for the on board timer
+ // based on the interrupt threshold
+
+ Adapter->RcvTxmPolling = max((ULONG)(1000/Adapter->InterruptThreshold),1) * ONE_MILLISECOND_TICK;
+ Adapter->TxmPolling = Adapter->RcvTxmPolling * 10;
+ }
+
+ Adapter->TiPeriod = DC21X4Configuration[RGS_TI].RegistryValue;
+
+ Adapter->PciCommand = DC21X4Configuration[RGS_CFCS].CsrValue;
+
+ Adapter->InterruptMask = DC21X4_MSK_MSK_DEFAULT_VALUE;
+
+ switch (Adapter->DeviceId) {
+
+ case DC21142_CFID:
+
+ Adapter->InterruptMask |= DC21X4_MSK_GEP_INTERRUPT;
+ break;
+ }
+
+ Adapter->TransmitDefaultDescriptorErrorMask = DC21X4_TDES_ERROR_MASK;
+
+ Adapter->PciLatencyTimer = DC21X4Configuration[RGS_CFLT].CsrValue;
+
+ Adapter->PciDriverArea |=
+ (DC21X4Configuration[RGS_SNOO].RegistryValue == 1) ? CFDA_SNOOZE_MODE : 0;
+
+ Adapter->NwayProtocol = (BOOLEAN)DC21X4Configuration[RGS_NWAY].RegistryValue;
+
+ Adapter->UnderrunThreshold = DC21X4Configuration[RGS_UTHR].RegistryValue;
+ Adapter->UnderrunMaxRetries = DC21X4Configuration[RGS_UNDR].RegistryValue;
+#if __DBG
+ DbgPrint("UnderrunThreshold = %d \n", Adapter->UnderrunThreshold);
+ DbgPrint("UnderrunMaxRetries = %d \n",Adapter->UnderrunMaxRetries);
+#endif
+
+ Adapter->TransceiverDelay = (INT)DC21X4Configuration[RGS_TRNS].RegistryValue;
+
+ // Allocate memory for all of the adapter structures:
+ // Rcv & Txm Descriptor rings
+ // Rcv Buffers
+ // Setup Buffer
+
+ Adapter->ReceiveRingSize =
+ max(min(DC21X4Configuration[RGS_RCVR].RegistryValue,DC21X4_MAX_RECEIVE_RING_SIZE),DC21X4_MIN_RECEIVE_RING_SIZE);
+
+
+ // Get the number of extra receive buffers that we need to allocate.
+ // If this platform has scare Map registers ressources, and no
+ // ExtraReceiveBuffers is specified into the Registry,
+ // do not allocate any extra receive buffers
+
+ Adapter->ExtraReceiveBuffers = DC21X4Configuration[RGS_RCV_BUFS].Present ?
+ DC21X4Configuration[RGS_RCV_BUFS].RegistryValue :
+ (Adapter->AllocMapRegisters < DC21X4_MAX_MAP_REGISTERS) ? 0 :
+ Adapter->ReceiveRingSize;
+
+ // Get the number of extra packets that we need for receive indications.
+ // If this platform has scare Map registers ressources, and no
+ // ExtraReceivePackets is specified into the Registry,
+ // allocate just enough packets for the receive ring but not extra ones.
+
+ Adapter->ExtraReceivePackets = DC21X4Configuration[RGS_RCV_PKTS].Present ?
+ DC21X4Configuration[RGS_RCV_PKTS].RegistryValue :
+ (Adapter->AllocMapRegisters < DC21X4_MAX_MAP_REGISTERS) ?
+ Adapter->ReceiveRingSize : DC21X4_RECEIVE_PACKETS;
+
+ // Make sure that there are enough packets for the receive ring.
+
+ Adapter->ExtraReceivePackets =
+ max(Adapter->ExtraReceivePackets, (Adapter->ReceiveRingSize + Adapter->ExtraReceiveBuffers));
+
+
+ Adapter->FreeMapRegisters = Adapter->AllocMapRegisters;
+
+#if __DBG
+ DbgPrint("ReceiveRingSize = %d \n", Adapter->ReceiveRingSize);
+ DbgPrint("FreeMapRegisters = %d \n", Adapter->FreeMapRegisters);
+ DbgPrint("ExtraReceiveBuffers = %d \n", Adapter->ExtraReceiveBuffers);
+ DbgPrint("ExtraReceivePackets = %d \n", Adapter->ExtraReceivePackets);
+#endif
+
+ // Get the size of the Cache line
+ // Sizes supported by DC21X4 are 16,32,64 or 128 bytes.
+ // Default value is 64 bytes
+
+ if (DC21X4Configuration[RGS_CLSZ].Present) {
+ Adapter->CacheLineSize = DC21X4Configuration[RGS_CLSZ].RegistryValue;
+#if __DBG
+ DbgPrint("CacheLineSize from Registry = %d\n",Adapter->CacheLineSize);
+#endif
+ }
+ else {
+ Adapter->CacheLineSize = NdisGetCacheFillSize() * sizeof(ULONG);
+#if __DBG
+ DbgPrint("NdisGetCacheFillSize = %d\n",Adapter->CacheLineSize);
+#endif
+ }
+
+ switch (Adapter->CacheLineSize) {
+
+ case 64:
+ case 128:
+ break;
+
+ default:
+ Adapter->CacheLineSize = DC21X4_DEFAULT_CACHE_LINE_SIZE;
+#if __DBG
+ DbgPrint("CacheLineSize defaulted to %d\n",Adapter->CacheLineSize);
+#endif
+ }
+
+ // DC21X4 maximum mapping address is 32 bits
+
+ NdisSetPhysicalAddressLow(Adapter->HighestAllocAddress,0xffffffff);
+ NdisSetPhysicalAddressHigh(Adapter->HighestAllocAddress,0);
+
+ // To avoid multiple write to the same cache line,
+ // one descriptor only is loaded per cache line:
+ // DescriptorSize is the size of an descriptor entry into the
+ // descriptor ring.
+ // Minimum descriptor size is 64 to keep 12 longwords within the descriptor
+ // as reserved area for the driver.
+
+ Adapter->BusMode &= ~(DC21X4_SKIP_LENGTH | DC21X4_CACHE_ALIGNMENT);
+
+ switch (Adapter->CacheLineSize) {
+
+ default :
+
+ Adapter->DescriptorSize = 64;
+ Adapter->BusMode |= DC21X4_SKIP_64;
+ break;
+
+ case 128 :
+
+ Adapter->DescriptorSize = 128;
+ Adapter->BusMode |= DC21X4_SKIP_128;
+ break;
+ }
+
+ switch (DC21X4Configuration[RGS_BLEN].RegistryValue) {
+
+ case 8 :
+
+ Adapter->BusMode |= DC21X4_ALIGN_32;
+ break;
+
+ case 16 :
+
+ Adapter->BusMode |= DC21X4_ALIGN_64;
+ break;
+
+ default:
+ case 32 :
+
+ Adapter->BusMode |= DC21X4_ALIGN_128;
+ break;
+ }
+
+#if __DBG
+ DbgPrint("AllocateAdapterMemory\n");
+#endif
+ if (!AllocateAdapterMemory(Adapter)) {
+
+ // Call to AllocateAdapterMemory failed.
+#if __DBG
+ DbgPrint(" Failed!\n");
+#endif
+ NdisWriteErrorLogEntry(
+ MiniportAdapterHandle,
+ NDIS_ERROR_CODE_OUT_OF_RESOURCES,
+ 1,
+ DC21X4_ERRMSG_ALLOC_MEMORY
+ );
+
+ FreeAdapterResources(Adapter,3);
+ return NDIS_STATUS_RESOURCES;
+ }
+
+#if __DBG
+ DbgPrint(" Tx Ring Va = %08x\n",Adapter->TransmitDescriptorRingVa);
+ DbgPrint(" Pa = %08x\n",Adapter->TransmitDescriptorRingPa);
+ DbgPrint("\n");
+ DbgPrint(" Rx Ring Va = %08x\n",Adapter->ReceiveDescriptorRingVa);
+ DbgPrint(" Pa = %08x\n",Adapter->ReceiveDescriptorRingPa);
+ DbgPrint("\n");
+ DbgPrint(" Sp Buff Va = %08x\n",Adapter->SetupBufferVa);
+ DbgPrint(" Pa = %08x\n",Adapter->SetupBufferPa);
+ DbgPrint("\n");
+
+
+#endif
+
+ // Initialize the descriptor index
+
+ Adapter->DequeueReceiveDescriptor =
+ (PDC21X4_RECEIVE_DESCRIPTOR)Adapter->ReceiveDescriptorRingVa;
+ Adapter->EnqueueTransmitDescriptor =
+ (PDC21X4_TRANSMIT_DESCRIPTOR)Adapter->TransmitDescriptorRingVa;
+ Adapter->DequeueTransmitDescriptor =
+ Adapter->EnqueueTransmitDescriptor;
+
+ Adapter->FreeTransmitDescriptorCount = TRANSMIT_RING_SIZE - 1;
+
+ // Initialize the DC21X4's PCI Configuration registers
+
+ DC21X4InitPciConfigurationRegisters(Adapter);
+ DC21X4StopAdapter(Adapter);
+
+
+ // Transmit Threshold:
+
+ switch (Adapter->DeviceId) {
+
+ case DC21040_CFID:
+
+ // DC21040 Pass1 & Pass2 FIFO Underrun workaround:
+ // set the minimal threshold to
+ // - 96 bytes if no SoftwareCRC
+ // 160 bytes if SoftwareCRC
+
+ switch (Adapter->RevisionNumber) {
+
+ case DC21040_REV1:
+ case DC21040_REV2_0:
+ case DC21040_REV2_2:
+
+ Adapter->TransmitDefaultDescriptorErrorMask &= ~(DC21X4_TDES_LOSS_OF_CARRIER);
+ Adapter->SoftwareCRC = DC21X4Configuration[RGS_SCRC].RegistryValue;
+
+ DC21X4Configuration[RGS_THRS].RegistryValue =
+ (Adapter->SoftwareCRC) ? 160 : max(96,DC21X4Configuration[RGS_THRS].RegistryValue);
+ }
+ }
+
+ switch (DC21X4Configuration[RGS_THRS].RegistryValue) {
+
+ case 160:
+ Adapter->Threshold10Mbps = DC21X4_TXM10_THRESHOLD_160;
+ break;
+
+ case 128:
+ Adapter->Threshold10Mbps = DC21X4_TXM10_THRESHOLD_128;
+ break;
+
+ case 96:
+ Adapter->Threshold10Mbps = DC21X4_TXM10_THRESHOLD_96;
+ break;
+
+ default:
+ DC21X4Configuration[RGS_THRS].RegistryValue = 96;
+ Adapter->Threshold10Mbps = DC21X4_DEFAULT_THRESHOLD_10MBPS;
+ }
+
+ Adapter->TxmThreshold = DC21X4Configuration[RGS_THRS].RegistryValue;
+
+ switch (DC21X4Configuration[RGS_THRS100].RegistryValue) {
+
+ case 1024:
+ Adapter->Threshold100Mbps = DC21X4_TXM100_THRESHOLD_1024;
+ break;
+
+ case 512:
+ Adapter->Threshold100Mbps = DC21X4_TXM100_THRESHOLD_512;
+ break;
+
+ case 256:
+ Adapter->Threshold100Mbps = DC21X4_TXM100_THRESHOLD_256;
+ break;
+
+ case 128:
+ Adapter->Threshold100Mbps = DC21X4_TXM100_THRESHOLD_128;
+ break;
+
+ default:
+ Adapter->Threshold100Mbps = DC21X4_DEFAULT_THRESHOLD_100MBPS;
+ }
+
+ if (DC21X4Configuration[RGS_STFD].RegistryValue == 1) {
+ Adapter->OperationMode |= DC21X4_STORE_AND_FORWARD;
+ }
+
+#if __DBG
+ DbgPrint("Threshold10Mbps=%x\n", Adapter->Threshold10Mbps);
+ DbgPrint("Threshold100Mbps=%x\n", Adapter->Threshold100Mbps);
+ DbgPrint("SoftwareCRC=%x\n", Adapter->SoftwareCRC);
+ DbgPrint("StoreAndForward=%x\n", Adapter->OperationMode & DC21X4_STORE_AND_FORWARD);
+#endif
+
+ // MediaType
+
+ if (DC21X4Configuration[RGS_CNCT].RegistryValue > MAX_MEDIA) {
+ DC21X4Configuration[RGS_CNCT].RegistryValue = 0;
+ }
+ Adapter->MediaType = ConnectionType[DC21X4Configuration[RGS_CNCT].RegistryValue];
+
+ // Read the DC21X4 SERIAL ROM
+
+ NdisStatus = DC21X4ReadSerialRom(Adapter);
+
+#ifndef _MIPS_
+
+ if (NdisStatus != NDIS_STATUS_SUCCESS) {
+
+ NdisWriteErrorLogEntry(
+ MiniportAdapterHandle,
+ NDIS_ERROR_CODE_INVALID_VALUE_FROM_ADAPTER,
+ 1,
+ DC21X4_ERRMSG_SROM
+ );
+ FreeAdapterResources(Adapter,3);
+ return NdisStatus;
+ }
+
+#endif
+
+ // Set the network address.
+
+ if (!NetworkAddress) {
+
+#ifdef _MIPS_
+
+ if (!Adapter->PermanentAddressValid) {
+
+ // Read the network address from the registry
+ // by iterating on MultifunctionAdapter and Controller.
+ // We set the global variables for these two entities so
+ // that for multiple adapters we don't re-use the same ethernet
+ // address, but rather we look in the registry for the next adapter
+ // instance.
+
+ for (;
+ MultifunctionAdapterNumber < 8;
+ MultifunctionAdapterNumber++) {
+
+ for (;
+ ControllerNumber < 16;
+ ControllerNumber++) {
+
+ NdisStatus = DC21X4HardwareGetDetails(Adapter,
+ MultifunctionAdapterNumber,
+ ControllerNumber);
+
+ if (NdisStatus == NDIS_STATUS_SUCCESS) {
+
+ ControllerNumber++;
+ break;
+
+ }
+ }
+ }
+
+ }
+#endif
+ if (Adapter->PermanentAddressValid) {
+ // Use the burnt-in network address
+ NetworkAddress = &Adapter->PermanentNetworkAddress[0];
+ }
+ else {
+ // no readable network address
+
+ NdisWriteErrorLogEntry(
+ MiniportAdapterHandle,
+ NDIS_ERROR_CODE_NETWORK_ADDRESS,
+ 0
+ );
+ FreeAdapterResources(Adapter,3);
+ return NDIS_STATUS_FAILURE;
+ }
+
+ }
+
+ MOVE_MEMORY(
+ &Adapter->CurrentNetworkAddress[0],
+ NetworkAddress,
+ ETH_LENGTH_OF_ADDRESS
+ );
+
+#if __DBG
+ DbgPrint("Network address = %.2x-%.2x-%.2x-%.2x-%.2x-%.2x\n",
+ Adapter->CurrentNetworkAddress[0],
+ Adapter->CurrentNetworkAddress[1],
+ Adapter->CurrentNetworkAddress[2],
+ Adapter->CurrentNetworkAddress[3],
+ Adapter->CurrentNetworkAddress[4],
+ Adapter->CurrentNetworkAddress[5]);
+#endif
+
+ Adapter->MaxMulticastAddresses = DC21X4_MAX_MULTICAST_ADDRESSES;
+
+ switch (Adapter->DeviceId) {
+
+ case DC21140_CFID:
+
+ switch (Adapter->RevisionNumber) {
+
+ // dc21140 pass1_1 & pass1_2 limited to
+ // perfect filtering only
+
+ case DC21140_REV1_1:
+ case DC21140_REV1_2:
+
+ Adapter->MaxMulticastAddresses = DC21X4_MAX_MULTICAST_PERFECT;
+ break;
+
+ case DC21140_REV2_0:
+ case DC21140_REV2_1:
+ case DC21140_REV2_2:
+
+ Adapter->OverflowWorkAround = TRUE;
+ break;
+ }
+ break;
+
+ case DC21142_CFID:
+
+ switch (Adapter->RevisionNumber) {
+
+ case DC21142_REV1_0:
+ case DC21142_REV1_1:
+
+ Adapter->OverflowWorkAround = TRUE;
+ break;
+ }
+ break;
+ }
+
+#if __DBG
+ DbgPrint("MaxMulticastAddresses = %d\n",Adapter->MaxMulticastAddresses);
+#endif
+
+ // Initialize DC21X4's CAM with the Network Address
+
+#if __DBG
+ DbgPrint("DC21X4InitializeCam\n");
+#endif
+ DC21X4InitializeCam (
+ Adapter,
+ (PUSHORT)Adapter->CurrentNetworkAddress
+ );
+
+
+ // Initialize the interrupt.
+#if __DBG
+ DbgPrint("Init Interrupt\n");
+#endif
+#if __DBG
+ DbgPrint("Interrupt Vector = 0x%x\n",InterruptVector);
+ DbgPrint("Interrupt Level = 0x%x\n",InterruptLevel);
+#endif
+
+ NdisStatus = NdisMRegisterInterrupt(
+ &Adapter->Interrupt,
+ MiniportAdapterHandle,
+ InterruptVector,
+ InterruptLevel,
+ FALSE,
+ TRUE, //SHARED
+ (NDIS_INTERRUPT_MODE)InterruptMode
+ );
+
+ if (NdisStatus != NDIS_STATUS_SUCCESS) {
+
+ NdisWriteErrorLogEntry(
+ MiniportAdapterHandle,
+ NDIS_ERROR_CODE_INTERRUPT_CONNECT,
+ 0
+ );
+
+ FreeAdapterResources(Adapter,3);
+ return NdisStatus;
+ }
+
+ // Initialize the FullDuplex SpinLocks
+
+ NdisAllocateSpinLock(
+ &Adapter->EnqueueSpinLock
+ );
+ NdisAllocateSpinLock(
+ &Adapter->FullDuplexSpinLock
+ );
+
+ // Register the adapter to receive shutdown notification:
+
+ NdisMRegisterAdapterShutdownHandler(
+ MiniportAdapterHandle,
+ Adapter,
+ (PVOID)DC21X4Shutdown
+ );
+
+ // Initialize the Media Autosense Timer
+
+ NdisMInitializeTimer(
+ &Adapter->Timer,
+ MiniportAdapterHandle,
+ (PNDIS_TIMER_FUNCTION)&DC21X4DynamicAutoSense,
+ (PVOID)Adapter
+ );
+
+ // Initialize the Reset Timer
+
+ NdisMInitializeTimer(
+ &Adapter->ResetTimer,
+ MiniportAdapterHandle,
+ (PNDIS_TIMER_FUNCTION)&DC21X4DeferredReset,
+ (PVOID)Adapter
+ );
+
+ // Initialize the Monitor Timer
+
+ NdisMInitializeTimer(
+ &Adapter->MonitorTimer,
+ MiniportAdapterHandle,
+ (PNDIS_TIMER_FUNCTION)&DC21X4ModerateInterrupt,
+ (PVOID)Adapter
+ );
+
+ // Initialize the DC21X4's CSRs
+
+ DC21X4InitializeRegisters(
+ Adapter
+ );
+
+ if (Adapter->PhyMediumInSrom) {
+
+ // Try to initialize the PHY.
+ Adapter->PhyPresent = DC21X4PhyInit(Adapter);
+#if __DBG
+ DbgPrint("Adapter->PhyPresent=%d\n",Adapter->PhyPresent);
+#endif
+ }
+#if __DBG
+ else {
+ DbgPrint("No PHY Medium in SROM\n");
+ }
+#endif
+
+ //Initialize the non PHY media
+
+ Mode = ( ((DC21X4Configuration[RGS_BKOC].RegistryValue) ? DC21X4_STOP_BACKOFF_COUNTER : 0 )
+ | ((DC21X4Configuration[RGS_BKPR].RegistryValue) ? DC21X4_BACK_PRESSURE : 0 )
+ | ((DC21X4Configuration[RGS_CPTE].RegistryValue) ? DC21X4_CAPTURE_EFFECT : 0 )
+ );
+
+ switch (Adapter->DeviceId) {
+
+ case DC21040_CFID:
+ case DC21041_CFID:
+ case DC21142_CFID:
+
+ if (DC21X4Configuration[RGS_ESIA].Present) {
+
+ //overwrite the SIA default values with the values stored in the
+ //Registry
+
+ i = ConnectionType[DC21X4Configuration[RGS_ESIA].RegistryValue] & 0xF;
+
+ Adapter->Media[i].SiaRegister[0] = DC21X4Configuration[RGS_SIA0].RegistryValue;
+ Adapter->Media[i].SiaRegister[1] = DC21X4Configuration[RGS_SIA1].RegistryValue;
+ Adapter->Media[i].SiaRegister[2] = DC21X4Configuration[RGS_SIA2].RegistryValue;
+ }
+ }
+
+ switch (Adapter->DeviceId) {
+
+ case DC21040_CFID:
+
+ Adapter->LinkSpeed = TEN_MBPS;
+
+ Mode |= Adapter->Threshold10Mbps;
+
+ Adapter->Media[Medium10BaseT].Mode |= Mode;
+ Adapter->Media[Medium10Base2].Mode |= Mode;
+ Adapter->Media[Medium10Base5].Mode |= Mode;
+
+ if (Adapter->MediaType == Medium10BaseTFullDuplex) {
+ Adapter->MediaType = (Medium10BaseT | MEDIA_FULL_DUPLEX);
+ Adapter->Media[Medium10BaseT].SiaRegister[1] = DC21040_SIA1_10BT_FULL_DUPLEX;
+ Adapter->Media[Medium10BaseT].Mode |= DC21X4_FULL_DUPLEX_MODE;
+ Adapter->FullDuplexLink = TRUE;
+ }
+ else if (Adapter->MediaType & MEDIA_LINK_DISABLE) {
+ //Disable Link Test
+ Adapter->Media[Medium10BaseT].SiaRegister[1] = DC21040_SIA1_10BT_LINK_DISABLE;
+ }
+
+ Adapter->SelectedMedium = Adapter->MediaType & MEDIA_MASK;
+ Adapter->MediaCapable &= (1 << Adapter->SelectedMedium);
+
+ break;
+
+ case DC21041_CFID:
+
+ Adapter->LinkSpeed = TEN_MBPS;
+
+ Mode |= Adapter->Threshold10Mbps;
+
+ Adapter->Media[Medium10BaseT].Mode |= Mode;
+ Adapter->Media[Medium10Base2].Mode |= Mode;
+ Adapter->Media[Medium10Base5].Mode |= Mode;
+
+ if (Adapter->MediaType == Medium10BaseTFullDuplex) {
+ Adapter->MediaType = (Medium10BaseT | MEDIA_FULL_DUPLEX);
+ }
+
+ if(Adapter->MediaType & MEDIA_NWAY) {
+
+ //Enable Nway Negotiation
+ DC21X4EnableNway (Adapter);
+ }
+
+ if (Adapter->MediaType & MEDIA_AUTOSENSE) {
+
+ //AutoSense mode:
+ Adapter->Media[Medium10Base2].SiaRegister[1] |= DC21041_LINK_TEST_ENABLED;
+ Adapter->Media[Medium10Base5].SiaRegister[1] |= DC21041_LINK_TEST_ENABLED;
+
+ // TP link is down after reset: Initialize to 10Base2 or 10Base5
+ Adapter->SelectedMedium = (Adapter->MediaCapable & MEDIUM_10B2) ?
+ Medium10Base2 : Medium10Base5;
+ }
+ else {
+ Adapter->SelectedMedium = Adapter->MediaType & MEDIA_MASK;
+ Adapter->MediaCapable &= (1 << Adapter->SelectedMedium);
+ }
+ if (Adapter->MediaType & MEDIA_FULL_DUPLEX) {
+
+ // Full Duplex mode:
+ Adapter->Media[Medium10BaseT].Mode |= DC21X4_FULL_DUPLEX_MODE;
+ Adapter->Media[Medium10BaseT].SiaRegister[1] = DC21041_SIA1_10BT_FULL_DUPLEX;
+ Adapter->FullDuplexLink = TRUE;
+ }
+ else if (Adapter->MediaType & MEDIA_LINK_DISABLE) {
+
+ //Disable Link Test mode:
+ Adapter->Media[Medium10BaseT].SiaRegister[1] = DC21041_SIA1_10BT_LINK_DISABLE;
+ }
+
+ break;
+
+ case DC21140_CFID :
+
+ Mode |= DC21X4_LINK_HYSTERESIS;
+
+ Adapter->Media[Medium10BaseT].Mode |= Mode;
+ Adapter->Media[Medium10Base2].Mode |= Mode;
+ Adapter->Media[Medium10Base5].Mode |= Mode;
+ Adapter->Media[Medium100BaseTx].Mode |= Mode;
+ Adapter->Media[Medium100BaseTxFd].Mode |= Mode;
+ Adapter->Media[Medium100BaseT4].Mode |= Mode;
+
+ // Select Scrambler mode to enable 100BaseTx link status
+ // while in 10BT mode
+
+ Adapter->Media[Medium10BaseT].Mode |= DC21X4_SCRAMBLER;
+ Adapter->Media[Medium10Base2].Mode |= DC21X4_SCRAMBLER;
+ Adapter->Media[Medium10Base5].Mode |= DC21X4_SCRAMBLER;
+ Adapter->Media[Medium100BaseTx].Mode |= DC21X4_OPMODE_100BTX;
+ Adapter->Media[Medium100BaseTxFd].Mode |= DC21X4_OPMODE_100BTX;
+
+ if (Adapter->MediaType & MEDIA_FULL_DUPLEX) {
+ Adapter->Media[Medium10BaseT].Mode |= DC21X4_FULL_DUPLEX_MODE;
+ Adapter->Media[Medium100BaseTxFd].Mode |= DC21X4_FULL_DUPLEX_MODE;
+ Adapter->FullDuplexLink = TRUE;
+ }
+
+ if (!(Adapter->MediaType & MEDIA_AUTOSENSE)) {
+ Adapter->SelectedMedium = Adapter->MediaType & MEDIA_MASK;
+ Adapter->MediaCapable &= (1 << Adapter->SelectedMedium);
+
+ Adapter->LinkSpeed =
+ (Adapter->Media[Adapter->SelectedMedium].Mode & DC21X4_SCRAMBLER) ?
+ TEN_MBPS : ONE_HUNDRED_MBPS;
+ }
+ else {
+ Adapter->LinkSpeed = TEN_MBPS;
+ }
+ break;
+
+ case DC21142_CFID:
+
+ Mask = Mode | Adapter->Threshold10Mbps;
+
+ Adapter->Media[Medium10BaseT].Mode |= Mask;
+ Adapter->Media[Medium10Base2].Mode |= Mask;
+ Adapter->Media[Medium10Base5].Mode |= Mask;
+
+ Mask = Mode | Adapter->Threshold100Mbps;
+
+ Adapter->Media[Medium100BaseTx].Mode |= Mask;
+ Adapter->Media[Medium100BaseT4].Mode |= Mask;
+
+ if (Adapter->MediaType == Medium10BaseTFullDuplex) {
+ Adapter->MediaType = (Medium10BaseT | MEDIA_FULL_DUPLEX);
+ }
+
+ if (Adapter->MediaType & MEDIA_NWAY) {
+
+ // if the PHY is present and NWAY capable, the Nway negotiation
+ // is performed by the PHY,otherwise by the DC21X4
+
+ if (!(Adapter->PhyPresent && Adapter->PhyNwayCapable)) {
+
+ //Enable DC21X4's Nway Negotiation
+ DC21X4EnableNway (Adapter);
+ }
+#if __DBG
+ else {
+ DbgPrint("PHY Nway capable: Disable DC21X4's NWAY\n");
+ }
+#endif
+ }
+
+ if (Adapter->MediaType & MEDIA_AUTOSENSE) {
+
+ //AutoSense mode:
+
+ Adapter->Media[Medium10Base2].SiaRegister[1] |=DC21142_LINK_TEST_ENABLED;
+ Adapter->Media[Medium10Base5].SiaRegister[1] |=DC21142_LINK_TEST_ENABLED;
+
+ // TP link is down after reset:
+ // Initialize to 10Base2 or 10Base5 if populated
+
+ Adapter->SelectedMedium =
+ (Adapter->MediaCapable & MEDIUM_10B2) ? Medium10Base2 :
+ (Adapter->MediaCapable & MEDIUM_10B5) ? Medium10Base5 :
+ Adapter->MediaType & MEDIA_MASK;
+
+ Adapter->LinkSpeed = TEN_MBPS;
+ }
+ else{
+
+ //Non AutoSense mode:
+
+ Adapter->SelectedMedium = Adapter->MediaType & MEDIA_MASK;
+ Adapter->MediaCapable &= (1 << Adapter->SelectedMedium);
+
+ switch (Adapter->SelectedMedium) {
+
+ case Medium100BaseTx:
+ case Medium100BaseT4:
+ case Medium100BaseFx:
+
+ Adapter->LinkSpeed = ONE_HUNDRED_MBPS;
+ break;
+
+ default:
+
+ Adapter->LinkSpeed = TEN_MBPS;
+ break;
+ }
+ }
+
+ if (Adapter->MediaType & MEDIA_FULL_DUPLEX) {
+
+ // Full Duplex mode:
+ Adapter->Media[Medium10BaseT].SiaRegister[1] = DC21142_SIA1_10BT_FULL_DUPLEX;
+
+ Adapter->Media[Medium10BaseT].Mode |= DC21X4_FULL_DUPLEX_MODE;
+ Adapter->Media[Medium100BaseTx].Mode |= DC21X4_FULL_DUPLEX_MODE;
+ Adapter->FullDuplexLink = TRUE;
+
+ }
+ else if (Adapter->MediaType & MEDIA_LINK_DISABLE) {
+
+ //Disable Link Test mode:
+ Adapter->Media[Medium10BaseT].SiaRegister[1] =DC21142_SIA1_10BT_LINK_DISABLE;
+ }
+ break;
+
+ }
+
+
+#if __DBG
+ DbgPrint ("MediaType = %x\n",Adapter->MediaType);
+#endif
+
+ if (Adapter->PhyPresent) {
+
+ //Try to establish the Mii PHY connection
+
+#if 0
+ if (!(Adapter->MiiMediaType & MEDIA_NWAY)) {
+
+ DC21X4SetPhyControl(
+ Adapter,
+ (USHORT)MiiGenAdminIsolate
+ );
+ }
+#endif
+
+ Adapter->PhyPresent=DC21X4SetPhyConnection(Adapter);
+#if __DBG
+ DbgPrint("PHY Connection %s for the requested medium: %x\n",
+ Adapter->PhyPresent ? "succeed" : "failed" , Adapter->MiiMediaType);
+#endif
+ }
+
+ //Check that at least one of the selected media is
+ //supported by this adapter
+
+ if (!Adapter->PhyPresent && !Adapter->MediaCapable) {
+ NdisWriteErrorLogEntry(
+ MiniportAdapterHandle,
+ NDIS_ERROR_CODE_UNSUPPORTED_CONFIGURATION,
+ 1,
+ DC21X4_ERRMSG_MEDIA
+ );
+ FreeAdapterResources(Adapter,4);
+ return NDIS_STATUS_UNSUPPORTED_MEDIA;
+ }
+
+ Adapter->OperationMode |= Adapter->Media[Adapter->SelectedMedium].Mode;
+
+ Adapter->TransmitDescriptorErrorMask =
+ Adapter->TransmitDefaultDescriptorErrorMask;
+ if (Adapter->FullDuplexLink) {
+ //Mask Loss_of_Carrrier and No_Carrier Txm status bits
+ Adapter->TransmitDescriptorErrorMask &=
+ ~(DC21X4_TDES_NO_CARRIER | DC21X4_TDES_LOSS_OF_CARRIER);
+ }
+
+ if (!Adapter->PhyPresent) {
+ // Initialize the Medium registers
+ DC21X4InitializeMediaRegisters(
+ Adapter,
+ FALSE
+ );
+ }
+
+ // Load DC21X4's Cam in polling mode
+
+ if (!DC21X4LoadCam(
+ Adapter,
+ FALSE)) {
+
+ NdisWriteErrorLogEntry(
+ MiniportAdapterHandle,
+ NDIS_ERROR_CODE_TIMEOUT,
+ 1,
+ DC21X4_ERRMSG_LOAD_CAM
+ );
+ FreeAdapterResources(Adapter,5);
+ return NDIS_STATUS_FAILURE;
+ }
+
+ if (Adapter->ParityError) {
+
+ FreeAdapterResources(Adapter,5);
+ return NDIS_STATUS_FAILURE;
+ }
+
+ // Start DC21X4's Txm and Rcv Processes
+
+ Adapter->FirstAncInterrupt = TRUE;
+
+ DC21X4StartAdapter(Adapter);
+
+ {
+ // Media link Detection
+ if (Adapter->PhyPresent) {
+ Link = DC21X4MiiAutoDetect(
+ Adapter
+ );
+ }
+ if ( (!Adapter->PhyPresent)
+ || (!Link
+ && (Adapter->MediaCapable)
+ )
+ ) {
+
+ StartTimer = DC21X4MediaDetect(
+ Adapter
+ );
+ }
+
+ // Start the Autosense timer if not yet started
+
+ if (StartTimer && (Adapter->TimerFlag==NoTimer)) {
+
+ DC21X4StartAutoSenseTimer(
+ Adapter,
+ (UINT)(2*DC21X4_SPA_TICK)
+ );
+ }
+
+ }
+
+ switch (Adapter->DeviceId) {
+
+ case DC21140_CFID:
+ case DC21142_CFID:
+
+ if (Adapter->InterruptThreshold) {
+#if __DBG
+ DbgPrint ("Start Monitor timer\n");
+#endif
+ NdisMSetTimer(
+ &Adapter->MonitorTimer,
+ INT_MONITOR_PERIOD
+ );
+ }
+ }
+
+ //The Initialization is completed
+#if __DBG
+ DbgPrint ("Initialize done\n");
+#endif
+ Adapter->Initializing = FALSE;
+ return NDIS_STATUS_SUCCESS;
+
+}
+
+#pragma NDIS_PAGABLE_FUNCTION(FreeAdapterResources)
+
+/*+
+ * DC21X4FreeAdapterResources
+ *
+ * Routine Description:
+ *
+ * Free the adapter resources
+ *
+ * Arguments:
+ *
+ * Adapter
+ * Step
+ *
+ * Return Value:
+ *
+ * None
+ *
+-*/
+
+extern
+VOID
+FreeAdapterResources(
+ IN PDC21X4_ADAPTER Adapter,
+ IN INT Step
+ )
+{
+
+ switch (Step) {
+
+ case 5:
+
+
+ NdisMDeregisterAdapterShutdownHandler(
+ Adapter->MiniportAdapterHandle
+ );
+
+ NdisFreeSpinLock(
+ &Adapter->EnqueueSpinLock
+ );
+ NdisFreeSpinLock(
+ &Adapter->FullDuplexSpinLock
+ );
+
+ NdisMDeregisterInterrupt(
+ &Adapter->Interrupt
+ );
+
+ case 4:
+
+ if (Adapter->PhyPresent) {
+ MiiFreeResources(Adapter);
+ }
+
+ case 3:
+
+ FreeAdapterMemory(
+ Adapter
+ );
+
+ NdisMFreeMapRegisters(
+ Adapter->MiniportAdapterHandle
+ );
+
+ case 2:
+
+ NdisMDeregisterIoPortRange(
+ Adapter->MiniportAdapterHandle,
+ Adapter->IOBaseAddress,
+ Adapter->IOSpace,
+ (PVOID)Adapter->PortOffset
+ );
+
+ case 1:
+
+ FREE_MEMORY(
+ Adapter,
+ sizeof(DC21X4_ADAPTER)
+ );
+ }
+
+}
+
+#pragma NDIS_PAGABLE_FUNCTION(FindPciConfiguration)
+
+/*+
+ * FindPciConfiguration
+ *
+ *
+ * Routine Description:
+ *
+ * Assign resources and walk the resource list
+ * to extract the configuration information
+ *
+ *
+ * Arguments:
+ *
+ * NdisMacHandle
+ * NdisWrapperHandle
+ * NdisConfigurationHandle
+ * SlotNumber
+ *
+ * Return Value:
+ *
+ * TRUE if valid information
+ *
+-*/
+
+
+NDIS_STATUS
+FindPciConfiguration(
+ IN NDIS_HANDLE MiniportAdapterHandle,
+ IN ULONG SlotNumber,
+ OUT PULONG PortStart,
+ OUT PULONG PortLength,
+ OUT PULONG InterruptLevel,
+ OUT PULONG InterruptVector
+ )
+{
+
+ PNDIS_RESOURCE_LIST ResourceList;
+ PCM_PARTIAL_RESOURCE_DESCRIPTOR ResourceDescriptor;
+
+ NDIS_STATUS NdisStatus;
+ ULONG i;
+
+#if __DBG
+ DbgPrint("PCI Assign Resources\n");
+#endif
+
+ NdisStatus = NdisMPciAssignResources(
+ MiniportAdapterHandle,
+ SlotNumber,
+ &ResourceList
+ );
+
+ if (NdisStatus!= NDIS_STATUS_SUCCESS) {
+ return NdisStatus;
+ }
+
+#if __DBG
+ DbgPrint(" ResourceList = %x Count = %d\n",
+ ResourceList,ResourceList->Count);
+#endif
+
+ // Walk the resources list to extract the configuration
+ // information needed to register the adapter
+
+ for (i=0;i < ResourceList->Count; i++) {
+
+ ResourceDescriptor = &ResourceList->PartialDescriptors[i];
+
+ switch (ResourceDescriptor->Type) {
+
+ case CmResourceTypeInterrupt:
+
+ *InterruptLevel = ResourceDescriptor->u.Interrupt.Level;
+ *InterruptVector = ResourceDescriptor->u.Interrupt.Vector;
+#if __DBG
+ DbgPrint(" Interrupt Level=%x Vector=%x\n",
+ ResourceDescriptor->u.Interrupt.Level,
+ ResourceDescriptor->u.Interrupt.Vector);
+#endif
+
+ break;
+
+ case CmResourceTypePort:
+
+ *PortStart = NdisGetPhysicalAddressLow(ResourceDescriptor->u.Port.Start);
+ *PortLength = ResourceDescriptor->u.Port.Length;
+#if __DBG
+ DbgPrint(" Port = %x Len = %x\n",
+ NdisGetPhysicalAddressLow(ResourceDescriptor->u.Port.Start),
+ ResourceDescriptor->u.Port.Length);
+#endif
+ break;
+ }
+ }
+
+ return NdisStatus;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+/*+
+ * DC21X4Halt
+ *
+ * Routine Description:
+ *
+ * DC21X4Halt stop the adapter and deregister all its resources
+ *
+-*/
+
+extern
+VOID
+DC21X4Halt(
+ IN NDIS_HANDLE MiniportAdapterContext
+ )
+{
+
+ PDC21X4_ADAPTER Adapter;
+ BOOLEAN Canceled;
+
+ Adapter = (PDC21X4_ADAPTER)MiniportAdapterContext;
+
+#if __DBG
+ DbgPrint("DC21X4Halt\n");
+#endif
+
+ //
+ // stop the adapter
+ //
+ switch (Adapter->AdapterType) {
+
+ case NdisInterfaceEisa:
+
+ // Use HW reset instead of SW reset
+
+#if _DBG
+ DbgPrint(" HW reset\n");
+#endif
+
+ NdisRawWritePortUchar (
+ Adapter->PortOffset + EISA_REG1_OFFSET,
+ 0x01
+ );
+
+ NdisRawWritePortUchar (
+ Adapter->PortOffset + EISA_REG1_OFFSET,
+ 0
+ );
+
+ break;
+
+ default:
+
+ // Set the SW Reset bit in BUS_MODE register
+
+#if _DBG
+ DbgPrint(" SW reset\n");
+#endif
+
+ DC21X4_WRITE_PORT(
+ DC21X4_BUS_MODE,
+ DC21X4_SW_RESET);
+ }
+
+ // Wait 50 PCI bus cycles to wait for reset completion
+
+ NdisStallExecution(2*MILLISECOND); // Wait for 2 ms
+
+ //Deregister the adapter's resources
+
+ FreeAdapterMemory(Adapter);
+
+ NdisMCancelTimer(
+ &Adapter->Timer,
+ &Canceled
+ );
+
+
+ NdisMCancelTimer(
+ &Adapter->MonitorTimer,
+ &Canceled
+ );
+
+
+ NdisMDeregisterAdapterShutdownHandler(
+ Adapter->MiniportAdapterHandle
+ );
+
+ NdisFreeSpinLock(
+ &Adapter->EnqueueSpinLock
+ );
+ NdisFreeSpinLock(
+ &Adapter->FullDuplexSpinLock
+ );
+
+
+ NdisMDeregisterInterrupt(
+ &Adapter->Interrupt
+ );
+
+ NdisMDeregisterIoPortRange(
+ Adapter->MiniportAdapterHandle,
+ Adapter->IOBaseAddress,
+ Adapter->IOSpace,
+ (PVOID)Adapter->PortOffset
+ );
+
+ NdisMFreeMapRegisters(
+ Adapter->MiniportAdapterHandle
+ );
+
+
+ if (Adapter->PhyPresent) {
+ MiiFreeResources(Adapter);
+ }
+
+ FREE_MEMORY(Adapter, sizeof(DC21X4_ADAPTER));
+
+ return;
+
+}
+
+
+
+
+
+
+
+
+
+
+/*+
+ *
+ * DC21X4Shutdown
+ *
+ * Routine Description:
+ *
+ * Handle system shutdown operation. This is currently done by
+ * forcing DC21X4 reset.
+ *
+ * Arguments:
+ *
+ * ShutdownContext - A pointer to a DC21X4_ADAPTER structure. This
+ * is the value passed as the context parameter
+ * to the function NdisRegisterAdapterShutdownHandler().
+ *
+ * Return Value:
+ *
+ * none
+ *
+-*/
+extern
+VOID
+DC21X4Shutdown(
+ IN PVOID ShutdownContext
+ )
+{
+
+ PDC21X4_ADAPTER Adapter = (PDC21X4_ADAPTER)ShutdownContext;
+
+#if __DBG
+ DbgPrint("DC21X4Shutdown\n");
+#endif
+
+ Adapter->Initializing = TRUE;
+ DC21X4StopAdapter(Adapter);
+
+}
+
+
+
+
+
+
+
+
+
+
+#ifdef _MIPS_
+
+// The next routines are to support reading the registry to
+// obtain information about the DC21X4 on MIPS machines.
+
+// This structure is used as the Context in the callbacks
+// to DC21X4HardwareSaveInformation.
+
+typedef struct _DC21X4_HARDWARE_INFO {
+
+ // These are read out of the "Configuration Data" data.
+
+ CCHAR InterruptVector;
+ KIRQL InterruptLevel;
+ USHORT DataConfigurationRegister;
+ LARGE_INTEGER PortAddress;
+ BOOLEAN DataValid;
+ UCHAR EthernetAddress[8];
+ BOOLEAN AddressValid;
+
+ // This is set to TRUE if "Identifier" is equal to "DC21040".
+
+ BOOLEAN DC21X4Identifier;
+
+} DC21X4_HARDWARE_INFO, *PDC21X4_HARDWARE_INFO;
+
+
+
+
+
+
+
+
+
+
+
+
+
+/*+
+ *
+ * DC21X4HardwareSaveInformation
+ *
+ * Routine Description:
+ *
+ * This routine is a callback routine for RtlQueryRegistryValues.
+ * It is called back with the data for the "Identifier" value
+ * and verifies that it is "DC21040", then is called back with
+ * the resource list and records the ports, interrupt number,
+ * and DCR value.
+ *
+ * Arguments:
+ *
+ * ValueName - The name of the value ("Identifier" or "Configuration Data").
+ * ValueType - The type of the value (REG_SZ or REG_BINARY).
+ * ValueData - The null-terminated data for the value.
+ * ValueLength - The length of ValueData (ignored).
+ * Context - A pointer to the DC21X4_HARDWARE_INFO structure.
+ * EntryContext - FALSE for "Identifier", TRUE for "Configuration Data".
+ *
+ * Return Value:
+ *
+ * STATUS_SUCCESS
+ *
+-*/
+
+NTSTATUS
+DC21X4HardwareSaveInformation(
+ IN PWSTR ValueName,
+ IN ULONG ValueType,
+ IN PVOID ValueData,
+ IN ULONG ValueLength,
+ IN PVOID Context,
+ IN PVOID EntryContext
+ )
+
+{
+ PDC21X4_HARDWARE_INFO HardwareInfo = (PDC21X4_HARDWARE_INFO)Context;
+
+ if ((BOOLEAN)EntryContext) {
+
+ // This is the "Configuration Data" callback.
+
+ if ((ValueType == REG_BINARY || ValueType == REG_FULL_RESOURCE_DESCRIPTOR) &&
+ (ValueLength >= sizeof(CM_FULL_RESOURCE_DESCRIPTOR))) {
+
+ BOOLEAN DeviceSpecificRead = FALSE;
+ UINT i;
+
+ PCM_PARTIAL_RESOURCE_LIST ResourceList;
+ PCM_PARTIAL_RESOURCE_DESCRIPTOR ResourceDescriptor;
+ PCM_SONIC_DEVICE_DATA DC21X4DeviceData;
+
+ ResourceList =
+ &((PCM_FULL_RESOURCE_DESCRIPTOR)ValueData)->PartialResourceList;
+
+ for (i = 0; i < ResourceList->Count; i++) {
+
+ ResourceDescriptor = &(ResourceList->PartialDescriptors[i]);
+
+ switch (ResourceDescriptor->Type) {
+
+ case CmResourceTypeDeviceSpecific:
+
+ if (i == ResourceList->Count-1) {
+
+ DC21X4DeviceData = (PCM_SONIC_DEVICE_DATA)
+ &(ResourceList->PartialDescriptors[ResourceList->Count]);
+
+ // Make sure we have enough room for each element we read.
+
+ if (ResourceDescriptor->u.DeviceSpecificData.DataSize >=
+ (ULONG)(FIELD_OFFSET (CM_SONIC_DEVICE_DATA, EthernetAddress[0]))) {
+
+ HardwareInfo->DataConfigurationRegister =
+ DC21X4DeviceData->DataConfigurationRegister;
+ DeviceSpecificRead = TRUE;
+
+ if (ResourceDescriptor->u.DeviceSpecificData.DataSize >=
+ (ULONG)(FIELD_OFFSET (CM_SONIC_DEVICE_DATA, EthernetAddress[0]) + 8)) {
+
+ MOVE_MEMORY(
+ HardwareInfo->EthernetAddress,
+ DC21X4DeviceData->EthernetAddress,
+ 8);
+
+ HardwareInfo->AddressValid = TRUE;
+ }
+ }
+ }
+ break;
+ }
+
+ }
+
+ // Make sure we got all we wanted.
+
+ if (DeviceSpecificRead) {
+ HardwareInfo->DataValid = TRUE;
+ }
+
+ }
+
+ }
+ else {
+
+ static const WCHAR DC21040String[] = L"DC21040";
+
+ // This is the "Identifier" callback.
+
+ if ((ValueType == REG_SZ) &&
+ (ValueLength >= sizeof(DC21040String)) &&
+ (RtlCompareMemory (ValueData, (PVOID)&DC21040String, sizeof(DC21040String)) == sizeof(DC21040String))) {
+
+ HardwareInfo->DC21X4Identifier = TRUE;
+
+ }
+ }
+
+ return STATUS_SUCCESS;
+
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+/*+
+ *
+ * DC21X4HardwareVerifyChecksum
+ *
+ * Routine Description:
+ *
+ * This routine verifies that the checksum on the address
+ * on MIPS systems.
+ *
+ * Arguments:
+ *
+ * Adapter - The adapter which is being verified.
+ *
+ * EthernetAddress - A pointer to the address, with the checksum
+ * following it.
+ *
+ * ErrorLogData - If the checksum is bad, returns the address
+ * and the checksum we expected.
+ *
+ * Return Value:
+ *
+ * TRUE if the checksum is correct.
+ *
+-*/
+
+BOOLEAN
+DC21X4HardwareVerifyChecksum(
+ IN PDC21X4_ADAPTER Adapter,
+ IN PUCHAR EthernetAddress
+ )
+
+{
+ UINT i;
+ USHORT CheckSum = 0;
+
+ // The network address is stored in the first 6 bytes of
+ // EthernetAddress. Following that is a zero byte followed
+ // by a value such that the sum of a checksum on the six
+ // bytes and this value is 0xff. The checksum is computed
+ // by adding together the six bytes, with the carry being
+ // wrapped back to the first byte.
+
+ for (i=0; i<6; i++) {
+
+ CheckSum += EthernetAddress[i];
+ if (CheckSum > 0xff) {
+ CheckSum -= 0xff;
+ }
+ }
+
+ if ((EthernetAddress[6] != 0x00) ||
+ ((EthernetAddress[7] + CheckSum) != 0xff)) {
+
+ return FALSE;
+ }
+
+ return TRUE;
+
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+/*+
+ * DC21X4HardwareGetDetails
+ *
+ * Routine Description:
+ *
+ * This routine gets the ethernet address from the registry
+ *
+ * Arguments:
+ *
+ * Adapter - The adapter in question.
+ *
+ * Controller - For the internal version, it is the
+ * NetworkController number.
+ *
+ * MultifunctionAdapter - For the internal version, it is the adapter number.
+ *
+ * Return Value:
+ *
+ * STATUS_SUCCESS if it read the ethernet address successfully;
+ * STATUS_FAILURE otherwise.
+ *
+-*/
+
+NDIS_STATUS
+DC21X4HardwareGetDetails(
+ IN PDC21X4_ADAPTER Adapter,
+ IN UINT Controller,
+ IN UINT MultifunctionAdapter
+ )
+
+{
+ LPWSTR ConfigDataPath = L"\\Registry\\Machine\\Hardware\\Description\\System\\MultifunctionAdapter\\#\\NetworkController\\#";
+ LPWSTR IdentifierString = L"Identifier";
+ LPWSTR ConfigDataString = L"Configuration Data";
+ RTL_QUERY_REGISTRY_TABLE QueryTable[4];
+ DC21X4_HARDWARE_INFO DC21X4HardwareInfo;
+ NTSTATUS Status;
+
+
+ switch (Adapter->AdapterType) {
+
+ case NdisInterfacePci:
+
+ // For MIPS systems, we have to query the registry to obtain
+ // information about the ethernet address.
+
+ // NOTE: The following code is NT-specific for the MIPS R4000 hardware.
+
+ // We initialize an RTL_QUERY_TABLE to retrieve the Identifer
+ // and ConfigurationData strings from the registry.
+
+ // Set up QueryTable to do the following:
+
+ // 1) Call DC21X4HardwareSaveInformation for the "Identifier" value.
+
+ QueryTable[0].QueryRoutine = DC21X4HardwareSaveInformation;
+ QueryTable[0].Flags = RTL_QUERY_REGISTRY_REQUIRED;
+ QueryTable[0].Name = IdentifierString;
+ QueryTable[0].EntryContext = (PVOID)FALSE;
+ QueryTable[0].DefaultType = REG_NONE;
+
+ // 2) Call DC21X4HardwareSaveInformation for the "Configuration Data" value.
+
+ QueryTable[1].QueryRoutine = DC21X4HardwareSaveInformation;
+ QueryTable[1].Flags = RTL_QUERY_REGISTRY_REQUIRED;
+ QueryTable[1].Name = ConfigDataString;
+ QueryTable[1].EntryContext = (PVOID)TRUE;
+ QueryTable[1].DefaultType = REG_NONE;
+
+ // 3) Stop
+
+ QueryTable[2].QueryRoutine = NULL;
+ QueryTable[2].Flags = 0;
+ QueryTable[2].Name = NULL;
+
+ // Modify ConfigDataPath to replace the two # symbols with
+ // the MultifunctionAdapter number and NetworkController number.
+
+ ConfigDataPath[67] = (WCHAR)('0' + MultifunctionAdapter);
+ ConfigDataPath[87] = (WCHAR)('0' + Controller);
+
+ DC21X4HardwareInfo.DataValid = FALSE;
+ DC21X4HardwareInfo.AddressValid = FALSE;
+ DC21X4HardwareInfo.DC21X4Identifier = FALSE;
+
+ Status = RtlQueryRegistryValues(
+ RTL_REGISTRY_ABSOLUTE,
+ ConfigDataPath,
+ QueryTable,
+ (PVOID)&DC21X4HardwareInfo,
+ NULL);
+
+ if (!NT_SUCCESS(Status)) {
+#if __DBG
+ DbgPrint ("Could not read hardware information\n");
+#endif
+ return NDIS_STATUS_FAILURE;
+ }
+
+ if (DC21X4HardwareInfo.DataValid && DC21X4HardwareInfo.DC21X4Identifier) {
+
+ if (DC21X4HardwareInfo.AddressValid) {
+
+ if (!DC21X4HardwareVerifyChecksum(Adapter, DC21X4HardwareInfo.EthernetAddress)) {
+#if __DBG
+ DbgPrint("Invalid registry network address checksum!!\n");
+#endif
+ return NDIS_STATUS_FAILURE;
+ }
+
+ MOVE_MEMORY(
+ Adapter->PermanentNetworkAddress,
+ DC21X4HardwareInfo.EthernetAddress,
+ 8);
+ Adapter->PermanentAddressValid = TRUE;
+
+ }
+
+ return NDIS_STATUS_SUCCESS;
+ }
+ else {
+
+#if __DBG
+ DbgPrint ("Incorrect registry hardware information\n");
+#endif
+ return NDIS_STATUS_FAILURE;
+
+ }
+
+ break;
+
+ default:
+
+ ASSERT(FALSE);
+ break;
+
+ }
+
+ return NDIS_STATUS_FAILURE;
+
+}
+
+#endif
+
diff --git a/private/ntos/ndis/dc21x4/request.c b/private/ntos/ndis/dc21x4/request.c
new file mode 100644
index 000000000..a29f09643
--- /dev/null
+++ b/private/ntos/ndis/dc21x4/request.c
@@ -0,0 +1,530 @@
+/*+
+ * file: request.c
+ *
+ * Copyright (C) 1992-1995 by
+ * Digital Equipment Corporation, Maynard, Massachusetts.
+ * All rights reserved.
+ *
+ * This software is furnished under a license and may be used and copied
+ * only in accordance of the terms of such license and with the
+ * inclusion of the above copyright notice. This software or any other
+ * copies thereof may not be provided or otherwise made available to any
+ * other person. No title to and ownership of the software is hereby
+ * transferred.
+ *
+ * The information in this software is subject to change without notice
+ * and should not be construed as a commitment by digital equipment
+ * corporation.
+ *
+ * Digital assumes no responsibility for the use or reliability of its
+ * software on equipment which is not supplied by digital.
+ *
+ *
+ * Abstract: This file contains the request handler for the NDIS 4.0
+ * miniport driver for DEC's DC21X4 Ethernet adapter.
+ *
+ * Author: Philippe Klein
+ *
+ * Revision History:
+ *
+ * phk 28-Aug-1994 Initial entry
+ *
+-*/
+
+#include <precomp.h>
+
+
+
+
+
+
+/*+
+ *
+ * DC21X4QueryInformation
+ *
+ * Routine Description:
+ *
+ * DC21X4QueryInformation handles a query operation for a
+ * single OID.
+ *
+-*/
+
+extern
+NDIS_STATUS
+DC21X4QueryInformation(
+ IN NDIS_HANDLE MiniportAdapterContext,
+ IN NDIS_OID Oid,
+ IN PVOID InformationBuffer,
+ IN ULONG InformationBufferLength,
+ OUT PULONG BytesWritten,
+ OUT PULONG BytesNeeded
+ )
+
+{
+ NDIS_STATUS NdisStatus;
+ PDC21X4_ADAPTER Adapter;
+
+ PNDIS_OID OidArray;
+ NDIS_OID OidIndex;
+ INT MaxOid;
+ BOOLEAN ValidOid;
+
+ UINT MissedFrames;
+ UINT Overflows;
+
+ ULONG Buffer;
+ PVOID BufferPtr;
+ UINT BufferLength;
+
+ INT i;
+
+#if _DBG
+ DbgPrint("DC21X4QueryInformation\n");
+ DbgPrint(" Oid = %08x\n",Oid);
+#endif
+
+ Adapter = (PDC21X4_ADAPTER)MiniportAdapterContext;
+
+ // Check that the OID is valid.
+
+ OidArray = (PNDIS_OID)DC21X4GlobalOids;
+ MaxOid = sizeof(DC21X4GlobalOids)/sizeof(ULONG);
+
+ ValidOid = FALSE;
+
+ for (i=0; i<MaxOid; i++) {
+
+ if (Oid == OidArray[i]) {
+ ValidOid = TRUE;
+ break;
+ }
+ }
+ if (ValidOid == FALSE) {
+#if _DBG
+ DbgPrint(" INVALID Oid\n");
+#endif
+ *BytesWritten = 0;
+ return NDIS_STATUS_INVALID_OID;
+ }
+
+ BufferPtr = &Buffer;
+ BufferLength = sizeof(Buffer);
+
+ switch (Oid & OID_TYPE_MASK) {
+
+ case OID_TYPE_GENERAL_OPERATIONAL:
+
+ switch (Oid) {
+
+ case OID_GEN_SUPPORTED_LIST:
+
+ BufferPtr = (PVOID)OidArray;
+ BufferLength = sizeof(DC21X4GlobalOids);
+ break;
+
+ case OID_GEN_HARDWARE_STATUS:
+
+ Buffer = NdisHardwareStatusReady;
+ break;
+
+ case OID_GEN_MEDIA_SUPPORTED:
+ case OID_GEN_MEDIA_IN_USE:
+
+ Buffer = NdisMedium802_3;
+ break;
+
+ case OID_GEN_MEDIA_CONNECT_STATUS:
+
+ Buffer = Adapter->LinkStatus == LinkFail ?
+ NdisMediaStateDisconnected : NdisMediaStateConnected;
+ break;
+
+ case OID_GEN_MAXIMUM_LOOKAHEAD:
+
+ Buffer = DC21X4_MAX_LOOKAHEAD;
+ break;
+
+ case OID_GEN_MAXIMUM_FRAME_SIZE:
+
+ Buffer = DC21X4_MAX_FRAME_SIZE - ETH_HEADER_SIZE;
+ break;
+
+ case OID_GEN_MAXIMUM_TOTAL_SIZE:
+
+ Buffer = DC21X4_MAX_FRAME_SIZE;
+ break;
+
+ case OID_GEN_LINK_SPEED:
+
+ Buffer = Adapter->LinkSpeed;
+ break;
+
+ case OID_GEN_MAC_OPTIONS:
+
+ Buffer = NDIS_MAC_OPTION_TRANSFERS_NOT_PEND
+ | NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA
+ | NDIS_MAC_OPTION_RECEIVE_SERIALIZED
+ | NDIS_MAC_OPTION_NO_LOOPBACK;
+ if (Adapter->FullDuplexLink) {
+ Buffer |= NDIS_MAC_OPTION_FULL_DUPLEX;
+ }
+ Adapter->FullDuplex = Adapter->FullDuplexLink;
+ break;
+
+ case OID_GEN_PROTOCOL_OPTIONS:
+
+ BufferLength = 0;
+ break;
+
+ case OID_GEN_TRANSMIT_BUFFER_SPACE:
+
+ Buffer =
+ ((DC21X4_NUMBER_OF_MAX_TRANSMIT_BUFFERS)
+ *(DC21X4_MAX_TRANSMIT_BUFFER_SIZE + Adapter->CacheLineSize))
+ + ((DC21X4_NUMBER_OF_MAX_TRANSMIT_BUFFERS)
+ *(DC21X4_MAX_TRANSMIT_BUFFER_SIZE + Adapter->CacheLineSize))
+ + (DC21X4_SETUP_BUFFER_SIZE);
+ break;
+
+ case OID_GEN_RECEIVE_BUFFER_SPACE:
+
+ if (Adapter->RcvBufferSpace.AllocSize) {
+ Buffer = Adapter->RcvBufferSpace.AllocSize;
+ }
+ else {
+ Buffer =
+ ( (Adapter->ReceiveRingSize + Adapter->ExtraReceiveBuffers)
+ * (DC21X4_RECEIVE_BUFFER_SIZE + Adapter->RcvHeaderSize + Adapter->CacheLineSize)
+ );
+ }
+ break;
+
+ case OID_GEN_TRANSMIT_BLOCK_SIZE:
+
+ Buffer = DC21X4_MAX_TRANSMIT_BUFFER_SIZE;
+ break;
+
+ case OID_GEN_RECEIVE_BLOCK_SIZE:
+
+ Buffer = DC21X4_RECEIVE_BUFFER_SIZE;
+ break;
+
+ case OID_GEN_VENDOR_ID:
+
+ if (Adapter->PermanentAddressValid) {
+
+ Buffer = 0;
+ MOVE_MEMORY (BufferPtr, Adapter->PermanentNetworkAddress, 3);
+ BufferLength = 3;
+ }
+ else {
+ BufferLength = 0;
+ }
+ break;
+
+ case OID_GEN_VENDOR_DESCRIPTION:
+
+ switch(Adapter->DeviceId) {
+
+ case DC21040_CFID:
+
+ switch (Adapter->AdapterType) {
+
+ case NdisInterfaceEisa:
+
+ BufferPtr = (PVOID)DC21040EisaDescriptor;
+ BufferLength = sizeof(DC21040EisaDescriptor);
+ break;
+
+ default:
+ case NdisInterfacePci:
+
+ BufferPtr = (PVOID)DC21040PciDescriptor;
+ BufferLength = sizeof(DC21040PciDescriptor);
+ break;
+ }
+ break;
+
+ case DC21041_CFID:
+
+ BufferPtr = (PVOID)DC21041PciDescriptor;
+ BufferLength = sizeof(DC21041PciDescriptor);
+ break;
+
+ case DC21140_CFID:
+
+ BufferPtr = (PVOID)DC21140PciDescriptor;
+ BufferLength = sizeof(DC21140PciDescriptor);
+ break;
+
+ case DC21142_CFID:
+
+ BufferPtr = (PVOID)DC21142PciDescriptor;
+ BufferLength = sizeof(DC21142PciDescriptor);
+ break;
+
+
+ default:
+
+ BufferLength = 0;
+ }
+
+ break;
+
+ case OID_GEN_CURRENT_LOOKAHEAD:
+
+ Buffer = DC21X4_MAX_LOOKAHEAD;
+ break;
+
+ case OID_GEN_DRIVER_VERSION:
+
+ Buffer = (DC21X4_NDIS_MAJOR_VERSION << 8)
+ + DC21X4_NDIS_MINOR_VERSION;
+ BufferLength = sizeof(USHORT);
+ }
+
+ break;
+
+ case OID_TYPE_GENERAL_STATISTICS:
+
+ DC21X4_READ_PORT(
+ DC21X4_MISSED_FRAME,
+ &Buffer
+ );
+
+ MissedFrames = Buffer & DC21X4_MISSED_FRAME_COUNTER;
+ Adapter->GeneralMandatory[GM_MISSED_FRAMES] += MissedFrames;
+
+ switch(Adapter->DeviceId) {
+
+ case DC21041_CFID:
+ case DC21142_CFID:
+
+ Overflows = (Buffer >> DC21X4_OVERFLOW_COUNTER_SHIFT)
+ & DC21X4_OVERFLOW_COUNTER;
+ Adapter->IndicateOverflow = (Overflows!=0);
+ Adapter->MediaOptional[MO_RECEIVE_OVERFLOW]+= Overflows;
+
+ }
+
+ OidIndex = (Oid & OID_INDEX_MASK) - 1;
+
+ switch (Oid & OID_REQUIRED_MASK) {
+
+ case OID_REQUIRED_MANDATORY:
+
+ BufferPtr = (PVOID)&Adapter->GeneralMandatory[OidIndex];
+#if _DBG
+ DbgPrint("GMandatory[%d] = %d\n", OidIndex,
+ Adapter->GeneralMandatory[OidIndex]);
+#endif
+ break;
+
+
+ case OID_REQUIRED_OPTIONAL:
+
+ if (Oid == OID_GEN_RCV_CRC_ERROR) {
+
+ BufferPtr = &Adapter->GeneralOptional[GO_RECEIVE_CRC_ERROR];
+ break;
+ }
+
+ if (Oid == OID_GEN_TRANSMIT_QUEUE_LENGTH) {
+
+ BufferPtr = &Adapter->GeneralOptional[GO_TRANSMIT_QUEUE_LENGTH];
+ break;
+ }
+
+ if (OidIndex & 0x01) {
+
+ // Frame count
+ BufferPtr = &Adapter->GeneralOptionalCount[OidIndex >> 1].FrameCount;
+#if _DBG
+ DbgPrint("FrameCount[%d] = %d\n", OidIndex >> 1,
+ Adapter->GeneralOptionalCount[OidIndex >> 1].FrameCount);
+#endif
+ } else {
+
+ // Byte count
+ BufferPtr = &Adapter->GeneralOptionalCount[OidIndex >> 1].ByteCount;
+ BufferLength = sizeof(DC21X4_LARGE_INTEGER);
+#if _DBG
+ DbgPrint("ByteCount[%d] = %d\n", OidIndex >> 1,
+ Adapter->GeneralOptionalCount[OidIndex >> 1].ByteCount);
+#endif
+ }
+
+ }
+
+ break;
+
+ case OID_TYPE_802_3_OPERATIONAL:
+
+ switch (Oid) {
+
+ case OID_802_3_PERMANENT_ADDRESS:
+
+ if (Adapter->PermanentAddressValid) {
+ BufferPtr = Adapter->PermanentNetworkAddress;
+ BufferLength = 6;
+ }
+ else {
+ BufferLength = 0;
+ }
+ break;
+
+ case OID_802_3_CURRENT_ADDRESS:
+
+ BufferPtr = Adapter->CurrentNetworkAddress;
+ BufferLength = 6;
+ break;
+
+ case OID_802_3_MAXIMUM_LIST_SIZE:
+
+ Buffer = Adapter->MaxMulticastAddresses;
+ }
+ break;
+
+ case OID_TYPE_802_3_STATISTICS:
+
+ OidIndex = (Oid & OID_INDEX_MASK) - 1;
+
+ switch (Oid & OID_REQUIRED_MASK) {
+
+ case OID_REQUIRED_MANDATORY:
+
+ BufferPtr = &Adapter->MediaMandatory[OidIndex];
+ break;
+
+ case OID_REQUIRED_OPTIONAL:
+
+ BufferPtr = &Adapter->MediaOptional[OidIndex];
+ }
+ break;
+
+ }
+
+
+ if (BufferLength > InformationBufferLength) {
+ *BytesNeeded = BufferLength;
+ NdisStatus = NDIS_STATUS_INVALID_LENGTH;
+ }
+ else {
+ MOVE_MEMORY(InformationBuffer,BufferPtr,BufferLength);
+ *BytesWritten = BufferLength;
+ NdisStatus = NDIS_STATUS_SUCCESS;
+ }
+
+ return NdisStatus;
+
+}
+
+
+
+
+
+
+
+
+/*+
+ * DC21X4SetInformation
+ *
+ * Routine Description:
+ *
+ * DC21X4SetInformation handles a set operation for a
+ * single OID.
+ *
+-*/
+extern
+NDIS_STATUS
+DC21X4SetInformation(
+ IN NDIS_HANDLE MiniportAdapterContext,
+ IN NDIS_OID Oid,
+ IN PVOID InformationBuffer,
+ IN ULONG InformationBufferLength,
+ OUT PULONG BytesRead,
+ OUT PULONG BytesNeeded
+ )
+
+{
+ NDIS_STATUS NdisStatus;
+ PDC21X4_ADAPTER Adapter;
+ ULONG Filter;
+
+#if _DBG
+ DbgPrint("DC21X4SetInformation\n");
+ DbgPrint(" Oid = %08x\n",Oid);
+#endif
+
+
+ Adapter = (PDC21X4_ADAPTER)MiniportAdapterContext;
+
+ *BytesNeeded = 0;
+
+ switch (Oid) {
+
+ case OID_802_3_MULTICAST_LIST:
+
+ if (InformationBufferLength % ETH_LENGTH_OF_ADDRESS) {
+ *BytesRead = 0;
+ NdisStatus = NDIS_STATUS_INVALID_LENGTH;
+ }
+ else {
+
+ NdisStatus = DC21X4ChangeMulticastAddresses(
+ Adapter,
+ InformationBuffer,
+ (InformationBufferLength/ETH_LENGTH_OF_ADDRESS)
+ );
+ }
+ break;
+
+ case OID_GEN_CURRENT_PACKET_FILTER:
+
+ if (InformationBufferLength != sizeof(Filter)) {
+ *BytesRead = 0;
+ *BytesNeeded = sizeof(Filter);
+ return NDIS_STATUS_INVALID_LENGTH;
+ }
+
+ MOVE_MEMORY(&Filter,InformationBuffer,sizeof(Filter));
+ *BytesRead = 4;
+
+ if (Filter & ( NDIS_PACKET_TYPE_SOURCE_ROUTING
+ | NDIS_PACKET_TYPE_SMT
+ | NDIS_PACKET_TYPE_MAC_FRAME
+ | NDIS_PACKET_TYPE_FUNCTIONAL
+ | NDIS_PACKET_TYPE_ALL_FUNCTIONAL
+ | NDIS_PACKET_TYPE_GROUP
+ )) {
+
+ NdisStatus = NDIS_STATUS_NOT_SUPPORTED;
+ }
+ else {
+
+ NdisStatus = DC21X4ChangeFilter (
+ Adapter,
+ Filter
+ );
+ }
+ break;
+
+ case OID_GEN_CURRENT_LOOKAHEAD:
+
+ // We indicate success but do not modify the
+ // DC21X4 Lookahead parameter which always
+ // indicate the whole packet.
+ //
+
+ NdisStatus = NDIS_STATUS_SUCCESS;
+ break;
+
+ default:
+
+ NdisStatus = NDIS_STATUS_INVALID_OID;
+ }
+
+ return NdisStatus;
+
+}
+
diff --git a/private/ntos/ndis/dc21x4/reset.c b/private/ntos/ndis/dc21x4/reset.c
new file mode 100644
index 000000000..b3fdcecd3
--- /dev/null
+++ b/private/ntos/ndis/dc21x4/reset.c
@@ -0,0 +1,337 @@
+/*+
+ * file: reset.c
+ *
+ * Copyright (C) 1992-1995 by
+ * Digital Equipment Corporation, Maynard, Massachusetts.
+ * All rights reserved.
+ *
+ * This software is furnished under a license and may be used and copied
+ * only in accordance of the terms of such license and with the
+ * inclusion of the above copyright notice. This software or any other
+ * copies thereof may not be provided or otherwise made available to any
+ * other person. No title to and ownership of the software is hereby
+ * transferred.
+ *
+ * The information in this software is subject to change without notice
+ * and should not be construed as a commitment by digital equipment
+ * corporation.
+ *
+ * Digital assumes no responsibility for the use or reliability of its
+ * software on equipment which is not supplied by digital.
+ *
+ *
+ * Abstract: This file contains the Reset code of the
+ * NDIS 4.0 miniport driver for DEC's DC21X4 Ethernet
+ * adapter family.
+ *
+ * Author: Philippe Klein
+ *
+ * Revision History:
+ *
+ * phk 08-Aug-1994 Initial entry
+ *
+-*/
+
+#include <precomp.h>
+
+
+
+
+
+
+
+/*+
+ *
+ *
+ * DC21X4Reset
+ *
+ * Routine Description:
+ *
+ * Reset the adapter
+ *
+-*/
+
+extern
+NDIS_STATUS
+DC21X4Reset(
+ OUT PBOOLEAN AddressingReset,
+ IN NDIS_HANDLE MiniportAdapterContext
+ )
+{
+ PDC21X4_ADAPTER Adapter;
+#if 0
+ PDC21X4_TRANSMIT_DESCRIPTOR CurrentDescriptor;
+#endif
+ INT i;
+ BOOLEAN StartTimer = TRUE;
+ BOOLEAN Link = FALSE;
+
+#if _DBG
+ DbgPrint("DC21X4Reset\n");
+#endif
+
+ Adapter = (PDC21X4_ADAPTER)MiniportAdapterContext;
+ *AddressingReset = FALSE;
+
+
+ //Stop the AutoSense Timer if active
+
+ if (Adapter->TimerFlag != NoTimer) {
+ DC21X4StopAutoSenseTimer(Adapter);
+ }
+
+ // Stop the adapter
+ DC21X4StopAdapter(Adapter);
+
+#if 0
+ // Walk down the Transmit descriptor ring to close all pending packets
+
+ while (Adapter->DequeueTransmitDescriptor != Adapter->EnqueueTransmitDescriptor) {
+
+ CurrentDescriptor = Adapter->DequeueTransmitDescriptor;
+
+ if (CurrentDescriptor->Control & DC21X4_TDES_SETUP_PACKET) {
+
+ // Setup buffer:
+ // Complete the pended Set Information request
+
+#if _DBG
+ DbgPrint("Reset: NdisMSetInformationComplete\n");
+#endif
+ NdisMSetInformationComplete (
+ Adapter->MiniportAdapterHandle,
+ NDIS_STATUS_FAILURE
+ );
+ }
+ else if (CurrentDescriptor->Control & DC21X4_TDES_LAST_SEGMENT) {
+
+#if _DBG
+ DbgPrint("Reset: NdisMSendComplete [Packet: %08x]\n",CurrentDescriptor->Packet);
+#endif
+ NdisMSendComplete(
+ Adapter->MiniportAdapterHandle,
+ CurrentDescriptor->Packet,
+ NDIS_STATUS_FAILURE
+ );
+ }
+ Adapter->DequeueTransmitDescriptor = CurrentDescriptor->Next;
+ }
+#endif
+
+ // Free up all the map registers
+ for (i=0;
+ i < (TRANSMIT_RING_SIZE * NUMBER_OF_SEGMENT_PER_DESC);
+ i++
+ ) {
+
+ if (Adapter->PhysicalMapping[i].Valid) {
+#if _DBG
+ DbgPrint("Reset: NdisMCompleteBufferPhysicalMapping (%d)\n",i);
+#endif
+ NdisMCompleteBufferPhysicalMapping(
+ Adapter->MiniportAdapterHandle,
+ Adapter->PhysicalMapping[i].Buffer,
+ Adapter->PhysicalMapping[i].Register
+ );
+ Adapter->PhysicalMapping[i].Valid = FALSE;
+ Adapter->FreeMapRegisters++;
+ }
+ }
+#if _DBG
+ DbgPrint("Reset: FreeMapRegisters = %d\n",Adapter->FreeMapRegisters);
+#endif
+
+ // Reinitialize the descriptor pointers
+
+ Adapter->DequeueReceiveDescriptor =
+ (PDC21X4_RECEIVE_DESCRIPTOR)Adapter->ReceiveDescriptorRingVa;
+ Adapter->EnqueueTransmitDescriptor =
+ (PDC21X4_TRANSMIT_DESCRIPTOR)Adapter->TransmitDescriptorRingVa;
+ Adapter->DequeueTransmitDescriptor =
+ Adapter->EnqueueTransmitDescriptor;
+
+ Adapter->FreeTransmitDescriptorCount = TRANSMIT_RING_SIZE - 1;
+
+ // Initialize the statistic counters
+
+ ZERO_MEMORY (
+ &Adapter->GeneralMandatory[0],
+ GM_ARRAY_SIZE * sizeof(ULONG)
+ );
+ ZERO_MEMORY (
+ &Adapter->GeneralOptional[0],
+ GO_ARRAY_SIZE * sizeof(ULONG)
+ );
+ ZERO_MEMORY (
+ &Adapter->GeneralOptionalCount[0],
+ GO_COUNT_ARRAY_SIZE * sizeof(GEN_OPTIONAL_COUNT)
+ );
+ ZERO_MEMORY (
+ &Adapter->MediaMandatory[0],
+ MM_ARRAY_SIZE * sizeof(ULONG)
+ );
+ ZERO_MEMORY (
+ &Adapter->MediaOptional[0],
+ MO_ARRAY_SIZE * sizeof(ULONG)
+ );
+
+#if _DBG
+ DbgPrint("initialize DC21X4 CSRS\n");
+#endif
+
+ // Renitialize the DC21X4 registers
+ DC21X4InitializeRegisters(Adapter);
+
+ // Initialize the PHY
+ if (Adapter->PhyMediumInSrom) {
+ Adapter->PhyPresent = DC21X4PhyInit(Adapter);
+ }
+ if (Adapter->PhyPresent) {
+
+#if 0
+ if (!(Adapter->MiiMediaType & MEDIA_NWAY)) {
+
+ DC21X4SetPhyControl(
+ Adapter,
+ (USHORT)MiiGenAdminIsolate
+ );
+ }
+#endif
+
+ DC21X4SetPhyConnection(Adapter);
+
+ }
+
+ // Because the DC21X4 wakes up in promiscuous mode after reset
+ // we reload the DC21X4's Cam (in polling mode)
+
+ if (!DC21X4LoadCam(
+ Adapter,
+ FALSE)) {
+ return NDIS_STATUS_HARD_ERRORS;
+ }
+
+ if (!Adapter->PhyPresent) {
+ DC21X4InitializeMediaRegisters(Adapter,FALSE);
+ }
+
+ Adapter->FirstAncInterrupt = TRUE;
+ Adapter->IndicateOverflow = FALSE;
+
+//// //Restart the Transmitter and Receiver
+//// DC21X4StartAdapter(Adapter);
+
+ // Media link Detection
+ if (Adapter->PhyPresent) {
+ Link = DC21X4MiiAutoDetect(
+ Adapter
+ );
+ }
+ if ( (!Adapter->PhyPresent)
+ || (!Link
+ && (Adapter->MediaCapable)
+ )
+ ) {
+
+ StartTimer = DC21X4MediaDetect(
+ Adapter
+ );
+ }
+
+ // Start the Autosense timer if not yet started
+
+ if (StartTimer && (Adapter->TimerFlag==NoTimer)) {
+
+ DC21X4StartAutoSenseTimer(
+ Adapter,
+ ((Adapter->PhyPresent) ? DC21X4_MII_TICK : DC21X4_SPA_TICK)
+ );
+ }
+
+ if (Adapter->LinkStatus == LinkFail) {
+
+ // Defer the completion of the reset routine
+ // until the Link is up
+
+ Adapter->LinkCheckCount = MAX_LINK_CHECK;
+
+ NdisMSetTimer(
+ &Adapter->ResetTimer,
+ LINK_CHECK_PERIOD
+ );
+ Adapter->ResetInProgress = TRUE;
+ return NDIS_STATUS_PENDING;
+
+ }
+ else {
+
+ //Restart the Receiver & Transmitter
+ DC21X4StartAdapter(Adapter);
+
+ //Complete the Reset routine synchronously
+ return NDIS_STATUS_SUCCESS;
+ }
+}
+
+/*+
+ *
+ *
+ * DC21X4DeferredReset
+ *
+ * Routine Description:
+ *
+ * Reset routine
+ *
+-*/
+extern
+VOID
+DC21X4DeferredReset (
+ IN PVOID Systemspecific1,
+ IN PDC21X4_ADAPTER Adapter,
+ IN PVOID Systemspecific2,
+ IN PVOID Systemspecific3
+ )
+{
+
+#if _DBG
+ DbgPrint("DC21X4DeferredReset\n");
+#endif
+
+#if __DBG
+ DbgPrint("DC21X4DeferredReset: LinkStatus=%x LinkCheckCount=%d\n",
+ Adapter->LinkStatus,Adapter->LinkCheckCount);
+#endif
+ Adapter->LinkCheckCount--;
+
+ if ( (Adapter->LinkStatus !=LinkFail)
+ || (Adapter->LinkCheckCount == 0)
+ ) {
+
+ //Indicate the assynchronous completion of the
+ //Reset routine
+
+#if __DBG
+ DbgPrint("DC21X4DeferredReset: Indicate ResetComplete\n");
+#endif
+ NdisMResetComplete(
+ Adapter->MiniportAdapterHandle,
+ NDIS_STATUS_SUCCESS,
+ FALSE
+ );
+
+ Adapter->ResetInProgress = FALSE;
+
+ //Restart the Receiver & Transmitter
+ DC21X4StartAdapter(Adapter);
+
+ }
+ else {
+ // Fire the ResetTimer for an other link check
+ NdisMSetTimer(
+ &Adapter->ResetTimer,
+ LINK_CHECK_PERIOD
+ );
+ }
+
+}
+
diff --git a/private/ntos/ndis/dc21x4/send.c b/private/ntos/ndis/dc21x4/send.c
new file mode 100644
index 000000000..7cfbacf94
--- /dev/null
+++ b/private/ntos/ndis/dc21x4/send.c
@@ -0,0 +1,664 @@
+/*+
+ * file: send.c
+ *
+ * Copyright (C) 1992-1995 by
+ * Digital Equipment Corporation, Maynard, Massachusetts.
+ * All rights reserved.
+ *
+ * This software is furnished under a license and may be used and copied
+ * only in accordance of the terms of such license and with the
+ * inclusion of the above copyright notice. This software or any other
+ * copies thereof may not be provided or otherwise made available to any
+ * other person. No title to and ownership of the software is hereby
+ * transferred.
+ *
+ * The information in this software is subject to change without notice
+ * and should not be construed as a commitment by digital equipment
+ * corporation.
+ *
+ * Digital assumes no responsibility for the use or reliability of its
+ * software on equipment which is not supplied by digital.
+ *
+ *
+ * Abstract: This file is part of the NDIS 4.0 miniport driver for
+ * Digital Equipment's DC21X4 Ethernet adapter family.
+ * It contains the code for submitting a packet for
+ * transmission.
+ *
+ * Author: Philippe Klein
+ *
+ * Revision History:
+ *
+ * phk 28-Aug-1994 creation date
+ *
+-*/
+
+#include <precomp.h>
+#include <crc.h>
+
+
+
+
+
+
+
+
+
+
+
+/*+
+ * DC21X4Send
+ *
+ * Routine Description:
+ *
+ * The DC21X4Send request instructs a MAC to transmit a packet through
+ * the adapter onto the medium.
+ *
+ * Arguments:
+ *
+ * MiniportAdapterContext -
+ * Packet - A pointer to a descriptor for the packet to transmit
+ *
+ * Return Value:
+ *
+ * The status of the operation.
+ *
+-*/
+
+extern
+NDIS_STATUS
+DC21X4Send(
+ IN NDIS_HANDLE MiniportAdapterContext,
+ IN PNDIS_PACKET Packet,
+ IN UINT Flags
+ )
+{
+
+ PDC21X4_ADAPTER Adapter;
+
+ UINT PacketSize;
+ UCHAR PacketType;
+
+ PNDIS_BUFFER CurrentBuffer;
+ UINT NdisBufferCount;
+ UINT PhysicalSegmentCount;
+ UINT MapTableIndex;
+
+ PVOID TxmBuffer;
+ PUCHAR Tmp;
+
+ NDIS_STATUS NdisStatus;
+ NDIS_PHYSICAL_ADDRESS_UNIT PhysicalSegmentArray[DC21X4_MAX_SEGMENTS];
+ UINT BufferPhysicalSegments;
+
+ BOOLEAN FirstSegment;
+ BOOLEAN FirstBuffer;
+
+ PDC21X4_TRANSMIT_DESCRIPTOR FirstSegmentDescriptor=NULL;
+ PDC21X4_TRANSMIT_DESCRIPTOR LastSegmentDescriptor=NULL;
+ PDC21X4_TRANSMIT_DESCRIPTOR CurrentDescriptor=NULL;
+
+ UINT Length;
+ UINT Buffer;
+ UINT Segment;
+
+ UCHAR SendMode;
+
+ BOOLEAN GenerateCRC=FALSE;
+
+ ULONG TxmDescriptorCount = 0;
+ ULONG MapRegistersCount = 0;
+ ULONG MaxTransmitBufferCount = 0;
+ ULONG MinTransmitBufferCount = 0;
+ ULONG GoTransmitCount = 0;
+
+#if _DBG
+ DbgPrint("DC21X4Send AdapterContext =%x Packet=%08x\n",
+ MiniportAdapterContext,Packet);
+#endif
+
+ Adapter = (PDC21X4_ADAPTER)(MiniportAdapterContext);
+
+ //Check the link status
+ if (Adapter->LinkStatus == LinkFail) {
+ return NDIS_STATUS_NO_CABLE;
+ }
+
+ NdisQueryPacket(
+ Packet,
+ &PhysicalSegmentCount,
+ &NdisBufferCount,
+ &CurrentBuffer,
+ &PacketSize
+ );
+
+ if (PacketSize > DC21X4_MAX_FRAME_SIZE) {
+ return NDIS_STATUS_INVALID_PACKET;
+ }
+
+ // NT BUG: Clean up the msw of the PhysicalSegmentCount
+ PhysicalSegmentCount &= 0xFFFF;
+
+#if _DBG
+ DbgPrint(" PacketSize= %d\n BufferCount= %d\n SegmentCount= %d\n",
+ PacketSize,NdisBufferCount,PhysicalSegmentCount);
+ DbgPrint(" FreeTxmDescCount = %d\n",Adapter->FreeTransmitDescriptorCount);
+#endif
+
+ ASSERT(NdisBufferCount != 0);
+
+ // DC21040 Pass1 and Pass2:
+ // if SoftwareCRC mode is enabled, generate the CRC by software
+ // for packet > Transmit threshold
+
+ if (Adapter->SoftwareCRC) {
+ GenerateCRC = (PacketSize > Adapter->TxmThreshold);
+ }
+
+ // if the Ndis Packet is too fragmented or GenerateCRC is on,
+ // copy the packet into a single buffer
+
+ if ( (PhysicalSegmentCount > Adapter->PhysicalSegmentThreshold) || GenerateCRC ) {
+
+ if ((Adapter->MaxTransmitBufferInUse == DC21X4_NUMBER_OF_MAX_TRANSMIT_BUFFERS) ||
+ (Adapter->FreeTransmitDescriptorCount <= DC21X4_NUMBER_OF_SETUP_DESCRIPTORS)
+ ) {
+
+ // All the Txm buffer are currently allocated or
+ // there is no free Txm descriptor in the ring
+#if _DBG
+ DbgPrint ("No free Txm buffer or Txm desc...\n");
+#endif
+ return NDIS_STATUS_RESOURCES;
+ }
+ else {
+ SendMode = CopyMaxBuffer;
+ }
+ }
+
+ // if the Ndis Packet is smaller than DC21X4_MIN_TXM_SIZE,
+ // copy the packet into a preallocated Txm buffer if the resource
+ // is available
+
+ else if ((PacketSize <= DC21X4_MIN_TXM_SIZE)
+ && (Adapter->MinTransmitBufferInUse < DC21X4_NUMBER_OF_MIN_TRANSMIT_BUFFERS)
+ && !Adapter->DontUseMinTransmitBuffer)
+ {
+ SendMode = CopyMinBuffer;
+ }
+
+ // Check if there are enough descriptors available in the ring to load
+ // the packet and enough free map registers to map the whole packet
+
+ else if ( (PhysicalSegmentCount >
+ ((Adapter->FreeTransmitDescriptorCount - DC21X4_NUMBER_OF_SETUP_DESCRIPTORS) * NUMBER_OF_SEGMENT_PER_DESC))
+ ||(PhysicalSegmentCount > Adapter->FreeMapRegisters)
+ ){
+
+ // not enough descriptors in the ring
+ // or enough map registers to load the whole packet
+#if _DBG
+ DbgPrint("Not enough txm desc or enough map registers\n");
+ DbgPrint("Phys. segment count=%d FreeTxDesc=%d FreeMapReg=%d\n",
+ PhysicalSegmentCount,
+ (Adapter->FreeTransmitDescriptorCount-DC21X4_NUMBER_OF_SETUP_DESCRIPTORS) * NUMBER_OF_SEGMENT_PER_DESC,
+ Adapter->FreeMapRegisters);
+#endif
+ return NDIS_STATUS_RESOURCES;
+ }
+ else {
+ SendMode = MappedBuffer;
+ }
+
+ // For now, do not separately count multicast, broadcast and
+ // directed packets/bytes and avoid having to map the buffer, which
+ // is a very expensive operation. The mapping happens when we call
+ // NdisQueryBuffer with a VirtualAddress argument.
+#if 0
+ NdisQueryBuffer(
+ CurrentBuffer,
+ &TxmBuffer,
+ &Length
+ );
+
+ ASSERT(Length >= ETH_LENGTH_OF_ADDRESS);
+
+ PacketType = CHECK_PACKET_TYPE(TxmBuffer);
+#else
+ PacketType = TXM_DIRECTED_FRAME;
+#endif
+
+
+ // Until Send and Request are serialized
+ // the Enqueue pointer which can modified in both
+ // send and filter routines should be protected by a SpinLock
+
+ if (Adapter->FullDuplex) {
+ NdisDprAcquireSpinLock(&Adapter->EnqueueSpinLock);
+ }
+
+
+ switch (SendMode) {
+
+ case CopyMaxBuffer:
+
+ // Copy the Packet into a Max Txm Buffer
+
+ TxmBuffer = (PVOID)Adapter->MaxTransmitBuffer[Adapter->MaxTransmitBufferIndex].Va;
+
+#if _DBG
+ DbgPrint ("Copy packet %x into a Max Txm buffer [%d]\n",Packet,Adapter->MaxTransmitBufferIndex);
+#endif
+
+ CopyFromPacketToBuffer (
+ Packet,
+ 0,
+ TxmBuffer,
+ PacketSize,
+ &Length
+ );
+
+ ASSERT (Length == PacketSize);
+ ASSERT(Length >= ETH_LENGTH_OF_ADDRESS);
+
+ CurrentDescriptor = Adapter->EnqueueTransmitDescriptor;
+
+ Adapter->EnqueueTransmitDescriptor = CurrentDescriptor->Next;
+
+ MaxTransmitBufferCount++;
+ TxmDescriptorCount++;
+
+
+ //Clear all the Descriptor Control word but the SECOND_ADDR_CHAINED flag;
+ CurrentDescriptor->Control &= DC21X4_TDES_SECOND_ADDR_CHAINED;
+
+ // If GenerateCRC, add the software generated CRC
+ // to the end of the buffer
+
+ if (GenerateCRC) {
+
+ Tmp = (PUCHAR)TxmBuffer;
+ *(UNALIGNED ULONG *)&Tmp[PacketSize] =
+ CRC32 (
+ &Tmp[0],
+ PacketSize
+ );
+ PacketSize += sizeof(UINT);
+ CurrentDescriptor->Control |= DC21X4_TDES_ADD_CRC_DISABLE;
+#if _DBG
+ DbgPrint(" Software CRC = %02x %02x %02x %02x\n",
+ Tmp[PacketSize-4],Tmp[PacketSize-3],
+ Tmp[PacketSize-2],Tmp[PacketSize-1]);
+#endif
+ }
+
+ CurrentDescriptor->Control |= (
+ DC21X4_TDES_FIRST_SEGMENT
+ | PacketSize);
+
+ FirstSegmentDescriptor = CurrentDescriptor;
+ LastSegmentDescriptor = FirstSegmentDescriptor;
+
+ CurrentDescriptor->FirstBufferAddress =
+ Adapter->MaxTransmitBuffer[Adapter->MaxTransmitBufferIndex].Pa;
+
+ NdisFlushBuffer(
+ Adapter->MaxTransmitBuffer[Adapter->MaxTransmitBufferIndex].FlushBuffer,
+ TRUE
+ );
+
+ Adapter->MaxTransmitBufferIndex++;
+ Adapter->MaxTransmitBufferIndex &= (DC21X4_NUMBER_OF_MAX_TRANSMIT_BUFFERS-1);
+
+#if _DBG
+ DbgPrint (" [%08x]\n %08x\n %08x\n %08x\n",
+ CurrentDescriptor,
+ CurrentDescriptor->Status,
+ CurrentDescriptor->Control,
+ CurrentDescriptor->FirstBufferAddress);
+#endif
+ NdisStatus = NDIS_STATUS_PENDING;
+// NdisStatus = NDIS_STATUS_SUCCESS; // hapi stress test pb
+
+ break;
+
+
+ case CopyMinBuffer:
+
+ // Copy the Packet into a Min Txm Buffer
+
+ TxmBuffer = (PVOID)Adapter->MinTransmitBuffer[Adapter->MinTransmitBufferIndex].Va;
+
+#if _DBG
+ DbgPrint ("Copy packet %x into a Min Txm buffer [%d]\n",
+ Packet,Adapter->MinTransmitBufferIndex);
+#endif
+
+ CopyFromPacketToBuffer (
+ Packet,
+ 0,
+ TxmBuffer,
+ PacketSize,
+ &Length
+ );
+
+ ASSERT (Length == PacketSize);
+
+ ASSERT(Length >= ETH_LENGTH_OF_ADDRESS);
+
+ CurrentDescriptor = Adapter->EnqueueTransmitDescriptor;
+
+ Adapter->EnqueueTransmitDescriptor = CurrentDescriptor->Next;
+
+ MinTransmitBufferCount++;
+ TxmDescriptorCount++;
+
+
+ //Clear all the Descriptor Control word but the SECOND_ADDR_CHAINED flag;
+ CurrentDescriptor->Control &= DC21X4_TDES_SECOND_ADDR_CHAINED;
+
+
+ CurrentDescriptor->Control |= (
+ DC21X4_TDES_FIRST_SEGMENT
+ | PacketSize);
+
+ FirstSegmentDescriptor = CurrentDescriptor;
+ LastSegmentDescriptor = FirstSegmentDescriptor;
+
+ CurrentDescriptor->FirstBufferAddress =
+ Adapter->MinTransmitBuffer[Adapter->MinTransmitBufferIndex].Pa;
+
+ NdisFlushBuffer(
+ Adapter->MinTransmitBuffer[Adapter->MinTransmitBufferIndex].FlushBuffer,
+ TRUE
+ );
+
+ Adapter->MinTransmitBufferIndex++;
+ Adapter->MinTransmitBufferIndex &= (DC21X4_NUMBER_OF_MIN_TRANSMIT_BUFFERS-1);
+
+#if _DBG
+ DbgPrint (" [%08x]\n %08x\n %08x\n %08x\n",
+ CurrentDescriptor,
+ CurrentDescriptor->Status,
+ CurrentDescriptor->Control,
+ CurrentDescriptor->FirstBufferAddress);
+#endif
+
+ NdisStatus = NDIS_STATUS_PENDING;
+// NdisStatus = NDIS_STATUS_SUCCESS; // hapi stress test pb
+
+ break;
+
+
+ case MappedBuffer:
+
+ FirstSegment = TRUE;
+ FirstBuffer = TRUE;
+
+ FirstSegmentDescriptor = Adapter->EnqueueTransmitDescriptor;
+ LastSegmentDescriptor = FirstSegmentDescriptor;
+
+ MapTableIndex = FirstSegmentDescriptor->MapTableIndex;
+
+ FirstSegmentDescriptor->Control &= DC21X4_TDES_SECOND_ADDR_CHAINED ;
+ FirstSegmentDescriptor->Control |= DC21X4_TDES_FIRST_SEGMENT;
+
+
+ for (Buffer=0; Buffer<NdisBufferCount; Buffer++) {
+
+ // Get the mapping of the physical segments
+ // of the current buffer
+#if _DBG
+ DbgPrint("NdisMStartBufferPhysicalMapping (%d)\n",MapTableIndex);
+ DbgPrint("MapRegisterIndex = %d\n",Adapter->MapRegisterIndex);
+ DbgPrint("FreeMapRegisters = %d\n",Adapter->FreeMapRegisters);
+#endif
+
+ NdisMStartBufferPhysicalMapping(
+ Adapter->MiniportAdapterHandle,
+ CurrentBuffer,
+ Adapter->MapRegisterIndex,
+ TRUE,
+ PhysicalSegmentArray,
+ &BufferPhysicalSegments
+ );
+
+ if (BufferPhysicalSegments) {
+
+ // Save the CurrentBuffer address for NdisCompleteBufferPhysicalMapping
+
+ Adapter->PhysicalMapping[MapTableIndex].Register = Adapter->MapRegisterIndex;
+ Adapter->PhysicalMapping[MapTableIndex].Buffer = CurrentBuffer;
+ Adapter->PhysicalMapping[MapTableIndex].Valid = TRUE;
+
+ Adapter->MapRegisterIndex++;
+ if (Adapter->MapRegisterIndex >= Adapter->AllocMapRegisters) {
+ Adapter->MapRegisterIndex = 0;
+ }
+
+ MapRegistersCount++;
+
+ // Put the physical segments for this buffer into
+ // the transmit descriptors.
+#if _DBG
+ DbgPrint(" Nb segments = %d\n",BufferPhysicalSegments);
+#endif
+ for (Segment=0; Segment<BufferPhysicalSegments;) {
+
+ ASSERT (NdisGetPhysicalAddressHigh(PhysicalSegmentArray[Segment].PhysicalAddress) == 0);
+
+ if (FirstBuffer) {
+
+ FirstBuffer = FALSE;
+
+ CurrentDescriptor = Adapter->EnqueueTransmitDescriptor;
+ LastSegmentDescriptor = CurrentDescriptor;
+
+ // Point to the next descriptor in the ring;
+ Adapter->EnqueueTransmitDescriptor= (Adapter->EnqueueTransmitDescriptor)->Next;
+
+ TxmDescriptorCount++;
+
+ if (FirstSegment) {
+
+ // The ownership bit of the first segment descriptor will be changed
+ // after the entire frame is fully mapped into the transmit ring
+
+ FirstSegment = FALSE;
+
+ }
+ else {
+
+ //Clear all the Descriptor Control word but the SECOND_ADDR_CHAINED flag;
+ CurrentDescriptor->Control &= DC21X4_TDES_SECOND_ADDR_CHAINED ;
+
+ // set the ownership bit to DC21X4
+ CurrentDescriptor->Status = DESC_OWNED_BY_DC21X4;
+ }
+
+ //First BufferSize
+ CurrentDescriptor->Control |= PhysicalSegmentArray[Segment].Length;
+
+ //First Buffer Address
+ CurrentDescriptor->FirstBufferAddress =
+ NdisGetPhysicalAddressLow(PhysicalSegmentArray[Segment].PhysicalAddress);
+
+ MapTableIndex++;
+
+ }
+ else {
+
+ FirstBuffer=TRUE;
+
+ MapTableIndex = (Adapter->EnqueueTransmitDescriptor)->MapTableIndex;
+
+ if (CurrentDescriptor->Control & DC21X4_TDES_SECOND_ADDR_CHAINED) {
+ continue;
+ }
+ else {
+
+ // Second BufferSize
+ CurrentDescriptor->Control |=
+ (PhysicalSegmentArray[Segment].Length << TDES_SECOND_BUFFER_SIZE_BIT_NUMBER);
+
+ // Second Buffer Address
+ CurrentDescriptor->SecondBufferAddress =
+ NdisGetPhysicalAddressLow(PhysicalSegmentArray[Segment].PhysicalAddress);
+ }
+ }
+ Segment++;
+ }
+ }
+
+ else {
+
+ // No physical segments in this Ndis buffer
+
+ NdisMCompleteBufferPhysicalMapping(
+ Adapter->MiniportAdapterHandle,
+ CurrentBuffer,
+ Adapter->MapRegisterIndex
+ );
+
+ }
+
+ NdisFlushBuffer(
+ CurrentBuffer,
+ TRUE
+ );
+
+ // Get the Next Buffer;
+
+ NdisGetNextBuffer(
+ CurrentBuffer,
+ &CurrentBuffer
+ );
+
+ }
+
+ NdisStatus = NDIS_STATUS_PENDING;
+
+ break;
+
+ }
+
+ // Save the information needed by the Txm interrupt handler
+ // to complete the Send request
+
+ LastSegmentDescriptor->Packet = Packet;
+ LastSegmentDescriptor->PacketType = PacketType;
+ LastSegmentDescriptor->PacketSize = PacketSize;
+ LastSegmentDescriptor->SendStatus = SendMode;
+
+ LastSegmentDescriptor->Control |= DC21X4_TDES_LAST_SEGMENT;
+
+ LastSegmentDescriptor->Control |= DC21X4_TDES_INTERRUPT_ON_COMPLETION;
+
+ GoTransmitCount++;
+
+ // Desc Pointer of last segment descriptor points the first segment descriptor
+ LastSegmentDescriptor->DescPointer = FirstSegmentDescriptor;
+
+ // Desc Pointer of first segment descriptor points the last segment descriptor
+ FirstSegmentDescriptor->DescPointer = LastSegmentDescriptor;
+
+ if (Adapter->FullDuplex) {
+ NdisDprReleaseSpinLock(&Adapter->EnqueueSpinLock);
+ NdisDprAcquireSpinLock(&Adapter->FullDuplexSpinLock);
+ }
+
+ Adapter->FreeTransmitDescriptorCount -= TxmDescriptorCount;
+
+ Adapter->FreeMapRegisters -= MapRegistersCount;
+
+ Adapter->MaxTransmitBufferInUse += MaxTransmitBufferCount;
+
+ Adapter->MinTransmitBufferInUse += MinTransmitBufferCount;
+
+ Adapter->GeneralOptional[GO_TRANSMIT_QUEUE_LENGTH] += GoTransmitCount;
+
+ if (Adapter->FullDuplex) {
+ NdisDprReleaseSpinLock(&Adapter->FullDuplexSpinLock);
+ }
+
+ // Set the Ownership bit off the First_Segment descriptor;
+ FirstSegmentDescriptor->Status = DESC_OWNED_BY_DC21X4;
+
+ if (!Adapter->DisableTransmitPolling) {
+
+ // Poll Transmit the adapter
+
+ DC21X4_WRITE_PORT(
+ DC21X4_TXM_POLL_DEMAND,
+ 1
+ );
+ }
+
+ return NdisStatus;
+
+}
+
+
+
+
+
+
+
+
+
+
+/*+
+ *
+ * CRC32
+ *
+ * Routine Description:
+ *
+ * Generate a CRC-32 from the data stream
+ *
+ * Arguments:
+ *
+ * Data - the data stream
+ * Len - the length of the stream
+ *
+ *Return Value:
+ *
+ * CRC-32
+ *
+-*/
+extern
+ULONG
+CRC32 (
+ IN PUCHAR Data,
+ IN UINT Len
+ )
+{
+ ULONG Crc = 0xffffffff;
+
+ while (Len--) {
+ Crc = CrcTable[(Crc ^ *Data++) & 0xFF] ^ (Crc >> 8);
+ }
+
+ return ~Crc;
+
+}
+
+
+
+
+
+
+/*+
+ *
+ * NdisSendPackets
+ *
+ *
+-*/
+NDIS_STATUS
+DC21X4SendPackets(
+ IN NDIS_HANDLE MiniportAdapterContext,
+ IN PPNDIS_PACKET PacketArray,
+ IN UINT NumberOfPackets
+ ) {
+ return NDIS_STATUS_SUCCESS;
+}
+
diff --git a/private/ntos/ndis/dc21x4/sources b/private/ntos/ndis/dc21x4/sources
new file mode 100644
index 000000000..646d7d741
--- /dev/null
+++ b/private/ntos/ndis/dc21x4/sources
@@ -0,0 +1,58 @@
+!if 0
+ Copyright (C) 1992-1995 by Digital Equipment Corporation
+
+Module Name:
+
+ sources.
+
+Abstract:
+
+ This file specifies the DC21X4 NDIS 4.0 miniport driver being built
+ and the list of sources files needed to build it.
+ It specifies also the compiler switches specific to this driver
+
+Author:
+
+ Philippe Klein
+
+!endif
+
+TARGETNAME=DC21X4
+TARGETTYPE=DRIVER
+
+TARGETPATH=$(BASEDIR)\public\sdk\lib
+TARGETLIBS=$(BASEDIR)\public\sdk\lib\*\ndis.lib
+INCLUDES=..\..\inc
+
+C_DEFINES=$(C_DEFINES) -DNDIS_MINIPORT_DRIVER
+C_DEFINES=$(C_DEFINES) -DNDIS40_MINIPORT
+C_DEFINES=$(C_DEFINES) -DBINARY_COMPATIBLE=0
+C_DEFINES=$(C_DEFINES) -DDBG=0
+
+MSC_WARNING_LEVEL=/W3 /WX
+
+SOURCES=alloc.c \
+ copy.c \
+ dc21x4.c \
+ filter.c \
+ init.c \
+ interrup.c \
+ media.c \
+ monitor.c \
+ register.c \
+ request.c \
+ reset.c \
+ send.c \
+ srom.c \
+ mactophy.c \
+ miigen.c \
+ miiphy.c \
+ dc21x4.rc
+
+NTTARGETFILES=dc21x4.hlp
+
+PRECOMPILED_INCLUDE=precomp.h
+PRECOMPILED_PCH=precomp.pch
+PRECOMPILED_OBJ=precomp.obj
+
+
diff --git a/private/ntos/ndis/dc21x4/srom.c b/private/ntos/ndis/dc21x4/srom.c
new file mode 100644
index 000000000..85962f2c2
--- /dev/null
+++ b/private/ntos/ndis/dc21x4/srom.c
@@ -0,0 +1,1521 @@
+/*+
+ * file: srom.c
+ *
+ * Copyright (C) 1992-1995 by
+ * Digital Equipment Corporation, Maynard, Massachusetts.
+ * All rights reserved.
+ *
+ * This software is furnished under a license and may be used and copied
+ * only in accordance of the terms of such license and with the
+ * inclusion of the above copyright notice. This software or any other
+ * copies thereof may not be provided or otherwise made available to any
+ * other person. No title to and ownership of the software is hereby
+ * transferred.
+ *
+ * The information in this software is subject to change without notice
+ * and should not be construed as a commitment by digital equipment
+ * corporation.
+ *
+ * Digital assumes no responsibility for the use or reliability of its
+ * software on equipment which is not supplied by digital.
+ *
+ *
+ * Abstract: This file contains the code to access the onboard ROM of
+ * adapters based on DEC's DC21X4 Ethernet Controller.
+ *
+ * Author: Philippe klein
+ *
+ * Revision History:
+ *
+ * 05-Oct-95 phk Modified Miniport version
+ * 10-Jan-95 phk Add ParseSRom
+ * 29-Nov-95 phk Add parsing for SROM format V3
+ *
+-*/
+
+#include <precomp.h>
+
+#define SROM_93LC46B_SIZE 64 //words
+#define SROM_93LC46B_MAX_CYCLES 25
+#define SROM_93LC46B_ADDRESS_MSB 5
+#define SROM_93LC46B_DATA_MSB 15
+#define SROM_93LC46B_DATA_BIT 3
+
+#define SROM_93LC46B_VALID_BITMASK 0x8
+
+#define SROM_93LC46B_DELAY (10)
+
+#define CSR_READ 0x4000
+#define CSR_WRITE 0x2000
+#define SEL_SROM 0x0800
+#define DATA_1 0x0004
+#define DATA_0 0x0000
+#define CLK 0x0002
+#define CS 0x0001
+
+#define DISABLE_AUTOSENSE 0x8000
+
+#define EXT 0x40
+#define DC21X4_MEDIA 0x3F
+
+
+#define MODE 0x0071
+#define SENSE_BN 0x000E
+#define SENSE_DIS 0x8000
+#define DEFAULT 0x4000
+#define POLARITY 0x0080
+
+#define SENSE_SHIFT 1
+#define MODE_SHIFT 18
+
+#define SROM_LEGACY 0x00
+#define SROM_V1 0x01
+#define SROM_V2 0x02
+#define SROM_V3 0x03
+
+#define SROM_SIZE (SROM_93LC46B_SIZE*2)
+
+#define SROM_IEEE_LEN 32
+#define TEST_PATTERN 0xAA5500FF
+#define SROM_TIMEOUT 50
+
+#define ZX312_SIGNATURE 0x0095C000
+
+#define GET_MODE(_command) \
+ ( (*(UNALIGNED ULONG *)(_command) & MODE) << MODE_SHIFT )
+
+#define IF_DEFAULT_MEDIA(_command) \
+ ( *(UNALIGNED ULONG *)(_command) & DEFAULT )
+
+#define GET_POLARITY(_command) \
+ ( (*(UNALIGNED ULONG *)(_command) & POLARITY) ? 0xffffffff : 0 )
+
+#define GET_SENSE_MASK(_command) \
+ ((*(UNALIGNED ULONG *)(_command) & SENSE_DIS) ? \
+ 0 : (ULONG)(1 << ((*(UNALIGNED ULONG *)(_command) & SENSE_BN)>> SENSE_SHIFT )))
+
+#pragma pack(1)
+typedef struct _SROM_ID_BLOCK{
+
+ USHORT VendorID;
+ USHORT SysID;
+ USHORT Reserved[6];
+ USHORT ID_Checksum;
+ UCHAR FormatVersion;
+ UCHAR AdapterCount;
+ UCHAR NetworkAddress[ETH_LENGTH_OF_ADDRESS];
+
+} SROM_ID_BLOCK, *PSROM_ID_BLOCK;
+
+typedef struct _ADAPTER_ENTRIES{
+
+ UCHAR DeviceNumber;
+ USHORT Offset;
+
+} ADAPTER_ENTRIES, *PADAPTER_ENTRIES;
+
+#pragma pack()
+
+#define DE500_STR 0x1D
+#define BOARD_SIGNATURE(_srom) \
+ ((*(UNALIGNED ULONG *)&(_srom)[DE500_STR] == *(PULONG)&DE500Strng[0]) && \
+ (*(UNALIGNED ULONG *)&(_srom)[DE500_STR+sizeof(ULONG)] == *(PULONG)&DE500Strng[sizeof(ULONG)]))
+
+// PHY Parsing definitions
+
+#define EXTENDED_FORMAT 0x80
+
+#define LENGTH 0x7f
+#define TYPE_0 0x0
+#define TYPE_1 0x1
+#define TYPE_2 0x2
+#define TYPE_3 0x3
+
+#define MEDIA_CAPABILITIES_MASK 0xf800
+#define NWAY_ADVERTISEMENT_MASK 0x03e0
+
+
+
+
+
+
+
+
+
+
+#pragma NDIS_PAGABLE_FUNCTION(DC21X4ReadSerialRom)
+
+/*+
+ *
+ * DC21X4ReadSerialRom
+ *
+ * Routine Description:
+ *
+ * Read the Dc21X4 Serial Rom to retrieve the adapter information
+ *
+ * Arguments:
+ *
+ * Adapter
+ *
+ * Return Value:
+ *
+ * Status
+ *
+ *
+-*/
+extern
+NDIS_STATUS
+DC21X4ReadSerialRom (
+ IN PDC21X4_ADAPTER Adapter
+ )
+
+{
+ UNALIGNED UCHAR *EthAddress;
+ UCHAR IdProm[SROM_IEEE_LEN *2];
+
+ ULONG Value;
+ INT Time;
+ UINT i;
+
+#if __DBG
+ DbgPrint ("DC21X4ReadSerialROM\n");
+#endif
+
+ //Read the Station Address
+
+ switch (Adapter->AdapterType) {
+
+ case NdisInterfacePci:
+
+ // Read the Network Address from the PCI board ID ROM
+ // through DC21X4's Serial ROM port
+
+ switch (Adapter->DeviceId) {
+
+ default:
+
+ return DC21X4ParseSRom(Adapter);
+
+ case DC21040_CFID:
+
+ Adapter->MediaCapable =
+ (MEDIUM_10BT | MEDIUM_10B2 | MEDIUM_10B5);
+
+ //Initialize DC21040s ID_PROM pointer
+
+ DC21X4_WRITE_PORT(
+ DC21X4_IDPROM,
+ 0
+ );
+
+ // Read the 32 bytes of the Ethernet ID PROM
+
+ for (i = 0; i < SROM_IEEE_LEN; i++) {
+
+ Time = SROM_TIMEOUT;
+
+ do {
+ NdisStallExecution(1*MILLISECOND); // Wait 1 ms
+ DC21X4_READ_PORT(
+ DC21X4_IDPROM,
+ &Value
+ );
+ }
+ while ((Value & DC21X4_IDPROM_DATA_UNVALID) && ((Time--)>0));
+ if (Time > 0) {
+ IdProm[i] = (UCHAR)(Value & DC21X4_IDPROM_DATA);
+ }
+ else {
+ return NDIS_STATUS_FAILURE;
+ }
+ }
+
+ EthAddress = &IdProm[0];
+
+ }
+ break;
+
+ case NdisInterfaceEisa:
+
+ Adapter->MediaCapable =
+ (MEDIUM_10BT | MEDIUM_10B2 | MEDIUM_10B5);
+
+ // Read the 32 bytes of the Ethernet ID PROM
+
+ for (i = 0; i < SROM_IEEE_LEN; i++) {
+
+ NdisRawReadPortUchar(
+ Adapter->PortOffset + EISA_ID_PROM_OFFSET,
+ &IdProm[i]
+ );
+#if __DBG
+ DbgPrint ("Eisa: IDROM @%x %x r\n",
+ Adapter->PortOffset + EISA_ID_PROM_OFFSET, IdProm[i]);
+#endif
+ }
+
+ // Duplicate the ID Prom data in the 32 upper bytes of
+ // the array to cover the case where the 2 test patterns
+ // rap around the 32 bytes block
+
+ MOVE_MEMORY (
+ &IdProm[SROM_IEEE_LEN],
+ &IdProm[0],
+ SROM_IEEE_LEN
+ );
+
+ //Align on the test patterns
+
+ for (i=4; i <= SROM_IEEE_LEN*2; i++) {
+
+ if ( (*(UNALIGNED ULONG *)&IdProm[i-4] == TEST_PATTERN) &&
+ (*(UNALIGNED ULONG *)&IdProm[i] == TEST_PATTERN)
+ ) break;
+ }
+
+ if ( i >= SROM_IEEE_LEN ) {
+ // The test patterns were not found
+ Adapter->PermanentAddressValid = FALSE;
+ return NDIS_STATUS_SUCCESS;
+ }
+ else {
+ EthAddress = &IdProm[i+4];
+ }
+
+ break;
+
+ }
+
+ if (IS_NULL_ADDRESS(EthAddress)) {
+ Adapter->PermanentAddressValid = FALSE;
+#if __DBG
+ DbgPrint ("SROM: NULL Burnt_In Ethernet Address\n");
+#endif
+ }
+ else if ((*(PULONG)EthAddress & 0xFFFFFF) == ZX312_SIGNATURE) {
+ // Zynx ZX312 Rev3's SROM does not contain a checksum
+ Adapter->PermanentAddressValid = TRUE;
+#if __DBG
+ DbgPrint ("SROM: ZX312 Rev3\n");
+#endif
+ }
+ else {
+ Adapter->PermanentAddressValid =
+ VerifyChecksum(EthAddress);
+#if __DBG
+ if (!Adapter->PermanentAddressValid)
+ DbgPrint ("SROM: Invalid CheckSum\n");
+#endif
+ }
+
+ if (Adapter->PermanentAddressValid) {
+ MOVE_MEMORY (
+ &Adapter->PermanentNetworkAddress[0],
+ EthAddress,
+ ETH_LENGTH_OF_ADDRESS
+ );
+ }
+
+
+ //Sia values
+
+ Adapter->Media[Medium10BaseT].SiaRegister[0] = DC21040_SIA0_10BT;
+ Adapter->Media[Medium10BaseT].SiaRegister[1] = DC21040_SIA1_10BT;
+ Adapter->Media[Medium10BaseT].SiaRegister[2] = DC21040_SIA2_10BT;
+
+ Adapter->Media[Medium10Base2].SiaRegister[0] = DC21040_SIA0_10B2;
+ Adapter->Media[Medium10Base2].SiaRegister[1] = DC21040_SIA1_10B2;
+ Adapter->Media[Medium10Base2].SiaRegister[2] = DC21040_SIA2_10B2;
+
+ Adapter->Media[Medium10Base5].SiaRegister[0] = DC21040_SIA0_10B5;
+ Adapter->Media[Medium10Base5].SiaRegister[1] = DC21040_SIA1_10B5;
+ Adapter->Media[Medium10Base5].SiaRegister[2] = DC21040_SIA2_10B5;
+
+ return NDIS_STATUS_SUCCESS;
+
+}
+
+
+
+
+
+
+
+
+
+
+#pragma NDIS_PAGABLE_FUNCTION(VerifyChecksum)
+
+/*+
+ *
+ * VerifyChecksum
+ *
+ * Routine Description:
+ *
+ * Verify the checksum of an Ethernet Address
+ *
+ * Arguments:
+ *
+ * Adapter - The adapter which is being verified.
+ *
+ * EthAddress - A pointer to the address to be checked
+ * This 6_byte Ethernet address is followed
+ * by a zero byte, followed by a value such
+ * that the sum of a checksum on the Ethernet
+ * address and this value is 0xff.
+ *
+ * Return Value:
+ *
+ * TRUE if success
+ *
+-*/
+
+
+BOOLEAN
+VerifyChecksum(
+ IN UNALIGNED UCHAR *EthAddress
+ )
+{
+
+ UINT i;
+ UCHAR CheckSum[2];
+ ULONG Sum = 0;
+
+ // The checksum yields from the polynom:
+ // 10 2 9 8
+ // (B[0]*2 + B[1]*2 + B[2]*2 + B[3]*2 + B[4]*2 + B[5]) mod (2**16-1)
+
+ for (i=0; i<= 2; i++) {
+
+ Sum *= 2;
+
+ if (Sum > 0xffff) Sum -= 0xffff;
+
+ Sum += (*(EthAddress+(2*i)) << 8) + *(EthAddress+(2*i)+1);
+
+ if (Sum > 0xffff) Sum -= 0xffff;
+ }
+
+ if (Sum >= 0xffff) {
+ Sum = 0;
+ }
+
+ CheckSum[0] = (UCHAR)(Sum / 0x100);
+ CheckSum[1] = (UCHAR)(Sum % 0x100);
+
+#if __DBG
+ DbgPrint(" CheckSum = %02x %02x\n",CheckSum[0],CheckSum[1]);
+#endif
+ return (*(UNALIGNED USHORT *)CheckSum == *(UNALIGNED USHORT *)(EthAddress + 6)) ;
+
+}
+
+
+
+
+
+
+
+
+
+
+/*+
+ * DC21X4ParseExtendedBlock
+ *
+ * Routine Description:
+ *
+ * This routine is called by the SROM Parser and takes care of the
+ * parsing of the info block with Extended format (EXT=1) in the 21140's
+ * info leaf.
+ *
+ * Arguments:
+ *
+ * Adapter - Pointer to the Data Structure
+ * MediaBlock - Pointer to the Serial Rom data.
+ * GeneralPurposeCtrl - Value of the General Purpose Ctrl
+ *
+ * Return Value:
+ *
+ * None
+ *
+-*/
+extern
+VOID
+DC21X4ParseExtendedBlock(
+ IN PDC21X4_ADAPTER Adapter,
+ IN OUT UNALIGNED UCHAR **MediaBlock,
+ IN USHORT GeneralPurposeCtrl,
+ OUT PUCHAR PMediaCode
+ )
+{
+
+ UNALIGNED UCHAR *DataBytePtr;
+ UNALIGNED USHORT *DataWordPtr;
+ UNALIGNED UCHAR *EndOfBlock;
+
+ UCHAR MediaCode;
+
+ INT i;
+ INT PhyNumber;
+ UCHAR Length;
+ UCHAR Type;
+ USHORT External;
+
+ DataBytePtr = (UNALIGNED CHAR *)(*MediaBlock);
+
+ Length = (*(DataBytePtr++) & LENGTH);
+ EndOfBlock = DataBytePtr + Length;
+
+ Type = *(DataBytePtr++);
+
+#if __DBG
+ DbgPrint("Block Length =%02x\n", Length);
+ DbgPrint("Block Type =%02x\n", Type);
+#endif
+
+
+ switch (Type) {
+
+ case TYPE_0:
+
+ DC21X4ParseFixedBlock(
+ Adapter,
+ &DataBytePtr,
+ GeneralPurposeCtrl,
+ PMediaCode
+ );
+ break;
+
+ case TYPE_1:
+ case TYPE_3:
+
+ PhyNumber = (INT) *(DataBytePtr++);
+ if (PhyNumber >= MAX_PHY_TABLE) {
+#if __DBG
+ DbgPrint("PhyNumber =%02x Out of RANGE!!!\n", PhyNumber);
+#endif
+ break;
+ }
+
+ //General Purpose Control
+ Adapter->Phy[PhyNumber].GeneralPurposeCtrl = GeneralPurposeCtrl;
+
+ //General Purpose Data
+
+ Adapter->Phy[PhyNumber].GepSequenceLength = (INT) *(DataBytePtr++);
+
+ if (Adapter->Phy[PhyNumber].GepSequenceLength > MAX_GPR_SEQUENCE) {
+#if __DBG
+ DbgPrint("GepSequence =%02x Out of RANGE!!!\n",
+ Adapter->Phy[PhyNumber].GepSequenceLength );
+#endif
+ break;
+ }
+
+ switch (Type) {
+
+ case TYPE_1:
+
+ //GepSequence Length in bytes
+
+ for (i=0; i < Adapter->Phy[PhyNumber].GepSequenceLength; i++) {
+ Adapter->Phy[PhyNumber].GepSequence[i] = *(DataBytePtr++);
+ }
+ break;
+
+ case TYPE_3:
+
+ //GepSequence Length in words
+
+ for (i=0; i < Adapter->Phy[PhyNumber].GepSequenceLength; i++) {
+ Adapter->Phy[PhyNumber].GepSequence[i] = *(UNALIGNED USHORT *)(DataBytePtr);
+ DataBytePtr += sizeof(USHORT);
+ }
+ break;
+ }
+
+ // Reset sequence
+
+ Adapter->Phy[PhyNumber].ResetSequenceLength = (INT) *(DataBytePtr++);
+
+ if (Adapter->Phy[PhyNumber].ResetSequenceLength > MAX_RESET_SEQUENCE) {
+#if __DBG
+ DbgPrint("ResetSequence =%02x Out of RANGE!!!\n",
+ Adapter->Phy[PhyNumber].ResetSequenceLength );
+#endif
+ break;
+ }
+
+ for (i=0; i < Adapter->Phy[PhyNumber].ResetSequenceLength; i++) {
+ Adapter->Phy[PhyNumber].ResetSequence[i] = *(DataBytePtr++);
+ }
+
+ // Capabilities,Nway,FullDuplex & TxmThreshold
+
+ DataWordPtr = (UNALIGNED USHORT *) DataBytePtr;
+
+ Adapter->Phy[PhyNumber].MediaCapabilities =
+ (*(DataWordPtr++) & MEDIA_CAPABILITIES_MASK);
+ Adapter->Phy[PhyNumber].NwayAdvertisement =
+ (*(DataWordPtr++) & NWAY_ADVERTISEMENT_MASK);
+ Adapter->Phy[PhyNumber].FullDuplexBits =
+ (*(DataWordPtr++) & MEDIA_CAPABILITIES_MASK);
+ Adapter->Phy[PhyNumber].TxThresholdModeBits =
+ (*(DataWordPtr++) & MEDIA_CAPABILITIES_MASK);
+ Adapter->Phy[PhyNumber].Present = TRUE;
+
+ Adapter->PhyMediumInSrom = TRUE;
+
+ DataBytePtr = (UNALIGNED UCHAR *) DataWordPtr;
+
+ // GEP Interrupt
+
+ switch (Type) {
+
+ case TYPE_3:
+
+ Adapter->Phy[PhyNumber].GepInterruptMask =
+ *(DataBytePtr++) << DC21X4_GEP_INTERRUPT_BIT_SHIFT;
+ break;
+ }
+
+
+#if __DBG
+ DbgPrint("PHY Number= %02x\n", PhyNumber);
+ DbgPrint("GPR Sequence Length= %d\n", Adapter->Phy[PhyNumber].GepSequenceLength);
+ for (i=0; i < Adapter->Phy[PhyNumber].GepSequenceLength; i++) {
+ DbgPrint("GPR Sequence[%d]=%02x\n", i, Adapter->Phy[PhyNumber].GepSequence[i]);
+ }
+ DbgPrint("RESET Sequence Length= %d\n", Adapter->Phy[PhyNumber].ResetSequenceLength);
+ for (i=0; i < Adapter->Phy[PhyNumber].ResetSequenceLength; i++) {
+ DbgPrint("RESET Sequence[%d]=%02x\n", i, Adapter->Phy[PhyNumber].ResetSequence[i]);
+ }
+ DbgPrint("Media Capabilities= %04x\n", Adapter->Phy[PhyNumber].MediaCapabilities);
+ DbgPrint("NWAY Advertisement= %04x\n", Adapter->Phy[PhyNumber].NwayAdvertisement);
+ DbgPrint("FD Bit map= %02x\n",Adapter->Phy[PhyNumber].FullDuplexBits);
+ DbgPrint("TTM Bit map= %02x\n",Adapter->Phy[PhyNumber].TxThresholdModeBits);
+ DbgPrint("GEP Interrupt mask = %01x\n",Adapter->Phy[PhyNumber].GepInterruptMask);
+#endif
+
+ break;
+
+ case TYPE_2:
+
+ MediaCode = *(DataBytePtr) & DC21X4_MEDIA;
+ if (MediaCode >= MAX_MEDIA_TABLE) {
+ break;
+ }
+ Adapter->MediaCapable |= 1 << MediaCode;
+ External = *(DataBytePtr++) & EXT;
+#if __DBG
+ DbgPrint("SRom: Media Code= %02x\n", MediaCode);
+ DbgPrint("SRom: Media Capable= %02x\n", Adapter->MediaCapable);
+#endif
+
+ DataWordPtr = (UNALIGNED USHORT *)DataBytePtr;
+
+ if (External) {
+
+ // EXT bit is set :
+ // overwrite the SIA Registers default values
+ // with the values stored into the SROM
+
+ Adapter->Media[MediaCode].SiaRegister[0] =
+ ((ULONG)*(DataWordPtr++) & 0xFFFF);
+ Adapter->Media[MediaCode].SiaRegister[1] =
+ ((ULONG)*(DataWordPtr++) & 0xFFFF);
+ Adapter->Media[MediaCode].SiaRegister[2] =
+ ((ULONG)*(DataWordPtr++) & 0xFFFF);
+#if __DBG
+ DbgPrint("SRom: EXT= 1:\n");
+ DbgPrint("SRom: SiaReg[0]= %08x\n",Adapter->Media[MediaCode].SiaRegister[0]);
+ DbgPrint("SRom: SiaReg[1]= %08x\n",Adapter->Media[MediaCode].SiaRegister[1]);
+ DbgPrint("SRom: SiaReg[2]= %08x\n",Adapter->Media[MediaCode].SiaRegister[2]);
+#endif
+ }
+ Adapter->Media[MediaCode].GeneralPurposeCtrl =
+ ((ULONG)*(DataWordPtr++) & 0xFFFF);
+ Adapter->Media[MediaCode].GeneralPurposeData =
+ ((ULONG)*(DataWordPtr) & 0xFFFF);
+#if __DBG
+ DbgPrint("SRom: Gep Ctrl = %08x\n",Adapter->Media[MediaCode].GeneralPurposeCtrl);
+ DbgPrint("SRom: Gep Data = %08x\n",Adapter->Media[MediaCode].GeneralPurposeData);
+#endif
+
+ *PMediaCode = MediaCode;
+
+ break;
+
+
+ default:
+
+#if __DBG
+ DbgPrint("Type =%02x unknown... skipping\n", Type );
+#endif
+ break;
+
+ }
+
+ *MediaBlock = EndOfBlock;
+
+}
+
+
+
+
+
+
+
+
+
+
+/*+
+ * DC21X4ParseFixedBlock
+ *
+ * Routine Description:
+ *
+ * This routine is called by the SROM Parser and takes care of the
+ * parsing of the info block with fixed format (EXT=0) in the 21140's
+ * info leaf.
+ *
+ * Arguments:
+ *
+ * Adapter - Pointer to the Data Structure
+ * DataBytePtr - Pointer to the Serial Rom data.
+ * GeneralPurposeCtrl - Value of the General Purpose Ctrl
+ *
+ * Return Value:
+ *
+ * None.
+ *
+-*/
+extern
+VOID
+DC21X4ParseFixedBlock(
+ IN PDC21X4_ADAPTER Adapter,
+ IN OUT UNALIGNED UCHAR **MediaBlock,
+ IN USHORT GeneralPurposeCtrl,
+ OUT PUCHAR PMediaCode
+ )
+{
+ UNALIGNED UCHAR *DataBytePtr;
+ UCHAR MediaCode;
+
+ DataBytePtr = (UNALIGNED CHAR *)(*MediaBlock);
+
+ MediaCode = *(DataBytePtr) & DC21X4_MEDIA;
+
+ if (MediaCode >= MAX_MEDIA_TABLE) {
+ DataBytePtr += ((2*sizeof(DataBytePtr)) + sizeof(USHORT));
+ *MediaBlock = DataBytePtr;
+ return ;
+ }
+ Adapter->MediaCapable |= 1 << MediaCode;
+
+ Adapter->Media[MediaCode].GeneralPurposeCtrl =
+ (ULONG)GeneralPurposeCtrl;
+ Adapter->Media[MediaCode].GeneralPurposeData =
+ (ULONG)(*(++DataBytePtr) & 0xFF);
+ Adapter->Media[MediaCode].Mode =
+ GET_MODE(++DataBytePtr);
+ Adapter->Media[MediaCode].Polarity =
+ GET_POLARITY(DataBytePtr);
+ Adapter->Media[MediaCode].SenseMask =
+ GET_SENSE_MASK(DataBytePtr);
+
+#if __DBG
+ DbgPrint("Media Code= %02x\n", MediaCode);
+ DbgPrint("Media Capable= %02x\n", Adapter->MediaCapable);
+ DbgPrint("GPData= %02x\n",Adapter->Media[MediaCode].GeneralPurposeData);
+ DbgPrint("Mode= %02x\n",Adapter->Media[MediaCode].Mode);
+ DbgPrint("Polarity= %x\n",Adapter->Media[MediaCode].Polarity);
+ DbgPrint("Sense Mask= %x\n",Adapter->Media[MediaCode].SenseMask);
+#endif
+
+ Adapter->Media[MediaCode].Mode |=
+ (Adapter->Media[MediaCode].Mode & DC21X4_TXM_THRESHOLD_MODE)?
+ Adapter->Threshold10Mbps : Adapter->Threshold100Mbps;
+
+ if ( Adapter->Media[MediaCode].SenseMask
+ && MediaCode != Medium10BaseTFd
+ && MediaCode != Medium100BaseTxFd
+ && MediaCode != Medium100BaseFxFd){
+
+ //Add the media code to the MediaPrecedence table
+ Adapter->MediaPrecedence[Adapter->MediaCount++] = MediaCode;
+ }
+
+ // Check if default media
+ if (IF_DEFAULT_MEDIA(DataBytePtr)) {
+ Adapter->DefaultMediumFlag = TRUE;
+ Adapter->DefaultMedium = MediaCode;
+#if __DBG
+ DbgPrint("SRom: Default Media = %04x\n",MediaCode);
+#endif
+ }
+
+
+ *PMediaCode = MediaCode;
+
+ DataBytePtr += sizeof(USHORT);
+ *MediaBlock = DataBytePtr;
+
+}
+
+
+
+
+
+
+
+
+
+
+
+#pragma NDIS_PAGABLE_FUNCTION(DC21X4ParseSRom)
+
+/*
+ * DC21X4ParseSRom
+ *
+ * Routine Description:
+ *
+ * ParseSRom parses the Serial ROM to retrieve the Ethernet Station
+ * address of the adapter and the adapter's media specific information
+ *
+ * Adapter - pointer to adapter structure
+ *
+ * Return Value:
+ *
+ * Ndis Status
+ *
+-*/
+
+
+NDIS_STATUS
+DC21X4ParseSRom(
+ IN PDC21X4_ADAPTER Adapter
+ )
+{
+
+ PSROM_ID_BLOCK SRomIdBlock;
+ UNALIGNED ADAPTER_ENTRIES *AdapterEntry;
+ UNALIGNED UCHAR *DataBytePtr;
+ UNALIGNED USHORT *DataWordPtr;
+ PUCHAR SRomData;
+
+ USHORT GeneralPurposeCtrl;
+ USHORT MediaCount;
+ USHORT MediaType;
+ UCHAR MediaCode;
+ ULONG Offset = 0;
+ INT Index = 0;
+ INT i;
+
+ BOOLEAN ExtendedFormat;
+
+ ULONG CheckSum;
+ UCHAR Tmp[ETH_LENGTH_OF_ADDRESS];
+
+ UCHAR DC21140Leaf [] = {
+ 0x00,0x08, // AutoSense
+ 0x1f, // General Purpose Ctrl
+ 0x04, // Media Count
+ 0x00,0x0b,0x8e,0x00, // Tp
+ 0x03,0x1b,0x6d,0x00, // 100BaseTx
+ 0x04,0x03,0x8e,0x00, // TpFd
+ 0x05,0x1b,0x6d,0x00 // 100BaseTxFd
+ };
+
+UCHAR DE500Strng[] = {"DE500-XA"};
+
+
+ NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS;
+
+
+ // Allocate space to dump the whole SROM
+
+ ALLOC_MEMORY (&NdisStatus, &SRomData, SROM_SIZE);
+ if (NdisStatus != NDIS_STATUS_SUCCESS) {
+#if __DBG
+ DbgPrint ( "SROM ALLOC_MEMORY FAILED\n");
+#endif
+ return NdisStatus;
+ }
+
+ // Read the whole ROM
+
+ if (DC21X4ReadSRom(
+ Adapter,
+ &Offset,
+ SROM_SIZE,
+ SRomData)) {
+
+ SRomIdBlock = (PSROM_ID_BLOCK)SRomData;
+ }
+ else {
+#if __DBG
+ DbgPrint ( "ReadSRom failed\n");
+#endif
+ FREE_MEMORY(SRomData, SROM_SIZE);
+ return NDIS_STATUS_HARD_ERRORS;
+ }
+
+ // Check the Checksum
+
+ CheckSum = CRC32(SRomData,SROM_SIZE-2) & 0xFFFF;
+ if (CheckSum != *(PUSHORT)&SRomData[SROM_SIZE-2]) {
+
+ // Check if the SROM is a "legacy" formated SROM
+ // containing only the network address
+
+ if ((Adapter-> DeviceId == DC21140_CFID)
+ && !IS_NULL_ADDRESS(SRomData)
+ && VerifyChecksum(SRomData)
+ ) {
+
+#if __DBG
+ DbgPrint ( "Legacy SRom...\n");
+#endif
+ MOVE_MEMORY (
+ &Adapter->PermanentNetworkAddress[0],
+ &SRomData[0],
+ ETH_LENGTH_OF_ADDRESS
+ );
+
+ Adapter->PermanentAddressValid = TRUE;
+
+ SRomIdBlock->FormatVersion = SROM_LEGACY;
+ DataBytePtr = &DC21140Leaf[0];
+ }
+
+ else {
+#if __DBG
+ DbgPrint ( "Invalid SROM Checksum - Expected:%04x Read:%04x\n",
+ CheckSum,*(PUSHORT)&SRomData[SROM_SIZE-2]);
+#endif
+ FREE_MEMORY(SRomData, SROM_SIZE);
+ return NDIS_STATUS_SOFT_ERRORS;
+ }
+ }
+
+ // Check the SROM Version
+
+ switch (SRomIdBlock->FormatVersion) {
+
+ default:
+
+#if __DBG
+ DbgPrint ("SRom: Unsupported Format Version (%x)!\n",
+ SRomIdBlock->FormatVersion);
+#endif
+ FREE_MEMORY(SRomData, SROM_SIZE);
+ return NDIS_STATUS_SOFT_ERRORS;
+
+ case SROM_V1:
+ case SROM_V3:
+
+ // Parse the Adapter Device Number.
+#if __DBG
+ DbgPrint ("SRom: Version: %2x\n",SRomIdBlock->FormatVersion );
+ DbgPrint ("SRom: Adapter Count: %2x\n", SRomIdBlock->AdapterCount);
+ DbgPrint ("SRom: Network Base Address: %02x-%02x-%02x-%02x-%02x-%02x\n",
+ SRomIdBlock->NetworkAddress[0],SRomIdBlock->NetworkAddress[1],
+ SRomIdBlock->NetworkAddress[2],SRomIdBlock->NetworkAddress[3],
+ SRomIdBlock->NetworkAddress[4],SRomIdBlock->NetworkAddress[5]);
+#endif
+
+ AdapterEntry = (PADAPTER_ENTRIES)&SRomData[sizeof(SROM_ID_BLOCK)];
+
+ if ((INT)SRomIdBlock->AdapterCount > 1) {
+
+ // Parse the Adapter's Device Number.
+ for (; Index < (INT)SRomIdBlock->AdapterCount; Index++,AdapterEntry++) {
+
+#if __DBG
+ DbgPrint ("SRom: DeviceNumber, %2x\n",AdapterEntry->DeviceNumber );
+ DbgPrint ("SRom: Offset, %4x\n", AdapterEntry->Offset);
+#endif
+ if (AdapterEntry->DeviceNumber == (UCHAR)Adapter->SlotNumber) {
+ break;
+ }
+ }
+ }
+
+ if (Index == (INT)SRomIdBlock->AdapterCount) {
+#if __DBG
+ DbgPrint("SRom: Adapter's Device Number %d not found in SROM\n",
+ Adapter->SlotNumber);
+#endif
+ FREE_MEMORY(SRomData, SROM_SIZE);
+ return NDIS_STATUS_ADAPTER_NOT_FOUND;
+ }
+
+ // Check if the Station Address is a NULL Address
+
+ if IS_NULL_ADDRESS(SRomIdBlock->NetworkAddress) {
+
+#if __DBG
+ DbgPrint ("SRom: NULL Network Address\n");
+#endif
+ Adapter->PermanentAddressValid = FALSE;
+ }
+ else {
+
+ if (Index !=0) {
+
+ // Add the adapter index to the base network Address
+ // (The carry is propagated to the 3 lower bytes
+ // of the address only (the 3 upper bytes are the vendor id))
+
+ for (i=0;i<3;i++) {
+ Tmp[i] = SRomIdBlock->NetworkAddress[ETH_LENGTH_OF_ADDRESS-(i+1)];
+ }
+ *(UNALIGNED ULONG *)&Tmp[0] += Index;
+ for (i=0;i<3;i++) {
+ SRomIdBlock->NetworkAddress[ETH_LENGTH_OF_ADDRESS-(i+1)] = Tmp[i];
+ }
+
+
+ }
+#if __DBG
+ DbgPrint ("SRom: Network Address: %02x-%02x-%02x-%02x-%02x-%02x\n",
+ SRomIdBlock->NetworkAddress[0],SRomIdBlock->NetworkAddress[1],
+ SRomIdBlock->NetworkAddress[2],SRomIdBlock->NetworkAddress[3],
+ SRomIdBlock->NetworkAddress[4],SRomIdBlock->NetworkAddress[5]);
+#endif
+ MOVE_MEMORY (
+ &Adapter->PermanentNetworkAddress[0],
+ SRomIdBlock->NetworkAddress,
+ ETH_LENGTH_OF_ADDRESS
+ );
+
+ Adapter->PermanentAddressValid = TRUE;
+ }
+
+ //Parse the Media Info Blocks.
+
+ DataBytePtr = &(SRomData[AdapterEntry->Offset]);
+
+ case SROM_LEGACY:
+
+ Adapter->MediaCapable = 0;
+
+ switch (Adapter-> DeviceId) {
+
+ case DC21041_CFID:
+
+ // Initialize the Media table with the default values.
+
+ Adapter->Media[Medium10BaseT].SiaRegister[0] = DC21041_SIA0_10BT;
+ Adapter->Media[Medium10BaseT].SiaRegister[1] = DC21041_SIA1_10BT;
+ Adapter->Media[Medium10BaseT].SiaRegister[2] = DC21041_SIA2_10BT;
+
+ Adapter->Media[Medium10Base2].SiaRegister[0] = DC21041_SIA0_10B2;
+ Adapter->Media[Medium10Base2].SiaRegister[1] = DC21041_SIA1_10B2;
+ Adapter->Media[Medium10Base2].SiaRegister[2] = DC21041_SIA2_10B2;
+
+ Adapter->Media[Medium10Base5].SiaRegister[0] = DC21041_SIA0_10B5;
+ Adapter->Media[Medium10Base5].SiaRegister[1] = DC21041_SIA1_10B5;
+ Adapter->Media[Medium10Base5].SiaRegister[2] = DC21041_SIA2_10B5;
+
+ MediaType = *(UNALIGNED USHORT *)DataBytePtr;
+ DataBytePtr += sizeof(USHORT);
+
+ MediaCount = *(DataBytePtr++);
+#if __DBG
+ DbgPrint("SRom: MediaType= %04x \n", MediaType);
+ DbgPrint("SRom: Media Count= %d \n", MediaCount);
+#endif
+ for (Index=0; Index < MediaCount; Index++) {
+
+ MediaCode = *DataBytePtr & DC21X4_MEDIA;
+
+ if (MediaCode >= MAX_MEDIA_TABLE) {
+ DataBytePtr += (sizeof(DataBytePtr)
+ + ((*DataBytePtr & EXT) ? (3 * sizeof(DataWordPtr)):0));
+ continue;
+ }
+
+ Adapter->MediaCapable |= 1 << MediaCode;
+#if __DBG
+ DbgPrint("SRom: Media Code= %02x\n", MediaCode);
+ DbgPrint("SRom: Media Capable= %02x\n", Adapter->MediaCapable);
+#endif
+
+ if (*(DataBytePtr++) & EXT) {
+
+ // EXT bit is set :
+ // overwrite the SIA Registers default values
+ // with the values stored into the SROM
+
+ DataWordPtr = (UNALIGNED USHORT *) DataBytePtr;
+ Adapter->Media[MediaCode].SiaRegister[0] =
+ ((ULONG)*(DataWordPtr++) & 0xFFFF);
+ Adapter->Media[MediaCode].SiaRegister[1] =
+ ((ULONG)*(DataWordPtr++) & 0xFFFF);
+ Adapter->Media[MediaCode].SiaRegister[2] =
+ ((ULONG)*(DataWordPtr++) & 0xFFFF);
+ DataBytePtr = (UNALIGNED UCHAR *) DataWordPtr;
+#if __DBG
+ DbgPrint("SRom: EXT= 1:\n");
+ DbgPrint("SRom: SiaReg[0]= %08x\n",Adapter->Media[MediaCode].SiaRegister[0]);
+ DbgPrint("SRom: SiaReg[1]= %08x\n",Adapter->Media[MediaCode].SiaRegister[1]);
+ DbgPrint("SRom: SiaReg[2]= %08x\n",Adapter->Media[MediaCode].SiaRegister[2]);
+#endif
+ }
+
+ }
+
+ break;
+
+ case DC21140_CFID:
+
+ switch (SRomIdBlock->FormatVersion) {
+
+ case SROM_LEGACY:
+ case SROM_V1:
+
+ if (Adapter->RevisionNumber == DC21140_REV1_1) {
+ Adapter->DynamicAutoSense = BOARD_SIGNATURE(SRomData);
+ break;
+ }
+
+ default:
+
+ //MediaType
+
+ MediaType = *(UNALIGNED USHORT *)DataBytePtr;
+ Adapter->DynamicAutoSense = ((MediaType & DISABLE_AUTOSENSE) == 0);
+#if __DBG
+ DbgPrint("SRom: MediaType= %04x \n", MediaType);
+#endif
+ }
+
+#if __DBG
+ DbgPrint("SRom: Dynamic Autosense %s\n",
+ Adapter->DynamicAutoSense? "Enabled":"Disabled");
+#endif
+
+ DataBytePtr += sizeof(USHORT);
+
+ GeneralPurposeCtrl = (((USHORT)*(DataBytePtr++) & 0xFF)|(0x100));
+
+ MediaCount = *(DataBytePtr++);
+
+#if __DBG
+ DbgPrint("SRom: General Purpose Control= %08x \n", GeneralPurposeCtrl);
+ DbgPrint("SRom: MediaCount= %d \n", MediaCount);
+#endif
+ for (Index=0; Index < MediaCount; Index++) {
+
+ ExtendedFormat = (*DataBytePtr & EXTENDED_FORMAT);
+
+ if ((SRomIdBlock->FormatVersion == SROM_V3) && ExtendedFormat) {
+ DC21X4ParseExtendedBlock(
+ Adapter,
+ &DataBytePtr,
+ GeneralPurposeCtrl,
+ &MediaCode
+ );
+ }
+ else {
+ DC21X4ParseFixedBlock(
+ Adapter,
+ &DataBytePtr,
+ GeneralPurposeCtrl,
+ &MediaCode
+ );
+ }
+
+ }
+
+ if (!Adapter->DefaultMediumFlag && Adapter->MediaCount>0) {
+ Adapter->DefaultMedium =
+ Adapter->MediaPrecedence[Adapter->MediaCount-1];
+ }
+ break;
+
+ case DC21142_CFID:
+
+ if (SRomIdBlock->FormatVersion < SROM_V3) {
+#if __DBG
+ DbgPrint ("SRom: Unsupported Format Version (%x)!\n",
+ SRomIdBlock->FormatVersion);
+#endif
+ FREE_MEMORY(SRomData, SROM_SIZE);
+ return NDIS_STATUS_SOFT_ERRORS;
+ }
+
+ // Initialize the Media table with the default values.
+
+ Adapter->Media[Medium10BaseT].SiaRegister[0] = DC21142_SIA0_10BT;
+ Adapter->Media[Medium10BaseT].SiaRegister[1] = DC21142_SIA1_10BT;
+ Adapter->Media[Medium10BaseT].SiaRegister[2] = DC21142_SIA2_10BT;
+
+ Adapter->Media[Medium10Base2].SiaRegister[0] = DC21142_SIA0_10B2;
+ Adapter->Media[Medium10Base2].SiaRegister[1] = DC21142_SIA1_10B2;
+ Adapter->Media[Medium10Base2].SiaRegister[2] = DC21142_SIA2_10B2;
+
+ Adapter->Media[Medium10Base5].SiaRegister[0] = DC21142_SIA0_10B5;
+ Adapter->Media[Medium10Base5].SiaRegister[1] = DC21142_SIA1_10B5;
+ Adapter->Media[Medium10Base5].SiaRegister[2] = DC21142_SIA2_10B5;
+
+
+ MediaType = *(UNALIGNED USHORT *)DataBytePtr;
+
+ Adapter->DynamicAutoSense = ((MediaType & DISABLE_AUTOSENSE) == 0);
+#if __DBG
+ DbgPrint("SRom: Dynamic Autosense %s\n",
+ Adapter->DynamicAutoSense? "Enabled":"Disabled");
+#endif
+ DataBytePtr += sizeof(USHORT);
+ MediaCount = *(DataBytePtr++);
+#if __DBG
+ DbgPrint("SRom: MediaType= %04x \n", MediaType);
+ DbgPrint("SRom: MediaCount= %d \n", MediaCount);
+#endif
+
+ for (Index=0; Index < MediaCount; Index++) {
+
+ DC21X4ParseExtendedBlock(
+ Adapter,
+ (PVOID)&DataBytePtr,
+ (USHORT)NULL,
+ &MediaCode
+ );
+ }
+
+ if (!Adapter->DefaultMediumFlag && Adapter->MediaCount>0) {
+ Adapter->DefaultMedium =
+ Adapter->MediaPrecedence[Adapter->MediaCount-1];
+ }
+
+ break;
+
+ default:
+
+ NdisStatus = NDIS_STATUS_DEVICE_FAILED;
+ }
+
+ break;
+
+ }
+
+ if ( (MediaCount == 1)
+ && Adapter->MediaCapable
+ && !Adapter->PhyMediumInSrom
+ ) {
+
+ //Force MediaType to the single supported medium
+#if __DBG
+ DbgPrint("SRom: One single supported medium: Force MediaType %04x to ",Adapter->MediaType);
+#endif
+ Adapter->MediaType &= ~(MEDIA_MASK | MEDIA_AUTOSENSE);
+ Adapter->MediaType |= MediaCode;
+#if __DBG
+ DbgPrint("%04x\n",Adapter->MediaType);
+#endif
+ }
+
+ //if no 10Base port is populated, switch Port_Select to 100Base
+
+ if (!(Adapter->MediaCapable & (MEDIUM_10BT | MEDIUM_10B2 | MEDIUM_10B5))) {
+ Adapter->OperationMode |= DC21X4_PORT_SELECT;
+ }
+
+ FREE_MEMORY(SRomData, SROM_SIZE);
+ return NdisStatus;
+
+
+}
+
+
+
+
+
+
+
+
+
+#pragma NDIS_PAGABLE_FUNCTION(DC21X4ReadSRom)
+
+/*
+ * DC21X4ReadSRom
+ *
+ * Routine Description:
+ *
+ * ReadSRom is called by DC21X4RegisterAdapter to read the onboard ROM
+ * for the network address and other parameters.
+ * This routine reads the required number of bytes from the given
+ * offset in the ROM.
+ *
+ * Arguments:
+ *
+ * Adapter -
+ *
+ * Offset - byte offset into SROM to start reading from. Must
+ * be word aligned
+ * Len - number of bytes to read
+ * Data - pointer to buffer to read data into.
+ * if NULL, don't return data
+ *
+ * Return Value:
+ *
+ * TRUE if success, FALSE if hardware failure encountered.
+ *
+-*/
+
+
+BOOLEAN
+DC21X4ReadSRom(
+ IN PDC21X4_ADAPTER Adapter,
+ IN OUT PULONG Offset,
+ IN USHORT Len,
+ OUT PUCHAR Buffer
+ )
+{
+
+ INT i;
+ INT j;
+ ULONG Dbit;
+ ULONG Dout;
+ USHORT WOffset;
+ USHORT WLen;
+ USHORT WData;
+
+ // Make sure the ROM_Address is EVEN.
+
+ if (*Offset & 1)
+ {
+#if __DBG
+ DbgPrint ("ReadSRom failure - Offset not word aligned\n");
+#endif
+ return FALSE;
+ }
+
+ // Round up the length to multiple of words.
+ WLen = (Len + 1) / 2;
+
+ // Convert the ROM_Address byte offset to word offset
+ WOffset = (USHORT)(*Offset >> 1);
+
+ // Make sure the requested read does not exceed the ROM size
+
+ if ( (WOffset + WLen) > SROM_93LC46B_SIZE) {
+#if __DBG
+ DbgPrint ("ReadSRom warning - address range excedes ROM size\n");
+#endif
+ return FALSE;
+ }
+
+
+ // Switch CSR to work with new SROM interface
+
+ DC21X4_WRITE_PORT(
+ DC21X4_IDPROM,
+ CSR_WRITE | SEL_SROM
+ );
+
+ // Make sure SROM is in idle state
+ // (deliver it enough clocks with CS set, Din = 0).
+
+ for (i = 0; i < SROM_93LC46B_MAX_CYCLES; i++) {
+
+ DC21X4_WRITE_PORT(
+ DC21X4_IDPROM,
+ CSR_WRITE | SEL_SROM | CS | CLK
+ );
+
+ NdisStallExecution(SROM_93LC46B_DELAY);
+
+ DC21X4_WRITE_PORT(
+ DC21X4_IDPROM,
+ CSR_WRITE | SEL_SROM | CS
+ );
+
+ NdisStallExecution(SROM_93LC46B_DELAY);
+
+ }
+
+ DC21X4_WRITE_PORT(
+ DC21X4_IDPROM,
+ CSR_WRITE | SEL_SROM
+ );
+
+ NdisStallExecution(SROM_93LC46B_DELAY);
+
+
+ // Read the data
+
+ for (j = 0; j < WLen; j++,WOffset++) {
+
+ //Output the READ command to the SROM
+
+ DC21X4_WRITE_PORT(
+ DC21X4_IDPROM,
+ CSR_WRITE | SEL_SROM | CS | DATA_1
+ );
+
+ DC21X4_WRITE_PORT(
+ DC21X4_IDPROM,
+ CSR_WRITE | SEL_SROM | CS | CLK | DATA_1
+ );
+
+ NdisStallExecution(SROM_93LC46B_DELAY);
+
+ DC21X4_WRITE_PORT(
+ DC21X4_IDPROM,
+ CSR_WRITE | SEL_SROM | CS | DATA_1
+ );
+
+ NdisStallExecution(SROM_93LC46B_DELAY);
+
+ DC21X4_WRITE_PORT(
+ DC21X4_IDPROM,
+ CSR_WRITE | SEL_SROM | CS | DATA_1
+ );
+
+ DC21X4_WRITE_PORT(
+ DC21X4_IDPROM,
+ CSR_WRITE | SEL_SROM | CS | CLK | DATA_1
+ );
+
+ NdisStallExecution(SROM_93LC46B_DELAY);
+
+ DC21X4_WRITE_PORT(
+ DC21X4_IDPROM,
+ CSR_WRITE | SEL_SROM | CS | DATA_1
+ );
+
+ NdisStallExecution(SROM_93LC46B_DELAY);
+
+ DC21X4_WRITE_PORT(
+ DC21X4_IDPROM,
+ CSR_WRITE | SEL_SROM | CS | DATA_0
+ );
+
+ DC21X4_WRITE_PORT(
+ DC21X4_IDPROM,
+ CSR_WRITE | SEL_SROM | CS | CLK | DATA_0
+ );
+
+ NdisStallExecution(SROM_93LC46B_DELAY);
+
+ DC21X4_WRITE_PORT(
+ DC21X4_IDPROM,
+ CSR_WRITE | SEL_SROM | CS | DATA_0
+ );
+
+ NdisStallExecution(SROM_93LC46B_DELAY);
+
+
+ // Output the WORD Address of the SROM
+
+ for (i = SROM_93LC46B_ADDRESS_MSB; i>= 0; i--) {
+
+ Dbit = (USHORT)((WOffset >> i) & 1) << 2;
+
+ DC21X4_WRITE_PORT(
+ DC21X4_IDPROM,
+ CSR_WRITE | SEL_SROM | CS | Dbit
+ );
+
+ DC21X4_WRITE_PORT(
+ DC21X4_IDPROM,
+ CSR_WRITE | SEL_SROM | CS | CLK | Dbit
+ );
+
+ NdisStallExecution(SROM_93LC46B_DELAY);
+
+ DC21X4_WRITE_PORT(
+ DC21X4_IDPROM,
+ CSR_WRITE | SEL_SROM | CS | Dbit
+ );
+
+ NdisStallExecution(SROM_93LC46B_DELAY);
+
+ }
+
+
+ // Verify that the SROM output data became now 0.
+
+ DC21X4_READ_PORT(
+ DC21X4_IDPROM,
+ &Dout
+ );
+
+ if (Dout & SROM_93LC46B_VALID_BITMASK) {
+#if __DBG
+ DbgPrint ("ReadSRom failure - SROM didn't become busy in read command\n");
+#endif
+ return(FALSE);
+ }
+
+ // Read the data from the SROM
+
+ WData = 0;
+ for (i = SROM_93LC46B_DATA_MSB; i >= 0; i--) {
+
+ DC21X4_WRITE_PORT(
+ DC21X4_IDPROM,
+ CSR_WRITE | SEL_SROM | CS | CLK
+ );
+
+ NdisStallExecution(SROM_93LC46B_DELAY);
+
+ DC21X4_READ_PORT(
+ DC21X4_IDPROM,
+ &Dout
+ );
+
+ DC21X4_WRITE_PORT(
+ DC21X4_IDPROM,
+ CSR_WRITE | SEL_SROM | CS
+ );
+
+ WData |= ((Dout >> SROM_93LC46B_DATA_BIT) & 1) << i;
+
+ NdisStallExecution(SROM_93LC46B_DELAY);
+
+ }
+
+#if _DBG
+ DbgPrint("Data = %04x\n",WData);
+#endif
+
+ // Put our read data in user buffer
+
+ if (Buffer) {
+
+ if (Len >= 2) {
+
+ *(PUSHORT)Buffer = WData;
+ Buffer += 2;
+ Len -= 2;
+ }
+ else {
+
+ // Least significant byte only is copied
+ *Buffer = WData & 0xff;
+ Buffer++;
+ Len--;
+ }
+
+ }
+
+ //Negate the chip select (CS) to end the SROM command
+
+ DC21X4_WRITE_PORT(
+ DC21X4_IDPROM,
+ CSR_WRITE | SEL_SROM
+ );
+
+ NdisStallExecution(SROM_93LC46B_DELAY);
+
+ }
+
+ *Offset = WOffset << 1;
+ return TRUE;
+
+}
+
diff --git a/private/ntos/ndis/dc21x4/transfer.c b/private/ntos/ndis/dc21x4/transfer.c
new file mode 100644
index 000000000..c45b88712
--- /dev/null
+++ b/private/ntos/ndis/dc21x4/transfer.c
@@ -0,0 +1,82 @@
+/*+
+ * file: transfer.c
+ *
+ * Copyright (C) 1992-1995 by
+ * Digital Equipment Corporation, Maynard, Massachusetts.
+ * All rights reserved.
+ *
+ * This software is furnished under a license and may be used and copied
+ * only in accordance of the terms of such license and with the
+ * inclusion of the above copyright notice. This software or any other
+ * copies thereof may not be provided or otherwise made available to any
+ * other person. No title to and ownership of the software is hereby
+ * transferred.
+ *
+ * The information in this software is subject to change without notice
+ * and should not be construed as a commitment by digital equipment
+ * corporation.
+ *
+ * Digital assumes no responsibility for the use or reliability of its
+ * software on equipment which is not supplied by digital.
+ *
+ *
+ * Abstract: This file is part of the NDIS3.0 miniport driver for DEC's
+ * DC21X4 Ethernet Adapter and implements the MiniportTransferData
+ * API
+ *
+ * Author: Philippe Klein
+ *
+ * Revision History:
+ *
+ * phk 28-Aug-1994 Initial entry
+ *
+-*/
+
+#include <precomp.h>
+
+
+
+/*+
+ *
+ * DC21X4TransferData
+ *
+ * Routine Description:
+ *
+ * The protocol driver calls DC21X4TransferData to instruct
+ * the driver to copy the contents of the received packet into
+ * a specified packet buffer.
+ *
+-*/
+
+extern
+NDIS_STATUS
+DC21X4TransferData(
+ OUT PNDIS_PACKET Packet,
+ OUT PUINT BytesTransferred,
+ IN NDIS_HANDLE MiniportAdapterContext,
+ IN NDIS_HANDLE MiniportReceiveContext,
+ IN UINT ByteOffset,
+ IN UINT BytesToTransfer
+ )
+
+{
+
+ PDC21X4_ADAPTER Adapter;
+
+#if _DBG
+ DbgPrint("DC21X4TransferData\n");
+#endif
+
+ Adapter = (PDC21X4_ADAPTER)MiniportAdapterContext;
+
+ CopyFromBufferToPacket(
+ (PCHAR)((ULONG)MiniportReceiveContext + ByteOffset),
+ Packet,
+ 0,
+ BytesToTransfer,
+ BytesTransferred
+ );
+
+ return NDIS_STATUS_SUCCESS;
+
+}
diff --git a/private/ntos/ndis/dc21x4/version.h b/private/ntos/ndis/dc21x4/version.h
new file mode 100644
index 000000000..133f3ddeb
--- /dev/null
+++ b/private/ntos/ndis/dc21x4/version.h
@@ -0,0 +1,7 @@
+// DC21X4 NDIS4.0 miniport driver version
+
+#define DRIVER_VERSION 4,03,00
+#define DRIVER_VERSION_STR "v4.03"
+
+
+