diff options
Diffstat (limited to 'sys/dev/dwc')
-rw-r--r-- | sys/dev/dwc/if_dwc.c | 29 | ||||
-rw-r--r-- | sys/dev/dwc/if_dwc.h | 2 |
2 files changed, 24 insertions, 7 deletions
diff --git a/sys/dev/dwc/if_dwc.c b/sys/dev/dwc/if_dwc.c index 988516e..a34879b 100644 --- a/sys/dev/dwc/if_dwc.c +++ b/sys/dev/dwc/if_dwc.c @@ -587,19 +587,25 @@ dwc_setup_rxfilter(struct dwc_softc *sc) struct ifmultiaddr *ifma; struct ifnet *ifp; uint8_t *eaddr, val; - uint32_t crc, ffval, hashbit, hashreg, hi, lo, reg; + uint32_t crc, ffval, hashbit, hashreg, hi, lo, hash[8]; + int nhash, i; DWC_ASSERT_LOCKED(sc); ifp = sc->ifp; + nhash = sc->mactype == DWC_GMAC_ALT_DESC ? 2 : 8; /* * Set the multicast (group) filter hash. */ - if ((ifp->if_flags & IFF_ALLMULTI)) + if ((ifp->if_flags & IFF_ALLMULTI) != 0) { ffval = (FRAME_FILTER_PM); - else { + for (i = 0; i < nhash; i++) + hash[i] = ~0; + } else { ffval = (FRAME_FILTER_HMC); + for (i = 0; i < nhash; i++) + hash[i] = 0; if_maddr_rlock(ifp); TAILQ_FOREACH(ifma, &sc->ifp->if_multiaddrs, ifma_link) { if (ifma->ifma_addr->sa_family != AF_LINK) @@ -609,12 +615,11 @@ dwc_setup_rxfilter(struct dwc_softc *sc) /* Take lower 8 bits and reverse it */ val = bitreverse(~crc & 0xff); + if (sc->mactype == DWC_GMAC_ALT_DESC) + val >>= nhash; /* Only need lower 6 bits */ hashreg = (val >> 5); hashbit = (val & 31); - - reg = READ4(sc, HASH_TABLE_REG(hashreg)); - reg |= (1 << hashbit); - WRITE4(sc, HASH_TABLE_REG(hashreg), reg); + hash[hashreg] |= (1 << hashbit); } if_maddr_runlock(ifp); } @@ -635,6 +640,13 @@ dwc_setup_rxfilter(struct dwc_softc *sc) WRITE4(sc, MAC_ADDRESS_LOW(0), lo); WRITE4(sc, MAC_ADDRESS_HIGH(0), hi); WRITE4(sc, MAC_FRAME_FILTER, ffval); + if (sc->mactype == DWC_GMAC_ALT_DESC) { + WRITE4(sc, GMAC_MAC_HTLOW, hash[0]); + WRITE4(sc, GMAC_MAC_HTHIGH, hash[1]); + } else { + for (i = 0; i < nhash; i++) + WRITE4(sc, HASH_TABLE_REG(i), hash[i]); + } } static int @@ -759,6 +771,9 @@ dwc_rxfinish_locked(struct dwc_softc *sc) m->m_len = len; if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1); + /* Remove trailing FCS */ + m_adj(m, -ETHER_CRC_LEN); + DWC_UNLOCK(sc); (*ifp->if_input)(ifp, m); DWC_LOCK(sc); diff --git a/sys/dev/dwc/if_dwc.h b/sys/dev/dwc/if_dwc.h index c9403da..d88ca0d 100644 --- a/sys/dev/dwc/if_dwc.h +++ b/sys/dev/dwc/if_dwc.h @@ -53,6 +53,8 @@ #define FRAME_FILTER_HMC (1 << 2) #define FRAME_FILTER_HUC (1 << 1) #define FRAME_FILTER_PR (1 << 0) /* All Incoming Frames */ +#define GMAC_MAC_HTHIGH 0x08 +#define GMAC_MAC_HTLOW 0x0c #define GMII_ADDRESS 0x10 #define GMII_ADDRESS_PA_MASK 0x1f /* Phy device */ #define GMII_ADDRESS_PA_SHIFT 11 |