summaryrefslogtreecommitdiffstats
path: root/sys/dev/sn
diff options
context:
space:
mode:
authorobrien <obrien@FreeBSD.org>2003-11-13 20:55:53 +0000
committerobrien <obrien@FreeBSD.org>2003-11-13 20:55:53 +0000
commitae5ec4308110fc11464507f63b5d9a1908a426b8 (patch)
tree9f53fad8ba546c1e709992d118c397465dd5b01f /sys/dev/sn
parenta9128aec4ed6ce7c8d433530c6899775e94045d0 (diff)
downloadFreeBSD-src-ae5ec4308110fc11464507f63b5d9a1908a426b8.zip
FreeBSD-src-ae5ec4308110fc11464507f63b5d9a1908a426b8.tar.gz
Try to create some sort of consistency in how the routings to find the
multicast hash are written. There are still two distinct algorithms used, and there actually isn't any reason each driver should have its own copy of this function as they could all share one copy of it (if it grew an additional argument).
Diffstat (limited to 'sys/dev/sn')
-rw-r--r--sys/dev/sn/if_sn.c31
1 files changed, 16 insertions, 15 deletions
diff --git a/sys/dev/sn/if_sn.c b/sys/dev/sn/if_sn.c
index 5d5c05c..90a3d46 100644
--- a/sys/dev/sn/if_sn.c
+++ b/sys/dev/sn/if_sn.c
@@ -134,7 +134,7 @@ static void snwatchdog(struct ifnet *);
static void sn_setmcast(struct sn_softc *);
static int sn_getmcf(struct arpcom *ac, u_char *mcf);
-static u_int sn_crc(u_char *);
+static u_int32_t sn_mchash(caddr_t);
/* I (GB) have been unlucky getting the hardware padding
* to work properly.
@@ -1440,7 +1440,8 @@ sn_getmcf(struct arpcom *ac, uint8_t *mcf)
TAILQ_FOREACH(ifma, &ac->ac_if.if_multiaddrs, ifma_link) {
if (ifma->ifma_addr->sa_family != AF_LINK)
return 0;
- index = sn_crc(LLADDR((struct sockaddr_dl *)ifma->ifma_addr)) & 0x3f;
+ index = sn_mchash(
+ LLADDR((struct sockaddr_dl *)ifma->ifma_addr)) & 0x3f;
index2 = 0;
for (i = 0; i < 6; i++) {
index2 <<= 1;
@@ -1452,21 +1453,21 @@ sn_getmcf(struct arpcom *ac, uint8_t *mcf)
return 1; /* use multicast filter */
}
-static u_int
-sn_crc(u_char *s)
+static u_int32_t
+sn_mchash(caddr_t addr)
{
- int perByte;
- int perBit;
const uint32_t poly = 0xedb88320;
- uint32_t v = 0xffffffff;
- uint8_t c;
-
- for (perByte = 0; perByte < ETHER_ADDR_LEN; perByte++) {
- c = s[perByte];
- for (perBit = 0; perBit < 8; perBit++) {
- v = (v >> 1)^(((v ^ c) & 0x01) ? poly : 0);
- c >>= 1;
+ u_int32_t crc;
+ int idx, bit;
+ u_int8_t data;
+
+ /* Compute CRC for the address value. */
+ crc = 0xFFFFFFFF; /* initial value */
+
+ for (idx = 0; idx < ETHER_ADDR_LEN; idx++) {
+ for (data = *addr++, bit = 0; bit < 8; bit++, data >>= 1) {
+ crc = (crc >> 1)^(((crc ^ data) & 0x01) ? poly : 0);
}
}
- return v;
+ return crc;
}
OpenPOWER on IntegriCloud