/*+
* 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
);
}
}