2048 lines
51 KiB
C
2048 lines
51 KiB
C
|
/*+
|
|||
|
* file: media.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 Media detection code of the
|
|||
|
* NDIS 4.0 miniport driver for DEC's DC21X4 Ethernet Adapter
|
|||
|
* family.
|
|||
|
*
|
|||
|
* Author: Philippe Klein
|
|||
|
*
|
|||
|
* Revision History:
|
|||
|
*
|
|||
|
* phk 01-Dec-1994 Initial entry
|
|||
|
* phk 31-Jan-1994 Add Polarity support
|
|||
|
* phk 26-Apr-1995 Modify the DC21140 MediaDetect and
|
|||
|
* AutoSense routines
|
|||
|
*
|
|||
|
-*/
|
|||
|
|
|||
|
#include <precomp.h>
|
|||
|
|
|||
|
#define MII100_TICK 30 // 2.5ms (81.9 us/tick)
|
|||
|
#define EXT10_TICK 12 // 2.5ms (204.8 us/tick)
|
|||
|
#define MII10_TICK 3 // 2.5ms (819.2 us/tick)
|
|||
|
|
|||
|
#define ONE_SECOND_DELAY 400 // * 2.5 ms
|
|||
|
#define FIVE_MILLISECONDS_DELAY 2 // * 2.5 ms
|
|||
|
|
|||
|
#define MAX_RETRY 4
|
|||
|
|
|||
|
#define GEP_READ_DELAY 200 // milliseconds
|
|||
|
|
|||
|
#define DC21X4_LINK_STATUS(_status,_adapter,_medium) \
|
|||
|
(BOOLEAN) ( ( ( (_status) ^ (_adapter)->Media[(_medium)].Polarity) \
|
|||
|
& (_adapter)->Media[(_medium)].SenseMask ) != 0)
|
|||
|
|
|||
|
#if __DBG
|
|||
|
PUCHAR MediumString[] = {
|
|||
|
"10BaseT",
|
|||
|
"10Base2",
|
|||
|
"10Base5",
|
|||
|
"100BaseTx",
|
|||
|
"10BaseT_FD",
|
|||
|
"100BaseTx_FD",
|
|||
|
"100BaseT4",
|
|||
|
"100BaseFx",
|
|||
|
"100BaseFx_FD",
|
|||
|
"Mii10BaseT",
|
|||
|
"Mii10BaseT_FD",
|
|||
|
"Mii10Base2",
|
|||
|
"Mii10Base5",
|
|||
|
"Mii100BaseTx",
|
|||
|
"Mii100BaseTx_FD",
|
|||
|
"Mii100BaseT4",
|
|||
|
"Mii100BaseFx",
|
|||
|
"Mii100BaseFx_FD"
|
|||
|
};
|
|||
|
|
|||
|
#endif
|
|||
|
|
|||
|
/*+
|
|||
|
* DC21X4MediaDetect
|
|||
|
*
|
|||
|
* Routine Description:
|
|||
|
*
|
|||
|
* DC21X4MediaDetect:
|
|||
|
*
|
|||
|
* checks the DC2104x media ports in the following order:
|
|||
|
* 10BaseT -> 10Base2 -> 10Base5
|
|||
|
*
|
|||
|
* checks the DC21140 link status
|
|||
|
*
|
|||
|
* Arguments:
|
|||
|
*
|
|||
|
* Adapter
|
|||
|
*
|
|||
|
* Return Value:
|
|||
|
*
|
|||
|
* TRUE if the Autosense timer should be fired
|
|||
|
*
|
|||
|
-*/
|
|||
|
|
|||
|
extern
|
|||
|
BOOLEAN
|
|||
|
DC21X4MediaDetect(
|
|||
|
IN PDC21X4_ADAPTER Adapter
|
|||
|
)
|
|||
|
{
|
|||
|
|
|||
|
PDC21X4_TRANSMIT_DESCRIPTOR TxmDescriptor;
|
|||
|
ULONG Status;
|
|||
|
UINT PacketSize = 64;
|
|||
|
INT Time;
|
|||
|
INT CurrentMedium=0;
|
|||
|
INT i;
|
|||
|
INT j;
|
|||
|
|
|||
|
BOOLEAN Link=FALSE;
|
|||
|
BOOLEAN Sensed=FALSE;
|
|||
|
#if __DBG
|
|||
|
DbgPrint("DC21X4MediaDetect\n");
|
|||
|
#endif
|
|||
|
|
|||
|
switch (Adapter->DeviceId) {
|
|||
|
|
|||
|
case DC21140_CFID:
|
|||
|
|
|||
|
if (Adapter->MediaType & MEDIA_AUTOSENSE) {
|
|||
|
|
|||
|
//AutoSense mode:
|
|||
|
|
|||
|
//Initialize the General Purpose Control register
|
|||
|
|
|||
|
CurrentMedium = Adapter->MediaPrecedence[0];
|
|||
|
|
|||
|
DC21X4_WRITE_PORT(
|
|||
|
DC21X4_GEN_PURPOSE,
|
|||
|
Adapter->Media[CurrentMedium].GeneralPurposeCtrl
|
|||
|
);
|
|||
|
|
|||
|
//Check the link status of each medium supported
|
|||
|
//by the adapter until afirst link is detected up.
|
|||
|
|
|||
|
for (i=Adapter->MediaCount; i>0; i--) {
|
|||
|
|
|||
|
CurrentMedium = Adapter->MediaPrecedence[i-1];
|
|||
|
#if __DBG
|
|||
|
DbgPrint("DC21X4MediaDetect: %d - Check medium %x \n",
|
|||
|
i,CurrentMedium);
|
|||
|
#endif
|
|||
|
|
|||
|
if (( (CurrentMedium == Medium100BaseTx)
|
|||
|
||(CurrentMedium == Medium10BaseT)
|
|||
|
)
|
|||
|
&& (!Sensed)
|
|||
|
) {
|
|||
|
|
|||
|
// 100BaseTx or 10BaseT medium:
|
|||
|
// Check the 100BaseTx & the 10BaseT link
|
|||
|
|
|||
|
Link = DC2114Sense100BaseTxLink(Adapter);
|
|||
|
Sensed = TRUE;
|
|||
|
#if __DBG
|
|||
|
DbgPrint(" Link[%x]=%d\n",
|
|||
|
(Link?Adapter->SelectedMedium:CurrentMedium),Link);
|
|||
|
#endif
|
|||
|
if (Link) {
|
|||
|
// a link was detected up
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
else {
|
|||
|
|
|||
|
//Medium is not 100BaseTx or 10BaseT:
|
|||
|
//Initialize the Mode and GEP registers
|
|||
|
//and check the link status
|
|||
|
|
|||
|
DC21X4_WRITE_PORT(
|
|||
|
DC21X4_OPERATION_MODE,
|
|||
|
((Adapter->OperationMode & ~(DC21X4_MEDIUM_MASK))
|
|||
|
| Adapter->Media[CurrentMedium].Mode)
|
|||
|
);
|
|||
|
|
|||
|
DC21X4_WRITE_PORT(
|
|||
|
DC21X4_GEN_PURPOSE,
|
|||
|
Adapter->Media[CurrentMedium].GeneralPurposeData
|
|||
|
);
|
|||
|
|
|||
|
for (j=0;j<(GEP_READ_DELAY/5);j++) {
|
|||
|
NdisStallExecution(5*MILLISECOND);
|
|||
|
}
|
|||
|
|
|||
|
DC21X4_READ_PORT(
|
|||
|
DC21X4_GEN_PURPOSE,
|
|||
|
&Status
|
|||
|
);
|
|||
|
|
|||
|
Link = DC21X4_LINK_STATUS(Status,Adapter,CurrentMedium);
|
|||
|
#if __DBG
|
|||
|
DbgPrint(" Link[%x]=%d\n",CurrentMedium,Link);
|
|||
|
#endif
|
|||
|
if (Link) {
|
|||
|
|
|||
|
// The link was detected up:
|
|||
|
// select the current medium
|
|||
|
|
|||
|
Adapter->SelectedMedium = CurrentMedium;
|
|||
|
Adapter->OperationMode &= ~(DC21X4_MEDIUM_MASK);
|
|||
|
Adapter->OperationMode |= Adapter->Media[CurrentMedium].Mode;
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
DC21X4IndicateMediaStatus(
|
|||
|
Adapter,
|
|||
|
Link ? LinkPass : LinkFail
|
|||
|
);
|
|||
|
|
|||
|
if (!Link) {
|
|||
|
|
|||
|
//No link detected: select the default medium
|
|||
|
#if __DBG
|
|||
|
DbgPrint("MediaDetect: No link - Select the default Medium (%x)\n",
|
|||
|
Adapter->DefaultMedium);
|
|||
|
#endif
|
|||
|
Adapter->SelectedMedium = Adapter->DefaultMedium;
|
|||
|
|
|||
|
Adapter->OperationMode &= ~(DC21X4_MEDIUM_MASK);
|
|||
|
Adapter->OperationMode |= Adapter->Media[Adapter->SelectedMedium].Mode;
|
|||
|
|
|||
|
DC21X4_WRITE_PORT(
|
|||
|
DC21X4_OPERATION_MODE,
|
|||
|
Adapter->OperationMode
|
|||
|
);
|
|||
|
|
|||
|
DC21X4_WRITE_PORT(
|
|||
|
DC21X4_GEN_PURPOSE,
|
|||
|
Adapter->Media[Adapter->SelectedMedium].GeneralPurposeData
|
|||
|
);
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
else {
|
|||
|
|
|||
|
// Not AutoSense mode
|
|||
|
|
|||
|
if (Adapter->Media[Adapter->SelectedMedium].SenseMask) {
|
|||
|
|
|||
|
//Check the link status of the select medium
|
|||
|
|
|||
|
DC21X4_READ_PORT(
|
|||
|
DC21X4_GEN_PURPOSE,
|
|||
|
&Status
|
|||
|
);
|
|||
|
|
|||
|
Link = DC21X4_LINK_STATUS(Status,Adapter,Adapter->SelectedMedium);
|
|||
|
DC21X4IndicateMediaStatus(
|
|||
|
Adapter,
|
|||
|
Link ? LinkPass : LinkFail
|
|||
|
);
|
|||
|
}
|
|||
|
else {
|
|||
|
|
|||
|
//There is no link status reported in the
|
|||
|
//General Purpose Register for the selected medium:
|
|||
|
//Set the LinkPass flag but do not start AutoSense
|
|||
|
|
|||
|
if (!Adapter->PhyPresent) {
|
|||
|
DC21X4IndicateMediaStatus(Adapter,LinkPass);
|
|||
|
}
|
|||
|
return Adapter->PhyPresent;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// if DynamicAutoSense mode is disabled clear
|
|||
|
// the AutoSense flag in MediaType to disable
|
|||
|
// the medium link dynamic check but fire the
|
|||
|
// Spa timer anyway to check the link status
|
|||
|
// of the selected medium
|
|||
|
|
|||
|
if (!Adapter->DynamicAutoSense) {
|
|||
|
Adapter->MediaType &= ~(MEDIA_AUTOSENSE);
|
|||
|
}
|
|||
|
|
|||
|
return TRUE;
|
|||
|
|
|||
|
|
|||
|
case DC21041_CFID:
|
|||
|
case DC21142_CFID:
|
|||
|
|
|||
|
if (!(Adapter->MediaType & MEDIA_AUTOSENSE)) {
|
|||
|
return Adapter->PhyPresent;
|
|||
|
}
|
|||
|
if (Adapter->SelectedMedium != Medium10BaseT) {
|
|||
|
|
|||
|
// Selected medium is 10Base2 or 10Base5
|
|||
|
|
|||
|
DC21X4IndicateMediaStatus(Adapter,LinkPass);
|
|||
|
|
|||
|
return TRUE;
|
|||
|
}
|
|||
|
return Adapter->PhyPresent;
|
|||
|
|
|||
|
case DC21040_CFID:
|
|||
|
|
|||
|
if (Adapter->SelectedMedium != Medium10BaseT) {
|
|||
|
|
|||
|
DC21X4IndicateMediaStatus(Adapter,LinkPass);
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
// Selected Medium = 10BaseT:
|
|||
|
// Check the TP Link status
|
|||
|
|
|||
|
do {
|
|||
|
|
|||
|
// Read the SIA satus
|
|||
|
|
|||
|
DC21X4_READ_PORT(
|
|||
|
DC21X4_SIA_STATUS,
|
|||
|
&Status
|
|||
|
);
|
|||
|
|
|||
|
#if __DBG
|
|||
|
DbgPrint("Sia Status = %08x\n",Status);
|
|||
|
#endif
|
|||
|
|
|||
|
if (!(Status & DC21X4_LINKFAIL_10)) {
|
|||
|
#if __DBG
|
|||
|
DbgPrint("MediaDetect: TP Link established\n");
|
|||
|
#endif
|
|||
|
DC21X4IndicateMediaStatus(Adapter,LinkPass);
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
if (Status & DC21X4_NETWORK_CONNECTION_ERROR) {
|
|||
|
#if __DBG
|
|||
|
DbgPrint("MediaDetect: TP Link failure\n");
|
|||
|
#endif
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
while ((Status & DC21X4_LINKFAIL_10)
|
|||
|
&& !(Status & DC21X4_NETWORK_CONNECTION_ERROR));
|
|||
|
|
|||
|
if (!(Adapter->MediaType & MEDIA_AUTOSENSE)) {
|
|||
|
|
|||
|
DC21X4IndicateMediaStatus(Adapter,LinkFail);
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
// AutoSense mode: Link Pass failure
|
|||
|
|
|||
|
#if __DBG
|
|||
|
DbgPrint(" 10BaseT link failure: switch to 10Base2 \n");
|
|||
|
#endif
|
|||
|
Adapter->SelectedMedium = Medium10Base2;
|
|||
|
DC2104InitializeSiaRegisters(
|
|||
|
Adapter
|
|||
|
);
|
|||
|
|
|||
|
// wait at least 300ms for the 10Base2 transceivers
|
|||
|
// to stabilize
|
|||
|
|
|||
|
for (i=0; i< max(Adapter->TransceiverDelay,30); i++) {
|
|||
|
for (j=0;j<2;j++) {
|
|||
|
NdisStallExecution(5*MILLISECOND);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//Send a minimal size packet (with an false CRC) to check
|
|||
|
//the carrier status
|
|||
|
|
|||
|
ZERO_MEMORY (
|
|||
|
Adapter->MaxTransmitBuffer[Adapter->MaxTransmitBufferIndex].Va,
|
|||
|
PacketSize
|
|||
|
);
|
|||
|
|
|||
|
MOVE_MEMORY (
|
|||
|
Adapter->MaxTransmitBuffer[Adapter->MaxTransmitBufferIndex].Va,
|
|||
|
Adapter->CurrentNetworkAddress,
|
|||
|
ETH_LENGTH_OF_ADDRESS
|
|||
|
);
|
|||
|
|
|||
|
MOVE_MEMORY (
|
|||
|
Adapter->MaxTransmitBuffer[Adapter->MaxTransmitBufferIndex].Va + ETH_LENGTH_OF_ADDRESS,
|
|||
|
Adapter->CurrentNetworkAddress,
|
|||
|
ETH_LENGTH_OF_ADDRESS
|
|||
|
);
|
|||
|
|
|||
|
TxmDescriptor = Adapter->EnqueueTransmitDescriptor;
|
|||
|
Adapter->EnqueueTransmitDescriptor = (Adapter->EnqueueTransmitDescriptor)->Next;
|
|||
|
Adapter->DequeueTransmitDescriptor = Adapter->EnqueueTransmitDescriptor;
|
|||
|
|
|||
|
// Initialize the descriptor
|
|||
|
|
|||
|
TxmDescriptor->Control &= DC21X4_TDES_SECOND_ADDR_CHAINED;
|
|||
|
TxmDescriptor->Control |=
|
|||
|
( DC21X4_TDES_FIRST_SEGMENT | DC21X4_TDES_LAST_SEGMENT
|
|||
|
| DC21X4_TDES_ADD_CRC_DISABLE | PacketSize );
|
|||
|
|
|||
|
TxmDescriptor->FirstBufferAddress =
|
|||
|
Adapter->MaxTransmitBuffer[Adapter->MaxTransmitBufferIndex].Pa;
|
|||
|
|
|||
|
TxmDescriptor->Status = DESC_OWNED_BY_DC21X4;
|
|||
|
|
|||
|
// Mask the interrupts
|
|||
|
DC21X4_WRITE_PORT(
|
|||
|
DC21X4_INTERRUPT_MASK,
|
|||
|
0
|
|||
|
);
|
|||
|
|
|||
|
#if __DBG
|
|||
|
DbgPrint(" send a test packet\n");
|
|||
|
#endif
|
|||
|
DC21X4_WRITE_PORT(
|
|||
|
DC21X4_TXM_POLL_DEMAND,
|
|||
|
1
|
|||
|
);
|
|||
|
|
|||
|
// Poll for completion
|
|||
|
|
|||
|
Time = DC21X4_TXM_TIMEOUT;
|
|||
|
|
|||
|
while (--Time) {
|
|||
|
|
|||
|
for (j=0;j<2;j++) {
|
|||
|
NdisStallExecution(5*MILLISECOND);
|
|||
|
}
|
|||
|
|
|||
|
DC21X4_READ_PORT(
|
|||
|
DC21X4_STATUS,
|
|||
|
&Status
|
|||
|
);
|
|||
|
#if __DBG
|
|||
|
DbgPrint(" CSR5 = %08x Time = %d\n",Status,Time);
|
|||
|
#endif
|
|||
|
if (Status & DC21X4_TXM_BUFFER_UNAVAILABLE) {
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
#if __DBG
|
|||
|
DbgPrint(" Desc status = %08x Time = %d \n",TxmDescriptor->Status,Time);
|
|||
|
#endif
|
|||
|
|
|||
|
//Check if Status_Error or Timeout
|
|||
|
|
|||
|
if (TxmDescriptor->Status & DC21X4_TDES_ERROR_SUMMARY || (Time <= 0) ) {
|
|||
|
|
|||
|
//switch to AUI Port
|
|||
|
#if __DBG
|
|||
|
DbgPrint(" 10Base2 failure: switch to 10Base5\n");
|
|||
|
#endif
|
|||
|
|
|||
|
Adapter->SelectedMedium = Medium10Base5;
|
|||
|
|
|||
|
//Reset the adapter to clean up the Txm path
|
|||
|
|
|||
|
DC21X4InitializeRegisters(
|
|||
|
Adapter
|
|||
|
);
|
|||
|
DC2104InitializeSiaRegisters(
|
|||
|
Adapter
|
|||
|
);
|
|||
|
|
|||
|
Adapter->DequeueReceiveDescriptor =
|
|||
|
(PDC21X4_RECEIVE_DESCRIPTOR)Adapter->ReceiveDescriptorRingVa;
|
|||
|
Adapter->EnqueueTransmitDescriptor =
|
|||
|
(PDC21X4_TRANSMIT_DESCRIPTOR)Adapter->TransmitDescriptorRingVa;
|
|||
|
Adapter->DequeueTransmitDescriptor =
|
|||
|
Adapter->EnqueueTransmitDescriptor;
|
|||
|
|
|||
|
DC21X4StartAdapter(Adapter);
|
|||
|
|
|||
|
}
|
|||
|
else {
|
|||
|
|
|||
|
//Clear Txm interrupts
|
|||
|
|
|||
|
DC21X4_WRITE_PORT(
|
|||
|
DC21X4_STATUS,
|
|||
|
Status
|
|||
|
);
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
//Restore the interrupt mask
|
|||
|
|
|||
|
DC21X4_WRITE_PORT(
|
|||
|
DC21X4_INTERRUPT_MASK,
|
|||
|
Adapter->InterruptMask
|
|||
|
);
|
|||
|
|
|||
|
DC21X4IndicateMediaStatus(Adapter,LinkPass);
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
/*+
|
|||
|
*
|
|||
|
*DC2114Sense100BaseTxLink
|
|||
|
*
|
|||
|
* Routine Description:
|
|||
|
*
|
|||
|
* Sense the DC2114X 100BaseTx and 10BaseT link status
|
|||
|
*
|
|||
|
* Arguments:
|
|||
|
*
|
|||
|
* Adapter
|
|||
|
*
|
|||
|
* Return Value:
|
|||
|
*
|
|||
|
* Link Status
|
|||
|
*
|
|||
|
-*/
|
|||
|
extern
|
|||
|
BOOLEAN
|
|||
|
DC2114Sense100BaseTxLink(
|
|||
|
IN PDC21X4_ADAPTER Adapter
|
|||
|
)
|
|||
|
|
|||
|
{
|
|||
|
|
|||
|
ULONG Status;
|
|||
|
ULONG Mode100Tx;
|
|||
|
ULONG CFDA_Data;
|
|||
|
INT Loop;
|
|||
|
INT Retry = MAX_RETRY;
|
|||
|
INT AssertionTime;
|
|||
|
INT CurrentTime;
|
|||
|
INT AssertionThreshold;
|
|||
|
INT Timeout;
|
|||
|
INT Medium10Tick;
|
|||
|
INT i;
|
|||
|
|
|||
|
BOOLEAN Link = FALSE;
|
|||
|
BOOLEAN Scrambler;
|
|||
|
|
|||
|
#if __DBG
|
|||
|
DbgPrint("Sense100BaseTxLink\n");
|
|||
|
#endif
|
|||
|
|
|||
|
// If the adapter is in Snooze mode,
|
|||
|
// switch to regular mode to enable the
|
|||
|
// built-in timer
|
|||
|
|
|||
|
if (Adapter->PciDriverArea & CFDA_SNOOZE_MODE) {
|
|||
|
|
|||
|
CFDA_Data = Adapter->PciDriverArea & ~CFDA_SNOOZE_MODE;
|
|||
|
|
|||
|
NdisWritePciSlotInformation(
|
|||
|
Adapter->MiniportAdapterHandle,
|
|||
|
Adapter->SlotNumber,
|
|||
|
PCI_CFDA_OFFSET,
|
|||
|
&CFDA_Data,
|
|||
|
sizeof(CFDA_Data)
|
|||
|
);
|
|||
|
}
|
|||
|
|
|||
|
//Mask the Timer_Expired interrupt
|
|||
|
|
|||
|
DC21X4_WRITE_PORT(
|
|||
|
DC21X4_INTERRUPT_MASK,
|
|||
|
Adapter->InterruptMask & ~(DC21X4_MSK_TIMER_EXPIRED)
|
|||
|
);
|
|||
|
|
|||
|
//Sense the 100BaseTx & 10BaseT link
|
|||
|
|
|||
|
Mode100Tx =
|
|||
|
( (Adapter->OperationMode & ~(DC21X4_MEDIUM_MASK))
|
|||
|
| Adapter->Media[Medium100BaseTx].Mode
|
|||
|
)
|
|||
|
& ~(DC21X4_SCRAMBLER);
|
|||
|
|
|||
|
// Set the 10 Mbps timer tick
|
|||
|
Medium10Tick =
|
|||
|
(Adapter->Media[Medium10BaseT].Mode & DC21X4_PORT_SELECT) ?
|
|||
|
MII10_TICK : EXT10_TICK;
|
|||
|
|
|||
|
while (Retry-- && !Link) {
|
|||
|
|
|||
|
//if DC21140 Rev1.1 disable the scrambler
|
|||
|
Scrambler = (Adapter->RevisionNumber != DC21140_REV1_1);
|
|||
|
|
|||
|
Loop=2;
|
|||
|
while(Loop-- && !Link) {
|
|||
|
|
|||
|
AssertionThreshold =
|
|||
|
Scrambler? FIVE_MILLISECONDS_DELAY : ONE_SECOND_DELAY;
|
|||
|
|
|||
|
Timeout = (3 * AssertionThreshold);
|
|||
|
|
|||
|
if (Adapter->MediaCapable & MEDIUM_100BTX) {
|
|||
|
|
|||
|
//Select 100BaseTx
|
|||
|
|
|||
|
DC21X4_WRITE_PORT(
|
|||
|
DC21X4_OPERATION_MODE,
|
|||
|
Mode100Tx
|
|||
|
| ( Scrambler ? DC21X4_SCRAMBLER : 0 )
|
|||
|
);
|
|||
|
|
|||
|
DC21X4_WRITE_PORT(
|
|||
|
DC21X4_GEN_PURPOSE,
|
|||
|
Adapter->Media[Medium100BaseTx].GeneralPurposeData
|
|||
|
);
|
|||
|
|
|||
|
// Check 100BaseTx Symbol Link for a
|
|||
|
// continuous assertion of 'AssertionThreshold'
|
|||
|
|
|||
|
AssertionTime = 0;
|
|||
|
CurrentTime = 0;
|
|||
|
|
|||
|
//Start the built_in timer in cyclic mode of
|
|||
|
//2.5 ms ticks
|
|||
|
DC21X4_WRITE_PORT(
|
|||
|
DC21X4_TIMER,
|
|||
|
MII100_TICK | DC21X4_TIMER_CON_MODE
|
|||
|
);
|
|||
|
|
|||
|
while ((CurrentTime < (Timeout+1)) && !Link) {
|
|||
|
|
|||
|
DC21X4_READ_PORT(
|
|||
|
DC21X4_STATUS,
|
|||
|
&Status
|
|||
|
);
|
|||
|
|
|||
|
if (Status & DC21X4_MSK_TIMER_EXPIRED) {
|
|||
|
|
|||
|
DC21X4_WRITE_PORT(
|
|||
|
DC21X4_STATUS,
|
|||
|
DC21X4_MSK_TIMER_EXPIRED
|
|||
|
);
|
|||
|
CurrentTime++;
|
|||
|
}
|
|||
|
|
|||
|
DC21X4_READ_PORT(
|
|||
|
DC21X4_GEN_PURPOSE,
|
|||
|
&Status
|
|||
|
);
|
|||
|
|
|||
|
if (DC21X4_LINK_STATUS(Status,Adapter,Medium100BaseTx)) {
|
|||
|
|
|||
|
// Link is asserted
|
|||
|
if (AssertionTime == 0 ) {
|
|||
|
//First assertion
|
|||
|
AssertionTime = CurrentTime+1;
|
|||
|
}
|
|||
|
else {
|
|||
|
Link = ((CurrentTime - AssertionTime) >= AssertionThreshold);
|
|||
|
}
|
|||
|
}
|
|||
|
else {
|
|||
|
// No link
|
|||
|
AssertionTime = 0;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//Stop the built_in timer
|
|||
|
|
|||
|
DC21X4_WRITE_PORT(
|
|||
|
DC21X4_TIMER,
|
|||
|
0
|
|||
|
);
|
|||
|
|
|||
|
DC21X4_WRITE_PORT(
|
|||
|
DC21X4_STATUS,
|
|||
|
DC21X4_MSK_TIMER_EXPIRED
|
|||
|
);
|
|||
|
|
|||
|
if (Link) {
|
|||
|
|
|||
|
// 100BaseTx link detected: Select 100BaseTx
|
|||
|
|
|||
|
Adapter->SelectedMedium = Medium100BaseTx;
|
|||
|
|
|||
|
Adapter->OperationMode &= ~(DC21X4_MEDIUM_MASK);
|
|||
|
Adapter->OperationMode |= Adapter->Media[Medium100BaseTx].Mode;
|
|||
|
|
|||
|
if (!Scrambler) {
|
|||
|
|
|||
|
//Turn the scrambler on
|
|||
|
|
|||
|
DC21X4_WRITE_PORT(
|
|||
|
DC21X4_OPERATION_MODE,
|
|||
|
Adapter->OperationMode
|
|||
|
);
|
|||
|
}
|
|||
|
|
|||
|
break;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
// No 100BaseTx link detected:
|
|||
|
|
|||
|
if (Adapter->MediaCapable & MEDIUM_10BT) {
|
|||
|
|
|||
|
// Switch to 10BaseT
|
|||
|
|
|||
|
DC21X4_WRITE_PORT(
|
|||
|
DC21X4_OPERATION_MODE,
|
|||
|
(Adapter->OperationMode &~(DC21X4_MEDIUM_MASK))
|
|||
|
| Adapter->Media[Medium10BaseT].Mode
|
|||
|
);
|
|||
|
|
|||
|
DC21X4_WRITE_PORT(
|
|||
|
DC21X4_GEN_PURPOSE,
|
|||
|
Adapter->Media[Medium10BaseT].GeneralPurposeData
|
|||
|
);
|
|||
|
|
|||
|
//Check the 10BaseT link status
|
|||
|
|
|||
|
// Start the built_in timer for
|
|||
|
// half the 100BaseTx timeout
|
|||
|
|
|||
|
DC21X4_WRITE_PORT(
|
|||
|
DC21X4_TIMER,
|
|||
|
(Timeout/2) * Medium10Tick
|
|||
|
);
|
|||
|
|
|||
|
while (!Link) {
|
|||
|
|
|||
|
//Check the 10BaseT link
|
|||
|
|
|||
|
for (i=0,Link=TRUE; i<2; i++) {
|
|||
|
|
|||
|
DC21X4_READ_PORT(
|
|||
|
DC21X4_GEN_PURPOSE,
|
|||
|
&Status
|
|||
|
);
|
|||
|
Link = Link && DC21X4_LINK_STATUS(Status,Adapter,Medium10BaseT);
|
|||
|
}
|
|||
|
|
|||
|
DC21X4_READ_PORT(
|
|||
|
DC21X4_STATUS,
|
|||
|
&Status
|
|||
|
);
|
|||
|
|
|||
|
if (Status & DC21X4_MSK_TIMER_EXPIRED) {
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
if (Link) {
|
|||
|
|
|||
|
// 10BaseT link detected:
|
|||
|
|
|||
|
//Stop the timer
|
|||
|
|
|||
|
DC21X4_WRITE_PORT(
|
|||
|
DC21X4_TIMER,
|
|||
|
0
|
|||
|
);
|
|||
|
|
|||
|
DC21X4_WRITE_PORT(
|
|||
|
DC21X4_STATUS,
|
|||
|
DC21X4_MSK_TIMER_EXPIRED
|
|||
|
);
|
|||
|
|
|||
|
if (Loop) {
|
|||
|
|
|||
|
// first detection of 10BT link:
|
|||
|
// check the 100BaseTx link again to reject
|
|||
|
// a 'false' 10BT link link induced by the 100BTX
|
|||
|
Link = FALSE;
|
|||
|
}
|
|||
|
else {
|
|||
|
|
|||
|
// 10BT link detected twice:
|
|||
|
// select Medium10BaseT
|
|||
|
|
|||
|
Adapter->SelectedMedium = Medium10BaseT;
|
|||
|
|
|||
|
Adapter->OperationMode &= ~(DC21X4_MEDIUM_MASK);
|
|||
|
Adapter->OperationMode |= Adapter->Media[Medium10BaseT].Mode;
|
|||
|
}
|
|||
|
}
|
|||
|
else if (Loop) {
|
|||
|
|
|||
|
if (Scrambler) {
|
|||
|
|
|||
|
//Disable the scrambler and restart the
|
|||
|
//link check
|
|||
|
Scrambler = FALSE;
|
|||
|
Loop = 2;
|
|||
|
}
|
|||
|
else {
|
|||
|
|
|||
|
// First loop & Scrambler disbled:
|
|||
|
// leave the loop and select the default medium
|
|||
|
Retry = 0;
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
} // endwhile Loop
|
|||
|
|
|||
|
} //endwhile Retry
|
|||
|
|
|||
|
|
|||
|
//Demask the Timer_Expired interrupt
|
|||
|
|
|||
|
DC21X4_WRITE_PORT(
|
|||
|
DC21X4_STATUS,
|
|||
|
DC21X4_MSK_TIMER_EXPIRED
|
|||
|
);
|
|||
|
|
|||
|
DC21X4_WRITE_PORT(
|
|||
|
DC21X4_INTERRUPT_MASK,
|
|||
|
Adapter->InterruptMask
|
|||
|
);
|
|||
|
|
|||
|
if (Adapter->PciDriverArea & CFDA_SNOOZE_MODE) {
|
|||
|
|
|||
|
//set to the initial snooze mode
|
|||
|
|
|||
|
NdisWritePciSlotInformation(
|
|||
|
Adapter->MiniportAdapterHandle,
|
|||
|
Adapter->SlotNumber,
|
|||
|
PCI_CFDA_OFFSET,
|
|||
|
&Adapter->PciDriverArea,
|
|||
|
sizeof(Adapter->PciDriverArea)
|
|||
|
);
|
|||
|
}
|
|||
|
|
|||
|
#if __DBG
|
|||
|
if (Link)
|
|||
|
DbgPrint("Sense: SelectMedium = %s\n",
|
|||
|
Adapter->SelectedMedium==Medium100BaseTx?"100BaseTx":"10BaseT");
|
|||
|
#endif
|
|||
|
|
|||
|
return Link;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
/*+
|
|||
|
* DC21X4DynamicAutoSense
|
|||
|
*
|
|||
|
* Routine Description:
|
|||
|
*
|
|||
|
* Autosense between the PHY's Autosense routine and the
|
|||
|
* other media autosense's routine
|
|||
|
*
|
|||
|
* Arguments:
|
|||
|
*
|
|||
|
* Adapter
|
|||
|
*
|
|||
|
-*/
|
|||
|
extern
|
|||
|
VOID
|
|||
|
DC21X4DynamicAutoSense (
|
|||
|
IN PVOID Systemspecific1,
|
|||
|
IN PDC21X4_ADAPTER Adapter,
|
|||
|
IN PVOID Systemspecific2,
|
|||
|
IN PVOID Systemspecific3
|
|||
|
)
|
|||
|
{
|
|||
|
|
|||
|
BOOLEAN LinkStatus=FALSE;
|
|||
|
BOOLEAN StartTimer=TRUE;
|
|||
|
BOOLEAN LoopbackMode;
|
|||
|
|
|||
|
#if _DBG
|
|||
|
DbgPrint("DC21X4DynamicAutoSense\n");
|
|||
|
#endif
|
|||
|
|
|||
|
if ( (Adapter->PhyPresent)
|
|||
|
&& (!Adapter->Force10)
|
|||
|
){
|
|||
|
LinkStatus = DC21X4MiiAutoSense(Adapter);
|
|||
|
}
|
|||
|
|
|||
|
if (Adapter->Indicate10BTLink) {
|
|||
|
|
|||
|
Adapter->Indicate10BTLink = FALSE;
|
|||
|
|
|||
|
if (!LinkStatus) {
|
|||
|
|
|||
|
// The current link is a 10BaseT link
|
|||
|
|
|||
|
#if 0
|
|||
|
DC21X4SetPhyControl(
|
|||
|
Adapter,
|
|||
|
(USHORT)MiiGenAdminIsolate
|
|||
|
);
|
|||
|
#endif
|
|||
|
|
|||
|
DC21X4SetPhyControl(
|
|||
|
Adapter,
|
|||
|
(USHORT)((Adapter->OperationMode & DC21X4_FULL_DUPLEX_MODE) ?
|
|||
|
MiiGenAdminForce10Fd : MiiGenAdminForce10)
|
|||
|
);
|
|||
|
|
|||
|
DC21X4IndicateMediaStatus(Adapter,LinkPass);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if ( !LinkStatus
|
|||
|
&& (Adapter->MediaCapable)
|
|||
|
) {
|
|||
|
StartTimer = DC21X4AutoSense(Adapter);
|
|||
|
}
|
|||
|
|
|||
|
// Restart the Autosense timer
|
|||
|
|
|||
|
if (StartTimer) {
|
|||
|
|
|||
|
DC21X4StartAutoSenseTimer(
|
|||
|
Adapter,
|
|||
|
(UINT)((Adapter->PhyPresent) ? DC21X4_MII_TICK : DC21X4_SPA_TICK)
|
|||
|
);
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/*+
|
|||
|
* DC21X4AutoSense
|
|||
|
*
|
|||
|
* Routine Description:
|
|||
|
*
|
|||
|
* Autosense the DC21041 10Base2/10Base5 port
|
|||
|
* Autosense the DC21140 100BaseTx/10BaseT link
|
|||
|
*
|
|||
|
* Arguments:
|
|||
|
*
|
|||
|
* Adapter
|
|||
|
*
|
|||
|
* Return:
|
|||
|
*
|
|||
|
* TRUE if AutoSense Timer should be fired
|
|||
|
*
|
|||
|
-*/
|
|||
|
extern
|
|||
|
BOOLEAN
|
|||
|
DC21X4AutoSense (
|
|||
|
IN PDC21X4_ADAPTER Adapter
|
|||
|
)
|
|||
|
{
|
|||
|
ULONG Status;
|
|||
|
BOOLEAN SelectedPortActive;
|
|||
|
BOOLEAN SwitchMedium;
|
|||
|
BOOLEAN FullDuplex;
|
|||
|
|
|||
|
INT CurrentMedium=0;
|
|||
|
INT NextMedium;
|
|||
|
INT index;
|
|||
|
|
|||
|
#if _DBG
|
|||
|
DbgPrint("Autosense routine\n");
|
|||
|
#endif
|
|||
|
|
|||
|
switch (Adapter->DeviceId) {
|
|||
|
|
|||
|
case DC21040_CFID:
|
|||
|
|
|||
|
if (Adapter->LinkStatus != LinkFail) {
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
//DC21040 supports Link_Fail interrupt
|
|||
|
//but does not support Link_Pass
|
|||
|
//Check the Link status:
|
|||
|
//If link is up wait for Link_Fail interrupt
|
|||
|
//otherwhise poll the link status
|
|||
|
|
|||
|
DC21X4_READ_PORT(
|
|||
|
DC21X4_SIA_STATUS,
|
|||
|
&Status
|
|||
|
);
|
|||
|
|
|||
|
if ((Status & DC21X4_LINKFAIL_10) == 0) {
|
|||
|
DC21X4IndicateMediaStatus(Adapter,LinkPass);
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
break;
|
|||
|
|
|||
|
case DC21041_CFID:
|
|||
|
case DC21142_CFID:
|
|||
|
if (!(Adapter->MediaType & MEDIA_AUTOSENSE)) {
|
|||
|
return Adapter->PhyPresent;
|
|||
|
}
|
|||
|
|
|||
|
if (Adapter->IgnoreTimer) {
|
|||
|
Adapter->IgnoreTimer = FALSE;
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
switch (Adapter->TimerFlag) {
|
|||
|
|
|||
|
case AncPolling:
|
|||
|
|
|||
|
if (Adapter->PollCount--) {
|
|||
|
|
|||
|
//Read the SIA Status
|
|||
|
|
|||
|
DC21X4_READ_PORT(
|
|||
|
DC21X4_SIA_STATUS,
|
|||
|
&Status
|
|||
|
);
|
|||
|
|
|||
|
//check the AutoNegotation State
|
|||
|
|
|||
|
switch (Status & DC21X4_AUTO_NEGOTIATION_STATE) {
|
|||
|
|
|||
|
case ANS_ACKNOWLEDGE_DETECTED:
|
|||
|
case ANS_ACKNOWLEDGE_COMPLETED:
|
|||
|
|
|||
|
//store the Sia status snapshot
|
|||
|
Adapter->SiaStatus = Status;
|
|||
|
|
|||
|
default:
|
|||
|
|
|||
|
// Restart the Poll timer
|
|||
|
NdisMSetTimer(
|
|||
|
&Adapter->Timer,
|
|||
|
DC21X4_POLL_DELAY
|
|||
|
);
|
|||
|
return FALSE;
|
|||
|
|
|||
|
case ANS_AUTO_NEGOTIATION_COMPLETED:
|
|||
|
|
|||
|
//Check the Link Partner capabilities
|
|||
|
|
|||
|
// LPN SF 10BT_FD 10BT Link_Partner Medium
|
|||
|
// 0 xx x x not_negotiable 10BT
|
|||
|
// 1 01 1 x 10BT_FD capable 10BT_FD
|
|||
|
// 1 01 0 1 10BT_HD capable 10BT
|
|||
|
// 1 01 0 0 no_common_mode 10B2/5
|
|||
|
// 1 !01 x x no_common_mode 10B2/5
|
|||
|
|
|||
|
if (!(Status & DC21X4_LINK_PARTNER_NEGOTIABLE)) {
|
|||
|
#if __DBG
|
|||
|
DbgPrint("Link Partner not negotiable\n");
|
|||
|
#endif
|
|||
|
if (++Adapter->AutoNegotiationCount < 2) {
|
|||
|
|
|||
|
|
|||
|
//Fire the Restart AutoNegotation Timer
|
|||
|
// to defer the restart of the auto_negotiation
|
|||
|
|
|||
|
Adapter->TimerFlag=DeferredAnc;
|
|||
|
NdisMSetTimer(
|
|||
|
&Adapter->Timer,
|
|||
|
DC21X4_ANC_DELAY
|
|||
|
);
|
|||
|
|
|||
|
return FALSE;
|
|||
|
|
|||
|
}
|
|||
|
else {
|
|||
|
NextMedium = Medium10BaseT;
|
|||
|
FullDuplex=FALSE;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
else {
|
|||
|
|
|||
|
// Link Partner negotiable
|
|||
|
|
|||
|
if (!Adapter->SiaStatus) {
|
|||
|
|
|||
|
//Restart the AutoNegotiation
|
|||
|
|
|||
|
//Reinitialize the Poll timeout counter
|
|||
|
Adapter->PollCount= POLL_COUNT_TIMEOUT;
|
|||
|
|
|||
|
DC21X4_WRITE_PORT(
|
|||
|
DC21X4_SIA_STATUS,
|
|||
|
DC21X4_RESTART_AUTO_NEGOTIATION
|
|||
|
);
|
|||
|
|
|||
|
//Restart the Poll timer to
|
|||
|
//poll on AutoNegotiation State
|
|||
|
|
|||
|
Adapter->TimerFlag=AncPolling;
|
|||
|
NdisMSetTimer(
|
|||
|
&Adapter->Timer,
|
|||
|
DC21X4_POLL_DELAY
|
|||
|
);
|
|||
|
|
|||
|
return FALSE;
|
|||
|
|
|||
|
}
|
|||
|
else if ((Adapter->SiaStatus & DC21X4_SELECTED_FIELD_MASK) != DC21X4_SELECTED_FIELD) {
|
|||
|
NextMedium=Medium10Base2_5;
|
|||
|
FullDuplex=FALSE;
|
|||
|
}
|
|||
|
else if (Adapter->SiaStatus & DC21X4_LINK_PARTNER_10BT_FD) {
|
|||
|
//10BT Full Duplex capable
|
|||
|
NextMedium=Medium10BaseT;
|
|||
|
FullDuplex=TRUE;
|
|||
|
}
|
|||
|
else if (Adapter->SiaStatus & DC21X4_LINK_PARTNER_10BT) {
|
|||
|
//10BT Half Duplex capable
|
|||
|
NextMedium=Medium10BaseT;
|
|||
|
FullDuplex=FALSE;
|
|||
|
}
|
|||
|
else {
|
|||
|
//no common mode
|
|||
|
NextMedium=Medium10Base2_5;
|
|||
|
FullDuplex=FALSE;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
else {
|
|||
|
//poll timeout
|
|||
|
NextMedium = Medium10Base2_5;
|
|||
|
FullDuplex=FALSE;
|
|||
|
}
|
|||
|
|
|||
|
Adapter->TimerFlag = NoTimer;
|
|||
|
|
|||
|
//Reinitialize the Sia status snapshot
|
|||
|
Adapter->SiaStatus = 0;
|
|||
|
|
|||
|
if (!FullDuplex) {
|
|||
|
// Stop the Receiver and Transmitter to
|
|||
|
// reset the Full_duplex mode
|
|||
|
DC21X4StopReceiverAndTransmitter(
|
|||
|
Adapter
|
|||
|
);
|
|||
|
|
|||
|
Adapter->OperationMode &= ~(DC21X4_FULL_DUPLEX_MODE);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
// Switch to the selected medium
|
|||
|
|
|||
|
Adapter->NwayEnabled=FALSE;
|
|||
|
|
|||
|
if (NextMedium == Medium10Base2_5) {
|
|||
|
|
|||
|
DC21X4SwitchMedia(
|
|||
|
Adapter,
|
|||
|
Medium10Base2_5
|
|||
|
);
|
|||
|
}
|
|||
|
else {
|
|||
|
|
|||
|
//10BaseT: Disable NWAY
|
|||
|
|
|||
|
DC21X4_WRITE_PORT(
|
|||
|
DC21X4_SIA_MODE_1,
|
|||
|
Adapter->Media[Medium10BaseT].SiaRegister[1]
|
|||
|
);
|
|||
|
|
|||
|
DC21X4IndicateMediaStatus(Adapter,LinkPass);
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
if (!FullDuplex) {
|
|||
|
|
|||
|
//Restart the Receiver and Transmitter
|
|||
|
DC21X4_WRITE_PORT(
|
|||
|
DC21X4_OPERATION_MODE,
|
|||
|
Adapter->OperationMode
|
|||
|
);
|
|||
|
}
|
|||
|
return FALSE;
|
|||
|
|
|||
|
case DeferredAnc:
|
|||
|
|
|||
|
//Restart the AutoNegotiation
|
|||
|
|
|||
|
//Reinitialize the Poll timeout counter
|
|||
|
Adapter->PollCount= POLL_COUNT_TIMEOUT;
|
|||
|
Adapter->SiaStatus = 0;
|
|||
|
|
|||
|
|
|||
|
DC21X4_WRITE_PORT(
|
|||
|
DC21X4_SIA_STATUS,
|
|||
|
DC21X4_RESTART_AUTO_NEGOTIATION
|
|||
|
);
|
|||
|
|
|||
|
//Restart the Poll timer to
|
|||
|
//poll on AutoNegotiation State
|
|||
|
|
|||
|
Adapter->TimerFlag=AncPolling;
|
|||
|
NdisMSetTimer(
|
|||
|
&Adapter->Timer,
|
|||
|
DC21X4_POLL_DELAY
|
|||
|
);
|
|||
|
|
|||
|
return FALSE;
|
|||
|
|
|||
|
|
|||
|
case AncTimeout:
|
|||
|
|
|||
|
// AutoNegotiation timeout:
|
|||
|
Adapter->TimerFlag = NoTimer;
|
|||
|
|
|||
|
if (Adapter->MediaType & MEDIA_AUTOSENSE) {
|
|||
|
|
|||
|
// Switch medium from 10BaseT
|
|||
|
DC21X4SwitchMedia(
|
|||
|
Adapter,
|
|||
|
Medium10Base2_5
|
|||
|
);
|
|||
|
}
|
|||
|
return FALSE;
|
|||
|
|
|||
|
|
|||
|
case DeferredLinkCheck:
|
|||
|
|
|||
|
Adapter->TimerFlag = NoTimer;
|
|||
|
|
|||
|
//Check the 10BaseT Link Status
|
|||
|
|
|||
|
DC21X4_READ_PORT(
|
|||
|
DC21X4_SIA_STATUS,
|
|||
|
&Status
|
|||
|
);
|
|||
|
|
|||
|
if ((Status & DC21X4_LINK_PASS_MASK) == DC21X4_LINK_PASS_STATUS) {
|
|||
|
|
|||
|
//Link Pass:
|
|||
|
|
|||
|
if (Adapter->SelectedMedium == Medium10BaseT) {
|
|||
|
|
|||
|
//10BaseT link is up
|
|||
|
DC21X4IndicateMediaStatus(Adapter,LinkPass);
|
|||
|
return Adapter->PhyPresent;
|
|||
|
}
|
|||
|
else {
|
|||
|
|
|||
|
//Switch the medium to 10BaseT and start the
|
|||
|
//Anc Timer to timeout if the Nway Autonegotiation
|
|||
|
//does not complete
|
|||
|
Adapter->TimerFlag = AncTimeout;
|
|||
|
NdisMSetTimer(
|
|||
|
&Adapter->Timer,
|
|||
|
DC21X4_ANC_TIMEOUT
|
|||
|
);
|
|||
|
DC21X4SwitchMedia(
|
|||
|
Adapter,
|
|||
|
Medium10BaseT
|
|||
|
);
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
}
|
|||
|
else {
|
|||
|
|
|||
|
// No 10baseT link:
|
|||
|
// If the current Medium is not 10BaseT,
|
|||
|
//ignore this state and enters the Selected_Port_Active check
|
|||
|
//instead
|
|||
|
if (Adapter->SelectedMedium == Medium10BaseT) {
|
|||
|
|
|||
|
if (Adapter->MediaType & MEDIA_AUTOSENSE) {
|
|||
|
|
|||
|
// Switch medium from 10BaseT
|
|||
|
DC21X4SwitchMedia(
|
|||
|
Adapter,
|
|||
|
Medium10Base2_5
|
|||
|
);
|
|||
|
}
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
case SpaTimer:
|
|||
|
|
|||
|
//Selected_Port_Active (10Base2/10Base5 media) periodic check
|
|||
|
|
|||
|
if (Adapter->SelectedMedium == Medium10BaseT) {
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
if ((Adapter->MediaCapable & (MEDIUM_10B2 | MEDIUM_10B5)) !=
|
|||
|
(MEDIUM_10B2 | MEDIUM_10B5)) {
|
|||
|
|
|||
|
//The board does not support both 10Base2 & 10Base5 ports
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
// Read the Selected_Port_Active Status
|
|||
|
|
|||
|
DC21X4_READ_PORT(
|
|||
|
DC21X4_SIA_STATUS,
|
|||
|
&Status
|
|||
|
);
|
|||
|
|
|||
|
SelectedPortActive = ((Status & DC21X4_SELECTED_PORT_ACTIVE) != 0);
|
|||
|
|
|||
|
#if __DBG
|
|||
|
DbgPrint("Autosense: SelectePortActive=%d Nocarrier=%d ExcessColl=%d\n",
|
|||
|
SelectedPortActive,
|
|||
|
Adapter->NoCarrierCount,
|
|||
|
Adapter->ExcessCollisionsCount);
|
|||
|
#endif
|
|||
|
if ( (!SelectedPortActive)
|
|||
|
|| (Adapter->NoCarrierCount >= NO_CARRIER_THRESHOLD)
|
|||
|
|| (Adapter->ExcessCollisionsCount >= EXCESS_COLLISIONS_THRESHOLD)
|
|||
|
) {
|
|||
|
|
|||
|
//Switch medium port
|
|||
|
Adapter->SelectedMedium = (Adapter->SelectedMedium == Medium10Base2) ?
|
|||
|
Medium10Base5 : Medium10Base2;
|
|||
|
#if __DBG
|
|||
|
DbgPrint("Autosense: Switch Media to %s\n",
|
|||
|
MediumString[Adapter->SelectedMedium]);
|
|||
|
#endif
|
|||
|
DC21X4_WRITE_PORT(
|
|||
|
DC21X4_SIA_MODE_2,
|
|||
|
Adapter->Media[Adapter->SelectedMedium].SiaRegister[2]
|
|||
|
);
|
|||
|
|
|||
|
//reset the NoCarrier and ExcessCollisions counters
|
|||
|
|
|||
|
Adapter->NoCarrierCount = 0;
|
|||
|
Adapter->ExcessCollisionsCount = 0;
|
|||
|
}
|
|||
|
|
|||
|
// clear the SPA flag into the Sia Status register:
|
|||
|
|
|||
|
DC21X4_WRITE_PORT(
|
|||
|
DC21X4_SIA_STATUS,
|
|||
|
DC21X4_SELECTED_PORT_ACTIVE
|
|||
|
);
|
|||
|
|
|||
|
break;
|
|||
|
|
|||
|
case NoTimer:
|
|||
|
|
|||
|
return FALSE;
|
|||
|
|
|||
|
}
|
|||
|
break;
|
|||
|
|
|||
|
case DC21140_CFID:
|
|||
|
|
|||
|
if (!Adapter->Media[Adapter->SelectedMedium].SenseMask) {
|
|||
|
DC21X4IndicateMediaStatus(Adapter,LinkPass);
|
|||
|
return Adapter->PhyPresent;
|
|||
|
}
|
|||
|
|
|||
|
if ( (!(Adapter->MediaType & MEDIA_AUTOSENSE))
|
|||
|
&& (Adapter->PhyPresent)
|
|||
|
) {
|
|||
|
return TRUE;
|
|||
|
}
|
|||
|
|
|||
|
//Check the Link status
|
|||
|
|
|||
|
DC21X4_READ_PORT(
|
|||
|
DC21X4_GEN_PURPOSE,
|
|||
|
&Status
|
|||
|
);
|
|||
|
|
|||
|
DC21X4IndicateMediaStatus(
|
|||
|
Adapter,
|
|||
|
DC21X4_LINK_STATUS(Status,Adapter,Adapter->SelectedMedium) ?
|
|||
|
LinkPass : LinkFail
|
|||
|
);
|
|||
|
|
|||
|
if (Adapter->MediaType & MEDIA_AUTOSENSE) {
|
|||
|
|
|||
|
//Check the link status of every medium supported
|
|||
|
//by the adapter
|
|||
|
|
|||
|
for (index=Adapter->MediaCount; index>0; index--) {
|
|||
|
|
|||
|
CurrentMedium = Adapter->MediaPrecedence[index-1];
|
|||
|
|
|||
|
if (DC21X4_LINK_STATUS(Status,Adapter,CurrentMedium)) {
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (index > 0) {
|
|||
|
|
|||
|
// A link was detected,switch to this medium if:
|
|||
|
// current > selected (a medium link of higher precedence is up
|
|||
|
// current < selected (selected medium link is down)
|
|||
|
|
|||
|
SwitchMedium = (CurrentMedium != Adapter->SelectedMedium);
|
|||
|
}
|
|||
|
else {
|
|||
|
|
|||
|
// no link detected:
|
|||
|
// switch to the default medium if defined and different
|
|||
|
// of the selected medium
|
|||
|
// otherwise stay with the selected medium
|
|||
|
|
|||
|
CurrentMedium = Adapter->DefaultMedium;
|
|||
|
SwitchMedium = Adapter->DefaultMediumFlag
|
|||
|
&& (Adapter->SelectedMedium != Adapter->DefaultMedium);
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
if (SwitchMedium) {
|
|||
|
#if __DBG
|
|||
|
DbgPrint("Autosense: 21140 - Switch Medium to %s\n",
|
|||
|
MediumString[CurrentMedium]);
|
|||
|
#endif
|
|||
|
|
|||
|
DC21X4SwitchMedia(
|
|||
|
Adapter,
|
|||
|
CurrentMedium
|
|||
|
);
|
|||
|
|
|||
|
DC21X4_READ_PORT(
|
|||
|
DC21X4_GEN_PURPOSE,
|
|||
|
&Status
|
|||
|
);
|
|||
|
#if __DBG
|
|||
|
DbgPrint("Autosense 21140: Link=%s\n",
|
|||
|
Adapter->LinkStatus ? "UP":"DOWN");
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
return TRUE;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
/*++
|
|||
|
*
|
|||
|
* DC21X4SwitchMedia
|
|||
|
*
|
|||
|
* Routine Description:
|
|||
|
*
|
|||
|
* This routine switches DC21X4's media ports
|
|||
|
*
|
|||
|
* Arguments:
|
|||
|
*
|
|||
|
* Adapter
|
|||
|
* NewMedium : the new medium to switch to
|
|||
|
*
|
|||
|
* Return Value:
|
|||
|
*
|
|||
|
* None
|
|||
|
*
|
|||
|
-*/
|
|||
|
extern
|
|||
|
VOID
|
|||
|
DC21X4SwitchMedia(
|
|||
|
IN PDC21X4_ADAPTER Adapter,
|
|||
|
IN LONG NewMedium
|
|||
|
)
|
|||
|
{
|
|||
|
|
|||
|
ULONG Status;
|
|||
|
BOOLEAN SpaTimer=FALSE;
|
|||
|
ULONG FullDuplex=0;
|
|||
|
UINT j;
|
|||
|
|
|||
|
#if __DBG
|
|||
|
DbgPrint("DC21X4SwitchMedia [->%x]\n",NewMedium);
|
|||
|
#endif
|
|||
|
|
|||
|
DC21X4IndicateMediaStatus(Adapter,LinkFail);
|
|||
|
|
|||
|
switch (Adapter->DeviceId) {
|
|||
|
|
|||
|
|
|||
|
|
|||
|
case DC21142_CFID:
|
|||
|
case DC21041_CFID:
|
|||
|
|
|||
|
switch (NewMedium) {
|
|||
|
|
|||
|
|
|||
|
case Medium10BaseT:
|
|||
|
#if __DBG
|
|||
|
DbgPrint("Medium = %s %s \n",
|
|||
|
MediumString[NewMedium],
|
|||
|
FullDuplex ? "Full_Duplex" : "");
|
|||
|
#endif
|
|||
|
Adapter->SelectedMedium = NewMedium;
|
|||
|
DC2104InitializeSiaRegisters(Adapter);
|
|||
|
return;
|
|||
|
|
|||
|
case Medium10BaseTNway:
|
|||
|
#if __DBG
|
|||
|
DbgPrint("Medium = 10BaseT - Nway enabled\n");
|
|||
|
#endif
|
|||
|
NewMedium &= MEDIA_MASK;
|
|||
|
Adapter->SelectedMedium = NewMedium;
|
|||
|
Adapter->NwayEnabled=TRUE;
|
|||
|
|
|||
|
//Stop the Receiver and the Transmitter
|
|||
|
DC21X4StopReceiverAndTransmitter(Adapter);
|
|||
|
|
|||
|
//enable Nway
|
|||
|
Adapter->Media[Medium10BaseT].SiaRegister[1] |= DC21X4_NWAY_ENABLED;
|
|||
|
|
|||
|
DC2104InitializeSiaRegisters(Adapter);
|
|||
|
|
|||
|
Adapter->Media[Medium10BaseT].SiaRegister[1] &= ~(DC21X4_NWAY_ENABLED);
|
|||
|
|
|||
|
//Restart the Receiver and Transmitter in Full Duplex mode
|
|||
|
Adapter->OperationMode |= DC21X4_FULL_DUPLEX_MODE;
|
|||
|
|
|||
|
DC21X4_WRITE_PORT(
|
|||
|
DC21X4_OPERATION_MODE,
|
|||
|
Adapter->OperationMode
|
|||
|
);
|
|||
|
|
|||
|
return;
|
|||
|
|
|||
|
case Medium10Base2:
|
|||
|
|
|||
|
//switch medium to 10Base2
|
|||
|
SpaTimer = (Adapter->MediaCapable & MEDIUM_10B5);
|
|||
|
break;
|
|||
|
|
|||
|
case Medium10Base5:
|
|||
|
|
|||
|
//switch medium to 10Base5
|
|||
|
SpaTimer = (Adapter->MediaCapable & MEDIUM_10B2);
|
|||
|
break;
|
|||
|
|
|||
|
case Medium10Base2_5:
|
|||
|
|
|||
|
switch (Adapter->MediaCapable & (MEDIUM_10B2 | MEDIUM_10B5)) {
|
|||
|
|
|||
|
case (MEDIUM_10B2 | MEDIUM_10B5) :
|
|||
|
|
|||
|
// 10Base2 & 10Base5 ports are both populated:
|
|||
|
// if Non_Selected_Port_Active select 10Base5
|
|||
|
// otherwise select 10Base2
|
|||
|
|
|||
|
DC21X4_READ_PORT(
|
|||
|
DC21X4_SIA_STATUS,
|
|||
|
&Status
|
|||
|
);
|
|||
|
|
|||
|
NewMedium = (Status & DC21X4_NON_SELECTED_PORT_ACTIVE) ?
|
|||
|
Medium10Base5 : Medium10Base2;
|
|||
|
|
|||
|
SpaTimer = TRUE;
|
|||
|
break;
|
|||
|
|
|||
|
case MEDIUM_10B2 :
|
|||
|
|
|||
|
// 10Base2 port only is populated:
|
|||
|
NewMedium = Medium10Base2;
|
|||
|
break;
|
|||
|
|
|||
|
case MEDIUM_10B5 :
|
|||
|
|
|||
|
// 10Base5 port only is populated
|
|||
|
NewMedium = Medium10Base5;
|
|||
|
break;
|
|||
|
|
|||
|
default:
|
|||
|
|
|||
|
if (Adapter->PhyPresent) {
|
|||
|
|
|||
|
//Start the AutoSense Timer to poll the PHY Link
|
|||
|
DC21X4StartAutoSenseTimer(
|
|||
|
Adapter,
|
|||
|
(UINT)DC21X4_MII_TICK
|
|||
|
);
|
|||
|
}
|
|||
|
return;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
#if __DBG
|
|||
|
DbgPrint("Medium = %s %s\n",
|
|||
|
MediumString[NewMedium],
|
|||
|
Adapter->Media[NewMedium].SiaRegister[1] & DC21X4_AUTO_NEGOTIATION_ENABLE ?
|
|||
|
"- NWAY Enabled" : "");
|
|||
|
#endif
|
|||
|
|
|||
|
Adapter->SelectedMedium=NewMedium;
|
|||
|
|
|||
|
DC2104InitializeSiaRegisters(Adapter);
|
|||
|
DC21X4IndicateMediaStatus(Adapter,LinkPass);
|
|||
|
|
|||
|
if (SpaTimer || Adapter->PhyPresent) {
|
|||
|
#if __DBG
|
|||
|
DbgPrint("Start the AutoSense timer\n");
|
|||
|
#endif
|
|||
|
//Reset the NoCarrier and ExcessCollisions counters
|
|||
|
|
|||
|
Adapter->NoCarrierCount = 0;
|
|||
|
Adapter->ExcessCollisionsCount = 0;
|
|||
|
|
|||
|
//Start the AutoSense Timer
|
|||
|
DC21X4StartAutoSenseTimer(
|
|||
|
Adapter,
|
|||
|
(UINT)((Adapter->PhyPresent) ? DC21X4_MII_TICK : DC21X4_SPA_TICK)
|
|||
|
);
|
|||
|
|
|||
|
}
|
|||
|
break;
|
|||
|
|
|||
|
|
|||
|
case DC21140_CFID:
|
|||
|
|
|||
|
// Switch medium:
|
|||
|
// Reload GEP and OperationMode registers
|
|||
|
|
|||
|
Adapter->OperationMode &= ~(DC21X4_MEDIUM_MASK);
|
|||
|
Adapter->OperationMode |= Adapter->Media[NewMedium].Mode;
|
|||
|
|
|||
|
Adapter->SelectedMedium = NewMedium;
|
|||
|
|
|||
|
DC21X4_WRITE_PORT(
|
|||
|
DC21X4_GEN_PURPOSE,
|
|||
|
Adapter->Media[NewMedium].GeneralPurposeData
|
|||
|
);
|
|||
|
|
|||
|
DC21X4_WRITE_PORT(
|
|||
|
DC21X4_OPERATION_MODE,
|
|||
|
Adapter->OperationMode
|
|||
|
);
|
|||
|
|
|||
|
for (j=0;j<(GEP_READ_DELAY/5);j++) {
|
|||
|
NdisStallExecution(5*MILLISECOND);
|
|||
|
}
|
|||
|
|
|||
|
DC21X4_READ_PORT(
|
|||
|
DC21X4_GEN_PURPOSE,
|
|||
|
&Status
|
|||
|
);
|
|||
|
|
|||
|
DC21X4IndicateMediaStatus(
|
|||
|
Adapter,
|
|||
|
DC21X4_LINK_STATUS(Status,Adapter,Adapter->SelectedMedium) ?
|
|||
|
LinkPass : LinkFail
|
|||
|
);
|
|||
|
|
|||
|
return;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
/*++
|
|||
|
*
|
|||
|
* DC21X4StartAutoSenseTimer
|
|||
|
*
|
|||
|
* Routine Description:
|
|||
|
*
|
|||
|
* Start the AutoSense Timer
|
|||
|
*
|
|||
|
* Arguments:
|
|||
|
*
|
|||
|
* Adapter
|
|||
|
*
|
|||
|
* Return Value:
|
|||
|
*
|
|||
|
* None
|
|||
|
*
|
|||
|
-*/
|
|||
|
extern
|
|||
|
VOID
|
|||
|
DC21X4StartAutoSenseTimer(
|
|||
|
IN PDC21X4_ADAPTER Adapter,
|
|||
|
IN UINT Value
|
|||
|
)
|
|||
|
{
|
|||
|
|
|||
|
|
|||
|
Adapter->TimerFlag=SpaTimer;
|
|||
|
|
|||
|
NdisMSetTimer(
|
|||
|
&Adapter->Timer,
|
|||
|
Value
|
|||
|
);
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
/*++
|
|||
|
*
|
|||
|
* DC21X4StopAutoSenseTimer
|
|||
|
*
|
|||
|
* Routine Description:
|
|||
|
*
|
|||
|
* Stop the AutoSense Timer
|
|||
|
*
|
|||
|
* Arguments:
|
|||
|
*
|
|||
|
* Adapter
|
|||
|
*
|
|||
|
* Return Value:
|
|||
|
*
|
|||
|
* None
|
|||
|
*
|
|||
|
-*/
|
|||
|
extern
|
|||
|
VOID
|
|||
|
DC21X4StopAutoSenseTimer(
|
|||
|
IN PDC21X4_ADAPTER Adapter
|
|||
|
)
|
|||
|
{
|
|||
|
BOOLEAN Canceled;
|
|||
|
|
|||
|
Adapter->TimerFlag = NoTimer;
|
|||
|
|
|||
|
NdisMCancelTimer(
|
|||
|
&Adapter->Timer,
|
|||
|
&Canceled
|
|||
|
);
|
|||
|
|
|||
|
Adapter->IgnoreTimer = !Canceled;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
/*+
|
|||
|
* DC21X4EnableNway
|
|||
|
*
|
|||
|
* Routine Description:
|
|||
|
*
|
|||
|
* Enable the Nway Negotiation
|
|||
|
*
|
|||
|
* Arguments:
|
|||
|
*
|
|||
|
* Adapter - The adapter in question.
|
|||
|
*
|
|||
|
* Return Value:
|
|||
|
*
|
|||
|
* None
|
|||
|
*
|
|||
|
-*/
|
|||
|
extern
|
|||
|
VOID
|
|||
|
DC21X4EnableNway(
|
|||
|
IN PDC21X4_ADAPTER Adapter
|
|||
|
)
|
|||
|
{
|
|||
|
|
|||
|
ULONG Mask;
|
|||
|
|
|||
|
#if __DBG
|
|||
|
DbgPrint("Enable Nway Negotiation\n");
|
|||
|
#endif
|
|||
|
|
|||
|
switch (Adapter->DeviceId) {
|
|||
|
|
|||
|
case DC21041_CFID:
|
|||
|
|
|||
|
switch (Adapter->RevisionNumber) {
|
|||
|
|
|||
|
case DC21041_REV2_0:
|
|||
|
if (Adapter->NwayProtocol) {
|
|||
|
Adapter->MediaNway = TRUE;
|
|||
|
Adapter->LinkHandlerMode=NwayWorkAround;
|
|||
|
break;
|
|||
|
}
|
|||
|
case DC21041_REV1_1:
|
|||
|
case DC21041_REV1_0:
|
|||
|
|
|||
|
Adapter->MediaNway = FALSE;
|
|||
|
Adapter->LinkHandlerMode=NoNway;
|
|||
|
break;
|
|||
|
|
|||
|
default:
|
|||
|
|
|||
|
Adapter->MediaNway = TRUE;
|
|||
|
Adapter->LinkHandlerMode=Nway;
|
|||
|
|
|||
|
Adapter->Media[Medium10BaseT].SiaRegister[1] |= DC21X4_NWAY_ENABLED;
|
|||
|
Adapter->Media[Medium10Base2].SiaRegister[1] |= DC21X4_NWAY_ENABLED;
|
|||
|
Adapter->Media[Medium10Base5].SiaRegister[1] |= DC21X4_NWAY_ENABLED;
|
|||
|
|
|||
|
Adapter->Media[Medium10BaseT].Mode |= DC21X4_FULL_DUPLEX_MODE;
|
|||
|
Adapter->Media[Medium10Base2].Mode |= DC21X4_FULL_DUPLEX_MODE;
|
|||
|
Adapter->Media[Medium10Base5].Mode |= DC21X4_FULL_DUPLEX_MODE;
|
|||
|
}
|
|||
|
break;
|
|||
|
|
|||
|
case DC21142_CFID:
|
|||
|
|
|||
|
switch (Adapter->RevisionNumber) {
|
|||
|
|
|||
|
case DC21142_REV1_0:
|
|||
|
case DC21142_REV1_1:
|
|||
|
|
|||
|
if (Adapter->NwayProtocol) {
|
|||
|
Adapter->MediaNway = TRUE;
|
|||
|
Adapter->LinkHandlerMode=NwayWorkAround;
|
|||
|
}
|
|||
|
else {
|
|||
|
Adapter->MediaNway = FALSE;
|
|||
|
Adapter->LinkHandlerMode=NoNway;
|
|||
|
}
|
|||
|
break;
|
|||
|
|
|||
|
default:
|
|||
|
|
|||
|
Adapter->MediaNway = TRUE;
|
|||
|
Adapter->LinkHandlerMode=Nway;
|
|||
|
|
|||
|
Adapter->Media[Medium10BaseT].SiaRegister[1] |= DC21X4_NWAY_ENABLED;
|
|||
|
Adapter->Media[Medium10Base2].SiaRegister[1] |= DC21X4_NWAY_ENABLED;
|
|||
|
Adapter->Media[Medium10Base5].SiaRegister[1] |= DC21X4_NWAY_ENABLED;
|
|||
|
|
|||
|
Adapter->Media[Medium10BaseT].Mode |= DC21X4_FULL_DUPLEX_MODE;
|
|||
|
Adapter->Media[Medium10Base2].Mode |= DC21X4_FULL_DUPLEX_MODE;
|
|||
|
Adapter->Media[Medium10Base5].Mode |= DC21X4_FULL_DUPLEX_MODE;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
break;
|
|||
|
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/*+
|
|||
|
* DC21X4DisableNway
|
|||
|
*
|
|||
|
* Routine Description:
|
|||
|
*
|
|||
|
* Disable the Nway Negotiation
|
|||
|
*
|
|||
|
* Arguments:
|
|||
|
*
|
|||
|
* Adapter - The adapter in question.
|
|||
|
*
|
|||
|
* Return Value:
|
|||
|
*
|
|||
|
* None
|
|||
|
*
|
|||
|
-*/
|
|||
|
extern
|
|||
|
VOID
|
|||
|
DC21X4DisableNway(
|
|||
|
IN PDC21X4_ADAPTER Adapter
|
|||
|
)
|
|||
|
{
|
|||
|
|
|||
|
#if __DBG
|
|||
|
DbgPrint("Disable Nway Negotiation\n");
|
|||
|
#endif
|
|||
|
|
|||
|
Adapter->MediaNway = FALSE;
|
|||
|
Adapter->LinkHandlerMode=NoNway;
|
|||
|
|
|||
|
switch (Adapter->DeviceId) {
|
|||
|
|
|||
|
case DC21041_CFID:
|
|||
|
case DC21142_CFID:
|
|||
|
Adapter->Media[Medium10BaseT].SiaRegister[1] &= ~DC21X4_NWAY_ENABLED;
|
|||
|
Adapter->Media[Medium10Base2].SiaRegister[1] &= ~DC21X4_NWAY_ENABLED;
|
|||
|
Adapter->Media[Medium10Base5].SiaRegister[1] &= ~DC21X4_NWAY_ENABLED;
|
|||
|
|
|||
|
Adapter->Media[Medium10BaseT].Mode &= ~DC21X4_FULL_DUPLEX_MODE;
|
|||
|
Adapter->Media[Medium10Base2].Mode &= ~DC21X4_FULL_DUPLEX_MODE;
|
|||
|
Adapter->Media[Medium10Base5].Mode &= ~DC21X4_FULL_DUPLEX_MODE;
|
|||
|
|
|||
|
break;
|
|||
|
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
/*++
|
|||
|
*
|
|||
|
* DC21X4IndicateMediaStatus
|
|||
|
*
|
|||
|
* Routine Description:
|
|||
|
*
|
|||
|
* Indicate the media status
|
|||
|
*
|
|||
|
* Arguments:
|
|||
|
*
|
|||
|
* Adapter
|
|||
|
*
|
|||
|
* Return Value:
|
|||
|
*
|
|||
|
* None
|
|||
|
*
|
|||
|
-*/
|
|||
|
extern
|
|||
|
VOID
|
|||
|
DC21X4IndicateMediaStatus(
|
|||
|
IN PDC21X4_ADAPTER Adapter,
|
|||
|
IN UINT Status
|
|||
|
)
|
|||
|
{
|
|||
|
|
|||
|
ULONG LinkPartner;
|
|||
|
|
|||
|
Adapter->LinkStatus=Status;
|
|||
|
|
|||
|
if (Status != Adapter->PreviousLinkStatus) {
|
|||
|
|
|||
|
switch (Adapter->LinkStatus) {
|
|||
|
|
|||
|
#if __DBG
|
|||
|
case LinkFail:
|
|||
|
DbgPrint("IndicateMediaStatus: Link FAIL\n");
|
|||
|
break;
|
|||
|
#endif
|
|||
|
|
|||
|
case LinkPass:
|
|||
|
|
|||
|
switch (Adapter->SelectedMedium) {
|
|||
|
|
|||
|
case Medium100BaseTx:
|
|||
|
case Medium100BaseT4:
|
|||
|
case Medium100BaseFx:
|
|||
|
|
|||
|
Adapter->LinkSpeed = ONE_HUNDRED_MBPS;
|
|||
|
break;
|
|||
|
|
|||
|
default:
|
|||
|
|
|||
|
Adapter->LinkSpeed = TEN_MBPS;
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
if (Adapter->MediaNway) {
|
|||
|
|
|||
|
//Nway: read the Link Partner Ability to check
|
|||
|
// Half/Full Duplex link mode
|
|||
|
|
|||
|
DC21X4_READ_PORT(
|
|||
|
DC21X4_SIA_STATUS,
|
|||
|
&LinkPartner
|
|||
|
);
|
|||
|
|
|||
|
Adapter->FullDuplexLink =
|
|||
|
LinkPartner & (DC21X4_LINK_PARTNER_10BT_FD) ?
|
|||
|
TRUE : FALSE ;
|
|||
|
}
|
|||
|
else {
|
|||
|
Adapter->FullDuplexLink =
|
|||
|
(Adapter->MediaType & MEDIA_FULL_DUPLEX) != 0;
|
|||
|
}
|
|||
|
|
|||
|
#if __DBG
|
|||
|
DbgPrint("IndicateMediaStatus: %s%s Link PASS\n",
|
|||
|
MediumString[Adapter->SelectedMedium],
|
|||
|
Adapter->FullDuplexLink ? " Full_Duplex" : "");
|
|||
|
#endif
|
|||
|
break;
|
|||
|
|
|||
|
case MiiLinkPass:
|
|||
|
|
|||
|
Adapter->LinkSpeed = TEN_MBPS;
|
|||
|
Adapter->FullDuplexLink = FALSE;
|
|||
|
|
|||
|
switch (Adapter->MiiMediaType & MEDIA_MASK) {
|
|||
|
|
|||
|
case MediumMii10BaseTFd:
|
|||
|
|
|||
|
Adapter->FullDuplexLink = TRUE;
|
|||
|
break;
|
|||
|
|
|||
|
case MediumMii100BaseTxFd:
|
|||
|
case MediumMii100BaseFxFd:
|
|||
|
|
|||
|
Adapter->FullDuplexLink = TRUE;
|
|||
|
|
|||
|
case MediumMii100BaseTx:
|
|||
|
case MediumMii100BaseT4:
|
|||
|
case MediumMii100BaseFx:
|
|||
|
|
|||
|
Adapter->LinkSpeed = ONE_HUNDRED_MBPS;
|
|||
|
break;
|
|||
|
}
|
|||
|
#if __DBG
|
|||
|
DbgPrint("IndicateMediaStatus: %s%s MiiLink PASS\n",
|
|||
|
MediumString[Adapter->MiiMediaType & MEDIA_MASK],
|
|||
|
Adapter->FullDuplexLink ? " Full_Duplex" : "");
|
|||
|
#endif
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
if (Adapter->FullDuplexLink) {
|
|||
|
Adapter->TransmitDescriptorErrorMask &=
|
|||
|
~(DC21X4_TDES_NO_CARRIER | DC21X4_TDES_LOSS_OF_CARRIER);
|
|||
|
}
|
|||
|
else {
|
|||
|
Adapter->TransmitDescriptorErrorMask =
|
|||
|
Adapter->TransmitDefaultDescriptorErrorMask;
|
|||
|
}
|
|||
|
|
|||
|
if (!Adapter->Initializing) {
|
|||
|
NdisMIndicateStatus (
|
|||
|
Adapter->MiniportAdapterHandle,
|
|||
|
(Status == LinkFail ? NDIS_STATUS_MEDIA_DISCONNECT : NDIS_STATUS_MEDIA_CONNECT),
|
|||
|
NULL,
|
|||
|
0
|
|||
|
);
|
|||
|
}
|
|||
|
|
|||
|
Adapter->PreviousLinkStatus = Status;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|