📄 ne2000.c
字号:
//
// Initialize the receive variables.
//
Adapter->NicReceiveConfig = RCR_REJECT_ERR;
//
// Initialize the transmit buffer control.
//
Adapter->CurBufXmitting = (XMIT_BUF)-1;
//
// Initialize the transmit buffer states.
//
for (i = 0; i < Adapter->NumBuffers; i++)
Adapter->BufferStatus[i] = EMPTY;
//
// Read the Ethernet address off of the PROM.
//
if (!CardReadEthernetAddress(Adapter))
{
DEBUGMSG(1,
(TEXT("NE2000:RegisterAdapter Could not read the ethernet address\n")));
NdisWriteErrorLogEntry(
Adapter->MiniportAdapterHandle,
NDIS_ERROR_CODE_ADAPTER_NOT_FOUND,
0
);
status = NDIS_STATUS_ADAPTER_NOT_FOUND;
goto fail2;
}
//
// Now initialize the NIC and Gate Array registers.
//
Adapter->NicInterruptMask = IMR_RCV | IMR_XMIT | IMR_XMIT_ERR | IMR_OVERFLOW;
//
// Link us on to the chain of adapters for this driver.
//
Adapter->NextAdapter = Ne2000MiniportBlock.AdapterQueue;
Ne2000MiniportBlock.AdapterQueue = Adapter;
//
// Setup the card based on the initialization information
//
DEBUGMSG(1, (TEXT("NE2000:RegisterAdapter CardSetup\n")));
if (!CardSetup(Adapter))
{
//
// The NIC could not be written to.
//
NdisWriteErrorLogEntry(
Adapter->MiniportAdapterHandle,
NDIS_ERROR_CODE_ADAPTER_NOT_FOUND,
0
);
DEBUGMSG(1,
(TEXT("NE2000:RegisterAdapter CardSetup -- Failed\n")));
status = NDIS_STATUS_ADAPTER_NOT_FOUND;
goto fail3;
}
DEBUGMSG(1,
(TEXT("NE2000:RegisterAdapter CardSetup -- Success\n")));
//
// Initialize the interrupt.
//
status = NdisMRegisterInterrupt(
&Adapter->Interrupt,
Adapter->MiniportAdapterHandle,
Adapter->InterruptNumber,
Adapter->InterruptNumber,
FALSE,
FALSE,
NdisInterruptLatched
);
if (status != NDIS_STATUS_SUCCESS)
{
DEBUGMSG(1,
(TEXT("NE2000:RegisterAdapter NdisMRegisterInterrupt failed 0x%x\n"), status));
NdisWriteErrorLogEntry(
Adapter->MiniportAdapterHandle,
NDIS_ERROR_CODE_INTERRUPT_CONNECT,
0
);
goto fail3;
}
DEBUGMSG(1,
(TEXT("NE2000:RegisterAdapter Interrupt Connected\n")));
// register a shutdown handler for this card
NdisMRegisterAdapterShutdownHandler(
Adapter->MiniportAdapterHandle, // miniport handle.
Adapter, // shutdown context.
Ne2000Shutdown // shutdown handler.
);
//
// Start up the adapter.
//
CardStart(Adapter);
//
// Initialization completed successfully.
//
DEBUGMSG(1, (TEXT("NE2000:RegisterAdapter OK\n")));
return(NDIS_STATUS_SUCCESS);
//
// Code to unwind what has already been set up when a part of
// initialization fails, which is jumped into at various
// points based on where the failure occured. Jumping to
// a higher-numbered failure point will execute the code
// for that block and all lower-numbered ones.
//
fail3:
//
// Take us out of the AdapterQueue.
//
if (Ne2000MiniportBlock.AdapterQueue == Adapter)
{
Ne2000MiniportBlock.AdapterQueue = Adapter->NextAdapter;
}
else
{
PNE2000_ADAPTER TmpAdapter = Ne2000MiniportBlock.AdapterQueue;
while (TmpAdapter->NextAdapter != Adapter)
{
TmpAdapter = TmpAdapter->NextAdapter;
}
TmpAdapter->NextAdapter = TmpAdapter->NextAdapter->NextAdapter;
}
//
// We already enabled the interrupt on the card, so
// turn it off.
//
NdisRawWritePortUchar(Adapter->IoPAddr+NIC_COMMAND, CR_STOP);
fail2:
NdisMDeregisterIoPortRange(
Adapter->MiniportAdapterHandle,
(ULONG)Adapter->IoBaseAddr,
0x20,
(PVOID)Adapter->IoPAddr
);
return(status);
}
extern
VOID
Ne2000Shutdown(
IN NDIS_HANDLE MiniportAdapterContext
)
/*++
Routine Description:
NE2000Shutdown is called to shut down the adapter. We need to unblock any
threads which may be called in, and terminate any loops. This function is
called by NDIS.DLL when a PCMCIA card removal is detected. At that
point, any access to the NE2000 registers may return random data, as the bus
is floating.
Arguments:
MiniportAdapterContext - The context value that the Miniport returned
from Ne2000Initialize; actually as pointer to an NE2000_ADAPTER.
Return Value:
None.
--*/
{
PNE2000_ADAPTER Adapter;
Adapter = PNE2000_ADAPTER_FROM_CONTEXT_HANDLE(MiniportAdapterContext);
Adapter->ShuttingDown = TRUE;
//
// Shut down the chip. Note that the card may not be present, so this
// routine should not do anything that might hang.
//
CardStop(Adapter);
}
extern
VOID
Ne2000Halt(
IN NDIS_HANDLE MiniportAdapterContext
)
/*++
Routine Description:
NE2000Halt removes an adapter that was previously initialized.
Arguments:
MiniportAdapterContext - The context value that the Miniport returned
from Ne2000Initialize; actually as pointer to an NE2000_ADAPTER.
Return Value:
None.
--*/
{
PNE2000_ADAPTER Adapter;
Adapter = PNE2000_ADAPTER_FROM_CONTEXT_HANDLE(MiniportAdapterContext);
//
// Shut down the chip.
//
CardStop(Adapter);
//
// Disconnect the interrupt line.
//
NdisMDeregisterInterrupt(&Adapter->Interrupt);
//
// Pause, waiting for any DPC stuff to clear.
//
NdisStallExecution(250000);
NdisMDeregisterIoPortRange(Adapter->MiniportAdapterHandle,
(ULONG)Adapter->IoBaseAddr,
0x20,
(PVOID)Adapter->IoPAddr
);
//
// Remove the adapter from the global queue of adapters.
//
if (Ne2000MiniportBlock.AdapterQueue == Adapter) {
Ne2000MiniportBlock.AdapterQueue = Adapter->NextAdapter;
} else {
PNE2000_ADAPTER TmpAdapter = Ne2000MiniportBlock.AdapterQueue;
while (TmpAdapter->NextAdapter != Adapter) {
TmpAdapter = TmpAdapter->NextAdapter;
}
TmpAdapter->NextAdapter = TmpAdapter->NextAdapter->NextAdapter;
}
// was this the last NIC?
if ((Ne2000MiniportBlock.AdapterQueue == NULL) &&
(Ne2000MiniportBlock.NdisWrapperHandle)) {
NdisTerminateWrapper (Ne2000MiniportBlock.NdisWrapperHandle, NULL);
Ne2000MiniportBlock.NdisWrapperHandle = NULL;
}
//
// Free up the memory
//
NdisFreeMemory(Adapter, sizeof(NE2000_ADAPTER), 0);
return;
}
NDIS_STATUS
Ne2000Reset(
OUT PBOOLEAN AddressingReset,
IN NDIS_HANDLE MiniportAdapterContext
)
/*++
Routine Description:
The NE2000Reset request instructs the Miniport to issue a hardware reset
to the network adapter. The driver also resets its software state. See
the description of NdisMReset for a detailed description of this request.
Arguments:
AddressingReset - Does the adapter need the addressing information reloaded.
MiniportAdapterContext - Pointer to the adapter structure.
Return Value:
The function value is the status of the operation.
--*/
{
//
// Pointer to the adapter structure.
//
PNE2000_ADAPTER Adapter = (PNE2000_ADAPTER)MiniportAdapterContext;
//
// Temporary looping variable
//
UINT i;
//
// Clear the values for transmits, they will be reset these for after
// the reset is completed.
//
Adapter->NextBufToFill = 0;
Adapter->NextBufToXmit = 0;
Adapter->CurBufXmitting = (XMIT_BUF)-1;
Adapter->FirstPacket = NULL;
Adapter->LastPacket = NULL;
for (i=0; i<Adapter->NumBuffers; i++) {
Adapter->BufferStatus[i] = EMPTY;
}
//
// Physically reset the card.
//
Adapter->NicInterruptMask = IMR_RCV | IMR_XMIT | IMR_XMIT_ERR | IMR_OVERFLOW;
return (CardReset(Adapter) ? NDIS_STATUS_SUCCESS : NDIS_STATUS_FAILURE);
}
NDIS_STATUS
Ne2000QueryInformation(
IN NDIS_HANDLE MiniportAdapterContext,
IN NDIS_OID Oid,
IN PVOID InformationBuffer,
IN ULONG InformationBufferLength,
OUT PULONG BytesWritten,
OUT PULONG BytesNeeded
)
/*++
Routine Description:
The NE2000QueryInformation process a Query request for
NDIS_OIDs that are specific about the Driver.
Arguments:
MiniportAdapterContext - a pointer to the adapter.
Oid - the NDIS_OID to process.
InformationBuffer - a pointer into the
NdisRequest->InformationBuffer into which store the result of the query.
InformationBufferLength - a pointer to the number of bytes left in the
InformationBuffer.
BytesWritten - a pointer to the number of bytes written into the
InformationBuffer.
BytesNeeded - If there is not enough room in the information buffer
then this will contain the number of bytes needed to complete the
request.
Return Value:
The function value is the status of the operation.
--*/
{
//
// Pointer to the adapter structure.
//
PNE2000_ADAPTER Adapter = (PNE2000_ADAPTER)MiniportAdapterContext;
//
// General Algorithm:
//
// Switch(Request)
// Get requested information
// Store results in a common variable.
// default:
// Try protocol query information
// If that fails, fail query.
//
// Copy result in common variable to result buffer.
// Finish processing
UINT BytesLeft = InformationBufferLength;
PUCHAR InfoBuffer = (PUCHAR)(InformationBuffer);
NDIS_STATUS StatusToReturn = NDIS_STATUS_SUCCESS;
NDIS_HARDWARE_STATUS HardwareStatus = NdisHardwareStatusReady;
NDIS_MEDIUM Medium = NdisMedium802_3;
//
// This variable holds result of query
//
ULONG GenericULong;
USHORT GenericUShort;
UCHAR GenericArray[6];
UINT MoveBytes = sizeof(ULONG);
PVOID MoveSource = (PVOID)(&GenericULong);
//
// Make sure that int is 4 bytes. Else GenericULong must change
// to something of size 4.
//
ASSERT(sizeof(ULONG) == 4);
//
// Switch on request type
//
switch (Oid) {
case OID_GEN_MAC_OPTIONS:
GenericULong = (ULONG)(NDIS_MAC_OPTION_TRANSFERS_NOT_PEND |
NDIS_MAC_OPTION_RECEIVE_SERIALIZED |
NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA |
NDIS_MAC_OPTION_NO_LOOPBACK
);
break;
case OID_GEN_SUPPORTED_LIST:
MoveSource = (PVOID)(Ne2000SupportedOids);
MoveBytes = sizeof(Ne2000SupportedOids);
break;
case OID_GEN_HARDWARE_STATUS:
HardwareStatus = NdisHardwareStatusReady;
MoveSource = (PVOID)(&HardwareStatus);
MoveBytes = sizeof(NDIS_HARDWARE_STATUS);
break;
case OID_GEN_MEDIA_SUPPORTED:
case OID_GEN_MEDIA_IN_USE:
MoveSource = (PVOID) (&Medium);
MoveBytes = sizeof(NDIS_MEDIUM);
break;
case OID_GEN_MAXIMUM_LOOKAHEAD:
GenericULong = NE2000_MAX_LOOKAHEAD;
break;
case OID_GEN_MAXIMUM_FRAME_SIZE:
GenericULong = (ULONG)(1514 - NE2000_HEADER_SIZE);
break;
case OID_GEN_MAXIMUM_TOTAL_SIZE:
GenericULong = (ULONG)(1514);
break;
case OID_GEN_LINK_SPEED:
GenericULong = (ULONG)(100000);
break;
case OID_GEN_TRANSMIT_BUFFER_SPACE:
GenericULong = (ULONG)(Adapter->NumBuffers * TX_BUF_SIZE);
break;
case OID_GEN_RECEIVE_BUFFER_SPACE:
GenericULong = (ULONG)(0x2000 - (Adapter->NumBuffers * TX_BUF_SIZE));
break;
case OID_GEN_TRANSMIT_BLOCK_SIZE:
GenericULong = (ULONG)(TX_BUF_SIZE);
break;
case OID_GEN_RECEIVE_BLOCK_SIZE:
GenericULong = (ULONG)(256);
break;
#ifdef NE2000
case OID_GEN_VENDOR_ID:
NdisMoveMemory(
(PVOID)&GenericULong,
Adapter->PermanentAddress,
3
);
GenericULong &= 0xFFFFFF00;
MoveSource = (PVOID)(&GenericULong);
MoveBytes = sizeof(GenericULong);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -