Changeset View
Changeset View
Standalone View
Standalone View
sys/dev/hme/if_hme.c
Show First 20 Lines • Show All 1,650 Lines • ▼ Show 20 Lines | hme_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) | ||||
default: | default: | ||||
error = ether_ioctl(ifp, cmd, data); | error = ether_ioctl(ifp, cmd, data); | ||||
break; | break; | ||||
} | } | ||||
return (error); | return (error); | ||||
} | } | ||||
static u_int | |||||
hme_hash_maddr(void *arg, struct sockaddr_dl *sdl, u_int cnt) | |||||
{ | |||||
uint32_t crc, *hash = arg; | |||||
crc = ether_crc32_le(LLADDR(sdl), ETHER_ADDR_LEN); | |||||
/* Just want the 6 most significant bits. */ | |||||
crc >>= 26; | |||||
/* Set the corresponding bit in the filter. */ | |||||
hash[crc >> 4] |= 1 << (crc & 0xf); | |||||
return (1); | |||||
} | |||||
/* | /* | ||||
* Set up the logical address filter. | * Set up the logical address filter. | ||||
*/ | */ | ||||
static void | static void | ||||
hme_setladrf(struct hme_softc *sc, int reenable) | hme_setladrf(struct hme_softc *sc, int reenable) | ||||
{ | { | ||||
struct ifnet *ifp = sc->sc_ifp; | struct ifnet *ifp = sc->sc_ifp; | ||||
struct ifmultiaddr *inm; | |||||
u_int32_t crc; | |||||
u_int32_t hash[4]; | u_int32_t hash[4]; | ||||
u_int32_t macc; | u_int32_t macc; | ||||
HME_LOCK_ASSERT(sc, MA_OWNED); | HME_LOCK_ASSERT(sc, MA_OWNED); | ||||
/* Clear the hash table. */ | /* Clear the hash table. */ | ||||
hash[3] = hash[2] = hash[1] = hash[0] = 0; | hash[3] = hash[2] = hash[1] = hash[0] = 0; | ||||
/* Get the current RX configuration. */ | /* Get the current RX configuration. */ | ||||
Show All 40 Lines | hme_setladrf(struct hme_softc *sc, int reenable) | ||||
/* | /* | ||||
* Set up multicast address filter by passing all multicast addresses | * Set up multicast address filter by passing all multicast addresses | ||||
* through a crc generator, and then using the high order 6 bits as an | * through a crc generator, and then using the high order 6 bits as an | ||||
* index into the 64 bit logical address filter. The high order bit | * index into the 64 bit logical address filter. The high order bit | ||||
* selects the word, while the rest of the bits select the bit within | * selects the word, while the rest of the bits select the bit within | ||||
* the word. | * the word. | ||||
*/ | */ | ||||
if_foreach_llmaddr(ifp, hme_hash_maddr, &hash); | |||||
if_maddr_rlock(ifp); | |||||
CK_STAILQ_FOREACH(inm, &ifp->if_multiaddrs, ifma_link) { | |||||
if (inm->ifma_addr->sa_family != AF_LINK) | |||||
continue; | |||||
crc = ether_crc32_le(LLADDR((struct sockaddr_dl *) | |||||
inm->ifma_addr), ETHER_ADDR_LEN); | |||||
/* Just want the 6 most significant bits. */ | |||||
crc >>= 26; | |||||
/* Set the corresponding bit in the filter. */ | |||||
hash[crc >> 4] |= 1 << (crc & 0xf); | |||||
} | |||||
if_maddr_runlock(ifp); | |||||
chipit: | chipit: | ||||
/* Now load the hash table into the chip */ | /* Now load the hash table into the chip */ | ||||
HME_MAC_WRITE_4(sc, HME_MACI_HASHTAB0, hash[0]); | HME_MAC_WRITE_4(sc, HME_MACI_HASHTAB0, hash[0]); | ||||
HME_MAC_WRITE_4(sc, HME_MACI_HASHTAB1, hash[1]); | HME_MAC_WRITE_4(sc, HME_MACI_HASHTAB1, hash[1]); | ||||
HME_MAC_WRITE_4(sc, HME_MACI_HASHTAB2, hash[2]); | HME_MAC_WRITE_4(sc, HME_MACI_HASHTAB2, hash[2]); | ||||
HME_MAC_WRITE_4(sc, HME_MACI_HASHTAB3, hash[3]); | HME_MAC_WRITE_4(sc, HME_MACI_HASHTAB3, hash[3]); | ||||
if (!hme_mac_bitflip(sc, HME_MACI_RXCFG, macc, 0, | if (!hme_mac_bitflip(sc, HME_MACI_RXCFG, macc, 0, | ||||
macc & (HME_MAC_RXCFG_ENABLE | HME_MAC_RXCFG_HENABLE | | macc & (HME_MAC_RXCFG_ENABLE | HME_MAC_RXCFG_HENABLE | | ||||
HME_MAC_RXCFG_ME))) | HME_MAC_RXCFG_ME))) | ||||
device_printf(sc->sc_dev, "cannot configure RX MAC\n"); | device_printf(sc->sc_dev, "cannot configure RX MAC\n"); | ||||
} | } |