+#ifdef MULTICAST
+/*
+ * Setup the logical address filter
+ */
+void
+lesetladrf(sc)
+ register struct le_softc *sc;
+{
+ register volatile struct lereg2 *ler2 = sc->sc_r2;
+ register struct ifnet *ifp = &sc->sc_if;
+ register struct ether_multi *enm;
+ register u_char *cp;
+ register u_long crc;
+ register u_long c;
+ register int i, len;
+ struct ether_multistep step;
+
+ /*
+ * Set up multicast address filter by passing all multicast
+ * addresses through a crc generator, and then using the high
+ * order 6 bits as a index into the 64 bit logical address
+ * filter. The high order two bits select the word, while the
+ * rest of the bits select the bit within the word.
+ */
+
+ ler2->ler2_ladrf[0] = 0;
+ ler2->ler2_ladrf[1] = 0;
+ ifp->if_flags &= ~IFF_ALLMULTI;
+ ETHER_FIRST_MULTI(step, &sc->sc_ac, enm);
+ while (enm != NULL) {
+ if (bcmp((caddr_t)&enm->enm_addrlo,
+ (caddr_t)&enm->enm_addrhi, sizeof(enm->enm_addrlo)) == 0) {
+ /*
+ * We must listen to a range of multicast
+ * addresses. For now, just accept all
+ * multicasts, rather than trying to set only
+ * those filter bits needed to match the range.
+ * (At this time, the only use of address
+ * ranges is for IP multicast routing, for
+ * which the range is big enough to require all
+ * bits set.)
+ */
+ LER2_ladrf0(ler2, 0xff);
+ LER2_ladrf1(ler2, 0xff);
+ LER2_ladrf2(ler2, 0xff);
+ LER2_ladrf3(ler2, 0xff);
+ ifp->if_flags |= IFF_ALLMULTI;
+ return;
+ }
+
+ cp = (unsigned char *)&enm->enm_addrlo;
+ c = *cp;
+ crc = 0xffffffff;
+ len = 6;
+ while (len-- > 0) {
+ c = *cp;
+ for (i = 0; i < 8; i++) {
+ if ((c & 0x01) ^ (crc & 0x01)) {
+ crc >>= 1;
+ crc = crc ^ 0xedb88320;
+ }
+ else
+ crc >>= 1;
+ c >>= 1;
+ }
+ cp++;
+ }
+ /* Just want the 6 most significant bits. */
+ crc = crc >> 26;
+
+ /* Turn on the corresponding bit in the filter. */
+ ler2->ler2_ladrf[crc >> 5] |= 1 << (crc & 0x1f);
+
+ ETHER_NEXT_MULTI(step, enm);
+ }
+}
+#endif
+