Changeset View
Changeset View
Standalone View
Standalone View
sys/dev/my/if_my.c
Show First 20 Lines • Show All 298 Lines • ▼ Show 20 Lines | else { | ||||
/* low MDC */ | /* low MDC */ | ||||
miir &= ~MY_MASK_MIIR_MII_MDC; | miir &= ~MY_MASK_MIIR_MII_MDC; | ||||
CSR_WRITE_4(sc, MY_MANAGEMENT, miir); | CSR_WRITE_4(sc, MY_MANAGEMENT, miir); | ||||
} | } | ||||
return; | return; | ||||
} | } | ||||
static u_int | |||||
my_hash_maddr(void *arg, struct sockaddr_dl *sdl, u_int cnt) | |||||
{ | |||||
uint32_t *hashes = arg; | |||||
int h; | |||||
h = ~ether_crc32_be(LLADDR(sdl), ETHER_ADDR_LEN) >> 26; | |||||
if (h < 32) | |||||
hashes[0] |= (1 << h); | |||||
else | |||||
hashes[1] |= (1 << (h - 32)); | |||||
return (1); | |||||
} | |||||
/* | /* | ||||
* Program the 64-bit multicast hash filter. | * Program the 64-bit multicast hash filter. | ||||
*/ | */ | ||||
static void | static void | ||||
my_setmulti(struct my_softc * sc) | my_setmulti(struct my_softc * sc) | ||||
{ | { | ||||
struct ifnet *ifp; | struct ifnet *ifp; | ||||
int h = 0; | |||||
u_int32_t hashes[2] = {0, 0}; | u_int32_t hashes[2] = {0, 0}; | ||||
struct ifmultiaddr *ifma; | |||||
u_int32_t rxfilt; | u_int32_t rxfilt; | ||||
int mcnt = 0; | |||||
MY_LOCK_ASSERT(sc); | MY_LOCK_ASSERT(sc); | ||||
ifp = sc->my_ifp; | ifp = sc->my_ifp; | ||||
rxfilt = CSR_READ_4(sc, MY_TCRRCR); | rxfilt = CSR_READ_4(sc, MY_TCRRCR); | ||||
if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) { | if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) { | ||||
rxfilt |= MY_AM; | rxfilt |= MY_AM; | ||||
CSR_WRITE_4(sc, MY_TCRRCR, rxfilt); | CSR_WRITE_4(sc, MY_TCRRCR, rxfilt); | ||||
CSR_WRITE_4(sc, MY_MAR0, 0xFFFFFFFF); | CSR_WRITE_4(sc, MY_MAR0, 0xFFFFFFFF); | ||||
CSR_WRITE_4(sc, MY_MAR1, 0xFFFFFFFF); | CSR_WRITE_4(sc, MY_MAR1, 0xFFFFFFFF); | ||||
return; | return; | ||||
} | } | ||||
/* first, zot all the existing hash bits */ | /* first, zot all the existing hash bits */ | ||||
CSR_WRITE_4(sc, MY_MAR0, 0); | CSR_WRITE_4(sc, MY_MAR0, 0); | ||||
CSR_WRITE_4(sc, MY_MAR1, 0); | CSR_WRITE_4(sc, MY_MAR1, 0); | ||||
/* now program new ones */ | /* now program new ones */ | ||||
if_maddr_rlock(ifp); | if (if_foreach_llmaddr(ifp, my_hash_maddr, hashes) > 0) | ||||
CK_STAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { | |||||
if (ifma->ifma_addr->sa_family != AF_LINK) | |||||
continue; | |||||
h = ~ether_crc32_be(LLADDR((struct sockaddr_dl *) | |||||
ifma->ifma_addr), ETHER_ADDR_LEN) >> 26; | |||||
if (h < 32) | |||||
hashes[0] |= (1 << h); | |||||
else | |||||
hashes[1] |= (1 << (h - 32)); | |||||
mcnt++; | |||||
} | |||||
if_maddr_runlock(ifp); | |||||
if (mcnt) | |||||
rxfilt |= MY_AM; | rxfilt |= MY_AM; | ||||
else | else | ||||
rxfilt &= ~MY_AM; | rxfilt &= ~MY_AM; | ||||
CSR_WRITE_4(sc, MY_MAR0, hashes[0]); | CSR_WRITE_4(sc, MY_MAR0, hashes[0]); | ||||
CSR_WRITE_4(sc, MY_MAR1, hashes[1]); | CSR_WRITE_4(sc, MY_MAR1, hashes[1]); | ||||
CSR_WRITE_4(sc, MY_TCRRCR, rxfilt); | CSR_WRITE_4(sc, MY_TCRRCR, rxfilt); | ||||
return; | |||||
} | } | ||||
/* | /* | ||||
* Initiate an autonegotiation session. | * Initiate an autonegotiation session. | ||||
*/ | */ | ||||
static void | static void | ||||
my_autoneg_xmit(struct my_softc * sc) | my_autoneg_xmit(struct my_softc * sc) | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 1,409 Lines • Show Last 20 Lines |