📄 d100.c
字号:
// Pointer to SwRfd
//
// DESCRIPTION: Re-initializes the given SwRfd super-structure
// and chains it onto the current receive chain
// We don't need to lock around this routine because
//
// RETURNS: nothing
//
//-----------------------------------------------------------------------------
VOID
InitAndChainPacket(PD100_ADAPTER Adapter,
PD100SwRfd SwRfdPtr)
{
PRFD_STRUC Rfd;
PD100SwRfd LastRfd;
DEBUGFUNC("InitAndChainPacket");
TRACE2(Adapter,("\n"));
DEBUGCHAR(Adapter,'9');
Rfd = SwRfdPtr->Rfd;
// Now we can release the receive resources back to the 82557.
// We are done with this RFD so re-initialize it.
Rfd->RfdCbHeader.CbStatus = 0;
Rfd->RfdActualCount = 0;
Rfd->RfdCbHeader.CbCommand = (RFD_EL_BIT);
Rfd->RfdCbHeader.CbLinkPointer = DRIVER_NULL;
// we remove this step right now because we
// don't use any of the OOB data besides status
// if we were noticing receive packet priorities we would probably
// uncomment this code.
// NdisZeroMemory(NDIS_OOB_DATA_FROM_PACKET(SwRfd->ReceivePacket),14);
// Append the RFD to the end of the 82557 RFD chain. Normally, this
// will always be done. The only exception would be if the driver
// was configured to use only 1 RFD (a degenerate case anyway).
if (!QueueEmpty(&Adapter->RfdList))
{
LastRfd = (PD100SwRfd)QueueGetTail(&Adapter->RfdList);
ASSERT(LastRfd);
// Link it onto the end of the chain dynamically
Rfd = LastRfd->Rfd;
Rfd->RfdCbHeader.CbLinkPointer = SwRfdPtr->RfdPhys;
Rfd->RfdCbHeader.CbCommand = 0;
DEBUGCHAR(Adapter,(char)(LastRfd->RfdNum+48));
}
// The processing on this RFD is done, so put it back on the tail of
// our list
QueuePutTail(&Adapter->RfdList, &SwRfdPtr->Link);
DEBUGCHAR(Adapter,'a');
}
//-----------------------------------------------------------------------------
// Procedure: D100CheckForHang
//
// Description: This routine should check to see if the adapter is "hung", and
// fix it if it is. Right now this routine does not check for a
// hang, because the adapter should never "timeout". In the
// future, this is where the code to check for a timeout would go,
// if there were bugs in the chipset that could cause transmit
// "timeouts".
//
// Arguments:
// MiniportAdapterContext (both) - pointer to the adapter object data area
//
// Returns:
// False (miniport) - Always
// Nothing (mac) - Cause the function is a VOID
//-----------------------------------------------------------------------------
BOOLEAN
D100CheckForHang(NDIS_HANDLE MiniportAdapterContext)
{
PD100_ADAPTER Adapter;
DEBUGFUNC("D100CheckForHang");
Adapter = PD100_ADAPTER_FROM_CONTEXT_HANDLE(MiniportAdapterContext);
NdisAcquireSpinLock(&Adapter->Lock);
DEBUGCHAR(Adapter,'U');
// We need to dump our statistics if we are implementing the "periodic multicast
// command workaround"
if (Adapter->McTimeoutFlag)
{
// Dump the current stats
DumpStatsCounters(Adapter);
// If we haven't received any frames recently, and we are implementing
// the "periodic multicast command workaround", then we'll chain in
// a multicast command to the transmit chain here.
if ((Adapter->McTimeoutFlag)
&& (!(Adapter->StatsCounters->RcvGoodFrames))
&& (Adapter->AiRevID < D101_A_STEP))
DoBogusMulticast(Adapter);
}
// this is the implementation of the NDIS 4 feature for detecting
// link status change. It effectively checks every two seconds
// for link.
if (Adapter->LinkIsActive != GetConnectionStatus(Adapter))
// if status has changed
{
DEBUGSTR(("e100bex: CheckforHang: media state changed to %s\n",
((Adapter->LinkIsActive == NdisMediaStateConnected)?
"Disconnected": "Connected")));
switch ( Adapter->LinkIsActive )
{
case NdisMediaStateConnected: // changing from connected
Adapter->LinkIsActive = NdisMediaStateDisconnected;
NdisReleaseSpinLock(&Adapter->Lock);
NdisMIndicateStatus(Adapter->D100AdapterHandle,
NDIS_STATUS_MEDIA_DISCONNECT,
(PVOID)0,
0);
// NOTE:
// have to indicate status complete every time you indicate status
NdisMIndicateStatusComplete(Adapter->D100AdapterHandle);
NdisAcquireSpinLock(&Adapter->Lock);
break;
case NdisMediaStateDisconnected: // changing from disconnected
Adapter->LinkIsActive = NdisMediaStateConnected;
NdisReleaseSpinLock(&Adapter->Lock);
NdisMIndicateStatus(Adapter->D100AdapterHandle,
NDIS_STATUS_MEDIA_CONNECT,
(PVOID)0,
0);
// NOTE:
// have to indicate status complete every time you indicate status
NdisMIndicateStatusComplete(Adapter->D100AdapterHandle);
NdisAcquireSpinLock(&Adapter->Lock);
break;
}
}
// return false to indicate that the adapter is not hung, and that
// D100Reset does NOT need to be called by the wrapper
DEBUGCHAR(Adapter,'u');
NdisReleaseSpinLock(&Adapter->Lock);
return(FALSE);
}
//-----------------------------------------------------------------------------
// Procedure: D100Halt
//
// Description: Removes an adapter instance that was previously initialized.
// To "halt" or "remove" an adapter, we disable its interrupt,
// abort its receive unit (otherwise it would continue to DMA in
// data), and release all of the resources (memory, i/o space,
// etc.) that the adapter instance was using.
// This routine is only called when the adapter is "stopped"
// or unloaded with a "net stop e100b". To see what is called
// at machine shutdown see D100ShutdownHandler.
//
// Arguments:
// MiniportAdapterContext - pointer to the adapter object data area.
//
// Returns: (none)
//-----------------------------------------------------------------------------
VOID
D100Halt(NDIS_HANDLE MiniportAdapterContext)
{
PD100_ADAPTER Adapter;
BOOLEAN Cancelled;
DEBUGFUNC("D100Halt");
DEBUGSTR(("D100Halt\n"));
Adapter = PD100_ADAPTER_FROM_CONTEXT_HANDLE(MiniportAdapterContext);
// Disable the device's interrupt line.
D100DisableInterrupt(Adapter);
// check to make sure there are no outstanding transmits
while(Adapter->FirstTxQueue)
{
PNDIS_PACKET QueuePacket = Adapter->FirstTxQueue;
Adapter->NumPacketsQueued--;
DequeuePacket(Adapter->FirstTxQueue, Adapter->LastTxQueue);
NdisMSendComplete(
Adapter->D100AdapterHandle,
QueuePacket,
NDIS_STATUS_FAILURE);
}
while (!(QueueEmpty(&Adapter->ActiveChainList)))
{
// here we have to fail any sends that haven't completed yet
PD100SwTcb pSwTcb = (PD100SwTcb) QueuePopHead(&Adapter->ActiveChainList);
// If this wasn't a multicast command, then we need to check to see
// if we need to issue send complete
if ((pSwTcb->Tcb->TxCbHeader.CbCommand & CB_CMD_MASK) != CB_MULTICAST)
{
DEBUGCHAR(Adapter,'-');
// Do a send Complete for this frame
NdisMSendComplete(
Adapter->D100AdapterHandle,
pSwTcb->Packet,
NDIS_STATUS_FAILURE);
}
}
// deregister shutdown handler because we are halting now, and don't
// want to have a bugcheck handler registered any more
NdisMDeregisterAdapterShutdownHandler(Adapter->D100AdapterHandle);
// added code to cancel our timer if for some reason it was active
NdisMCancelTimer(&Adapter->D100AsyncResetTimer,
&Cancelled);
// Free the interrupt object
NdisMDeregisterInterrupt(&Adapter->Interrupt);
// Abort the Receive unit. so we don't continue to receive packets. If
// we didn't abort the Receive unit we could still DMA receive packets
// into host memory after a warm boot.
DEBUGCHAR(Adapter,'<');
D100IssueScbCommand(Adapter, SCB_RUC_ABORT, TRUE);
// Wait 30 Milliseconds for the device to abort the RU. This really
// is not necessary, but I'm a little paranoid about reseting the PHY
// when the RU is active.
D100StallExecution(30);
// Reset the PHY chip. We do this so that after a warm boot, the PHY will
// be in a known state, with auto-negotiation enabled.
ResetPhy(Adapter);
NdisFreeSpinLock(&Adapter->Lock);
// Free the entire adapter object, including the shared memory structures.
FreeAdapterObject(Adapter);
}
//-----------------------------------------------------------------------------
// Procedure: D100ShutdownHandler
//
// Description: Removes an adapter instance that was previously initialized.
// To Shutdown simply Disable interrupts and Stop the receive unit.
// Since the system is shutting down there is no need to release
// resources (memory, i/o space, etc.) that the adapter instance
// was using.
//
// Arguments:
// MiniportAdapterContext - pointer to the adapter object data area.
//
// Returns: (none)
//-----------------------------------------------------------------------------
VOID
D100ShutdownHandler(NDIS_HANDLE MiniportAdapterContext)
{
PD100_ADAPTER Adapter;
DEBUGFUNC("D100ShutdownHandler");
Adapter = PD100_ADAPTER_FROM_CONTEXT_HANDLE(MiniportAdapterContext);
DEBUGSTR(("D100ShutdownHandler %8x\n",Adapter));
DEBUGCHAR(Adapter,'!');
// Disable the device's interrupt line.
D100DisableInterrupt(Adapter);
// Abort the Receive unit. so we don't continue to receive packets. If
// we didn't abort the Receive unit we could still DMA receive packets
// into host memory after a warm boot.
D100IssueScbCommand(Adapter, SCB_RUC_ABORT, TRUE);
// Wait 30 Milliseconds for the device to abort the RU. This really
// is not necessary, but I'm a little paranoid about reseting the PHY
// when the RU is active.
D100StallExecution(30);
// Reset the PHY chip. We do this so that after a warm boot, the PHY will
// be in a known state, with auto-negotiation enabled.
ResetPhy(Adapter);
}
//-----------------------------------------------------------------------------
// Procedure: D100Initialize/D100AddAdapter
//
// Description: This routine is called once per each supported adapter card in
// the system. This routine is responsible for initializing each
// adapter. This includes parsing all of the necessary parameters
// from the registry, allocating and initializing shared memory
// structures, configuring the 82557 chip, registering the
// interrupt, and starting the receive unit.
//
// Arguments:
// OpenErrorStatus (mini) - Returns more info about any failure
// SelectedMediumIndex (mini) - Returns the index in MediumArray of the
// medium that the miniport is using
// MediumArraySize (mini) - An array of medium types that the driver
// supports
// MiniportAdapterHandle (mini) - pointer to the adapter object data area.
//
// WrapperConfigurationContext (both) - A value that we will pass to
// NdisOpenConfiguration.
//
//
// Returns:
// NDIS_STATUS_SUCCESS - If the adapter was initialized successfully.
// <not NDIS_STATUS_SUCCESS> - If for some reason the adapter didn't
// initialize
//-----------------------------------------------------------------------------
NDIS_STATUS
D100Initialize(PNDIS_STATUS OpenErrorStatus,
PUINT SelectedMediumIndex,
PNDIS_MEDIUM MediumArray,
UINT MediumArraySize,
NDIS_HANDLE MiniportAdapterHandle,
NDIS_HANDLE WrapperConfigurationContext)
{
ULONG i;
NDIS_STATUS Status;
PD100_ADAPTER Adapter;
NDIS_HANDLE ConfigHandle;
NDIS_INTERFACE_TYPE IfType;
PVOID OverrideNetAddress;
DEBUGFUNC("D100Initialize");
INITSTR(("\n"));
// If this is a miniport, then fill in the media information.
// if medium type 802.3 not found in list, exit with error)
for (i = 0; i < MediumArraySize; i++)
{
if (MediumArray[i] == NdisMedium802_3) break;
}
if (i == MediumArraySize)
{
DEBUGSTR(("802.3 Media type not found.\n"));
return NDIS_STATUS_UNSUPPORTED_MEDIA;
}
// Select ethernet
*SelectedMediumIndex = i;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -