mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
337 lines
7.5 KiB
337 lines
7.5 KiB
/*+
|
|
* file: reset.c
|
|
*
|
|
* Copyright (C) 1992-1995 by
|
|
* Digital Equipment Corporation, Maynard, Massachusetts.
|
|
* All rights reserved.
|
|
*
|
|
* This software is furnished under a license and may be used and copied
|
|
* only in accordance of the terms of such license and with the
|
|
* inclusion of the above copyright notice. This software or any other
|
|
* copies thereof may not be provided or otherwise made available to any
|
|
* other person. No title to and ownership of the software is hereby
|
|
* transferred.
|
|
*
|
|
* The information in this software is subject to change without notice
|
|
* and should not be construed as a commitment by digital equipment
|
|
* corporation.
|
|
*
|
|
* Digital assumes no responsibility for the use or reliability of its
|
|
* software on equipment which is not supplied by digital.
|
|
*
|
|
*
|
|
* Abstract: This file contains the Reset code of the
|
|
* NDIS 4.0 miniport driver for DEC's DC21X4 Ethernet
|
|
* adapter family.
|
|
*
|
|
* Author: Philippe Klein
|
|
*
|
|
* Revision History:
|
|
*
|
|
* phk 08-Aug-1994 Initial entry
|
|
*
|
|
-*/
|
|
|
|
#include <precomp.h>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*+
|
|
*
|
|
*
|
|
* DC21X4Reset
|
|
*
|
|
* Routine Description:
|
|
*
|
|
* Reset the adapter
|
|
*
|
|
-*/
|
|
|
|
extern
|
|
NDIS_STATUS
|
|
DC21X4Reset(
|
|
OUT PBOOLEAN AddressingReset,
|
|
IN NDIS_HANDLE MiniportAdapterContext
|
|
)
|
|
{
|
|
PDC21X4_ADAPTER Adapter;
|
|
#if 0
|
|
PDC21X4_TRANSMIT_DESCRIPTOR CurrentDescriptor;
|
|
#endif
|
|
INT i;
|
|
BOOLEAN StartTimer = TRUE;
|
|
BOOLEAN Link = FALSE;
|
|
|
|
#if _DBG
|
|
DbgPrint("DC21X4Reset\n");
|
|
#endif
|
|
|
|
Adapter = (PDC21X4_ADAPTER)MiniportAdapterContext;
|
|
*AddressingReset = FALSE;
|
|
|
|
|
|
//Stop the AutoSense Timer if active
|
|
|
|
if (Adapter->TimerFlag != NoTimer) {
|
|
DC21X4StopAutoSenseTimer(Adapter);
|
|
}
|
|
|
|
// Stop the adapter
|
|
DC21X4StopAdapter(Adapter);
|
|
|
|
#if 0
|
|
// Walk down the Transmit descriptor ring to close all pending packets
|
|
|
|
while (Adapter->DequeueTransmitDescriptor != Adapter->EnqueueTransmitDescriptor) {
|
|
|
|
CurrentDescriptor = Adapter->DequeueTransmitDescriptor;
|
|
|
|
if (CurrentDescriptor->Control & DC21X4_TDES_SETUP_PACKET) {
|
|
|
|
// Setup buffer:
|
|
// Complete the pended Set Information request
|
|
|
|
#if _DBG
|
|
DbgPrint("Reset: NdisMSetInformationComplete\n");
|
|
#endif
|
|
NdisMSetInformationComplete (
|
|
Adapter->MiniportAdapterHandle,
|
|
NDIS_STATUS_FAILURE
|
|
);
|
|
}
|
|
else if (CurrentDescriptor->Control & DC21X4_TDES_LAST_SEGMENT) {
|
|
|
|
#if _DBG
|
|
DbgPrint("Reset: NdisMSendComplete [Packet: %08x]\n",CurrentDescriptor->Packet);
|
|
#endif
|
|
NdisMSendComplete(
|
|
Adapter->MiniportAdapterHandle,
|
|
CurrentDescriptor->Packet,
|
|
NDIS_STATUS_FAILURE
|
|
);
|
|
}
|
|
Adapter->DequeueTransmitDescriptor = CurrentDescriptor->Next;
|
|
}
|
|
#endif
|
|
|
|
// Free up all the map registers
|
|
for (i=0;
|
|
i < (TRANSMIT_RING_SIZE * NUMBER_OF_SEGMENT_PER_DESC);
|
|
i++
|
|
) {
|
|
|
|
if (Adapter->PhysicalMapping[i].Valid) {
|
|
#if _DBG
|
|
DbgPrint("Reset: NdisMCompleteBufferPhysicalMapping (%d)\n",i);
|
|
#endif
|
|
NdisMCompleteBufferPhysicalMapping(
|
|
Adapter->MiniportAdapterHandle,
|
|
Adapter->PhysicalMapping[i].Buffer,
|
|
Adapter->PhysicalMapping[i].Register
|
|
);
|
|
Adapter->PhysicalMapping[i].Valid = FALSE;
|
|
Adapter->FreeMapRegisters++;
|
|
}
|
|
}
|
|
#if _DBG
|
|
DbgPrint("Reset: FreeMapRegisters = %d\n",Adapter->FreeMapRegisters);
|
|
#endif
|
|
|
|
// Reinitialize the descriptor pointers
|
|
|
|
Adapter->DequeueReceiveDescriptor =
|
|
(PDC21X4_RECEIVE_DESCRIPTOR)Adapter->ReceiveDescriptorRingVa;
|
|
Adapter->EnqueueTransmitDescriptor =
|
|
(PDC21X4_TRANSMIT_DESCRIPTOR)Adapter->TransmitDescriptorRingVa;
|
|
Adapter->DequeueTransmitDescriptor =
|
|
Adapter->EnqueueTransmitDescriptor;
|
|
|
|
Adapter->FreeTransmitDescriptorCount = TRANSMIT_RING_SIZE - 1;
|
|
|
|
// Initialize the statistic counters
|
|
|
|
ZERO_MEMORY (
|
|
&Adapter->GeneralMandatory[0],
|
|
GM_ARRAY_SIZE * sizeof(ULONG)
|
|
);
|
|
ZERO_MEMORY (
|
|
&Adapter->GeneralOptional[0],
|
|
GO_ARRAY_SIZE * sizeof(ULONG)
|
|
);
|
|
ZERO_MEMORY (
|
|
&Adapter->GeneralOptionalCount[0],
|
|
GO_COUNT_ARRAY_SIZE * sizeof(GEN_OPTIONAL_COUNT)
|
|
);
|
|
ZERO_MEMORY (
|
|
&Adapter->MediaMandatory[0],
|
|
MM_ARRAY_SIZE * sizeof(ULONG)
|
|
);
|
|
ZERO_MEMORY (
|
|
&Adapter->MediaOptional[0],
|
|
MO_ARRAY_SIZE * sizeof(ULONG)
|
|
);
|
|
|
|
#if _DBG
|
|
DbgPrint("initialize DC21X4 CSRS\n");
|
|
#endif
|
|
|
|
// Renitialize the DC21X4 registers
|
|
DC21X4InitializeRegisters(Adapter);
|
|
|
|
// Initialize the PHY
|
|
if (Adapter->PhyMediumInSrom) {
|
|
Adapter->PhyPresent = DC21X4PhyInit(Adapter);
|
|
}
|
|
if (Adapter->PhyPresent) {
|
|
|
|
#if 0
|
|
if (!(Adapter->MiiMediaType & MEDIA_NWAY)) {
|
|
|
|
DC21X4SetPhyControl(
|
|
Adapter,
|
|
(USHORT)MiiGenAdminIsolate
|
|
);
|
|
}
|
|
#endif
|
|
|
|
DC21X4SetPhyConnection(Adapter);
|
|
|
|
}
|
|
|
|
// Because the DC21X4 wakes up in promiscuous mode after reset
|
|
// we reload the DC21X4's Cam (in polling mode)
|
|
|
|
if (!DC21X4LoadCam(
|
|
Adapter,
|
|
FALSE)) {
|
|
return NDIS_STATUS_HARD_ERRORS;
|
|
}
|
|
|
|
if (!Adapter->PhyPresent) {
|
|
DC21X4InitializeMediaRegisters(Adapter,FALSE);
|
|
}
|
|
|
|
Adapter->FirstAncInterrupt = TRUE;
|
|
Adapter->IndicateOverflow = FALSE;
|
|
|
|
//// //Restart the Transmitter and Receiver
|
|
//// DC21X4StartAdapter(Adapter);
|
|
|
|
// Media link Detection
|
|
if (Adapter->PhyPresent) {
|
|
Link = DC21X4MiiAutoDetect(
|
|
Adapter
|
|
);
|
|
}
|
|
if ( (!Adapter->PhyPresent)
|
|
|| (!Link
|
|
&& (Adapter->MediaCapable)
|
|
)
|
|
) {
|
|
|
|
StartTimer = DC21X4MediaDetect(
|
|
Adapter
|
|
);
|
|
}
|
|
|
|
// Start the Autosense timer if not yet started
|
|
|
|
if (StartTimer && (Adapter->TimerFlag==NoTimer)) {
|
|
|
|
DC21X4StartAutoSenseTimer(
|
|
Adapter,
|
|
((Adapter->PhyPresent) ? DC21X4_MII_TICK : DC21X4_SPA_TICK)
|
|
);
|
|
}
|
|
|
|
if (Adapter->LinkStatus == LinkFail) {
|
|
|
|
// Defer the completion of the reset routine
|
|
// until the Link is up
|
|
|
|
Adapter->LinkCheckCount = MAX_LINK_CHECK;
|
|
|
|
NdisMSetTimer(
|
|
&Adapter->ResetTimer,
|
|
LINK_CHECK_PERIOD
|
|
);
|
|
Adapter->ResetInProgress = TRUE;
|
|
return NDIS_STATUS_PENDING;
|
|
|
|
}
|
|
else {
|
|
|
|
//Restart the Receiver & Transmitter
|
|
DC21X4StartAdapter(Adapter);
|
|
|
|
//Complete the Reset routine synchronously
|
|
return NDIS_STATUS_SUCCESS;
|
|
}
|
|
}
|
|
|
|
/*+
|
|
*
|
|
*
|
|
* DC21X4DeferredReset
|
|
*
|
|
* Routine Description:
|
|
*
|
|
* Reset routine
|
|
*
|
|
-*/
|
|
extern
|
|
VOID
|
|
DC21X4DeferredReset (
|
|
IN PVOID Systemspecific1,
|
|
IN PDC21X4_ADAPTER Adapter,
|
|
IN PVOID Systemspecific2,
|
|
IN PVOID Systemspecific3
|
|
)
|
|
{
|
|
|
|
#if _DBG
|
|
DbgPrint("DC21X4DeferredReset\n");
|
|
#endif
|
|
|
|
#if __DBG
|
|
DbgPrint("DC21X4DeferredReset: LinkStatus=%x LinkCheckCount=%d\n",
|
|
Adapter->LinkStatus,Adapter->LinkCheckCount);
|
|
#endif
|
|
Adapter->LinkCheckCount--;
|
|
|
|
if ( (Adapter->LinkStatus !=LinkFail)
|
|
|| (Adapter->LinkCheckCount == 0)
|
|
) {
|
|
|
|
//Indicate the assynchronous completion of the
|
|
//Reset routine
|
|
|
|
#if __DBG
|
|
DbgPrint("DC21X4DeferredReset: Indicate ResetComplete\n");
|
|
#endif
|
|
NdisMResetComplete(
|
|
Adapter->MiniportAdapterHandle,
|
|
NDIS_STATUS_SUCCESS,
|
|
FALSE
|
|
);
|
|
|
|
Adapter->ResetInProgress = FALSE;
|
|
|
|
//Restart the Receiver & Transmitter
|
|
DC21X4StartAdapter(Adapter);
|
|
|
|
}
|
|
else {
|
|
// Fire the ResetTimer for an other link check
|
|
NdisMSetTimer(
|
|
&Adapter->ResetTimer,
|
|
LINK_CHECK_PERIOD
|
|
);
|
|
}
|
|
|
|
}
|
|
|