📄 detect.c
字号:
//---------------------------------------------------------------------------
//
// Copyright (C) 1996-1997. Unpublished Work of Crystal Semiconductor Corp.
// All Rights Reserved.
//
// THIS WORK IS AN UNPUBLISHED WORK AND CONTAINS CONFIDENTIAL,
// PROPRIETARY AND TRADE SECRET INFORMATION OF CRYSTAL SEMICONDUCTOR.
// ACCESS TO THIS WORK IS RESTRICTED TO (I) CRYSTAL SEMICONDUCTOR EMPLOYEES
// WHO HAVE A NEED TO KNOW TO PERFORM TASKS WITHIN THE SCOPE OF THEIR
// ASSIGNMENTS AND (II) ENTITIES OTHER THAN CRYSTAL SEMICONDUCTOR WHO
// HAVE ENTERED INTO APPROPRIATE LICENSE AGREEMENTS. NO PART OF THIS
// WORK MAY BE USED, PRACTICED, PERFORMED, COPIED, DISTRIBUTED, REVISED,
// MODIFIED, TRANSLATED, ABRIDGED, CONDENSED, EXPANDED, COLLECTED,
// COMPILED,LINKED,RECAST, TRANSFORMED, ADAPTED IN ANY FORM OR BY ANY
// MEANS,MANUAL, MECHANICAL, CHEMICAL, ELECTRICAL, ELECTRONIC, OPTICAL,
// BIOLOGICAL, OR OTHERWISE WITHOUT THE PRIOR WRITTEN PERMISSION AND
// CONSENT OF CRYSTAL SEMICONDUCTOR . ANY USE OR EXPLOITATION OF THIS WORK
// WITHOUT THE PRIOR WRITTEN CONSENT OF CRYSTAL SEMICONDUCTOR COULD
// SUBJECT THE PERPETRATOR TO CRIMINAL AND CIVIL LIABILITY.
//
//---------------------------------------------------------------------------
#include "cs8900a.h"
#include "cshrd.h"
/* External prototypes */
WORD ReadPacketPage( WORD Offset );
void PurgeTransmitQueue( IN PCHIP );
/* Internal prototypes */
//@drsc 11-3-97 3.21 add cs8900 support
void CrystalDetermineDuplexMode( PCHIP pChip );
extern BOOL IsAPIReady( DWORD hAPI );
void CrystalEnableAUILoopback( PCHIP pChip )
{
WORD Data;
PRINTDEBUGMSG(1, (TEXT("==>CS8900:CrystalEnableAUILoopback\r\n")));
//
// Set the RX_OK_ACCEPT+RX_IA_ACCEPT+RX_RUNT_ACCEPT +
// CRYSTAL_RCR_RX_PROM_ACCEPTin RX_CTL_REG
//
WritePacketPage(CRYSTAL_RX_CONTROL_REGISTER, CRYSTAL_RCR_RX_IA_ACCEPT |
CRYSTAL_RCR_RX_RUNT_ACCEPT |
CRYSTAL_RCR_RX_OK_ACCEPT |
CRYSTAL_RCR_RX_PROM_ACCEPT);
VominiDelay( 1 );
//
// Read the Line Control Register and or it with AUI only mode.
// Also enable the transmitter and receiver.
//
Data = ReadPacketPage(CRYSTAL_LINE_CONTROL_REGISTER);
Data |= CRYSTAL_LCR_AUI_ONLY | CRYSTAL_LCR_SERIAL_RX_ON | CRYSTAL_LCR_SERIAL_TX_ON;
WritePacketPage(CRYSTAL_LINE_CONTROL_REGISTER, Data);
//
// Start AUI Loop Back now.
// Read the TEST_CTL register and OR it with AUI loopback mode
//
Data = ReadPacketPage(CRYSTAL_TEST_CONTROL_REGISTER);
Data &= ~(CRYSTAL_TCR_FULL_DUPLEX_ON |CRYSTAL_TCR_ENDEC_LOOPBACK);
//
// Or it with AUI_LOOPBACK mode
//
WritePacketPage(CRYSTAL_TEST_CONTROL_REGISTER, Data | CRYSTAL_TCR_AUI_LOOPBACK);
PRINTDEBUGMSG(1, (TEXT("<==CS8900:CrystalEnableAUILoopback\r\n")));
}
void CrystalDisableAUILoopback( PCHIP pChip )
{
WORD Data;
PRINTDEBUGMSG(1, (TEXT("==>CS8900:CrystalDisableAUILoopback\r\n")));
//
// Disable AUI LOOPBACK mode.
//
Data = ReadPacketPage(CRYSTAL_TEST_CONTROL_REGISTER);
WritePacketPage(CRYSTAL_TEST_CONTROL_REGISTER, (Data & ~CRYSTAL_TCR_AUI_LOOPBACK));
/* Clear the AUI only bit in the Line Control register */
Data = ReadPacketPage(CRYSTAL_LINE_CONTROL_REGISTER);
Data &= ~(CRYSTAL_LCR_AUI_ONLY | CRYSTAL_LCR_SERIAL_RX_ON | CRYSTAL_LCR_SERIAL_TX_ON);
WritePacketPage(CRYSTAL_LINE_CONTROL_REGISTER, Data);
PRINTDEBUGMSG(1, (TEXT("<==CS8900:CrystalDisableAUILoopback\r\n")));
}
void CrystalEnableDCConverter( PCHIP pChip )
{
WORD Data;
PCD pData = pChip->pData;
PRINTDEBUGMSG(1, (TEXT("==>CS8900:CrystalEnableDCConverter\r\n")));
//
// Read the self control register
//
Data = ReadPacketPage(CRYSTAL_SELF_CONTROL_REGISTER);
Data |= CRYSTAL_SCR_HCO_1_ENABLE;
//
// Depending on the polarity existing the Dc/Dc converter must be
// turned on
//
if (pData->ConfigFlags & CFGFLG_DCDC_POLARITY)
Data &= ~CRYSTAL_SCR_HCO_1;
else
Data |= CRYSTAL_SCR_HCO_1;
WritePacketPage(CRYSTAL_SELF_CONTROL_REGISTER, Data);
//
// Delay to give the DC/DC converter time to stabilize
//
// Delay for 8 milliseconds. This delay was extended
// from 1.5 millisecond for the Etherjet cost reduced card.
VominiDelay( 8 );
PRINTDEBUGMSG(1, (TEXT("<==CS8900:CrystalEnableDCConverter\r\n")));
}
void CrystalDisableDCConverter( PCHIP pChip )
{
WORD Data;
PCD pData = pChip->pData;
PRINTDEBUGMSG(1, (TEXT("==>CS8900:CrystalDisableDCConverter\r\n")));
//
// Disable the DC/DC converter by turning off the self control register
//
Data = ReadPacketPage(CRYSTAL_SELF_CONTROL_REGISTER);
if (pData->ConfigFlags & CFGFLG_DCDC_POLARITY)
Data |= CRYSTAL_SCR_HCO_1;
else
Data &= ~CRYSTAL_SCR_HCO_1;
WritePacketPage(CRYSTAL_SELF_CONTROL_REGISTER, Data);
PRINTDEBUGMSG(1, (TEXT("<==CS8900:CrystalDisableDCConverter\r\n")));
}
WORD CrystalPollForRxOK( PCHIP pChip, WORD Timeout )
{
DWORD i;
WORD Data;
PRINTDEBUGMSG(1, (TEXT("==>CS8900:CrystalPollForRxOK\r\n")));
//
// Poll for the receive event
//
Timeout = Timeout * 10;
for (i=0; i < Timeout; i++)
{
Data = ReadPacketPage(CRYSTAL_RX_EVENT_REGISTER);
if (Data & CRYSTAL_RER_PACKET_RECEIVED_OK)
return TRUE;
VominiDelay( 1 ); // delay 1 millesecond
}
PRINTDEBUGMSG(1, (TEXT("<==CS8900:CrystalPollForRxOK\r\n")));
//
// Couldn't get RX_OK return false
//
return FALSE;
}
WORD CrystalSendMediaTestPacket( PCHIP pChip )
{
//
// A variable to read the data from packet page.
//
WORD Data;
DWORD i;
PWORD EthernetAddress;
#define CRYSTAL_MEDIA_TEST_PACKET_LENGTH 2+ (2*ETH_LENGTH_OF_ADDRESS)
PRINTDEBUGMSG(1, (TEXT("==>CS8900:CrystalSendMediaTestPacket\r\n")));
//
// Write the transmit command to TX_CMD port.
//
v_pCS8900Regs->TXCMD = CRYSTAL_TCR_TX_START_ALL_BYTES | CRYSTAL_TCR_TX_FORCE;
//
// Write the transmit length to TX_LENGTH port.
//
v_pCS8900Regs->TXLENGTH = CRYSTAL_MEDIA_TEST_PACKET_LENGTH ;
//
// Now, check whether the chip is ready to transmit by checking the
// Ready for transmit bit of the BusStatusRegister.
//
//
// Wait for up to 10 milliseconds for the read for transmit now
//
for (i=0; i < 10; i++)
{
Data = ReadPacketPage(CRYSTAL_BUS_STATUS_REGISTER);
if (Data & CRYSTAL_BSR_READY_FOR_TRANSMIT_NOW)
break;
VominiDelay( 1 );
}
if (!(Data & CRYSTAL_BSR_READY_FOR_TRANSMIT_NOW))
{
//
// Could not get READY_FOR_TX,return with error
//
// Send with FORCE ???? and restart?
PRINTDEBUGMSG(1, (TEXT("<==CS8900:CrystalSendMediaTestPacket FALSE\r\n")));
return FALSE;
}
//
// Transmit a frame that is addressed to ourself.
// Write source and destination address
//
EthernetAddress = (PWORD)&(pChip->Config.EthernetAddr);
for(i=0; i < ETH_LENGTH_OF_ADDRESS/2; i++)
v_pCS8900Regs->DATA0 = *EthernetAddress++;
EthernetAddress = (PWORD)&(pChip->Config.EthernetAddr);
for(i=0; i < ETH_LENGTH_OF_ADDRESS/2; i++)
v_pCS8900Regs->DATA0 = *EthernetAddress++;
//
// Transmit the length of the packet.
//
v_pCS8900Regs->DATA0 = CRYSTAL_MEDIA_TEST_PACKET_LENGTH;
//
// Wait for 1 ms. In this time we should have transmitted else there is
// traffic so we could receive some packet from the network
//
VominiDelay( 1 );
//
// Read the TxEvent register and discard this event
//
ReadPacketPage(CRYSTAL_TX_EVENT_REGISTER);
PRINTDEBUGMSG(1, (TEXT("<==CS8900:CrystalSendMediaTestPacket\r\n")));
//
// Poll for the receive event
//
return CrystalPollForRxOK(pChip, 12);
}
void CrystalDetect10baseT( PCHIP pChip )
{
WORD LineStatus;
PRINTDEBUGMSG(1, (TEXT("==>CS8900:CrystalDetect10baseT\r\n")));
if ( pChip->Config.CurrentDuplexMode == DUPLEX_NONE )
{
/* Read the line status register */
LineStatus = ReadPacketPage( CRYSTAL_LINE_STATUS_REGISTER );
/* If the link is OK */
if ( LineStatus & CRYSTAL_LSR_LINK_OK )
{
CrystalDetermineDuplexMode( pChip );
if ( pChip->Config.CurrentDuplexMode == DUPLEX_PENDING )
pChip->Config.DetectedMediaType = MEDIA_PENDING;
else
pChip->Config.DetectedMediaType = MEDIA_BASE_T;
}
else if ( pChip->Config.DetectedMediaType == MEDIA_NONE )
pChip->Config.DetectedMediaType = MEDIA_PENDING;
else /* DetectedMediaType == MEDIA_PENDING */
pChip->Config.DetectedMediaType = MEDIA_NONE;
}
else if ( pChip->Config.CurrentDuplexMode == DUPLEX_PENDING )
{
CrystalDetermineDuplexMode( pChip );
if ( pChip->Config.CurrentDuplexMode == DUPLEX_PENDING )
pChip->Config.DetectedMediaType = MEDIA_PENDING;
else
pChip->Config.DetectedMediaType = MEDIA_BASE_T;
}
PRINTDEBUGMSG(1, (TEXT("<==CS8900:CrystalDetect10baseT CurrentDuplexMode = %d, DetectedMediaType = %d, \r\n"),
pChip->Config.CurrentDuplexMode,
pChip->Config.DetectedMediaType));
}
void CrystalDetectAUI( PCHIP pChip )
{
PRINTDEBUGMSG(1, (TEXT("==>CS8900:CrystalDetectAUI\r\n")));
CrystalEnableAUILoopback(pChip);
CrystalDisableDCConverter(pChip);
//
// Send the Media Test Packet . If transmission succeeds it is AUI
//
if (CrystalSendMediaTestPacket(pChip))
{
//
// The media detected is AUI
//
pChip->Config.DetectedMediaType = MEDIA_BASE_AUI;
pChip->Config.CurrentDuplexMode = DUPLEX_HALF;
}
//
// Disable the AUI loop back mode
//
CrystalDisableAUILoopback(pChip);
PRINTDEBUGMSG(1, (TEXT("<==CS8900:CrystalDetectAUI\r\n")));
}
void CrystalDetectBNC( PCHIP pChip )
{
PRINTDEBUGMSG(1, (TEXT("==>CS8900:CrystalDetectBNC\r\n")));
CrystalEnableAUILoopback(pChip);
CrystalEnableDCConverter(pChip);
//
// Send the media test packet . If the test transmission succeeds ,the
// medium is BNC.
//
if ( CrystalSendMediaTestPacket(pChip) )
{
//
// Success, BNC is connected
//
pChip->Config.DetectedMediaType = MEDIA_BASE_2;
pChip->Config.CurrentDuplexMode = DUPLEX_HALF;
}
CrystalDisableDCConverter(pChip);
//
// Disable the AUI loop back mode
//
CrystalDisableAUILoopback(pChip);
PRINTDEBUGMSG(1, (TEXT("<==CS8900:CrystalDetectBNC\r\n")));
} /*endproc*/
void CrystalAutoDetectMedia( PCHIP pChip )
{
PCD pData;
PRINTDEBUGMSG(1, (TEXT("==>CS8900:CrystalAutoDetectMedia\r\n")));
pData = pChip->pData;
/* If the hardware is capable of 10BaseT */
if ( pData->ConfigFlags & CFGFLG_MEDIA_CAP_BASE_T )
{
CrystalDetect10baseT( pChip );
if ( pChip->Config.DetectedMediaType == MEDIA_BASE_T ||
pChip->Config.DetectedMediaType == MEDIA_PENDING )
{
PRINTDEBUGMSG(1, (TEXT("<==CS8900:CrystalAutoDetectMedia 111\r\n")));
return;
}
}
/* If the hardware is capable of AUI */
if ( pData->ConfigFlags & CFGFLG_MEDIA_CAP_BASE_AUI )
{
CrystalDetectAUI( pChip );
if ( pChip->Config.DetectedMediaType == MEDIA_BASE_AUI )
{
PRINTDEBUGMSG(1, (TEXT("<==CS8900:CrystalAutoDetectMedia 222\r\n")));
return;
}
}
/* If the hardware is capable of 10Base2 */
if ( pData->ConfigFlags & CFGFLG_MEDIA_CAP_BASE_2 )
{
CrystalDetectBNC( pChip );
if ( pChip->Config.DetectedMediaType == MEDIA_BASE_2 )
{
PRINTDEBUGMSG(1, (TEXT("<==CS8900:CrystalAutoDetectMedia 333\r\n")));
return;
}
}
PRINTDEBUGMSG(1, (TEXT("<==CS8900:CrystalAutoDetectMedia\r\n")));
}
void DetectMedia( PCHIP pChip )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -