Author: jmcneill
Date: Sun Jun 12 22:55:50 2016
New Revision: 301841
URL: https://svnweb.freebsd.org/changeset/base/301841

Log:
  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 <guy...@gmail.com>

Modified:
  head/sys/dev/dwc/if_dwc.c
  head/sys/dev/dwc/if_dwc.h

Modified: head/sys/dev/dwc/if_dwc.c
==============================================================================
--- head/sys/dev/dwc/if_dwc.c   Sun Jun 12 15:37:35 2016        (r301840)
+++ head/sys/dev/dwc/if_dwc.c   Sun Jun 12 22:55:50 2016        (r301841)
@@ -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

Modified: head/sys/dev/dwc/if_dwc.h
==============================================================================
--- head/sys/dev/dwc/if_dwc.h   Sun Jun 12 15:37:35 2016        (r301840)
+++ head/sys/dev/dwc/if_dwc.h   Sun Jun 12 22:55:50 2016        (r301841)
@@ -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
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to