#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");
+ ASSERT_IRQL_EQUAL(DISPATCH_LEVEL);
+
NdisDprAcquireSpinLock(&Adapter->Lock);
NdisRawWritePortUshort(Adapter->PortOffset + RAP, CSR0);
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 =
Adapter->Statistics.RcvGoodFrames++;
}
+
+ if (IndicatedData)
+ NdisMEthIndicateReceiveComplete(Adapter->MiniportAdapterHandle);
}
if(Data & CSR0_TINT)
{
}
static BOOLEAN
-STDCALL
+NTAPI
MiSyncStop(
IN PVOID SynchronizeContext)
/*
}
static VOID
-STDCALL
+NTAPI
MiniportHalt(
IN NDIS_HANDLE MiniportAdapterContext)
/*
/* deregister i/o port range */
NdisMDeregisterIoPortRange(Adapter->MiniportAdapterHandle, Adapter->IoBaseAddress, NUMBER_OF_PORTS, (PVOID)Adapter->PortOffset);
+ /* deregister the shutdown routine */
+ NdisMDeregisterAdapterShutdownHandler(Adapter->MiniportAdapterHandle);
+
/* free shared memory */
MiFreeSharedMemory(Adapter);
}
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,
{
PADAPTER Adapter = (PADAPTER)FunctionContext;
+ ASSERT_IRQL_EQUAL(DISPATCH_LEVEL);
+
if (NdisMSynchronizeWithInterrupt(&Adapter->InterruptObject,
MiSyncMediaDetection,
FunctionContext))
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
+NTAPI
+MiniportShutdown( PVOID Context )
+{
+ PADAPTER Adapter = Context;
+
+ DPRINT("Stopping the chip\n");
+
+ NdisRawWritePortUshort(Adapter->PortOffset + RAP, CSR0);
+ NdisRawWritePortUshort(Adapter->PortOffset + RDP, CSR0_STOP);
+}
+
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);
/* Pick a medium */
for(i = 0; i < MediumArraySize; i++)
/* 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
}
static VOID
-STDCALL
+NTAPI
MiniportISR(
OUT PBOOLEAN InterruptRecognized,
OUT PBOOLEAN QueueMiniportHandleInterrupt,
}
static NDIS_STATUS
-STDCALL
+NTAPI
MiniportReset(
OUT PBOOLEAN AddressingReset,
IN NDIS_HANDLE MiniportAdapterContext)
{
DPRINT("Called\n");
+ ASSERT_IRQL_EQUAL(PASSIVE_LEVEL);
+
/* MiniportReset doesn't do anything at the moment... perhaps this should be fixed. */
*AddressingReset = FALSE;
}
static BOOLEAN
-STDCALL
+NTAPI
MiSyncStartTransmit(
IN PVOID SynchronizeContext)
/*
}
static NDIS_STATUS
-STDCALL
+NTAPI
MiniportSend(
IN NDIS_HANDLE MiniportAdapterContext,
IN PNDIS_PACKET Packet,
DPRINT("Called\n");
+ ASSERT_IRQL_EQUAL(DISPATCH_LEVEL);
+
NdisDprAcquireSpinLock(&Adapter->Lock);
/* Check if we have free entry in our circular buffer. */
}
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)