#include <debug.h>
NTSTATUS
-STDCALL
+NTAPI
DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath);
static VOID
-STDCALL
+NTAPI
MiniportHandleInterrupt(
IN NDIS_HANDLE MiniportAdapterContext)
/*
{
PADAPTER Adapter = (PADAPTER)MiniportAdapterContext;
USHORT Data;
+ UINT i = 0;
DPRINT("Called\n");
DPRINT("CSR0 is 0x%x\n", Data);
- while(Data & CSR0_INTR)
+ while((Data & CSR0_INTR) && i++ < INTERRUPT_LIMIT)
{
/* Clear interrupt flags early to avoid race conditions. */
NdisRawWritePortUshort(Adapter->PortOffset + RDP, Data);
}
if(Data & CSR0_RINT)
{
+ BOOLEAN IndicatedData = FALSE;
+
DPRINT("receive interrupt\n");
while(1)
DPRINT("Indicating a %d-byte packet (index %d)\n", ByteCount, Adapter->CurrentReceiveDescriptorIndex);
NdisMEthIndicateReceive(Adapter->MiniportAdapterHandle, 0, Buffer, 14, Buffer+14, ByteCount-14, ByteCount-14);
- NdisMEthIndicateReceiveComplete(Adapter->MiniportAdapterHandle);
+
+ IndicatedData = TRUE;
RtlZeroMemory(Descriptor, sizeof(RECEIVE_DESCRIPTOR));
Descriptor->RBADR =
- (ULONG)(Adapter->ReceiveBufferPtrPhys + Adapter->CurrentReceiveDescriptorIndex * BUFFER_SIZE);
+ (ULONG_PTR)(Adapter->ReceiveBufferPtrPhys + Adapter->CurrentReceiveDescriptorIndex * BUFFER_SIZE);
Descriptor->BCNT = (-BUFFER_SIZE) | 0xf000;
Descriptor->FLAGS |= RD_OWN;
Adapter->Statistics.RcvGoodFrames++;
}
+
+ if (IndicatedData)
+ NdisMEthIndicateReceiveComplete(Adapter->MiniportAdapterHandle);
}
if(Data & CSR0_TINT)
{
return NDIS_STATUS_RESOURCES;
}
- if(((ULONG)Adapter->InitializationBlockVirt & 0x00000003) != 0)
+ if(((ULONG_PTR)Adapter->InitializationBlockVirt & 0x00000003) != 0)
{
DPRINT("address 0x%x not dword-aligned\n", Adapter->InitializationBlockVirt);
BREAKPOINT;
return NDIS_STATUS_RESOURCES;
}
- Adapter->InitializationBlockPhys = (PINITIALIZATION_BLOCK)NdisGetPhysicalAddressLow(PhysicalAddress);
+ Adapter->InitializationBlockPhys = (PINITIALIZATION_BLOCK)(ptrdiff_t)NdisGetPhysicalAddressLow(PhysicalAddress);
/* allocate the transport descriptor ring */
Adapter->TransmitDescriptorRingLength = sizeof(TRANSMIT_DESCRIPTOR) * NUMBER_OF_BUFFERS;
return NDIS_STATUS_RESOURCES;
}
- if(((ULONG)Adapter->TransmitDescriptorRingVirt & 0x00000003) != 0)
+ if(((ULONG_PTR)Adapter->TransmitDescriptorRingVirt & 0x00000003) != 0)
{
DPRINT("address 0x%x not dword-aligned\n", Adapter->TransmitDescriptorRingVirt);
BREAKPOINT;
return NDIS_STATUS_RESOURCES;
}
- Adapter->TransmitDescriptorRingPhys = (PTRANSMIT_DESCRIPTOR)NdisGetPhysicalAddressLow(PhysicalAddress);
+ Adapter->TransmitDescriptorRingPhys = (PTRANSMIT_DESCRIPTOR)(ptrdiff_t)NdisGetPhysicalAddressLow(PhysicalAddress);
RtlZeroMemory(Adapter->TransmitDescriptorRingVirt, sizeof(TRANSMIT_DESCRIPTOR) * NUMBER_OF_BUFFERS);
/* allocate the receive descriptor ring */
return NDIS_STATUS_RESOURCES;
}
- if(((ULONG)Adapter->ReceiveDescriptorRingVirt & 0x00000003) != 0)
+ if(((ULONG_PTR)Adapter->ReceiveDescriptorRingVirt & 0x00000003) != 0)
{
DPRINT("address 0x%x not dword-aligned\n", Adapter->ReceiveDescriptorRingVirt);
BREAKPOINT;
return NDIS_STATUS_RESOURCES;
}
- Adapter->ReceiveDescriptorRingPhys = (PRECEIVE_DESCRIPTOR)NdisGetPhysicalAddressLow(PhysicalAddress);
+ Adapter->ReceiveDescriptorRingPhys = (PRECEIVE_DESCRIPTOR)(ptrdiff_t)NdisGetPhysicalAddressLow(PhysicalAddress);
RtlZeroMemory(Adapter->ReceiveDescriptorRingVirt, sizeof(RECEIVE_DESCRIPTOR) * NUMBER_OF_BUFFERS);
/* allocate transmit buffers */
return NDIS_STATUS_RESOURCES;
}
- if(((ULONG)Adapter->TransmitBufferPtrVirt & 0x00000003) != 0)
+ if(((ULONG_PTR)Adapter->TransmitBufferPtrVirt & 0x00000003) != 0)
{
DPRINT("address 0x%x not dword-aligned\n", Adapter->TransmitBufferPtrVirt);
BREAKPOINT;
return NDIS_STATUS_RESOURCES;
}
- Adapter->TransmitBufferPtrPhys = (PCHAR)NdisGetPhysicalAddressLow(PhysicalAddress);
+ Adapter->TransmitBufferPtrPhys = (PCHAR)(ULONG_PTR)NdisGetPhysicalAddressLow(PhysicalAddress);
RtlZeroMemory(Adapter->TransmitBufferPtrVirt, BUFFER_SIZE * NUMBER_OF_BUFFERS);
/* allocate receive buffers */
return NDIS_STATUS_RESOURCES;
}
- if(((ULONG)Adapter->ReceiveBufferPtrVirt & 0x00000003) != 0)
+ if(((ULONG_PTR)Adapter->ReceiveBufferPtrVirt & 0x00000003) != 0)
{
DPRINT("address 0x%x not dword-aligned\n", Adapter->ReceiveBufferPtrVirt);
BREAKPOINT;
return NDIS_STATUS_RESOURCES;
}
- Adapter->ReceiveBufferPtrPhys = (PCHAR)NdisGetPhysicalAddressLow(PhysicalAddress);
+ Adapter->ReceiveBufferPtrPhys = (PCHAR)(ULONG_PTR)NdisGetPhysicalAddressLow(PhysicalAddress);
RtlZeroMemory(Adapter->ReceiveBufferPtrVirt, BUFFER_SIZE * NUMBER_OF_BUFFERS);
/* initialize tx descriptors */
TransmitDescriptor = Adapter->TransmitDescriptorRingVirt;
for(i = 0; i < NUMBER_OF_BUFFERS; i++)
{
- (TransmitDescriptor+i)->TBADR = (ULONG)Adapter->TransmitBufferPtrPhys + i * BUFFER_SIZE;
+ (TransmitDescriptor+i)->TBADR = (ULONG_PTR)Adapter->TransmitBufferPtrPhys + i * BUFFER_SIZE;
(TransmitDescriptor+i)->BCNT = 0xf000 | -BUFFER_SIZE; /* 2's compliment + set top 4 bits */
(TransmitDescriptor+i)->FLAGS = TD1_STP | TD1_ENP;
}
ReceiveDescriptor = Adapter->ReceiveDescriptorRingVirt;
for(i = 0; i < NUMBER_OF_BUFFERS; i++)
{
- (ReceiveDescriptor+i)->RBADR = (ULONG)Adapter->ReceiveBufferPtrPhys + i * BUFFER_SIZE;
+ (ReceiveDescriptor+i)->RBADR = (ULONG_PTR)Adapter->ReceiveBufferPtrPhys + i * BUFFER_SIZE;
(ReceiveDescriptor+i)->BCNT = 0xf000 | -BUFFER_SIZE; /* 2's compliment + set top 4 bits */
(ReceiveDescriptor+i)->FLAGS = RD_OWN;
}
/* set up receive ring */
DPRINT("Receive ring physical address: 0x%x\n", Adapter->ReceiveDescriptorRingPhys);
- Adapter->InitializationBlockVirt->RDRA = (ULONG)Adapter->ReceiveDescriptorRingPhys;
+ Adapter->InitializationBlockVirt->RDRA = (ULONG_PTR)Adapter->ReceiveDescriptorRingPhys;
Adapter->InitializationBlockVirt->RLEN = (LOG_NUMBER_OF_BUFFERS << 4) & 0xf0;
/* set up transmit ring */
DPRINT("Transmit ring physical address: 0x%x\n", Adapter->TransmitDescriptorRingPhys);
- Adapter->InitializationBlockVirt->TDRA = (ULONG)Adapter->TransmitDescriptorRingPhys;
+ Adapter->InitializationBlockVirt->TDRA = (ULONG_PTR)Adapter->TransmitDescriptorRingPhys;
Adapter->InitializationBlockVirt->TLEN = (LOG_NUMBER_OF_BUFFERS << 4) & 0xf0;
}
if(Adapter->InitializationBlockVirt)
{
- PhysicalAddress.u.LowPart = (ULONG)Adapter->InitializationBlockPhys;
+ PhysicalAddress.u.LowPart = (ULONG_PTR)Adapter->InitializationBlockPhys;
NdisMFreeSharedMemory(Adapter->MiniportAdapterHandle, Adapter->InitializationBlockLength,
FALSE, Adapter->InitializationBlockVirt, PhysicalAddress);
}
if(Adapter->TransmitDescriptorRingVirt)
{
- PhysicalAddress.u.LowPart = (ULONG)Adapter->TransmitDescriptorRingPhys;
+ PhysicalAddress.u.LowPart = (ULONG_PTR)Adapter->TransmitDescriptorRingPhys;
NdisMFreeSharedMemory(Adapter->MiniportAdapterHandle, Adapter->TransmitDescriptorRingLength,
FALSE, Adapter->TransmitDescriptorRingVirt, PhysicalAddress);
}
if(Adapter->ReceiveDescriptorRingVirt)
{
- PhysicalAddress.u.LowPart = (ULONG)Adapter->ReceiveDescriptorRingPhys;
+ PhysicalAddress.u.LowPart = (ULONG_PTR)Adapter->ReceiveDescriptorRingPhys;
NdisMFreeSharedMemory(Adapter->MiniportAdapterHandle, Adapter->ReceiveDescriptorRingLength,
FALSE, Adapter->ReceiveDescriptorRingVirt, PhysicalAddress);
}
if(Adapter->TransmitBufferPtrVirt)
{
- PhysicalAddress.u.LowPart = (ULONG)Adapter->TransmitBufferPtrPhys;
+ PhysicalAddress.u.LowPart = (ULONG_PTR)Adapter->TransmitBufferPtrPhys;
NdisMFreeSharedMemory(Adapter->MiniportAdapterHandle, Adapter->TransmitBufferLength,
FALSE, Adapter->TransmitBufferPtrVirt, PhysicalAddress);
}
if(Adapter->ReceiveBufferPtrVirt)
{
- PhysicalAddress.u.LowPart = (ULONG)Adapter->ReceiveBufferPtrPhys;
+ PhysicalAddress.u.LowPart = (ULONG_PTR)Adapter->ReceiveBufferPtrPhys;
NdisMFreeSharedMemory(Adapter->MiniportAdapterHandle, Adapter->ReceiveBufferLength,
FALSE, Adapter->ReceiveBufferPtrVirt, PhysicalAddress);
}
}
static BOOLEAN
-STDCALL
+NTAPI
MiSyncStop(
IN PVOID SynchronizeContext)
/*
}
static VOID
-STDCALL
+NTAPI
MiniportHalt(
IN NDIS_HANDLE MiniportAdapterContext)
/*
}
static BOOLEAN
-STDCALL
+NTAPI
MiSyncMediaDetection(
IN PVOID SynchronizeContext)
/*
{
PADAPTER Adapter = (PADAPTER)SynchronizeContext;
NDIS_MEDIA_STATE MediaState = MiGetMediaState(Adapter);
+ UINT MediaSpeed = MiGetMediaSpeed(Adapter);
+ BOOLEAN FullDuplex = MiGetMediaDuplex(Adapter);
DPRINT("Called\n");
DPRINT("MediaState: %d\n", MediaState);
- if (MediaState != Adapter->MediaState)
+ if (MediaState != Adapter->MediaState ||
+ MediaSpeed != Adapter->MediaSpeed ||
+ FullDuplex != Adapter->FullDuplex)
{
Adapter->MediaState = MediaState;
+ Adapter->MediaSpeed = MediaSpeed;
+ Adapter->FullDuplex = FullDuplex;
return TRUE;
}
return FALSE;
}
static VOID
-STDCALL
+NTAPI
MiniportMediaDetectionTimer(
IN PVOID SystemSpecific1,
IN PVOID FunctionContext,
/* set up csr1 and csr2 with init block */
NdisRawWritePortUshort(Adapter->PortOffset + RAP, CSR1);
- NdisRawWritePortUshort(Adapter->PortOffset + RDP, (USHORT)((ULONG)Adapter->InitializationBlockPhys & 0xffff));
+ NdisRawWritePortUshort(Adapter->PortOffset + RDP, (USHORT)((ULONG_PTR)Adapter->InitializationBlockPhys & 0xffff));
NdisRawWritePortUshort(Adapter->PortOffset + RAP, CSR2);
- NdisRawWritePortUshort(Adapter->PortOffset + RDP, (USHORT)((ULONG)Adapter->InitializationBlockPhys >> 16) & 0xffff);
+ NdisRawWritePortUshort(Adapter->PortOffset + RDP, (USHORT)((ULONG_PTR)Adapter->InitializationBlockPhys >> 16) & 0xffff);
DPRINT("programmed with init block\n");
NdisRawWritePortUshort(Adapter->PortOffset + RAP, CSR0);
NdisRawWritePortUshort(Adapter->PortOffset + RDP, CSR0_STRT|CSR0_INIT|CSR0_IENA);
- /* detect the media state */
+ /* Allow LED programming */
+ NdisRawWritePortUshort(Adapter->PortOffset + RAP, BCR2);
+ NdisRawWritePortUshort(Adapter->PortOffset + BDP, BCR2_LEDPE);
+
+ /* LED0 is configured for link status (on = up, off = down) */
NdisRawWritePortUshort(Adapter->PortOffset + RAP, BCR4);
- NdisRawWritePortUshort(Adapter->PortOffset + BDP, BCR4_LNKSTE|BCR4_FDLSE);
+ NdisRawWritePortUshort(Adapter->PortOffset + BDP, BCR4_LNKSTE | BCR4_PSE);
+
+ /* LED1 is configured for link duplex (on = full, off = half) */
+ NdisRawWritePortUshort(Adapter->PortOffset + RAP, BCR5);
+ NdisRawWritePortUshort(Adapter->PortOffset + BDP, BCR5_FDLSE | BCR5_PSE);
+
+ /* LED2 is configured for link speed (on = 100M, off = 10M) */
+ NdisRawWritePortUshort(Adapter->PortOffset + RAP, BCR6);
+ NdisRawWritePortUshort(Adapter->PortOffset + BDP, BCR6_E100 | BCR6_PSE);
+
+ /* LED3 is configured for trasmit/receive activity */
+ NdisRawWritePortUshort(Adapter->PortOffset + RAP, BCR7);
+ NdisRawWritePortUshort(Adapter->PortOffset + BDP, BCR7_XMTE | BCR7_RCVE | BCR7_PSE);
+
Adapter->MediaState = MiGetMediaState(Adapter);
+ Adapter->FullDuplex = MiGetMediaDuplex(Adapter);
+ Adapter->MediaSpeed = MiGetMediaSpeed(Adapter);
DPRINT("card started\n");
#endif
VOID
-STDCALL
+NTAPI
MiniportShutdown( PVOID Context )
{
PADAPTER Adapter = Context;
}
static NDIS_STATUS
-STDCALL
+NTAPI
MiniportInitialize(
OUT PNDIS_STATUS OpenErrorStatus,
OUT PUINT SelectedMediumIndex,
PADAPTER Adapter = 0;
NDIS_STATUS Status = NDIS_STATUS_FAILURE;
BOOLEAN InterruptRegistered = FALSE;
+ NDIS_HANDLE ConfigurationHandle;
+ UINT *RegNetworkAddress = 0;
+ UINT RegNetworkAddressLength = 0;
ASSERT_IRQL_EQUAL(PASSIVE_LEVEL);
/* set up the initialization block */
MiPrepareInitializationBlock(Adapter);
+ /* see if someone set a network address manually */
+ NdisOpenConfiguration(&Status, &ConfigurationHandle, WrapperConfigurationContext);
+ if (Status == NDIS_STATUS_SUCCESS)
+ {
+ NdisReadNetworkAddress(&Status, (PVOID *)&RegNetworkAddress, &RegNetworkAddressLength, ConfigurationHandle);
+ if(Status == NDIS_STATUS_SUCCESS && RegNetworkAddressLength == 6)
+ {
+ int i;
+ DPRINT("NdisReadNetworkAddress returned successfully, address %x:%x:%x:%x:%x:%x\n",
+ RegNetworkAddress[0], RegNetworkAddress[1], RegNetworkAddress[2], RegNetworkAddress[3],
+ RegNetworkAddress[4], RegNetworkAddress[5]);
+
+ for(i = 0; i < 6; i++)
+ Adapter->InitializationBlockVirt->PADR[i] = RegNetworkAddress[i];
+ }
+
+ NdisCloseConfiguration(ConfigurationHandle);
+ }
+
DPRINT("Interrupt registered successfully\n");
/* Initialize and start the chip */
Adapter);
NdisMSetPeriodicTimer(&Adapter->MediaDetectionTimer,
MEDIA_DETECTION_INTERVAL);
+ NdisMRegisterAdapterShutdownHandler(Adapter->MiniportAdapterHandle,
+ Adapter,
+ MiniportShutdown);
}
#if DBG
ASSERT(0);
#endif
- NdisMRegisterAdapterShutdownHandler(Adapter->MiniportAdapterHandle, Adapter, MiniportShutdown);
-
DPRINT("returning 0x%x\n", Status);
*OpenErrorStatus = Status;
return Status;
}
static VOID
-STDCALL
+NTAPI
MiniportISR(
OUT PBOOLEAN InterruptRecognized,
OUT PBOOLEAN QueueMiniportHandleInterrupt,
}
static NDIS_STATUS
-STDCALL
+NTAPI
MiniportReset(
OUT PBOOLEAN AddressingReset,
IN NDIS_HANDLE MiniportAdapterContext)
}
static BOOLEAN
-STDCALL
+NTAPI
MiSyncStartTransmit(
IN PVOID SynchronizeContext)
/*
}
static NDIS_STATUS
-STDCALL
+NTAPI
MiniportSend(
IN NDIS_HANDLE MiniportAdapterContext,
IN PNDIS_PACKET Packet,
}
static ULONG
-STDCALL
+NTAPI
MiEthernetCrc(UCHAR *Address)
/*
* FUNCTION: Calculate Ethernet CRC32
}
NDIS_STATUS
-STDCALL
+NTAPI
MiSetMulticast(
PADAPTER Adapter,
UCHAR *Addresses,
return NDIS_STATUS_SUCCESS;
}
+BOOLEAN
+NTAPI
+MiGetMediaDuplex(PADAPTER Adapter)
+{
+ ULONG Data;
+
+ NdisRawWritePortUshort(Adapter->PortOffset + RAP, BCR5);
+ NdisRawReadPortUshort(Adapter->PortOffset + BDP, &Data);
+
+ return Data & BCR5_LEDOUT;
+}
+
+UINT
+NTAPI
+MiGetMediaSpeed(PADAPTER Adapter)
+{
+ ULONG Data;
+
+ NdisRawWritePortUshort(Adapter->PortOffset + RAP, BCR6);
+ NdisRawReadPortUshort(Adapter->PortOffset + BDP, &Data);
+
+ return Data & BCR6_LEDOUT ? 100 : 10;
+}
+
NDIS_MEDIA_STATE
-STDCALL
+NTAPI
MiGetMediaState(PADAPTER Adapter)
/*
* FUNCTION: Determine the link state
}
NTSTATUS
-STDCALL
+NTAPI
DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath)
Characteristics.SendHandler = MiniportSend;
NdisMInitializeWrapper(&WrapperHandle, DriverObject, RegistryPath, 0);
+ if (!WrapperHandle) return NDIS_STATUS_FAILURE;
Status = NdisMRegisterMiniport(WrapperHandle, &Characteristics, sizeof(Characteristics));
if(Status != NDIS_STATUS_SUCCESS)