// $Header$ // Kernel Version: // VERSION = 2 // PATCHLEVEL = 5 // SUBLEVEL = 50 // EXTRAVERSION = --- 2.5/include/linux/crc32.h 2002-11-04 23:30:16.000000000 +0100 +++ build-2.5/include/linux/crc32.h 2002-12-10 19:15:50.000000000 +0100 @@ -9,9 +9,19 @@ extern u32 crc32_le(u32 crc, unsigned char const *p, size_t len); extern u32 crc32_be(u32 crc, unsigned char const *p, size_t len); +extern u32 bitreverse(u32 in); #define crc32(seed, data, length) crc32_le(seed, (unsigned char const *)data, length) + +/* + * Helpers for hash table generation of ethernet nics: + * + * Ethernet sends the least significant bit of a byte first, thus crc32_le + * is used. The output of crc32_le is bit reversed [most significant bit + * is in bit nr 0], thus it must be reversed before use. Except for + * nics that bit swap the result internally... + */ +#define ether_crc(length, data) bitreverse(crc32_le(~0, data, length)) #define ether_crc_le(length, data) crc32_le(~0, data, length) -#define ether_crc(length, data) crc32_be(~0, data, length) #endif /* _LINUX_CRC32_H */ --- 2.5/lib/crc32.c 2002-11-04 23:30:03.000000000 +0100 +++ build-2.5/lib/crc32.c 2002-12-10 19:16:47.000000000 +0100 @@ -255,6 +255,16 @@ } #endif +u32 bitreverse(u32 x) +{ + x = (x >> 16) | (x << 16); + x = (x >> 8 & 0x00ff00ff) | (x << 8 & 0xff00ff00); + x = (x >> 4 & 0x0f0f0f0f) | (x << 4 & 0xf0f0f0f0); + x = (x >> 2 & 0x33333333) | (x << 2 & 0xcccccccc); + x = (x >> 1 & 0x55555555) | (x << 1 & 0xaaaaaaaa); + return x; +} + /* * A brief CRC tutorial. * @@ -399,16 +409,6 @@ } #endif -static u32 attribute((const)) bitreverse(u32 x) -{ - x = (x >> 16) | (x << 16); - x = (x >> 8 & 0x00ff00ff) | (x << 8 & 0xff00ff00); - x = (x >> 4 & 0x0f0f0f0f) | (x << 4 & 0xf0f0f0f0); - x = (x >> 2 & 0x33333333) | (x << 2 & 0xcccccccc); - x = (x >> 1 & 0x55555555) | (x << 1 & 0xaaaaaaaa); - return x; -} - static void bytereverse(unsigned char *buf, size_t len) { while (len--) { --- 2.5/drivers/net/natsemi.c 2002-11-04 23:30:05.000000000 +0100 +++ build-2.5/drivers/net/natsemi.c 2002-12-10 19:20:01.000000000 +0100 @@ -164,6 +164,7 @@ #include #include #include +#include #include /* Processor type for cache alignment. */ #include #include @@ -1898,44 +1899,6 @@ return &np->stats; } -/** - * dp83815_crc - computer CRC for hash table entries - * - * Note - this is, for some reason, *not* the same function - * as ether_crc_le() or ether_crc(), though it uses the - * same big-endian polynomial. - */ -#define DP_POLYNOMIAL 0x04C11DB7 -static unsigned dp83815_crc(int length, unsigned char *data) -{ - u32 crc; - u8 cur_byte; - u8 msb; - u8 byte, bit; - - crc = ~0; - for (byte=0; byte> 31; - crc <<= 1; - if (msb ^ (cur_byte & 1)) { - crc ^= DP_POLYNOMIAL; - crc |= 1; - } - cur_byte >>= 1; - } - } - crc >>= 23; - - return (crc); -} - - -void set_bit_le(int offset, unsigned char * data) -{ - data[offset >> 3] |= (1 << (offset & 0x07)); -} #define HASH_TABLE 0x200 static void __set_rx_mode(struct net_device *dev) { @@ -1960,9 +1923,8 @@ memset(mc_filter, 0, sizeof(mc_filter)); for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count; i++, mclist = mclist->next) { - set_bit_le( - dp83815_crc(ETH_ALEN, mclist->dmi_addr) & 0x1ff, - mc_filter); + int i = (ether_crc(ETH_ALEN, mclist->dmi_addr) >> 23) & 0x1ff; + mc_filter[i/8] |= (1 << (i & 0x07)); } rx_mode = RxFilterEnable | AcceptBroadcast | AcceptMulticast | AcceptMyPhys;