www.pudn.com > 2410winceCE_l80t64.rar > FLTR.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.
//
//---------------------------------------------------------------------------
/* vc20fltr.c - CS8900 VChip filtering */
#include "cs8900a.h"
#include "cshrd.h"
/* External Prototypes */
WORD ReadPacketPage( PCHIP pChip, PORT IOBase, WORD Offset );
void WritePacketPage( PCHIP pChip, PORT IOBase, WORD Offset, WORD Value );
/******************************************************************************
*
* CalculateHashIndex()
*
******************************************************************************/
BYTE CalculateHashIndex( BYTE *pMulticastAddr )
{
DWORD CRC;
BYTE HashIndex;
BYTE AddrByte;
DWORD HighBit;
int Byte;
int Bit;
/* Prime the CRC */
CRC = CRC_PRIME;
/* For each of the six bytes of the multicast address */
for ( Byte=0; Byte<6; Byte++ )
{
AddrByte = *pMulticastAddr++;
/* For each bit of the byte */
for ( Bit=8; Bit>0; Bit-- )
{
HighBit = CRC >> 31;
CRC <<= 1;
if ( HighBit ^ (AddrByte & 1) )
{
CRC ^= CRC_POLYNOMIAL;
CRC |= 1;
}
AddrByte >>= 1;
}
}
/* Take the least significant six bits of the CRC and copy them */
/* to the HashIndex in reverse order. */
for( Bit=0,HashIndex=0; Bit<6; Bit++ )
{
HashIndex <<= 1;
HashIndex |= (BYTE)(CRC & 1);
CRC >>= 1;
}
return HashIndex;
}
/******************************************************************************
*
* SetMulticastTable()
*
******************************************************************************/
void SetMulticastTable( PCHIP pChip, PWORD McastHashTable )
{
PORT IOBase = pChip->Config.IOBase;
WORD i;
for(i=0; i < 4; i++)
{
NdisRawWritePortUshort((PORT)(IOBase+CRYSTAL_ADDRESS_PORT),
CRYSTAL_LOGICAL_ADDRESS_FILTER+i*2 );
NdisRawWritePortUshort((PORT)(IOBase+CRYSTAL_DATA_PORT), *McastHashTable++);
}
}
/******************************************************************************
*
* GetMulticastTable()
*
******************************************************************************/
void GetMulticastTable( PCHIP pChip, WORD *McastHashTable )
{
PORT IOBase = pChip->Config.IOBase;
WORD i;
for(i=0; i < 4; i++)
{
NdisRawWritePortUshort((PORT)(IOBase+CRYSTAL_ADDRESS_PORT),
CRYSTAL_LOGICAL_ADDRESS_FILTER+i*2 );
NdisRawReadPortUshort((PORT)(IOBase+CRYSTAL_DATA_PORT), McastHashTable++);
}
}
/******************************************************************************
*
* VchipMulticastDeleteAll()
*
******************************************************************************/
void VchipMulticastDeleteAll( PCHIP pChip )
{
PORT IOBase;
WORD McastHashTable[4] = {0,0,0,0};
WORD LineControl;
IOBase = pChip->Config.IOBase;
/* Turn the receiver off while changing filtering criteria */
LineControl = ReadPacketPage( pChip, IOBase, CRYSTAL_LINE_CONTROL_REGISTER );
WritePacketPage( pChip, IOBase, CRYSTAL_LINE_CONTROL_REGISTER,
(WORD)(LineControl & ~CRYSTAL_LCR_SERIAL_RX_ON) );
SetMulticastTable( pChip, McastHashTable );
/* Turn the receiver back on */
WritePacketPage( pChip, IOBase, CRYSTAL_LINE_CONTROL_REGISTER, LineControl );
};
/******************************************************************************
*
* VchipMulticastAdd()
*
******************************************************************************/
void VchipMulticastAdd( PCHIP pChip, PEA pMulticastAddr )
{
PORT IOBase;
WORD McastHashTable[4];
WORD LineControl;
BYTE HashIndex;
IOBase = pChip->Config.IOBase;
/* Turn the receiver off while changing filtering criteria */
LineControl = ReadPacketPage( pChip, IOBase, CRYSTAL_LINE_CONTROL_REGISTER );
WritePacketPage( pChip, IOBase, CRYSTAL_LINE_CONTROL_REGISTER,
(WORD)(LineControl & ~CRYSTAL_LCR_SERIAL_RX_ON) );
GetMulticastTable( pChip, (PWORD)&McastHashTable );
HashIndex = CalculateHashIndex((PBYTE)pMulticastAddr);
McastHashTable[HashIndex/16] |= 1 << (HashIndex%16);
SetMulticastTable( pChip, McastHashTable );
/* Turn the receiver back on */
WritePacketPage( pChip, IOBase, CRYSTAL_LINE_CONTROL_REGISTER, LineControl );
};
/******************************************************************************
*
* VchipMulticastDelete()
*
******************************************************************************/
void VchipMulticastDelete( PCHIP pChip, PEA pMulticastAddr )
{
PORT IOBase;
WORD McastHashTable[4];
WORD LineControl;
BYTE HashIndex;
IOBase = pChip->Config.IOBase;
/* Turn the receiver off while changing filtering criteria */
LineControl = ReadPacketPage( pChip, IOBase, CRYSTAL_LINE_CONTROL_REGISTER );
WritePacketPage( pChip, IOBase, CRYSTAL_LINE_CONTROL_REGISTER,
(WORD)(LineControl & ~CRYSTAL_LCR_SERIAL_RX_ON) );
GetMulticastTable( pChip, (PWORD)&McastHashTable );
HashIndex = CalculateHashIndex((PBYTE)pMulticastAddr);
McastHashTable[HashIndex/16] &= (~(1 << (HashIndex%16)));
SetMulticastTable( pChip, McastHashTable );
/* Turn the receiver back on */
WritePacketPage( pChip, IOBase, CRYSTAL_LINE_CONTROL_REGISTER, LineControl );
};
/******************************************************************************
*
* VchipChangeFiltering()
*
******************************************************************************/
void VchipChangeFiltering( PCHIP pChip )
{
PORT IOBase;
WORD LineControl;
WORD RxControl;
IOBase = pChip->Config.IOBase;
/* Turn the receiver off while changing filtering criteria */
LineControl = ReadPacketPage( pChip, IOBase, CRYSTAL_LINE_CONTROL_REGISTER );
WritePacketPage( pChip, IOBase, CRYSTAL_LINE_CONTROL_REGISTER,
(WORD)(LineControl & ~CRYSTAL_LCR_SERIAL_RX_ON) );
/* Get the current setting of the receiver control register */
RxControl = ReadPacketPage( pChip, IOBase, CRYSTAL_RX_CONTROL_REGISTER );
/* Clear the broadcast, multicast and promiscuous bits */
RxControl &= ~(CRYSTAL_RCR_RX_BROADCAST_ACCEPT | CRYSTAL_RCR_RX_IA_ACCEPT |
CRYSTAL_RCR_RX_MULTICAST_ACCEPT | CRYSTAL_RCR_RX_PROM_ACCEPT);
/* Set the specified filtering bits */
if ( pChip->Config.Filtering & FILTER_INDIVIDUAL_ACCEPT )
RxControl |= CRYSTAL_RCR_RX_IA_ACCEPT;
if ( pChip->Config.Filtering & FILTER_BROADCAST_ACCEPT )
RxControl |= CRYSTAL_RCR_RX_BROADCAST_ACCEPT;
if ( pChip->Config.Filtering & FILTER_MULTICAST_ACCEPT )
RxControl |= CRYSTAL_RCR_RX_MULTICAST_ACCEPT;
if ( pChip->Config.Filtering & FILTER_PROMISCUOUS_ACCEPT )
RxControl |= CRYSTAL_RCR_RX_PROM_ACCEPT;
/* Write the new filtering criteria to the receiver control register */
WritePacketPage( pChip, IOBase, CRYSTAL_RX_CONTROL_REGISTER, RxControl );
/* Turn the receiver back on */
WritePacketPage( pChip, IOBase, CRYSTAL_LINE_CONTROL_REGISTER, LineControl );
}
/******************************************************************************
*
* VchipMulticastAddAll()
*
******************************************************************************/
void VchipMulticastAddAll( PCHIP pChip )
{
PORT IOBase;
WORD McastHashTable[4] = {0xffff,0xffff,0xffff,0xffff};
WORD LineControl;
IOBase = pChip->Config.IOBase;
/* Turn the receiver off while changing filtering criteria */
LineControl = ReadPacketPage( pChip, IOBase, CRYSTAL_LINE_CONTROL_REGISTER );
WritePacketPage( pChip, IOBase, CRYSTAL_LINE_CONTROL_REGISTER,
(WORD)(LineControl & ~CRYSTAL_LCR_SERIAL_RX_ON) );
SetMulticastTable( pChip, McastHashTable );
/* Turn the receiver back on */
WritePacketPage( pChip, IOBase, CRYSTAL_LINE_CONTROL_REGISTER, LineControl );
};