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 ); 
};