summaryrefslogtreecommitdiffstats
path: root/sys/dev/sn/if_sn.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/sn/if_sn.c')
-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