Fix multicast hashes.

Atmel uses a simple xor hash instead of the typical crc based one.
This commit is contained in:
Bernd Walter 2010-02-28 16:11:13 +00:00
parent b974b08f1d
commit 31e94ae09f

View File

@ -380,6 +380,20 @@ ate_load_rx_buf(void *arg, bus_dma_segment_t *segs, int nsegs, int error)
bus_dmamap_sync(sc->rxtag, sc->rx_map[i], BUS_DMASYNC_PREREAD);
}
static uint32_t
ate_mac_hash(const uint8_t *buf)
{
uint32_t index = 0;
uint8_t bit;
uint8_t bitshift;
for (int i = 0; i < 48; i++) {
bit = i / 6;
bitshift = i - bit * 6;
index ^= ((buf[i >> 3] >> (i & 7)) & 1) << bitshift;
}
return (index);
}
/*
* Compute the multicast filter for this device using the standard
* algorithm. I wonder why this isn't in ether somewhere as a lot
@ -414,8 +428,9 @@ ate_setmcast(struct ate_softc *sc)
TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
if (ifma->ifma_addr->sa_family != AF_LINK)
continue;
index = ether_crc32_be(LLADDR((struct sockaddr_dl *)
ifma->ifma_addr), ETHER_ADDR_LEN) >> 26;
index = 0;
index = ate_mac_hash(LLADDR((struct sockaddr_dl *)
ifma->ifma_addr));
af[index >> 3] |= 1 << (index & 7);
}
if_maddr_runlock(ifp);