📄 detect.c
字号:
{
PCD pData;
PRINTDEBUGMSG(1, (TEXT("==>CS8900:DetectMedia\r\n")));
pData = pChip->pData;
/* This routine should only be called with */
/* DetectedMediaType set to MEDIA_NONE or MEDIA_PENDING */
switch ( pChip->Config.RequestedMediaType )
{
case MEDIA_BASE_T:
CrystalDetect10baseT( pChip );
break;
case MEDIA_BASE_AUI:
CrystalDetectAUI( pChip );
break;
case MEDIA_BASE_2:
CrystalDetectBNC( pChip );
break;
case MEDIA_AUTO_DETECT:
default:
CrystalAutoDetectMedia( pChip );
break;
}
PRINTDEBUGMSG(1, (TEXT("<==CS8900:DetectMedia\r\n")));
}
//@drsc 11-3-97 3.21 add cs8900 support
VOID CrystalDetermineDuplexMode( PCHIP pChip )
{
WORD AutoNegControl;
PRINTDEBUGMSG(1, (TEXT("==>CS8900:CrystalDetermineDuplexMode\r\n")));
// Determine if it is half or full duplex. The CS8900
// does not auto negotiate.
// @kml 6/25/99
if (pChip->Config.RequestedDuplexMode == DUPLEX_FULL)
{
AutoNegControl = CRYSTAL_TCR_FULL_DUPLEX_ON;
pChip->Config.CurrentDuplexMode = DUPLEX_FULL;
}
else
{
AutoNegControl = 0;
pChip->Config.CurrentDuplexMode = DUPLEX_HALF;
}
WritePacketPage(CRYSTAL_TEST_CONTROL_REGISTER, AutoNegControl);
PRINTDEBUGMSG(1, (TEXT("<==CS8900:CrystalDetermineDuplexMode\r\n")));
}
void SetLanIndicator(WORD Status)
{
/* P_IND_CTRL pIndicatorLightAddr = (P_IND_CTRL)(INDICATOR_LIGHT_BASE_U_VIRTUAL);
///--- Set the Indicator status on the control...
if(0 == Status)
{
if(pIndicatorLightAddr->control & LAN_LIGHT_BIT)
{
return ;
}
WAIT_FOR_WRITE_SIG( pIndicatorLightAddr );
pIndicatorLightAddr->control |= (LAN_LIGHT_BIT);
}
else
{
if(!(pIndicatorLightAddr->control & LAN_LIGHT_BIT))
{
return ;
}
WAIT_FOR_WRITE_SIG( pIndicatorLightAddr );
pIndicatorLightAddr->control &= (~(LAN_LIGHT_BIT));
}*/
}
// Function: PostShellWindowMessage
// Purpose: Post Shell Window Some Message.
// Returns:
//---------------------------------------------------------------------------------------------------------------
void PostShellWindowMessage(int Message,WPARAM wParam ,LPARAM lParam)
{
LONG regError;
HKEY hKey;
DWORD dwDataSize;
TCHAR ShellWindow [128] ;
HWND hShellWindow ;
if(IsAPIReady(SH_WMGR))
{
wcscpy(ShellWindow , TEXT(""));
regError = RegOpenKeyEx(HKEY_CURRENT_USER,TEXT("Software\\HuaWei\\BITShell"),0,KEY_ALL_ACCESS,&hKey);
if (regError == ERROR_SUCCESS)
{
dwDataSize = sizeof(ShellWindow);
regError = RegQueryValueEx(hKey,TEXT("DesktopName"),NULL,NULL,(LPBYTE)ShellWindow,&dwDataSize);
RegCloseKey(hKey);
if(regError != ERROR_SUCCESS)
{
return;
}
hShellWindow = FindWindow(SHELLWINDOW_CLASS_NAME,ShellWindow);
if(hShellWindow)
{
//RETAILMSG(1,(TEXT("ShellWindows HANDLE = 0x%x.\r\n"),hShellWindow)) ;
PostMessage(hShellWindow,Message,wParam,lParam);
// SendMessage(hShellWindow,Message,wParam,lParam);
}
}
}
}
void VchipDetectMediaDaemon( PCHIP pChip, WORD TimerID, PVOID pParm )
{
PCD pData;
WORD LineStatus;
WORD JustDisconnected;
PRINTDEBUGMSG(1, (TEXT("==>CS8900:VchipDetectMediaDaemon\r\n")));
pData = pChip->pData;
JustDisconnected = FALSE;
/* If the cable is not currently connected */
if ( pChip->Config.DetectedMediaType == MEDIA_NONE ||
pChip->Config.DetectedMediaType == MEDIA_PENDING )
{
/* Try to detect the media */
DetectMedia( pChip );
/* If the cable was just connected */
if ( pChip->Config.DetectedMediaType != MEDIA_NONE &&
pChip->Config.DetectedMediaType != MEDIA_PENDING )
{
///--- Light up Lan Indicator...
SetLanIndicator(1);
// if ( pChip->Config.DetectedMediaType != MEDIA_BASE_T )
{
/* Reset the chip, avoids pending receives */
VchipReset( pChip );
}
/* Initialize the chip */
VchipInit( pChip );
/* Inform the protocol stack that the media is now connected */
VpsMediaChanged( pChip );
///--- When we get Net Connected Status , Notice Shell the Message.
///--- Use wParam 1 for connect Message, 0 for disconnected Message.
PostShellWindowMessage(WM_BIT_NETCONNECTED,1,0);
}
else
{
///--- Light off Lan Indicator...
SetLanIndicator(0);
}
}
else if ( pChip->Config.DetectedMediaType == MEDIA_BASE_T )
{
/* Read the line status register */
LineStatus = ReadPacketPage( CRYSTAL_LINE_STATUS_REGISTER );
/* If the link has been lost */
if ( !(LineStatus & CRYSTAL_LSR_LINK_OK) )
JustDisconnected = TRUE;
}
else if ( !pData->TransmitStarted && pData->TransmitInProgress )
{
/* A transmit did not complete within two daemon ticks. */
/* An AUI or 10Base2 cable has just been disconnected. */
JustDisconnected = TRUE;
}
if ( JustDisconnected )
{
///--- Light off Lan Indicator...
SetLanIndicator(0);
pChip->Config.DetectedMediaType = MEDIA_NONE;
pChip->Config.CurrentDuplexMode = DUPLEX_NONE;
PurgeTransmitQueue( pChip );
pData->TransmitInProgress = FALSE;
VpsMediaChanged( pChip );
VominiDelay( 2L );
//@drs 5-17-99 VchipReset( pChip );
///--- When we get Net Disonnected Status , Notice Shell the Message.
///--- Use wParam 1 for connect Message, 0 for disconnected Message.
PostShellWindowMessage(WM_BIT_NETCONNECTED,0,0);
}
/* Reset the TransmitStarted flag */
pData->TransmitStarted = FALSE;
VominiStartTimer( pChip, VchipDetectMediaDaemon, 2500, &pData->DetectMediaTimer, NULL );
PRINTDEBUGMSG(1, (TEXT("<==CS8900:VchipDetectMediaDaemon\r\n")));
}
/*++
Routine Description:
This routine tests the basic functionality of the chip. It transmits a
predefined packet and then polls the chip for a valid receive. If
Successful then it returns True indicating that the chip is functional.
Return Value:
TRUE or FALSE
--*/
BOOLEAN CrystalTestInternalLoopBack( PCHIP pChip )
{
#define CRYSTAL_INTERNAL_LOOPBACK_DATA_SIZE 1514
WORD Data;
WORD LineControl;
DWORD i = 0;
PWORD EthernetAddress;
PRINTDEBUGMSG(1, (TEXT("==>CS8900:CrystalTestInternalLoopBack\r\n")));
//
// Read the LineControl register
//
// @jla waste this stupid subroutine
PRINTDEBUGMSG(1, (TEXT("<==CS8900:CrystalTestInternalLoopBack\r\n")));
return CHIP_SUCCESS;
LineControl = ReadPacketPage(CRYSTAL_LINE_CONTROL_REGISTER);
WritePacketPage(CRYSTAL_LINE_CONTROL_REGISTER, 0);
//
// Set the RX_OK_ACCEPT+RX_IA_ACCEPT+RX_RUNT_ACCEPT in RX_CTL_REG
//
WritePacketPage(CRYSTAL_RX_CONTROL_REGISTER, CRYSTAL_RCR_RX_IA_ACCEPT |
CRYSTAL_RCR_RX_RUNT_ACCEPT|
CRYSTAL_RCR_RX_OK_ACCEPT );
//
// Write our address to the chip.
//
/* Put Ethernet address into the Individual Address register */
for (i=0; i<ETH_LENGTH_OF_ADDRESS/2; i++ )
WritePacketPage((WORD)(CRYSTAL_INDIVIDUAL_ADDRESS+(i*2)), pChip->Config.EthernetAddr.Part[i]);
//
// Enable loopback bits in the TEST_CTL register i.e. FDX_ON and ENDEC
// LOOPBACK
//
WritePacketPage(CRYSTAL_TEST_CONTROL_REGISTER, CRYSTAL_TCR_ENDEC_LOOPBACK |
CRYSTAL_TCR_FULL_DUPLEX_ON |
CRYSTAL_TCR_LINK_OFF );
//
// Set the serial transmit and receive on.
//
Data = ReadPacketPage(CRYSTAL_LINE_CONTROL_REGISTER);
WritePacketPage(CRYSTAL_LINE_CONTROL_REGISTER, Data |
CRYSTAL_LCR_SERIAL_RX_ON |
CRYSTAL_LCR_SERIAL_TX_ON );
VominiDelay( 1);
//
// Now bid for transmit and then transmit pattern
//
v_pCS8900Regs->TXCMD = CRYSTAL_TCR_TX_START_ALL_BYTES;
v_pCS8900Regs->TXLENGTH = CRYSTAL_INTERNAL_LOOPBACK_DATA_SIZE;
//
// Loop till you get READY_FOR_TRANSMIT_NOW on
//
for (i=0; i <100; 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) != CRYSTAL_BSR_READY_FOR_TRANSMIT_NOW )
return CHIP_FAILURE;
//
// Write the destination address (which is same as source ) on the chip
//
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++;
//
// Write the transmit packet to the chip.
//
for (i = 0; i < (CRYSTAL_INTERNAL_LOOPBACK_DATA_SIZE-(ETH_LENGTH_OF_ADDRESS*2))/2; i++)
v_pCS8900Regs->DATA0 = (WORD)0x55AA;
VominiDelay( 1);
//
// Poll for the Transmit Ok
//
for (i=0; i<100; i++)
{
Data = ReadPacketPage(CRYSTAL_TX_EVENT_REGISTER);
if ( Data & CRYSTAL_TER_PACKET_TRANSMITTED_OK)
break;
VominiDelay( 3);
}
if ( (Data & CRYSTAL_TER_PACKET_TRANSMITTED_OK) != CRYSTAL_TER_PACKET_TRANSMITTED_OK)
{
//
// Couldn't get TX_OK return false
//
return CHIP_FAILURE;
}
//
// Poll for the receive event
//
for (i=0; i< 100; i++)
{
Data = ReadPacketPage(CRYSTAL_RX_EVENT_REGISTER);
if (Data & CRYSTAL_RER_PACKET_RECEIVED_OK)
break;
VominiDelay( 1);
}
if ((Data & CRYSTAL_RER_PACKET_RECEIVED_OK) != CRYSTAL_RER_PACKET_RECEIVED_OK)
{
//
// Couldn't get RX_OK return false
//
return CHIP_FAILURE;
}
//
// Now read the received legth if less then bad receive
//
Data = ReadPacketPage(CRYSTAL_RECEIVE_LENGTH);
//
// If received data size does not match the transmitted data size
// it is not the same transmitted packet.
// Added 4 if CRC enabled.
//
if (Data != CRYSTAL_INTERNAL_LOOPBACK_DATA_SIZE)
return CHIP_FAILURE;
//
// Validate the destination address (it must be ours)
//
for (i = 0; i < ETH_LENGTH_OF_ADDRESS/2 ; i++)
{
Data = v_pCS8900Regs->DATA0;
if ( Data != pChip->Config.EthernetAddr.Part[i] )
return CHIP_FAILURE;
}
//
// Validate the source address (it must be ours)
//
for (i = 0; i < ETH_LENGTH_OF_ADDRESS/2 ; i++)
{
Data = v_pCS8900Regs->DATA0;
if ( Data != pChip->Config.EthernetAddr.Part[i] )
return CHIP_FAILURE;
}
//
// Now validate the receive bits
//
for (i = 0; i < (CRYSTAL_INTERNAL_LOOPBACK_DATA_SIZE-(ETH_LENGTH_OF_ADDRESS*2))/2; i++)
{
Data = v_pCS8900Regs->DATA0;
if (Data != 0x55AA)
return CHIP_FAILURE;
}
//
// Restore the serial transmit and receive.
//
WritePacketPage(CRYSTAL_LINE_CONTROL_REGISTER, LineControl);
VominiDelay( 75 );
return CHIP_SUCCESS;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -