Changeset View
Changeset View
Standalone View
Standalone View
sys/dev/et/if_et.c
Show First 20 Lines • Show All 1,554 Lines • ▼ Show 20 Lines | if (rb->rb_mbuf != NULL) { | ||||
BUS_DMASYNC_POSTREAD); | BUS_DMASYNC_POSTREAD); | ||||
bus_dmamap_unload(sc->sc_rx_tag, rb->rb_dmap); | bus_dmamap_unload(sc->sc_rx_tag, rb->rb_dmap); | ||||
m_freem(rb->rb_mbuf); | m_freem(rb->rb_mbuf); | ||||
rb->rb_mbuf = NULL; | rb->rb_mbuf = NULL; | ||||
} | } | ||||
} | } | ||||
} | } | ||||
static u_int | |||||
et_hash_maddr(void *arg, struct sockaddr_dl *sdl, u_int cnt) | |||||
{ | |||||
uint32_t h, *hp, *hash = arg; | |||||
h = ether_crc32_be(LLADDR(sdl), ETHER_ADDR_LEN); | |||||
h = (h & 0x3f800000) >> 23; | |||||
hp = &hash[0]; | |||||
if (h >= 32 && h < 64) { | |||||
h -= 32; | |||||
hp = &hash[1]; | |||||
} else if (h >= 64 && h < 96) { | |||||
h -= 64; | |||||
hp = &hash[2]; | |||||
} else if (h >= 96) { | |||||
h -= 96; | |||||
hp = &hash[3]; | |||||
} | |||||
*hp |= (1 << h); | |||||
return (1); | |||||
} | |||||
static void | static void | ||||
et_setmulti(struct et_softc *sc) | et_setmulti(struct et_softc *sc) | ||||
{ | { | ||||
struct ifnet *ifp; | struct ifnet *ifp; | ||||
uint32_t hash[4] = { 0, 0, 0, 0 }; | uint32_t hash[4] = { 0, 0, 0, 0 }; | ||||
uint32_t rxmac_ctrl, pktfilt; | uint32_t rxmac_ctrl, pktfilt; | ||||
struct ifmultiaddr *ifma; | |||||
int i, count; | int i, count; | ||||
ET_LOCK_ASSERT(sc); | ET_LOCK_ASSERT(sc); | ||||
ifp = sc->ifp; | ifp = sc->ifp; | ||||
pktfilt = CSR_READ_4(sc, ET_PKTFILT); | pktfilt = CSR_READ_4(sc, ET_PKTFILT); | ||||
rxmac_ctrl = CSR_READ_4(sc, ET_RXMAC_CTRL); | rxmac_ctrl = CSR_READ_4(sc, ET_RXMAC_CTRL); | ||||
pktfilt &= ~(ET_PKTFILT_BCAST | ET_PKTFILT_MCAST | ET_PKTFILT_UCAST); | pktfilt &= ~(ET_PKTFILT_BCAST | ET_PKTFILT_MCAST | ET_PKTFILT_UCAST); | ||||
if (ifp->if_flags & (IFF_PROMISC | IFF_ALLMULTI)) { | if (ifp->if_flags & (IFF_PROMISC | IFF_ALLMULTI)) { | ||||
rxmac_ctrl |= ET_RXMAC_CTRL_NO_PKTFILT; | rxmac_ctrl |= ET_RXMAC_CTRL_NO_PKTFILT; | ||||
goto back; | goto back; | ||||
} | } | ||||
count = 0; | count = if_foreach_llmaddr(ifp, et_hash_maddr, &hash); | ||||
if_maddr_rlock(ifp); | |||||
CK_STAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { | |||||
uint32_t *hp, h; | |||||
if (ifma->ifma_addr->sa_family != AF_LINK) | |||||
continue; | |||||
h = ether_crc32_be(LLADDR((struct sockaddr_dl *) | |||||
ifma->ifma_addr), ETHER_ADDR_LEN); | |||||
h = (h & 0x3f800000) >> 23; | |||||
hp = &hash[0]; | |||||
if (h >= 32 && h < 64) { | |||||
h -= 32; | |||||
hp = &hash[1]; | |||||
} else if (h >= 64 && h < 96) { | |||||
h -= 64; | |||||
hp = &hash[2]; | |||||
} else if (h >= 96) { | |||||
h -= 96; | |||||
hp = &hash[3]; | |||||
} | |||||
*hp |= (1 << h); | |||||
++count; | |||||
} | |||||
if_maddr_runlock(ifp); | |||||
for (i = 0; i < 4; ++i) | for (i = 0; i < 4; ++i) | ||||
CSR_WRITE_4(sc, ET_MULTI_HASH + (i * 4), hash[i]); | CSR_WRITE_4(sc, ET_MULTI_HASH + (i * 4), hash[i]); | ||||
if (count > 0) | if (count > 0) | ||||
pktfilt |= ET_PKTFILT_MCAST; | pktfilt |= ET_PKTFILT_MCAST; | ||||
rxmac_ctrl &= ~ET_RXMAC_CTRL_NO_PKTFILT; | rxmac_ctrl &= ~ET_RXMAC_CTRL_NO_PKTFILT; | ||||
back: | back: | ||||
▲ Show 20 Lines • Show All 1,132 Lines • Show Last 20 Lines |