mirror of
https://github.com/reactos/reactos.git
synced 2024-12-29 02:25:17 +00:00
- Compile with W32API headers.
- Add multicast support. - Add media state detection support. - Protect the adapter context with spinlock and move code talking to card to inside NdisMSynchronizeWithInterrupt calls where necessary. svn path=/trunk/; revision=11301
This commit is contained in:
parent
3d1e209ba7
commit
d788739c0e
4 changed files with 263 additions and 109 deletions
|
@ -6,9 +6,9 @@ TARGET_NAME = pcnet
|
||||||
# - must define NDIS50 to get the right characteristics struct
|
# - must define NDIS50 to get the right characteristics struct
|
||||||
# - must define anonymous unions to make physical addresses work right
|
# - must define anonymous unions to make physical addresses work right
|
||||||
#
|
#
|
||||||
TARGET_CFLAGS = -I. -Wall -Werror -DNDIS50 -DANONYMOUSUNIONS
|
TARGET_CFLAGS = -I. -Wall -Werror -DNDIS50_MINIPORT
|
||||||
|
TARGET_CFLAGS += -I$(W32API_PATH)/include/ddk -D__USE_W32API
|
||||||
# TARGET_CFLAGS += -I$(W32API_PATH)/include/ddk -D__USE_W32API
|
# TARGET_CFLAGS += -DDBG=1
|
||||||
|
|
||||||
TARGET_OBJECTS = pcnet.o requests.o
|
TARGET_OBJECTS = pcnet.o requests.o
|
||||||
TARGET_DDKLIBS = ndis.a
|
TARGET_DDKLIBS = ndis.a
|
||||||
|
|
|
@ -27,9 +27,14 @@
|
||||||
* - Don't read slot number from registry and
|
* - Don't read slot number from registry and
|
||||||
* report itself as NDIS 5.0 miniport.
|
* report itself as NDIS 5.0 miniport.
|
||||||
* 11-Oct-2004 navaraf - Fix nasty bugs in halt code path.
|
* 11-Oct-2004 navaraf - Fix nasty bugs in halt code path.
|
||||||
|
* 17-Oct-2004 navaraf - Add multicast support.
|
||||||
|
* - Add media state detection support.
|
||||||
|
* - Protect the adapter context with spinlock
|
||||||
|
* and move code talking to card to inside
|
||||||
|
* NdisMSynchronizeWithInterrupt calls where
|
||||||
|
* necessary.
|
||||||
*
|
*
|
||||||
* NOTES:
|
* NOTES:
|
||||||
* - this is hard-coded to NDIS5
|
|
||||||
* - this assumes a 32-bit machine
|
* - this assumes a 32-bit machine
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -52,15 +57,11 @@ MiniportHandleInterrupt(
|
||||||
{
|
{
|
||||||
PADAPTER Adapter = (PADAPTER)MiniportAdapterContext;
|
PADAPTER Adapter = (PADAPTER)MiniportAdapterContext;
|
||||||
USHORT Data;
|
USHORT Data;
|
||||||
#if DBG
|
|
||||||
BOOLEAN ReceiveHandled = FALSE;
|
|
||||||
BOOLEAN ErrorHandled = FALSE;
|
|
||||||
BOOLEAN IdonHandled = FALSE;
|
|
||||||
BOOLEAN TransmitHandled = FALSE;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
PCNET_DbgPrint(("Called\n"));
|
PCNET_DbgPrint(("Called\n"));
|
||||||
|
|
||||||
|
NdisDprAcquireSpinLock(&Adapter->Lock);
|
||||||
|
|
||||||
NdisRawWritePortUshort(Adapter->PortOffset + RAP, CSR0);
|
NdisRawWritePortUshort(Adapter->PortOffset + RAP, CSR0);
|
||||||
NdisRawReadPortUshort(Adapter->PortOffset + RDP, &Data);
|
NdisRawReadPortUshort(Adapter->PortOffset + RDP, &Data);
|
||||||
|
|
||||||
|
@ -73,46 +74,16 @@ MiniportHandleInterrupt(
|
||||||
|
|
||||||
if(Data & CSR0_ERR)
|
if(Data & CSR0_ERR)
|
||||||
{
|
{
|
||||||
#if DBG
|
|
||||||
if(ErrorHandled)
|
|
||||||
{
|
|
||||||
PCNET_DbgPrint(("ERROR HANDLED TWO TIMES\n"));
|
|
||||||
ASSERT(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
ErrorHandled = TRUE;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
PCNET_DbgPrint(("error: %x\n", Data & (CSR0_MERR|CSR0_BABL|CSR0_CERR|CSR0_MISS)))
|
PCNET_DbgPrint(("error: %x\n", Data & (CSR0_MERR|CSR0_BABL|CSR0_CERR|CSR0_MISS)))
|
||||||
if (Data & CSR0_CERR)
|
if (Data & CSR0_CERR)
|
||||||
Adapter->Statistics.XmtCollisions++;
|
Adapter->Statistics.XmtCollisions++;
|
||||||
}
|
}
|
||||||
else if(Data & CSR0_IDON)
|
else if(Data & CSR0_IDON)
|
||||||
{
|
{
|
||||||
#if DBG
|
|
||||||
if(IdonHandled)
|
|
||||||
{
|
|
||||||
PCNET_DbgPrint(("IDON HANDLED TWO TIMES\n"));
|
|
||||||
ASSERT(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
IdonHandled = TRUE;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
PCNET_DbgPrint(("IDON\n"));
|
PCNET_DbgPrint(("IDON\n"));
|
||||||
}
|
}
|
||||||
else if(Data & CSR0_RINT)
|
else if(Data & CSR0_RINT)
|
||||||
{
|
{
|
||||||
#if DBG
|
|
||||||
if(ReceiveHandled)
|
|
||||||
{
|
|
||||||
PCNET_DbgPrint(("RECEIVE HANDLED TWO TIMES\n"));
|
|
||||||
ASSERT(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
ReceiveHandled = TRUE;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
PCNET_DbgPrint(("receive interrupt\n"));
|
PCNET_DbgPrint(("receive interrupt\n"));
|
||||||
|
|
||||||
while(1)
|
while(1)
|
||||||
|
@ -171,16 +142,6 @@ MiniportHandleInterrupt(
|
||||||
{
|
{
|
||||||
PTRANSMIT_DESCRIPTOR Descriptor;
|
PTRANSMIT_DESCRIPTOR Descriptor;
|
||||||
|
|
||||||
#if DBG
|
|
||||||
if(TransmitHandled)
|
|
||||||
{
|
|
||||||
PCNET_DbgPrint(("TRANSMIT HANDLED TWO TIMES\n"));
|
|
||||||
ASSERT(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
TransmitHandled = TRUE;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
PCNET_DbgPrint(("transmit interrupt\n"));
|
PCNET_DbgPrint(("transmit interrupt\n"));
|
||||||
|
|
||||||
while (Adapter->CurrentTransmitStartIndex !=
|
while (Adapter->CurrentTransmitStartIndex !=
|
||||||
|
@ -198,6 +159,14 @@ MiniportHandleInterrupt(
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Descriptor->FLAGS & TD1_STP)
|
||||||
|
{
|
||||||
|
if (Descriptor->FLAGS & TD1_ONE)
|
||||||
|
Adapter->Statistics.XmtOneRetry++;
|
||||||
|
else if (Descriptor->FLAGS & TD1_MORE)
|
||||||
|
Adapter->Statistics.XmtMoreThanOneRetry++;
|
||||||
|
}
|
||||||
|
|
||||||
if (Descriptor->FLAGS & TD1_ERR)
|
if (Descriptor->FLAGS & TD1_ERR)
|
||||||
{
|
{
|
||||||
PCNET_DbgPrint(("major error: %x\n", Descriptor->FLAGS2));
|
PCNET_DbgPrint(("major error: %x\n", Descriptor->FLAGS2));
|
||||||
|
@ -237,6 +206,8 @@ MiniportHandleInterrupt(
|
||||||
|
|
||||||
NdisRawReadPortUshort(Adapter->PortOffset + RDP, &Data);
|
NdisRawReadPortUshort(Adapter->PortOffset + RDP, &Data);
|
||||||
PCNET_DbgPrint(("CSR0 is now 0x%x\n", Data));
|
PCNET_DbgPrint(("CSR0 is now 0x%x\n", Data));
|
||||||
|
|
||||||
|
NdisDprAcquireSpinLock(&Adapter->Lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
NDIS_STATUS
|
NDIS_STATUS
|
||||||
|
@ -546,6 +517,22 @@ MiFreeSharedMemory(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOLEAN
|
||||||
|
STDCALL
|
||||||
|
MiSyncStop(
|
||||||
|
IN PVOID SynchronizeContext)
|
||||||
|
/*
|
||||||
|
* FUNCTION: Stop the adapter
|
||||||
|
* ARGUMENTS:
|
||||||
|
* SynchronizeContext: Adapter context
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
PADAPTER Adapter = (PADAPTER)SynchronizeContext;
|
||||||
|
NdisRawWritePortUshort(Adapter->PortOffset + RAP, CSR0);
|
||||||
|
NdisRawWritePortUshort(Adapter->PortOffset + RDP, CSR0_STOP);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
STDCALL
|
STDCALL
|
||||||
MiniportHalt(
|
MiniportHalt(
|
||||||
|
@ -559,13 +546,16 @@ MiniportHalt(
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
PADAPTER Adapter = (PADAPTER)MiniportAdapterContext;
|
PADAPTER Adapter = (PADAPTER)MiniportAdapterContext;
|
||||||
|
BOOLEAN TimerCancelled;
|
||||||
|
|
||||||
PCNET_DbgPrint(("Called\n"));
|
PCNET_DbgPrint(("Called\n"));
|
||||||
ASSERT(Adapter);
|
ASSERT(Adapter);
|
||||||
|
|
||||||
|
/* stop the media detection timer */
|
||||||
|
NdisMCancelTimer(&Adapter->MediaDetectionTimer, &TimerCancelled);
|
||||||
|
|
||||||
/* stop the chip */
|
/* stop the chip */
|
||||||
NdisRawWritePortUshort(Adapter->PortOffset + RAP, CSR0);
|
NdisMSynchronizeWithInterrupt(&Adapter->InterruptObject, MiSyncStop, Adapter);
|
||||||
NdisRawWritePortUshort(Adapter->PortOffset + RDP, CSR0_STOP);
|
|
||||||
|
|
||||||
/* deregister the interrupt */
|
/* deregister the interrupt */
|
||||||
NdisMDeregisterInterrupt(&Adapter->InterruptObject);
|
NdisMDeregisterInterrupt(&Adapter->InterruptObject);
|
||||||
|
@ -579,10 +569,65 @@ MiniportHalt(
|
||||||
/* free map registers */
|
/* free map registers */
|
||||||
NdisMFreeMapRegisters(Adapter->MiniportAdapterHandle);
|
NdisMFreeMapRegisters(Adapter->MiniportAdapterHandle);
|
||||||
|
|
||||||
|
/* free the lock */
|
||||||
|
NdisFreeSpinLock(&Adapter->Lock);
|
||||||
|
|
||||||
/* free the adapter */
|
/* free the adapter */
|
||||||
NdisFreeMemory(Adapter, 0, 0);
|
NdisFreeMemory(Adapter, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOLEAN
|
||||||
|
STDCALL
|
||||||
|
MiSyncMediaDetection(
|
||||||
|
IN PVOID SynchronizeContext)
|
||||||
|
/*
|
||||||
|
* FUNCTION: Stop the adapter
|
||||||
|
* ARGUMENTS:
|
||||||
|
* SynchronizeContext: Adapter context
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
PADAPTER Adapter = (PADAPTER)SynchronizeContext;
|
||||||
|
NDIS_MEDIA_STATE MediaState = MiGetMediaState(Adapter);
|
||||||
|
|
||||||
|
PCNET_DbgPrint(("Called\n"));
|
||||||
|
PCNET_DbgPrint(("MediaState: %d\n", MediaState));
|
||||||
|
if (MediaState != Adapter->MediaState)
|
||||||
|
{
|
||||||
|
Adapter->MediaState = MediaState;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
STDCALL
|
||||||
|
MiniportMediaDetectionTimer(
|
||||||
|
IN PVOID SystemSpecific1,
|
||||||
|
IN PVOID FunctionContext,
|
||||||
|
IN PVOID SystemSpecific2,
|
||||||
|
IN PVOID SystemSpecific3)
|
||||||
|
/*
|
||||||
|
* FUNCTION: Periodially query media state
|
||||||
|
* ARGUMENTS:
|
||||||
|
* FunctionContext: Adapter context
|
||||||
|
* NOTES:
|
||||||
|
* - Called by NDIS at DISPATCH_LEVEL
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
PADAPTER Adapter = (PADAPTER)FunctionContext;
|
||||||
|
|
||||||
|
if (NdisMSynchronizeWithInterrupt(&Adapter->InterruptObject,
|
||||||
|
MiSyncMediaDetection,
|
||||||
|
FunctionContext))
|
||||||
|
{
|
||||||
|
NdisMIndicateStatus(Adapter->MiniportAdapterHandle,
|
||||||
|
Adapter->MediaState == NdisMediaStateConnected ?
|
||||||
|
NDIS_STATUS_MEDIA_CONNECT : NDIS_STATUS_MEDIA_DISCONNECT,
|
||||||
|
(PVOID)0, 0);
|
||||||
|
NdisMIndicateStatusComplete(Adapter->MiniportAdapterHandle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
MiInitChip(
|
MiInitChip(
|
||||||
PADAPTER Adapter)
|
PADAPTER Adapter)
|
||||||
|
@ -655,6 +700,11 @@ MiInitChip(
|
||||||
NdisRawWritePortUshort(Adapter->PortOffset + RAP, CSR0);
|
NdisRawWritePortUshort(Adapter->PortOffset + RAP, CSR0);
|
||||||
NdisRawWritePortUshort(Adapter->PortOffset + RDP, CSR0_STRT|CSR0_INIT|CSR0_IENA);
|
NdisRawWritePortUshort(Adapter->PortOffset + RDP, CSR0_STRT|CSR0_INIT|CSR0_IENA);
|
||||||
|
|
||||||
|
/* detect the media state */
|
||||||
|
NdisRawWritePortUshort(Adapter->PortOffset + RAP, BCR4);
|
||||||
|
NdisRawWritePortUshort(Adapter->PortOffset + BDP, BCR4_LNKSTE|BCR4_FDLSE/*|BCR4_XMTE|BCR4_RCVME|BCR4_MPSE|BCR4_JABE*/);
|
||||||
|
Adapter->MediaState = MiGetMediaState(Adapter);
|
||||||
|
|
||||||
PCNET_DbgPrint(("card started\n"));
|
PCNET_DbgPrint(("card started\n"));
|
||||||
|
|
||||||
Adapter->Flags &= ~RESET_IN_PROGRESS;
|
Adapter->Flags &= ~RESET_IN_PROGRESS;
|
||||||
|
@ -849,6 +899,8 @@ MiniportInitialize(
|
||||||
/* Initialize and start the chip */
|
/* Initialize and start the chip */
|
||||||
MiInitChip(Adapter);
|
MiInitChip(Adapter);
|
||||||
|
|
||||||
|
NdisAllocateSpinLock(&Adapter->Lock);
|
||||||
|
|
||||||
Status = NDIS_STATUS_SUCCESS;
|
Status = NDIS_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
while(0);
|
while(0);
|
||||||
|
@ -870,6 +922,16 @@ MiniportInitialize(
|
||||||
NdisFreeMemory(Adapter, 0, 0);
|
NdisFreeMemory(Adapter, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(Status == NDIS_STATUS_SUCCESS)
|
||||||
|
{
|
||||||
|
NdisMInitializeTimer(&Adapter->MediaDetectionTimer,
|
||||||
|
Adapter->MiniportAdapterHandle,
|
||||||
|
MiniportMediaDetectionTimer,
|
||||||
|
Adapter);
|
||||||
|
NdisMSetPeriodicTimer(&Adapter->MediaDetectionTimer,
|
||||||
|
MEDIA_DETECTION_INTERVAL);
|
||||||
|
}
|
||||||
|
|
||||||
#if DBG
|
#if DBG
|
||||||
if(!MiTestCard(Adapter))
|
if(!MiTestCard(Adapter))
|
||||||
ASSERT(0);
|
ASSERT(0);
|
||||||
|
@ -958,6 +1020,22 @@ MiniportReset(
|
||||||
return NDIS_STATUS_SUCCESS;
|
return NDIS_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOLEAN
|
||||||
|
STDCALL
|
||||||
|
MiSyncStartTransmit(
|
||||||
|
IN PVOID SynchronizeContext)
|
||||||
|
/*
|
||||||
|
* FUNCTION: Stop the adapter
|
||||||
|
* ARGUMENTS:
|
||||||
|
* SynchronizeContext: Adapter context
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
PADAPTER Adapter = (PADAPTER)SynchronizeContext;
|
||||||
|
NdisRawWritePortUshort(Adapter->PortOffset + RAP, CSR0);
|
||||||
|
NdisRawWritePortUshort(Adapter->PortOffset + RDP, CSR0_IENA | CSR0_TDMD);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
NDIS_STATUS
|
NDIS_STATUS
|
||||||
STDCALL
|
STDCALL
|
||||||
MiniportSend(
|
MiniportSend(
|
||||||
|
@ -985,6 +1063,8 @@ MiniportSend(
|
||||||
|
|
||||||
PCNET_DbgPrint(("Called\n"));
|
PCNET_DbgPrint(("Called\n"));
|
||||||
|
|
||||||
|
NdisDprAcquireSpinLock(&Adapter->Lock);
|
||||||
|
|
||||||
/* Check if we have free entry in our circular buffer. */
|
/* Check if we have free entry in our circular buffer. */
|
||||||
if ((Adapter->CurrentTransmitEndIndex + 1 ==
|
if ((Adapter->CurrentTransmitEndIndex + 1 ==
|
||||||
Adapter->CurrentTransmitStartIndex) ||
|
Adapter->CurrentTransmitStartIndex) ||
|
||||||
|
@ -992,6 +1072,7 @@ MiniportSend(
|
||||||
Adapter->CurrentTransmitStartIndex == 0))
|
Adapter->CurrentTransmitStartIndex == 0))
|
||||||
{
|
{
|
||||||
PCNET_DbgPrint(("No free space in circular buffer\n"));
|
PCNET_DbgPrint(("No free space in circular buffer\n"));
|
||||||
|
NdisDprReleaseSpinLock(&Adapter->Lock);
|
||||||
return NDIS_STATUS_RESOURCES;
|
return NDIS_STATUS_RESOURCES;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1017,7 +1098,7 @@ MiniportSend(
|
||||||
NdisGetNextBuffer(NdisBuffer, &NdisBuffer);
|
NdisGetNextBuffer(NdisBuffer, &NdisBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if DBG
|
#if DBG && 0
|
||||||
{
|
{
|
||||||
PUCHAR Ptr = Adapter->TransmitBufferPtrVirt +
|
PUCHAR Ptr = Adapter->TransmitBufferPtrVirt +
|
||||||
Adapter->CurrentTransmitEndIndex * BUFFER_SIZE;
|
Adapter->CurrentTransmitEndIndex * BUFFER_SIZE;
|
||||||
|
@ -1037,12 +1118,73 @@ MiniportSend(
|
||||||
Desc->FLAGS = TD1_OWN | TD1_STP | TD1_ENP;
|
Desc->FLAGS = TD1_OWN | TD1_STP | TD1_ENP;
|
||||||
Desc->BCNT = 0xf000 | -TotalPacketLength;
|
Desc->BCNT = 0xf000 | -TotalPacketLength;
|
||||||
|
|
||||||
NdisRawWritePortUshort(Adapter->PortOffset + RAP, CSR0);
|
NdisMSynchronizeWithInterrupt(&Adapter->InterruptObject, MiSyncStartTransmit, Adapter);
|
||||||
NdisRawWritePortUshort(Adapter->PortOffset + RDP, CSR0_IENA | CSR0_TDMD);
|
|
||||||
|
NdisDprReleaseSpinLock(&Adapter->Lock);
|
||||||
|
|
||||||
return NDIS_STATUS_SUCCESS;
|
return NDIS_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ULONG
|
||||||
|
STDCALL
|
||||||
|
MiEthernetCrc(UCHAR *Address)
|
||||||
|
/*
|
||||||
|
* FUNCTION: Calculate Ethernet CRC32
|
||||||
|
* ARGUMENTS:
|
||||||
|
* Address: 6-byte ethernet address
|
||||||
|
* RETURNS:
|
||||||
|
* The calculated CRC32 value.
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
UINT Counter, Length;
|
||||||
|
ULONG Value = ~0;
|
||||||
|
|
||||||
|
for (Length = 0; Length < 6; Length++)
|
||||||
|
{
|
||||||
|
Value ^= *Address++;
|
||||||
|
for (Counter = 0; Counter < 8; Counter++)
|
||||||
|
{
|
||||||
|
Value >>= 1;
|
||||||
|
Value ^= (Value & 1) * 0xedb88320;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
NDIS_STATUS
|
||||||
|
STDCALL
|
||||||
|
MiSetMulticast(
|
||||||
|
PADAPTER Adapter,
|
||||||
|
UCHAR *Addresses,
|
||||||
|
UINT AddressCount)
|
||||||
|
{
|
||||||
|
UINT Index;
|
||||||
|
ULONG CrcIndex;
|
||||||
|
|
||||||
|
NdisZeroMemory(Adapter->InitializationBlockVirt->LADR, 8);
|
||||||
|
for (Index = 0; Index < AddressCount; Index++)
|
||||||
|
{
|
||||||
|
CrcIndex = MiEthernetCrc(Addresses) >> 26;
|
||||||
|
Adapter->InitializationBlockVirt->LADR[CrcIndex >> 3] |= 1 << (CrcIndex & 15);
|
||||||
|
Addresses += 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* FIXME: The specification mentions we need to reload the init block here. */
|
||||||
|
|
||||||
|
return NDIS_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
NDIS_MEDIA_STATE
|
||||||
|
STDCALL
|
||||||
|
MiGetMediaState(PADAPTER Adapter)
|
||||||
|
{
|
||||||
|
ULONG Data;
|
||||||
|
NdisRawWritePortUshort(Adapter->PortOffset + RAP, BCR4);
|
||||||
|
NdisRawReadPortUshort(Adapter->PortOffset + BDP, &Data);
|
||||||
|
return Data & BCR4_LEDOUT ? NdisMediaStateConnected : NdisMediaStateDisconnected;
|
||||||
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
STDCALL
|
STDCALL
|
||||||
DriverEntry(
|
DriverEntry(
|
||||||
|
@ -1066,8 +1208,8 @@ DriverEntry(
|
||||||
NDIS_STATUS Status;
|
NDIS_STATUS Status;
|
||||||
|
|
||||||
RtlZeroMemory(&Characteristics, sizeof(Characteristics));
|
RtlZeroMemory(&Characteristics, sizeof(Characteristics));
|
||||||
Characteristics.MajorNdisVersion = NDIS_MAJOR_VERSION;
|
Characteristics.MajorNdisVersion = NDIS_MINIPORT_MAJOR_VERSION;
|
||||||
Characteristics.MinorNdisVersion = NDIS_MINOR_VERSION;
|
Characteristics.MinorNdisVersion = NDIS_MINIPORT_MINOR_VERSION;
|
||||||
Characteristics.HaltHandler = MiniportHalt;
|
Characteristics.HaltHandler = MiniportHalt;
|
||||||
Characteristics.HandleInterruptHandler = MiniportHandleInterrupt;
|
Characteristics.HandleInterruptHandler = MiniportHandleInterrupt;
|
||||||
Characteristics.InitializeHandler = MiniportInitialize;
|
Characteristics.InitializeHandler = MiniportInitialize;
|
||||||
|
@ -1075,7 +1217,7 @@ DriverEntry(
|
||||||
Characteristics.QueryInformationHandler = MiniportQueryInformation;
|
Characteristics.QueryInformationHandler = MiniportQueryInformation;
|
||||||
Characteristics.ResetHandler = MiniportReset;
|
Characteristics.ResetHandler = MiniportReset;
|
||||||
Characteristics.SetInformationHandler = MiniportSetInformation;
|
Characteristics.SetInformationHandler = MiniportSetInformation;
|
||||||
Characteristics.u1.SendHandler = MiniportSend;
|
Characteristics.SendHandler = MiniportSend;
|
||||||
|
|
||||||
NdisMInitializeWrapper(&WrapperHandle, DriverObject, RegistryPath, 0);
|
NdisMInitializeWrapper(&WrapperHandle, DriverObject, RegistryPath, 0);
|
||||||
|
|
||||||
|
|
|
@ -28,19 +28,6 @@
|
||||||
#ifndef _PCNET_H_
|
#ifndef _PCNET_H_
|
||||||
#define _PCNET_H_
|
#define _PCNET_H_
|
||||||
|
|
||||||
/* FIXME: We should use a general way to do this for all drivers. */
|
|
||||||
#ifdef __GNUC__
|
|
||||||
#define memcpy(a,b,c) __builtin_memcpy(a,b,c)
|
|
||||||
#define memset(a,b,c) __builtin_memset(a,b,c)
|
|
||||||
#undef RtlFillMemory
|
|
||||||
#define RtlFillMemory(a,b,c) __builtin_memset(a,b,c)
|
|
||||||
#undef RtlZeroMemory
|
|
||||||
#define RtlZeroMemory(a,b) __builtin_memset(a,0,b)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define NDIS_MAJOR_VERSION 5
|
|
||||||
#define NDIS_MINOR_VERSION 0
|
|
||||||
|
|
||||||
/* statistics struct */
|
/* statistics struct */
|
||||||
typedef struct _ADAPTER_STATS
|
typedef struct _ADAPTER_STATS
|
||||||
{
|
{
|
||||||
|
@ -52,6 +39,8 @@ typedef struct _ADAPTER_STATS
|
||||||
ULONG XmtExcessiveDefferals;
|
ULONG XmtExcessiveDefferals;
|
||||||
ULONG XmtBufferUnderflows;
|
ULONG XmtBufferUnderflows;
|
||||||
ULONG XmtBufferErrors;
|
ULONG XmtBufferErrors;
|
||||||
|
ULONG XmtOneRetry;
|
||||||
|
ULONG XmtMoreThanOneRetry;
|
||||||
ULONG RcvGoodFrames;
|
ULONG RcvGoodFrames;
|
||||||
ULONG RcvBufferErrors;
|
ULONG RcvBufferErrors;
|
||||||
ULONG RcvCrcErrors;
|
ULONG RcvCrcErrors;
|
||||||
|
@ -62,12 +51,16 @@ typedef struct _ADAPTER_STATS
|
||||||
/* adapter struct */
|
/* adapter struct */
|
||||||
typedef struct _ADAPTER
|
typedef struct _ADAPTER
|
||||||
{
|
{
|
||||||
|
NDIS_SPIN_LOCK Lock;
|
||||||
|
|
||||||
NDIS_HANDLE MiniportAdapterHandle;
|
NDIS_HANDLE MiniportAdapterHandle;
|
||||||
ULONG Flags;
|
ULONG Flags;
|
||||||
ULONG InterruptVector;
|
ULONG InterruptVector;
|
||||||
ULONG IoBaseAddress;
|
ULONG IoBaseAddress;
|
||||||
PVOID PortOffset;
|
PVOID PortOffset;
|
||||||
NDIS_MINIPORT_INTERRUPT InterruptObject;
|
NDIS_MINIPORT_INTERRUPT InterruptObject;
|
||||||
|
NDIS_MEDIA_STATE MediaState;
|
||||||
|
NDIS_MINIPORT_TIMER MediaDetectionTimer;
|
||||||
ULONG CurrentReceiveDescriptorIndex;
|
ULONG CurrentReceiveDescriptorIndex;
|
||||||
ULONG CurrentPacketFilter;
|
ULONG CurrentPacketFilter;
|
||||||
ULONG CurrentLookaheadSize;
|
ULONG CurrentLookaheadSize;
|
||||||
|
@ -125,10 +118,23 @@ MiniportSetInformation(
|
||||||
OUT PULONG BytesRead,
|
OUT PULONG BytesRead,
|
||||||
OUT PULONG BytesNeeded);
|
OUT PULONG BytesNeeded);
|
||||||
|
|
||||||
|
NDIS_STATUS
|
||||||
|
STDCALL
|
||||||
|
MiSetMulticast(
|
||||||
|
PADAPTER Adapter,
|
||||||
|
UCHAR *Addresses,
|
||||||
|
UINT AddressCount);
|
||||||
|
|
||||||
|
NDIS_MEDIA_STATE
|
||||||
|
STDCALL
|
||||||
|
MiGetMediaState(PADAPTER Adapter);
|
||||||
|
|
||||||
/* operational constants */
|
/* operational constants */
|
||||||
#define NUMBER_OF_BUFFERS 0x20
|
#define NUMBER_OF_BUFFERS 0x20
|
||||||
#define LOG_NUMBER_OF_BUFFERS 5 /* log2(NUMBER_OF_BUFFERS) */
|
#define LOG_NUMBER_OF_BUFFERS 5 /* log2(NUMBER_OF_BUFFERS) */
|
||||||
#define BUFFER_SIZE 0x600
|
#define BUFFER_SIZE 0x600
|
||||||
|
#define MAX_MULTICAST_ADDRESSES 32
|
||||||
|
#define MEDIA_DETECTION_INTERVAL 5000
|
||||||
|
|
||||||
/* flags */
|
/* flags */
|
||||||
#define RESET_IN_PROGRESS 0x1
|
#define RESET_IN_PROGRESS 0x1
|
||||||
|
|
|
@ -24,7 +24,13 @@
|
||||||
* borrowed very heavily from the ReactOS ne2000 driver by
|
* borrowed very heavily from the ReactOS ne2000 driver by
|
||||||
* Casper S. Hornstrup (chorns@users.sourceforge.net)
|
* Casper S. Hornstrup (chorns@users.sourceforge.net)
|
||||||
* REVISIONS:
|
* REVISIONS:
|
||||||
* 14-Sept-2003 vizzini - Created
|
* 14-Sep-2003 vizzini - Created
|
||||||
|
* 17-Oct-2004 navaraf - Add multicast support.
|
||||||
|
* - Add media state detection support.
|
||||||
|
* - Protect the adapter context with spinlock
|
||||||
|
* and move code talking to card to inside
|
||||||
|
* NdisMSynchronizeWithInterrupt calls where
|
||||||
|
* necessary.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <ndis.h>
|
#include <ndis.h>
|
||||||
|
@ -61,6 +67,7 @@ static ULONG MiniportOIDList[] =
|
||||||
OID_GEN_XMIT_ERROR,
|
OID_GEN_XMIT_ERROR,
|
||||||
OID_GEN_RCV_ERROR,
|
OID_GEN_RCV_ERROR,
|
||||||
OID_GEN_RCV_NO_BUFFER,
|
OID_GEN_RCV_NO_BUFFER,
|
||||||
|
OID_GEN_RCV_CRC_ERROR,
|
||||||
OID_802_3_PERMANENT_ADDRESS,
|
OID_802_3_PERMANENT_ADDRESS,
|
||||||
OID_802_3_CURRENT_ADDRESS,
|
OID_802_3_CURRENT_ADDRESS,
|
||||||
OID_802_3_MULTICAST_LIST,
|
OID_802_3_MULTICAST_LIST,
|
||||||
|
@ -110,6 +117,8 @@ MiniportQueryInformation(
|
||||||
|
|
||||||
ASSERT(Adapter);
|
ASSERT(Adapter);
|
||||||
|
|
||||||
|
NdisAcquireSpinLock(&Adapter->Lock);
|
||||||
|
|
||||||
Status = NDIS_STATUS_SUCCESS;
|
Status = NDIS_STATUS_SUCCESS;
|
||||||
CopyFrom = (PVOID)&GenericULONG;
|
CopyFrom = (PVOID)&GenericULONG;
|
||||||
CopySize = sizeof(ULONG);
|
CopySize = sizeof(ULONG);
|
||||||
|
@ -191,15 +200,20 @@ MiniportQueryInformation(
|
||||||
|
|
||||||
case OID_GEN_VENDOR_ID:
|
case OID_GEN_VENDOR_ID:
|
||||||
{
|
{
|
||||||
GenericULONG = 0x1022;
|
UCHAR *CharPtr = (UCHAR *)&GenericULONG;
|
||||||
|
GenericULONG = 0;
|
||||||
|
/* Read the first three bytes of the permanent MAC address */
|
||||||
|
NdisRawReadPortUchar(Adapter->PortOffset, CharPtr);
|
||||||
|
NdisRawReadPortUchar(Adapter->PortOffset + 1, CharPtr + 1);
|
||||||
|
NdisRawReadPortUchar(Adapter->PortOffset + 2, CharPtr + 2);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case OID_GEN_VENDOR_DESCRIPTION:
|
case OID_GEN_VENDOR_DESCRIPTION:
|
||||||
{
|
{
|
||||||
/* XXX implement me */
|
static UCHAR VendorDesc[] = "ReactOS Team";
|
||||||
CopyFrom = 0;
|
CopyFrom = VendorDesc;
|
||||||
CopySize = 0;
|
CopySize = sizeof(VendorDesc);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -220,7 +234,7 @@ MiniportQueryInformation(
|
||||||
{
|
{
|
||||||
/* NDIS version used by the driver. */
|
/* NDIS version used by the driver. */
|
||||||
static const USHORT DriverVersion =
|
static const USHORT DriverVersion =
|
||||||
(NDIS_MAJOR_VERSION << 8) + NDIS_MINOR_VERSION;
|
(NDIS_MINIPORT_MAJOR_VERSION << 8) + NDIS_MINIPORT_MINOR_VERSION;
|
||||||
CopyFrom = (PVOID)&DriverVersion;
|
CopyFrom = (PVOID)&DriverVersion;
|
||||||
CopySize = sizeof(DriverVersion);
|
CopySize = sizeof(DriverVersion);
|
||||||
break;
|
break;
|
||||||
|
@ -244,14 +258,13 @@ MiniportQueryInformation(
|
||||||
{
|
{
|
||||||
GenericULONG = NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA |
|
GenericULONG = NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA |
|
||||||
NDIS_MAC_OPTION_RECEIVE_SERIALIZED |
|
NDIS_MAC_OPTION_RECEIVE_SERIALIZED |
|
||||||
NDIS_MAC_OPTION_TRANSFERS_NOT_PEND |
|
NDIS_MAC_OPTION_TRANSFERS_NOT_PEND;
|
||||||
NDIS_MAC_OPTION_NO_LOOPBACK;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case OID_GEN_MEDIA_CONNECT_STATUS:
|
case OID_GEN_MEDIA_CONNECT_STATUS:
|
||||||
{
|
{
|
||||||
GenericULONG = (ULONG)NdisMediaStateConnected;
|
GenericULONG = Adapter->MediaState;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -269,26 +282,9 @@ MiniportQueryInformation(
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case OID_802_3_MULTICAST_LIST:
|
|
||||||
{
|
|
||||||
/* XXX Implement me */
|
|
||||||
PCNET_DbgPrint(("OID_802_3_MULTICAST_LIST.\n"));
|
|
||||||
Status = NDIS_STATUS_NOT_SUPPORTED;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case OID_802_3_MAXIMUM_LIST_SIZE:
|
case OID_802_3_MAXIMUM_LIST_SIZE:
|
||||||
{
|
{
|
||||||
/* XXX Implement me */
|
GenericULONG = MAX_MULTICAST_ADDRESSES;
|
||||||
GenericULONG = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case OID_802_3_MAC_OPTIONS:
|
|
||||||
{
|
|
||||||
/* XXX Implement me */
|
|
||||||
PCNET_DbgPrint(("OID_802_3_MAC_OPTIONS.\n"));
|
|
||||||
Status = NDIS_STATUS_NOT_SUPPORTED;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -318,29 +314,30 @@ MiniportQueryInformation(
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OID_GEN_RCV_NO_BUFFER:
|
case OID_GEN_RCV_NO_BUFFER:
|
||||||
/* FIXME: Is this correct? */
|
GenericULONG = Adapter->Statistics.RcvBufferErrors +
|
||||||
GenericULONG = Adapter->Statistics.RcvBufferErrors;
|
Adapter->Statistics.RcvOverflowErrors;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OID_GEN_RCV_CRC_ERROR:
|
||||||
|
GenericULONG = Adapter->Statistics.RcvCrcErrors;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OID_802_3_RCV_ERROR_ALIGNMENT:
|
case OID_802_3_RCV_ERROR_ALIGNMENT:
|
||||||
/* XXX Implement me */
|
GenericULONG = Adapter->Statistics.RcvFramingErrors;
|
||||||
GenericULONG = 0;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OID_802_3_XMIT_ONE_COLLISION:
|
case OID_802_3_XMIT_ONE_COLLISION:
|
||||||
/* FIXME: Is this correct? */
|
GenericULONG = Adapter->Statistics.XmtOneRetry;
|
||||||
GenericULONG = Adapter->Statistics.XmtCollisions;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OID_802_3_XMIT_MORE_COLLISIONS:
|
case OID_802_3_XMIT_MORE_COLLISIONS:
|
||||||
/* FIXME: Is this correct? */
|
GenericULONG = Adapter->Statistics.XmtMoreThanOneRetry;
|
||||||
GenericULONG = Adapter->Statistics.XmtLateCollisions;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
PCNET_DbgPrint(("Unknown OID\n"));
|
PCNET_DbgPrint(("Unknown OID\n"));
|
||||||
Status = NDIS_STATUS_INVALID_OID;
|
Status = NDIS_STATUS_NOT_SUPPORTED;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -361,6 +358,8 @@ MiniportQueryInformation(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NdisReleaseSpinLock(&Adapter->Lock);
|
||||||
|
|
||||||
PCNET_DbgPrint(("Leaving. Status is 0x%x\n", Status));
|
PCNET_DbgPrint(("Leaving. Status is 0x%x\n", Status));
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
|
@ -400,6 +399,8 @@ MiniportSetInformation(
|
||||||
|
|
||||||
PCNET_DbgPrint(("Called, OID 0x%x\n", Oid));
|
PCNET_DbgPrint(("Called, OID 0x%x\n", Oid));
|
||||||
|
|
||||||
|
NdisAcquireSpinLock(&Adapter->Lock);
|
||||||
|
|
||||||
switch (Oid)
|
switch (Oid)
|
||||||
{
|
{
|
||||||
case OID_GEN_CURRENT_PACKET_FILTER:
|
case OID_GEN_CURRENT_PACKET_FILTER:
|
||||||
|
@ -470,10 +471,13 @@ MiniportSetInformation(
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ASSERT((InformationBufferLength / 6) <= MAX_MULTICAST_ADDRESSES);
|
||||||
|
|
||||||
/* Set new multicast address list */
|
/* Set new multicast address list */
|
||||||
//NdisMoveMemory(Adapter->Addresses, InformationBuffer, InformationBufferLength);
|
//NdisMoveMemory(Adapter->Addresses, InformationBuffer, InformationBufferLength);
|
||||||
|
|
||||||
/* FIXME: Update hardware */
|
/* Update hardware */
|
||||||
|
Status = MiSetMulticast(Adapter, InformationBuffer, InformationBufferLength / 6);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -483,7 +487,7 @@ MiniportSetInformation(
|
||||||
PCNET_DbgPrint(("Invalid object ID (0x%X).\n", Oid));
|
PCNET_DbgPrint(("Invalid object ID (0x%X).\n", Oid));
|
||||||
*BytesRead = 0;
|
*BytesRead = 0;
|
||||||
*BytesNeeded = 0;
|
*BytesNeeded = 0;
|
||||||
Status = NDIS_STATUS_INVALID_OID;
|
Status = NDIS_STATUS_NOT_SUPPORTED;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -494,6 +498,8 @@ MiniportSetInformation(
|
||||||
*BytesNeeded = 0;
|
*BytesNeeded = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NdisReleaseSpinLock(&Adapter->Lock);
|
||||||
|
|
||||||
PCNET_DbgPrint(("Leaving. Status (0x%X).\n", Status));
|
PCNET_DbgPrint(("Leaving. Status (0x%X).\n", Status));
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
|
|
Loading…
Reference in a new issue