diff options
author | jmcneill <jmcneill@FreeBSD.org> | 2016-06-12 22:55:50 +0000 |
---|---|---|
committer | jmcneill <jmcneill@FreeBSD.org> | 2016-06-12 22:55:50 +0000 |
commit | 83b176045cd0be35522afc4c6ac8a114bee4c924 (patch) | |
tree | 8d7e9916011e617fcd5b498eab61f00fdb37e29e | |
parent | 480f64e0481af9d3d82f2e2db4c4bd08105333dd (diff) | |
download | FreeBSD-src-83b176045cd0be35522afc4c6ac8a114bee4c924.zip FreeBSD-src-83b176045cd0be35522afc4c6ac8a114bee4c924.tar.gz |
Fix an issue with multicast hash filters on Amlogic and Allwinner boards.
For DWC_GMAC_ALT_DESC implementations, the multicast hash table has only
64 entries. Instead of 8 registers starting at 0x500, a pair of registers
at 0x08 and 0x0c are used instead.
Approved by: re (hrs)
Submitted by: Guy Yur <guyyur@gmail.com>
-rw-r--r-- | sys/dev/dwc/if_dwc.c | 19 | ||||
-rw-r--r-- | sys/dev/dwc/if_dwc.h | 2 |
2 files changed, 13 insertions, 8 deletions
diff --git a/sys/dev/dwc/if_dwc.c b/sys/dev/dwc/if_dwc.c index d7a38a0..a34879b 100644 --- a/sys/dev/dwc/if_dwc.c +++ b/sys/dev/dwc/if_dwc.c @@ -587,14 +587,13 @@ 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, hash[8], hmask; + 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; - hmask = ((nhash << 5) - 1) | 0xf; /* * Set the multicast (group) filter hash. @@ -615,11 +614,10 @@ dwc_setup_rxfilter(struct dwc_softc *sc) ifma->ifma_addr), ETHER_ADDR_LEN); /* Take lower 8 bits and reverse it */ - val = bitreverse(~crc & 0xff) & hmask; + val = bitreverse(~crc & 0xff); if (sc->mactype == DWC_GMAC_ALT_DESC) - hashreg = (val >> 5) == 0; - else - hashreg = (val >> 5); + val >>= nhash; /* Only need lower 6 bits */ + hashreg = (val >> 5); hashbit = (val & 31); hash[hashreg] |= (1 << hashbit); } @@ -642,8 +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); - for (i = 0; i < nhash; i++) - WRITE4(sc, HASH_TABLE_REG(i), hash[i]); + 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 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 |