📄 chip.c
字号:
//---------------------------------------------------------------------------
//
// Copyright (C) 1996-2003. Unpublished Work of Cirrus Logic Inc.
// 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.
//
//---------------------------------------------------------------------------
/* chip.c - CS8900A VChip Initialization */
#include "cs8900a.h"
#include "cshrd.h"
//#include "bvd1bd.h"
#include "Ind.h"
extern volatile CS8900_REGS *v_pCS8900Regs;
/******************************************************************************
*
* VchipStartup()
*
******************************************************************************/
WORD VchipStartup( PCHIP pChip )
{
PCD pData;
WORD Result;
// P_IND_CTRL pIndicatorLightAddr = (P_IND_CTRL)(INDICATOR_LIGHT_BASE_U_VIRTUAL); //cs4
// P_IND_CTRL pIndicatorLightAddr = (P_IND_CTRL)(ETHERNET_CS8900_BASE_U_VIRTUAL); //cs2,dlp
PRINTDEBUGMSG(1, (TEXT("==>CS8900:VchipStartup\r\n")));
pData = pChip->pData;
/* Initialize configuration flags to zero */
pData->ConfigFlags = 0;
PRINTDEBUGMSG(1, (TEXT("dlp#: ******001\r\n")));
//dlp WAIT_FOR_WRITE_SIG( pIndicatorLightAddr );
PRINTDEBUGMSG(1, (TEXT("dlp#: ******002\r\n")));
// pIndicatorLightAddr->control |= LAN_ENABLE_BIT;
Result = VchipReset( pChip ); //@drsa
if ( Result != CHIP_SUCCESS ) //@drsa
{ //@drsa
PRINTDEBUGMSG(1, (TEXT("<==CS8900:VchipStartup 1 Result = 0x%x\r\n"), Result));
return Result; //@drsa
} //@drsa
// @kml 6/30/99 Wait for the LinkOK bit in Line Control Reg.
VominiDelay(100);
PRINTDEBUGMSG(1, (TEXT("dlp#: ******003\r\n")));
#if 0
DetectMedia( pChip );
while ( pChip->Config.DetectedMediaType == MEDIA_PENDING )
{
if (pChip->Config.CurrentDuplexMode == DUPLEX_PENDING)
{
// @kml Auto Config Duplex mode
VominiDelay( 2500 );
}
else
{
// @kml 6/30/99 quick init time when in Force Full or Half Duplex mode
VominiDelay( 100 );
}
DetectMedia( pChip );
}
if ( pChip->Config.DetectedMediaType != MEDIA_NONE )
{
if ( pChip->Config.DetectedMediaType != MEDIA_BASE_T )
{
Result = VchipReset( pChip ); //@rosa avoids pending receives
if ( Result != CHIP_SUCCESS ) //@rosa
{
PRINTDEBUGMSG(1, (TEXT("<==CS8900:VchipStartup 2 Result = 0x%x\r\n"), Result));
return Result; //@rosa
}
}
/* Initialize the chip */
Result = VchipInit( pChip );
if ( Result != CHIP_SUCCESS )
{
PRINTDEBUGMSG(1, (TEXT("<==CS8900:VchipStartup 3 Result = 0x%x\r\n"), Result));
return Result;
}
}
#else
/* Initialize the chip */
Result = VchipInit( pChip );
if ( Result != CHIP_SUCCESS )
{
PRINTDEBUGMSG(1, (TEXT("<==CS8900:VchipStartup 3 Result = 0x%x\r\n"), Result));
return Result;
}
#endif
/* Must start Timer routine to detect cable Status */
Result = VominiStartTimer( pChip, VchipDetectMediaDaemon, 2500,
&pData->DetectMediaTimer, NULL );
if ( Result != CHIP_SUCCESS )
{
PRINTDEBUGMSG(1, (TEXT("<==CS8900:VchipStartup 4 Result = 0x%x\r\n"), Result));
return Result;
}
PRINTDEBUGMSG(1, (TEXT("<==CS8900:VchipStartup SUCCESS\r\n")));
return CHIP_SUCCESS;
}
/******************************************************************************
*
* VchipInit()
*
* Note: This driver does not support memory mode.
*
******************************************************************************/
WORD VchipInit( PCHIP pChip )
{
PCD pData;
PRINTDEBUGMSG(1, (TEXT("==>CS8900:VchipInit\r\n")));
pData = pChip->pData;
/*
if (( pChip->Config.DetectedMediaType == MEDIA_PENDING ) ||
( pChip->Config.DetectedMediaType == MEDIA_NONE ))
{
PRINTDEBUGMSG(1, (TEXT("<==CS8900:VchipInit 1 SUCCESS\r\n")));
return CHIP_SUCCESS;
}*/
pData->TransmitBidPending = FALSE;
pData->TransmitInProgress = FALSE;
pData->TransmitThresholdCount = 0;
pData->TransmitStarted = FALSE;
pData->StartTX = FALSE;
pData->TransmitCommand = CRYSTAL_TCR_TX_START_381_BYTES;
pData->CurrentReceiveConfiguration = CRYSTAL_DEFAULT_RX_CONFIG_VALUE;
InitQueues( pChip );
WritePacketPage( CRYSTAL_LINE_CONTROL_REGISTER, CRYSTAL_LCR_DEFAULT_VALUE );
/* Initialize the config and control registers */
WritePacketPage( CRYSTAL_RX_CONFIG_REGISTER, CRYSTAL_DEFAULT_RX_CONFIG_VALUE );
WritePacketPage( CRYSTAL_RX_CONTROL_REGISTER, CRYSTAL_RCR_DEFAULT_VALUE );
WritePacketPage( CRYSTAL_TX_CONFIG_REGISTER, CRYSTAL_TCR_DEFAULT_VALUE);
WritePacketPage( CRYSTAL_BUFFER_CONFIG_REGISTER, CRYSTAL_BCR_DEFAULT_VALUE);
/* Setup initial filtering criteria */
VchipChangeFiltering( pChip );
/* The INTRQ pin number is independent from pChip->Config.IntLine.
Write the INTRQ pin number which is connected to Processor to CS8900's register.*/
WritePacketPage( CRYSTAL_ISA_INTERRUPT_NUMBER, CS8900_INTERRUPT_REQUEST_PIN_NUM );
/* Enable reception and transmission of frames */
WritePacketPage( CRYSTAL_LINE_CONTROL_REGISTER,
(WORD)(ReadPacketPage( CRYSTAL_LINE_CONTROL_REGISTER) |
CRYSTAL_LCR_SERIAL_RX_ON | CRYSTAL_LCR_SERIAL_TX_ON) );
/* Enable interrupt at the chip */
VchipEnableInterrupts( pChip );
PRINTDEBUGMSG(1, (TEXT("<==CS8900:VchipInit 2 SUCCESS\r\n")));
return CHIP_SUCCESS;
}
/******************************************************************************
*
* InitQueues()
*
******************************************************************************/
void InitQueues( PCHIP pChip )
{
PCD pData = pChip->pData;
PRINTDEBUGMSG(1, (TEXT("==>CS8900:InitQueues\r\n")));
pData->TransmitQueue.Head = pData->TransmitQueue.Tail = NULL;
PRINTDEBUGMSG(1, (TEXT("<==CS8900:InitQueues\r\n")));
}
/******************************************************************************
*
* VchipReset()
*
******************************************************************************/
WORD VchipReset( PCHIP pChip )
{
PCD pData;
int x;
PRINTDEBUGMSG(1, (TEXT("==>CS8900:VchipReset\r\n")));
pData = pChip->pData;
/* We are now resetting the chip */
/* A spurious interrupt is generated by the chip when it is reset. */
/* This variable informs the interrupt handler to ignore this interrupt. */
pData->Resetting = TRUE;
/* Issue a reset command to the chip */
WritePacketPage( CRYSTAL_SELF_CONTROL_REGISTER, CRYSTAL_SCR_POWER_ON_RESET );
/* Delay for 20 milliseconds */
VominiDelay( 20 );
/* Wait until the EEPROM is not busy */
for ( x=0; x<MAXLOOP; x++ )
if ( !(ReadPacketPage(CRYSTAL_SELF_STATUS_REGISTER) & CRYSTAL_SSR_SI_BUSY) )
break;
if ( x == MAXLOOP )
{
PRINTDEBUGMSG(1, (TEXT("<==CS8900:VchipReset CHIP_FAILURE 1\r\n")));
return CHIP_FAILURE;
}
/* Wait until initialization is done */
for ( x=0; x<MAXLOOP; x++ )
if ( ReadPacketPage(CRYSTAL_SELF_STATUS_REGISTER) & CRYSTAL_SSR_INIT_DONE )
break;
if ( x == MAXLOOP )
{
PRINTDEBUGMSG(1, (TEXT("<==CS8900:VchipReset CHIP_FAILURE 2\r\n")));
return CHIP_FAILURE;
}
/* Reset is no longer in progress */
pData->Resetting = FALSE;
PRINTDEBUGMSG(1, (TEXT("<==CS8900:VchipReset CHIP_SUCCESS\r\n")));
return CHIP_SUCCESS;
}
/******************************************************************************
*
* VchipShutdown()
*
******************************************************************************/
void VchipShutdown( PCHIP pChip )
{
PCD pData;
WORD SelfStatus;
PRINTDEBUGMSG(1, (TEXT("==>CS8900:VchipShutdown\r\n")));
pData = pChip->pData;
VominiStopTimer( pChip, pData->DetectMediaTimer );
VchipReset( pChip );
/* Read the self status register */
SelfStatus = ReadPacketPage( CRYSTAL_SELF_STATUS_REGISTER );
PRINTDEBUGMSG(1, (TEXT("<==CS8900:VchipShutdown\r\n")));
}
/******************************************************************************
*
* VchipTest()
*
******************************************************************************/
void VchipTest( PCHIP pChip )
{
WORD BuffConfig;
PRINTDEBUGMSG(1, (TEXT("==>CS8900:VchipTest\r\n")));
/* Generate a software initiated interrupt */
BuffConfig = ReadPacketPage( CRYSTAL_BUFFER_CONFIG_REGISTER );
BuffConfig |= CRYSTAL_BCR_GENERATE_SW_INTERRUPT;
WritePacketPage( CRYSTAL_BUFFER_CONFIG_REGISTER, BuffConfig );
PRINTDEBUGMSG(1, (TEXT("<==CS8900:VchipTest\r\n")));
}
/******************************************************************************
*
* ReadPacketPage()
*
******************************************************************************/
WORD ReadPacketPage( WORD Offset )
{
v_pCS8900Regs->PAGEIX = Offset;
return v_pCS8900Regs->PAGE0;
}
/******************************************************************************
*
* WritePacketPage()
*
******************************************************************************/
void WritePacketPage( WORD Offset, WORD Value )
{
v_pCS8900Regs->PAGEIX = Offset;
v_pCS8900Regs->PAGE0 = Value;
}
NDIS_STATUS VchipFindIOBase( PCHIP pChip)
{
WORD Result;
WORD SelfStatus;
PRINTDEBUGMSG(1, (TEXT("==>CS8900:VchipFindIOBase\r\n")));
/* Read the EISA ID from the packet page */
Result = ReadPacketPage( CRYSTAL_CHIPEISA_ID );
PRINTDEBUGMSG(1, (TEXT("EISA ID = 0x%04x\r\n"), Result));
/* If the EISA ID is for Crystal Semiconductor */
if ( Result == CS89XX_ID )
{
/* Read the product ID from the packet page */
Result = ReadPacketPage( CRYSTAL_PRODUCT_ID );
pChip->Config.ChipType = Result & PRODUCT_ID_MASK;
pChip->Config.ChipRev = Result & REVISION_ID_MASK;
PRINTDEBUGMSG(1, (TEXT("Product ID = 0x%04x\r\n"), Result));
}
else
{
PRINTDEBUGMSG(1, (TEXT("<==CS8900:VchipFindIOBase, FAILURE\r\n")));
return NDIS_STATUS_FAILURE;
}
/* Read the self status register */
SelfStatus = ReadPacketPage( CRYSTAL_SELF_STATUS_REGISTER );
/* If the EEPROM is not present or the EEPROM is not OK,
then sofeware reset the chip. */
pChip->Config.IOBase = ETHERNET_CS8900_BASE_U_VIRTUAL;
pChip->Config.MemoryBase = ETHERNET_CS8900_BASE_U_VIRTUAL;
pChip->Config.IOSize = CRYSTAL_IO_SIZE;
PRINTDEBUGMSG(1, (TEXT("<==CS8900:VchipFindIOBase\r\n")));
return NDIS_STATUS_SUCCESS;
}
extern NDIS_STATUS GetNetworkAddress(IN NDIS_HANDLE ConfigHandle,
OUT PUCHAR CurrentNetworkAddress)
{
USHORT MacAddr[3];
PRINTRETAILMSG(1, (TEXT("==>CS8900:GetNetworkAddress\r\n")));
///important by marsahal
WritePacketPage( CRYSTAL_INDIVIDUAL_ADDRESS + 0, 0x0000 );
WritePacketPage( CRYSTAL_INDIVIDUAL_ADDRESS + 2, 0x5577 );
WritePacketPage( CRYSTAL_INDIVIDUAL_ADDRESS + 4, 0x9bad );
MacAddr[0] = ReadPacketPage(CRYSTAL_INDIVIDUAL_ADDRESS + 0);
MacAddr[1] = ReadPacketPage(CRYSTAL_INDIVIDUAL_ADDRESS + 2);
MacAddr[2] = ReadPacketPage(CRYSTAL_INDIVIDUAL_ADDRESS + 4);
/* MAcAddr=0000:0000:0000 means to use EEPROM setting, so return Failure.*/
if ( MacAddr[0] == 0 &&
MacAddr[1] == 0 &&
MacAddr[2] == 0)
{
return NDIS_STATUS_FAILURE;
}
NdisMoveMemory(CurrentNetworkAddress,
(unsigned char *)MacAddr,
(ULONG) ETH_LENGTH_OF_ADDRESS);
PRINTRETAILMSG(1, (TEXT("<==CS8900:GetNetworkAddress\r\n")));
return NDIS_STATUS_SUCCESS;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -