Changeset View
Changeset View
Standalone View
Standalone View
head/sys/dev/dwc/if_dwc.c
Show First 20 Lines • Show All 581 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
static void | static void | ||||
dwc_setup_rxfilter(struct dwc_softc *sc) | dwc_setup_rxfilter(struct dwc_softc *sc) | ||||
{ | { | ||||
struct ifmultiaddr *ifma; | struct ifmultiaddr *ifma; | ||||
struct ifnet *ifp; | struct ifnet *ifp; | ||||
uint8_t *eaddr, val; | uint8_t *eaddr, val; | ||||
uint32_t crc, ffval, hashbit, hashreg, hi, lo, reg; | uint32_t crc, ffval, hashbit, hashreg, hi, lo, hash[8], hmask; | ||||
int nhash, i; | |||||
DWC_ASSERT_LOCKED(sc); | DWC_ASSERT_LOCKED(sc); | ||||
ifp = sc->ifp; | ifp = sc->ifp; | ||||
nhash = sc->mactype == DWC_GMAC_ALT_DESC ? 2 : 8; | |||||
hmask = ((nhash << 5) - 1) | 0xf; | |||||
/* | /* | ||||
* Set the multicast (group) filter hash. | * Set the multicast (group) filter hash. | ||||
*/ | */ | ||||
if ((ifp->if_flags & IFF_ALLMULTI)) | if ((ifp->if_flags & IFF_ALLMULTI) != 0) { | ||||
ffval = (FRAME_FILTER_PM); | ffval = (FRAME_FILTER_PM); | ||||
else { | for (i = 0; i < nhash; i++) | ||||
hash[i] = ~0; | |||||
} else { | |||||
ffval = (FRAME_FILTER_HMC); | ffval = (FRAME_FILTER_HMC); | ||||
for (i = 0; i < nhash; i++) | |||||
hash[i] = 0; | |||||
if_maddr_rlock(ifp); | if_maddr_rlock(ifp); | ||||
TAILQ_FOREACH(ifma, &sc->ifp->if_multiaddrs, ifma_link) { | TAILQ_FOREACH(ifma, &sc->ifp->if_multiaddrs, ifma_link) { | ||||
if (ifma->ifma_addr->sa_family != AF_LINK) | if (ifma->ifma_addr->sa_family != AF_LINK) | ||||
continue; | continue; | ||||
crc = ether_crc32_le(LLADDR((struct sockaddr_dl *) | crc = ether_crc32_le(LLADDR((struct sockaddr_dl *) | ||||
ifma->ifma_addr), ETHER_ADDR_LEN); | ifma->ifma_addr), ETHER_ADDR_LEN); | ||||
/* Take lower 8 bits and reverse it */ | /* Take lower 8 bits and reverse it */ | ||||
val = bitreverse(~crc & 0xff); | val = bitreverse(~crc & 0xff) & hmask; | ||||
if (sc->mactype == DWC_GMAC_ALT_DESC) | |||||
hashreg = (val >> 5) == 0; | |||||
else | |||||
hashreg = (val >> 5); | hashreg = (val >> 5); | ||||
hashbit = (val & 31); | hashbit = (val & 31); | ||||
hash[hashreg] |= (1 << hashbit); | |||||
reg = READ4(sc, HASH_TABLE_REG(hashreg)); | |||||
reg |= (1 << hashbit); | |||||
WRITE4(sc, HASH_TABLE_REG(hashreg), reg); | |||||
} | } | ||||
if_maddr_runlock(ifp); | if_maddr_runlock(ifp); | ||||
} | } | ||||
/* | /* | ||||
* Set the individual address filter hash. | * Set the individual address filter hash. | ||||
*/ | */ | ||||
if (ifp->if_flags & IFF_PROMISC) | if (ifp->if_flags & IFF_PROMISC) | ||||
ffval |= (FRAME_FILTER_PR); | ffval |= (FRAME_FILTER_PR); | ||||
/* | /* | ||||
* Set the primary address. | * Set the primary address. | ||||
*/ | */ | ||||
eaddr = IF_LLADDR(ifp); | eaddr = IF_LLADDR(ifp); | ||||
lo = eaddr[0] | (eaddr[1] << 8) | (eaddr[2] << 16) | | lo = eaddr[0] | (eaddr[1] << 8) | (eaddr[2] << 16) | | ||||
(eaddr[3] << 24); | (eaddr[3] << 24); | ||||
hi = eaddr[4] | (eaddr[5] << 8); | hi = eaddr[4] | (eaddr[5] << 8); | ||||
WRITE4(sc, MAC_ADDRESS_LOW(0), lo); | WRITE4(sc, MAC_ADDRESS_LOW(0), lo); | ||||
WRITE4(sc, MAC_ADDRESS_HIGH(0), hi); | WRITE4(sc, MAC_ADDRESS_HIGH(0), hi); | ||||
WRITE4(sc, MAC_FRAME_FILTER, ffval); | WRITE4(sc, MAC_FRAME_FILTER, ffval); | ||||
for (i = 0; i < nhash; i++) | |||||
WRITE4(sc, HASH_TABLE_REG(i), hash[i]); | |||||
} | } | ||||
static int | static int | ||||
dwc_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) | dwc_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) | ||||
{ | { | ||||
struct dwc_softc *sc; | struct dwc_softc *sc; | ||||
struct mii_data *mii; | struct mii_data *mii; | ||||
struct ifreq *ifr; | struct ifreq *ifr; | ||||
▲ Show 20 Lines • Show All 107 Lines • ▼ Show 20 Lines | for (;;) { | ||||
len = (rdes0 >> DDESC_RDES0_FL_SHIFT) & DDESC_RDES0_FL_MASK; | len = (rdes0 >> DDESC_RDES0_FL_SHIFT) & DDESC_RDES0_FL_MASK; | ||||
if (len != 0) { | if (len != 0) { | ||||
m = sc->rxbuf_map[idx].mbuf; | m = sc->rxbuf_map[idx].mbuf; | ||||
m->m_pkthdr.rcvif = ifp; | m->m_pkthdr.rcvif = ifp; | ||||
m->m_pkthdr.len = len; | m->m_pkthdr.len = len; | ||||
m->m_len = len; | m->m_len = len; | ||||
if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1); | if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1); | ||||
/* Remove trailing FCS */ | |||||
m_adj(m, -ETHER_CRC_LEN); | |||||
DWC_UNLOCK(sc); | DWC_UNLOCK(sc); | ||||
(*ifp->if_input)(ifp, m); | (*ifp->if_input)(ifp, m); | ||||
DWC_LOCK(sc); | DWC_LOCK(sc); | ||||
} else { | } else { | ||||
/* XXX Zero-length packet ? */ | /* XXX Zero-length packet ? */ | ||||
} | } | ||||
▲ Show 20 Lines • Show All 611 Lines • Show Last 20 Lines |