Changeset View
Changeset View
Standalone View
Standalone View
sys/dev/altera/atse/if_atse.c
Show First 20 Lines • Show All 421 Lines • ▼ Show 20 Lines | if ((val4 & mask) != 0) { | ||||
/* Punt. */ | /* Punt. */ | ||||
} | } | ||||
sc->atse_flags &= ~ATSE_FLAGS_LINK; | sc->atse_flags &= ~ATSE_FLAGS_LINK; | ||||
return (0); | return (0); | ||||
} | } | ||||
static uint8_t | static u_int | ||||
atse_mchash(struct atse_softc *sc __unused, const uint8_t *addr) | atse_hash_maddr(void *arg, struct sockaddr_dl *sdl, u_int cnt) | ||||
{ | { | ||||
uint8_t x, y; | uint64_t *h = arg; | ||||
uint8_t *addr, x, y; | |||||
int i, j; | int i, j; | ||||
addr = LLADDR(sdl); | |||||
x = 0; | x = 0; | ||||
for (i = 0; i < ETHER_ADDR_LEN; i++) { | for (i = 0; i < ETHER_ADDR_LEN; i++) { | ||||
y = addr[i] & 0x01; | y = addr[i] & 0x01; | ||||
for (j = 1; j < 8; j++) | for (j = 1; j < 8; j++) | ||||
y ^= (addr[i] >> j) & 0x01; | y ^= (addr[i] >> j) & 0x01; | ||||
x |= (y << i); | x |= (y << i); | ||||
} | } | ||||
*h |= (1 << x); | |||||
return (x); | return (1); | ||||
} | } | ||||
static int | static int | ||||
atse_rxfilter_locked(struct atse_softc *sc) | atse_rxfilter_locked(struct atse_softc *sc) | ||||
{ | { | ||||
struct ifmultiaddr *ifma; | |||||
struct ifnet *ifp; | struct ifnet *ifp; | ||||
uint32_t val4; | uint32_t val4; | ||||
int i; | int i; | ||||
/* XXX-BZ can we find out if we have the MHASH synthesized? */ | /* XXX-BZ can we find out if we have the MHASH synthesized? */ | ||||
val4 = CSR_READ_4(sc, BASE_CFG_COMMAND_CONFIG); | val4 = CSR_READ_4(sc, BASE_CFG_COMMAND_CONFIG); | ||||
/* For simplicity always hash full 48 bits of addresses. */ | /* For simplicity always hash full 48 bits of addresses. */ | ||||
if ((val4 & BASE_CFG_COMMAND_CONFIG_MHASH_SEL) != 0) | if ((val4 & BASE_CFG_COMMAND_CONFIG_MHASH_SEL) != 0) | ||||
Show All 14 Lines | for (i = 0; i <= MHASH_LEN; i++) | ||||
CSR_WRITE_4(sc, MHASH_START + i, 0x1); | CSR_WRITE_4(sc, MHASH_START + i, 0x1); | ||||
} else { | } else { | ||||
/* | /* | ||||
* Can hold MHASH_LEN entries. | * Can hold MHASH_LEN entries. | ||||
* XXX-BZ bitstring.h would be more general. | * XXX-BZ bitstring.h would be more general. | ||||
*/ | */ | ||||
uint64_t h; | uint64_t h; | ||||
h = 0; | |||||
/* | /* | ||||
* Re-build and re-program hash table. First build the | * Re-build and re-program hash table. First build the | ||||
* bit-field "yes" or "no" for each slot per address, then | * bit-field "yes" or "no" for each slot per address, then | ||||
* do all the programming afterwards. | * do all the programming afterwards. | ||||
*/ | */ | ||||
if_maddr_rlock(ifp); | h = 0; | ||||
CK_STAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { | (void)if_foreach_llmaddr(ifp, atse_hash_maddr, &h); | ||||
if (ifma->ifma_addr->sa_family != AF_LINK) { | |||||
continue; | |||||
} | |||||
h |= (1 << atse_mchash(sc, | |||||
LLADDR((struct sockaddr_dl *)ifma->ifma_addr))); | |||||
} | |||||
if_maddr_runlock(ifp); | |||||
for (i = 0; i <= MHASH_LEN; i++) { | for (i = 0; i <= MHASH_LEN; i++) { | ||||
CSR_WRITE_4(sc, MHASH_START + i, | CSR_WRITE_4(sc, MHASH_START + i, | ||||
(h & (1 << i)) ? 0x01 : 0x00); | (h & (1 << i)) ? 0x01 : 0x00); | ||||
} | } | ||||
} | } | ||||
return (0); | return (0); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 1,104 Lines • Show Last 20 Lines |