error_t xmc4400EthUpdateMacAddrFilter(NetInterface *interface)
{
   uint_t i;
   uint_t j;
   uint_t k;
   uint32_t crc;
   uint32_t hashTable[2];
   MacAddr unicastMacAddr[3];
   MacFilterEntry *entry;

   //Debug message
   TRACE_DEBUG("Updating MAC filter...\r\n");

   //Set the MAC address of the station
   ETH0->MAC_ADDRESS0_LOW = interface->macAddr.w[0] | (interface->macAddr.w[1] << 16);
   ETH0->MAC_ADDRESS0_HIGH = interface->macAddr.w[2];

   //The MAC supports 3 additional addresses for unicast perfect filtering
   unicastMacAddr[0] = MAC_UNSPECIFIED_ADDR;
   unicastMacAddr[1] = MAC_UNSPECIFIED_ADDR;
   unicastMacAddr[2] = MAC_UNSPECIFIED_ADDR;

   //The hash table is used for multicast address filtering
   hashTable[0] = 0;
   hashTable[1] = 0;

   //The MAC address filter contains the list of MAC addresses to accept
   //when receiving an Ethernet frame
   for(i = 0, j = 0; i < MAC_ADDR_FILTER_SIZE; i++)
   {
      //Point to the current entry
      entry = &interface->macAddrFilter[i];

      //Valid entry?
      if(entry->refCount > 0)
      {
         //Multicast address?
         if(macIsMulticastAddr(&entry->addr))
         {
            //Compute CRC over the current MAC address
            crc = xmc4400EthCalcCrc(&entry->addr, sizeof(MacAddr));

            //The upper 6 bits in the CRC register are used to index the
            //contents of the hash table
            k = (crc >> 26) & 0x3F;

            //Update hash table contents
            hashTable[k / 32] |= (1 << (k % 32));
         }
         else
         {
            //Up to 3 additional MAC addresses can be specified
            if(j < 3)
            {
               //Save the unicast address
               unicastMacAddr[j++] = entry->addr;
            }
         }
      }
   }

   //Configure the first unicast address filter
   if(j >= 1)
   {
      //When the AE bit is set, the entry is used for perfect filtering
      ETH0->MAC_ADDRESS1_LOW = unicastMacAddr[0].w[0] | (unicastMacAddr[0].w[1] << 16);
      ETH0->MAC_ADDRESS1_HIGH = unicastMacAddr[0].w[2] | ETH_MAC_ADDRESS1_HIGH_AE_Msk;
   }
   else
   {
      //When the AE bit is cleared, the entry is ignored
      ETH0->MAC_ADDRESS1_LOW = 0;
      ETH0->MAC_ADDRESS1_HIGH = 0;
   }

   //Configure the second unicast address filter
   if(j >= 2)
   {
      //When the AE bit is set, the entry is used for perfect filtering
      ETH0->MAC_ADDRESS2_LOW = unicastMacAddr[1].w[0] | (unicastMacAddr[1].w[1] << 16);
      ETH0->MAC_ADDRESS2_HIGH = unicastMacAddr[1].w[2] | ETH_MAC_ADDRESS2_HIGH_AE_Msk;
   }
   else
   {
      //When the AE bit is cleared, the entry is ignored
      ETH0->MAC_ADDRESS2_LOW = 0;
      ETH0->MAC_ADDRESS2_HIGH = 0;
   }

   //Configure the third unicast address filter
   if(j >= 3)
   {
      //When the AE bit is set, the entry is used for perfect filtering
      ETH0->MAC_ADDRESS3_LOW = unicastMacAddr[2].w[0] | (unicastMacAddr[2].w[1] << 16);
      ETH0->MAC_ADDRESS3_HIGH = unicastMacAddr[2].w[2] | ETH_MAC_ADDRESS3_HIGH_AE_Msk;
   }
   else
   {
      //When the AE bit is cleared, the entry is ignored
      ETH0->MAC_ADDRESS3_LOW = 0;
      ETH0->MAC_ADDRESS3_HIGH = 0;
   }

   //Configure the multicast address filter
   ETH0->HASH_TABLE_LOW = hashTable[0];
   ETH0->HASH_TABLE_HIGH = hashTable[1];

   //Debug message
   TRACE_DEBUG("  HASH_TABLE_LOW = %08" PRIX32 "\r\n", ETH0->HASH_TABLE_LOW);
   TRACE_DEBUG("  HASH_TABLE_HIGH = %08" PRIX32 "\r\n", ETH0->HASH_TABLE_HIGH);

   //Successful processing
   return NO_ERROR;
}
error_t xmc4400EthUpdateMacAddrFilter(NetInterface *interface)
{
   uint_t i;
   uint_t j;
   uint_t k;
   uint32_t crc;
   uint32_t hashTable[2];
   MacAddr unicastMacAddr[3];
   MacFilterEntry *entry;

    
   TRACE_DEBUG("Updating MAC filter...\r\n");

    
   ETH0->MAC_ADDRESS0_LOW = interface->macAddr.w[0] | (interface->macAddr.w[1] << 16);
   ETH0->MAC_ADDRESS0_HIGH = interface->macAddr.w[2];

    
   unicastMacAddr[0] = MAC_UNSPECIFIED_ADDR;
   unicastMacAddr[1] = MAC_UNSPECIFIED_ADDR;
   unicastMacAddr[2] = MAC_UNSPECIFIED_ADDR;

    
   hashTable[0] = 0;
   hashTable[1] = 0;

    
    
   for(i = 0, j = 0; i < MAC_ADDR_FILTER_SIZE; i++)
   {
       
      entry = &interface->macAddrFilter[i];

       
      if(entry->refCount > 0)
      {
          
         if(macIsMulticastAddr(&entry->addr))
         {
             
            crc = xmc4400EthCalcCrc(&entry->addr, sizeof(MacAddr));

             
             
            k = (crc >> 26) & 0x3F;

             
            hashTable[k / 32] |= (1 << (k % 32));
         }
         else
         {
             
            if(j < 3)
            {
                
               unicastMacAddr[j++] = entry->addr;
            }
         }
      }
   }

    
   if(j >= 1)
   {
       
      ETH0->MAC_ADDRESS1_LOW = unicastMacAddr[0].w[0] | (unicastMacAddr[0].w[1] << 16);
      ETH0->MAC_ADDRESS1_HIGH = unicastMacAddr[0].w[2] | ETH_MAC_ADDRESS1_HIGH_AE_Msk;
   }
   else
   {
       
      ETH0->MAC_ADDRESS1_LOW = 0;
      ETH0->MAC_ADDRESS1_HIGH = 0;
   }

    
   if(j >= 2)
   {
       
      ETH0->MAC_ADDRESS2_LOW = unicastMacAddr[1].w[0] | (unicastMacAddr[1].w[1] << 16);
      ETH0->MAC_ADDRESS2_HIGH = unicastMacAddr[1].w[2] | ETH_MAC_ADDRESS2_HIGH_AE_Msk;
   }
   else
   {
       
      ETH0->MAC_ADDRESS2_LOW = 0;
      ETH0->MAC_ADDRESS2_HIGH = 0;
   }

    
   if(j >= 3)
   {
       
      ETH0->MAC_ADDRESS3_LOW = unicastMacAddr[2].w[0] | (unicastMacAddr[2].w[1] << 16);
      ETH0->MAC_ADDRESS3_HIGH = unicastMacAddr[2].w[2] | ETH_MAC_ADDRESS3_HIGH_AE_Msk;
   }
   else
   {
       
      ETH0->MAC_ADDRESS3_LOW = 0;
      ETH0->MAC_ADDRESS3_HIGH = 0;
   }

    
   ETH0->HASH_TABLE_LOW = hashTable[0];
   ETH0->HASH_TABLE_HIGH = hashTable[1];

    
   TRACE_DEBUG("  HASH_TABLE_LOW = %08" PRIX32 "\r\n", ETH0->HASH_TABLE_LOW);
   TRACE_DEBUG("  HASH_TABLE_HIGH = %08" PRIX32 "\r\n", ETH0->HASH_TABLE_HIGH);

    
   return NO_ERROR;
}