📄 chip.c
字号:
for (i=MAX_RETRY; i>0; i--) {
if (!(ReadCs8900Register(PKTPG_SELF_ST) & SELF_ST_SI_BUSY))
break;
}
if (i <= 0)
{
DEBUGMSG(ZONE_INIT, (TEXT("CS8900A readFromEEPROM:: Timeout0.\r\n")));
return FALSE;
}
// Now write to EEPROM Command register
WriteCs8900Register(PKTPG_EEPROM_CMD, (EEPROM_CMD_READ | EEPROMAddress));
// Wait for NO BUSY signal
for (i=MAX_RETRY; i>0; i--)
{
if (!(ReadCs8900Register(PKTPG_SELF_ST) & SELF_ST_SI_BUSY))
break;
}
if (i <= 0)
{
DEBUGMSG(ZONE_INIT, (TEXT("CS8900A readFromEEPROM:: Timeout1.\r\n")));
return FALSE;
}
// Get the data
Value = ReadCs8900Register(PKTPG_EEPROM_DATA);
DEBUGMSG(ZONE_INIT, (TEXT("CS8900A-readFromEEPROM (%x) value:%x\r\n"),EEPROMAddress, Value));
DEBUGMSG(ZONE_FUNCTION, (TEXT("CS8900A: -cs8900aReadFromEEPROM [0x%.8X]\r\n"), Value));
return Value;
}
//------------------------------------------------------------------------------
//
// Function: InterruptChip
//
// This function enables or disables the interrupt of CS8900 chip
//
// Parameters:
// pEthernet
// [in] pointer to the CS8900 structure.
//
// Action
// [in] TRUE indicates interrupt enable. FALSE indicates interrupt disable.
//
// Returns:
// None.
//
//------------------------------------------------------------------------------
void InterruptChip(pCs8900_t pEthernet, WORD Action)
{
WORD Data;
DEBUGMSG(ZONE_FUNCTION, (TEXT("CS8900A: +InterruptChip\r\n")));
EnterCriticalSection (&gCS8900RegCs);
NdisRawWritePortUshort( (unsigned long)&(g_pCS8900Reg->CS8900_PAGE_POINTER), PKTPG_BUS_CTL );
NdisRawReadPortUshort((unsigned long)&(g_pCS8900Reg->CS8900_PAGE_DATA_0), &Data);
if(Action == TRUE)
{
NdisRawWritePortUshort((unsigned long)&(g_pCS8900Reg->CS8900_PAGE_DATA_0),(Data |IRQ_IE));
}
else
{
NdisRawWritePortUshort((unsigned long)&(g_pCS8900Reg->CS8900_PAGE_DATA_0),(Data & (~IRQ_IE)));
}
LeaveCriticalSection (&gCS8900RegCs);
DEBUGMSG(ZONE_FUNCTION, (TEXT("CS8900A: -InterruptChip\r\n")));
}
//------------------------------------------------------------------------------
//
// Function: UpdateMediaConnectStatus
//
// This function updates the status of media.
//
// Parameters:
// pEthernet
// [in] pointer to the CS8900 structure.
//
// CurStatus
// [in] Status of media.
//
// Returns:
// Returns NDIS_STATUS_MEDIA_CONNECT if media is connected.
// Returns NDIS_STATUS_MEDIA_DISCONNECT if media is disconnected.
//
//------------------------------------------------------------------------------
NDIS_STATUS UpdateMediaConnectStatus(pCs8900_t pEthernet, NDIS_STATUS CurStatus)
{
WORD data;
PNDIS_PACKET pNdisPacket;
NDIS_STATUS Status;
DEBUGMSG(ZONE_FUNCTION, (TEXT("CS8900A: +UpdateMediaConnectStatus\r\n")));
data = ReadCs8900Register(PKTPG_LINE_ST);
if(data & LSR_LINKOK)
{
pEthernet->MediaState = NdisMediaStateConnected;
Status = NDIS_STATUS_MEDIA_CONNECT;
}
else
{
pEthernet->MediaState = NdisMediaStateDisconnected;
Status = NDIS_STATUS_MEDIA_DISCONNECT;
}
if(CurStatus != pEthernet->MediaState)
{
if(CurStatus == NdisMediaStateConnected && pEthernet->MediaState == NdisMediaStateDisconnected)
{
RETAILMSG(1, (TEXT("cs8900a: PKTPG_LINE_ST: 0x%8x. removing the packet from queue in UpdateMediaConnectStatus. \r\n"), data));
//
// Remove the packet from the queue.
//
EnterCriticalSection (&gCS8900BufCs);
pNdisPacket = pEthernet->HeadPacket;
while(pNdisPacket != NULL)
{
pEthernet->HeadPacket = RESERVED(pNdisPacket)->Next;
if (pNdisPacket == pEthernet->TailPacket)
{
pEthernet->TailPacket = NULL;
}
NdisMSendComplete(pEthernet->ndisAdapterHandle, pNdisPacket, NDIS_STATUS_SUCCESS);
pNdisPacket = pEthernet->HeadPacket;
}
LeaveCriticalSection (&gCS8900BufCs);
}
if ( pEthernet->CurrentState != NdisHardwareStatusInitializing )
{
NdisMIndicateStatus( pEthernet->ndisAdapterHandle, Status, NULL, 0 );
NdisMIndicateStatusComplete( pEthernet->ndisAdapterHandle );
}
}
DEBUGMSG(ZONE_FUNCTION, (TEXT("CS8900A: -UpdateMediaConnectStatus\r\n")));
return (pEthernet->MediaState);
}
//------------------------------------------------------------------------------
//
// Function: CalculateHashValue
//
// This function calculates the Hash value for multicasting.
//
// Parameters:
// pAddr
// [in] pointer to a ethernet address
//
// Returns:
// Returns the calculated Hash value.
//
//------------------------------------------------------------------------------
UCHAR CalculateHashValue(UCHAR *pAddr)
{
ULONG CRC;
UCHAR HashValue;
UCHAR AddrByte;
int byte, j, DiscardBit;
DEBUGMSG(ZONE_FUNCTION, (TEXT("CS8900A: +CalculateHashValue\r\n")));
CRC = CRC_PRIME;
for(byte=0; byte<ETHER_ADDR_SIZE; byte++)
{
AddrByte = *pAddr++;
// calculation of CRC32 value based on straightfoward CRC implementation
for(j=0; j<8; j++)
{
DiscardBit = ((CRC & 0x80000000) ? 0x01 : 0) ^ ((AddrByte >> j) & 0x01);
CRC <<= 1;
if(DiscardBit)
{
CRC ^= CRC_POLYNOMIAL;
CRC |= DiscardBit;
}
}
}
HashValue = 0;
// Taking the 6 LSB of the CRC result and put it in reverse order
for( j=0; j<6; j++ )
{
HashValue <<= 1;
HashValue |= (UCHAR)((CRC>>j) & 1);
}
DEBUGMSG(ZONE_FUNCTION, (TEXT("CS8900A: -CalculateHashValue [0x%.8X]\r\n"), HashValue));
return HashValue;
}
//------------------------------------------------------------------------------
//
// Function: AddMultiCast
//
// This function adds the Hash value to the Hash table.
//
// Parameters:
// pEthernet
// [in] pointer to the CS8900 structure.
//
// pAddr
// [in] pointer to a ethernet address.
//
// Returns:
// None.
//
//------------------------------------------------------------------------------
void AddMultiCast(pCs8900_t pEthernet, UCHAR *pAddr)
{
UCHAR HashValue;
WORD data;
WORD HashTable[4];
DEBUGMSG(ZONE_FUNCTION, (TEXT("CS8900A: +AddMultiCast\r\n")));
// Turn off the receiver
data = ReadCs8900Register(PKTPG_LINE_CTL);
data &= (~LCR_RX_ON);
WriteCs8900Register(PKTPG_LINE_CTL, data);
ReadMultiCastTable(pEthernet, HashTable);
HashValue = CalculateHashValue(pAddr);
HashTable[HashValue/16] |= 1 << (HashValue%16);
WriteMultiCastTable(pEthernet, HashTable);
// Turn on the receiver
data |= LCR_RX_ON;
WriteCs8900Register(PKTPG_LINE_CTL, data);
DEBUGMSG(ZONE_FUNCTION, (TEXT("CS8900A: -AddMultiCast\r\n")));
}
//------------------------------------------------------------------------------
//
// Function: DeleteMultiCast
//
// This function delete the Hash value from the Hash table.
//
// Parameters:
// pEthernet
// [in] pointer to the CS8900 structure.
//
// pAddr
// [in] pointer to a ethernet address.
//
// Returns:
// None.
//
//------------------------------------------------------------------------------
void DeleteMultiCast(pCs8900_t pEthernet, UCHAR *pAddr)
{
UCHAR HashValue;
WORD data;
WORD HashTable[4];
DEBUGMSG(ZONE_FUNCTION, (TEXT("CS8900A: +DeleteMultiCast\r\n")));
// Turn off the receiver
data = ReadCs8900Register(PKTPG_LINE_CTL);
data &= (~LCR_RX_ON);
WriteCs8900Register(PKTPG_LINE_CTL, data);
ReadMultiCastTable(pEthernet, HashTable);
HashValue = CalculateHashValue(pAddr);
HashTable[HashValue/16] &= (~(1 << (HashValue%16)));
WriteMultiCastTable(pEthernet, HashTable);
// Turn on the receiver
data |= LCR_RX_ON;
WriteCs8900Register(PKTPG_LINE_CTL, data);
DEBUGMSG(ZONE_FUNCTION, (TEXT("CS8900A: -DeleteMultiCast\r\n")));
}
//------------------------------------------------------------------------------
//
// Function: ReadMultiCastTable
//
// This function reads the Hash table.
//
// Parameters:
// pEthernet
// [in] pointer to the CS8900 structure.
//
// pHashTable
// [out] pointer to Hash table array.
//
// Returns:
// None.
//
//------------------------------------------------------------------------------
void ReadMultiCastTable(pCs8900_t pEthernet, WORD *pHashTable)
{
WORD Counter;
DEBUGMSG(ZONE_FUNCTION, (TEXT("CS8900A: +ReadMultiCastTable\r\n")));
for(Counter=0; Counter < 4; Counter++)
{
*pHashTable = ReadCs8900Register(PKTPG_LOG_ADDR+Counter*2);
pHashTable++;
}
DEBUGMSG(ZONE_FUNCTION, (TEXT("CS8900A: -ReadMultiCastTable\r\n")));
}
//------------------------------------------------------------------------------
//
// Function: WriteMultiCastTable
//
// This function writes the Hash table.
//
// Parameters:
// pEthernet
// [in] pointer to the CS8900 structure.
//
// pHashTable
// [out] pointer to Hash table array.
//
// Returns:
// None.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -