Author: marius
Date: Mon Jul 25 18:32:54 2011
New Revision: 224366
URL: http://svn.freebsd.org/changeset/base/224366

Log:
  MFC: r223648, r223949
  
  - In gem_reset_rx() also reset the RX MAC which is necessary in order to
    get it out of a stuck condition that can be caused by GEM_MAC_RX_OVERFLOW.
  - In gem_reset_rxdma() call gem_setladrf() in order to reprogram the RX
    filter and restore the previous content of GEM_MAC_RX_CONFIG. While at it
    consistently use the newly introduced sc_mac_rxcfg throughout the driver
    instead of reading the its old content.
  - Increment if_iqdrops instead of if_ierrors in case of RX buffer allocation
    failure.
  - According to the GEM datasheet the RX MAC should also be disabled in
    gem_setladrf() before changing its configuration.
  - Add error messages to gem_disable_{r,t}x() and take advantage of these
    throughout the driver instead of duplicating their functionality all over
    the place.
  
  In joint forces with: yongari

Modified:
  stable/7/sys/dev/gem/if_gem.c
  stable/7/sys/dev/gem/if_gemvar.h
Directory Properties:
  stable/7/sys/   (props changed)
  stable/7/sys/cddl/contrib/opensolaris/   (props changed)
  stable/7/sys/contrib/dev/acpica/   (props changed)
  stable/7/sys/contrib/pf/   (props changed)

Modified: stable/7/sys/dev/gem/if_gem.c
==============================================================================
--- stable/7/sys/dev/gem/if_gem.c       Mon Jul 25 18:29:35 2011        
(r224365)
+++ stable/7/sys/dev/gem/if_gem.c       Mon Jul 25 18:32:54 2011        
(r224366)
@@ -705,7 +705,7 @@ gem_reset_rx(struct gem_softc *sc)
         * Resetting while DMA is in progress can cause a bus hang, so we
         * disable DMA first.
         */
-       gem_disable_rx(sc);
+       (void)gem_disable_rx(sc);
        GEM_BANK1_WRITE_4(sc, GEM_RX_CONFIG, 0);
        GEM_BANK1_BARRIER(sc, GEM_RX_CONFIG, 4,
            BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);
@@ -715,7 +715,7 @@ gem_reset_rx(struct gem_softc *sc)
        /* Wait 5ms extra. */
        DELAY(5000);
 
-       /* Finally, reset the ERX. */
+       /* Reset the ERX. */
        GEM_BANK2_WRITE_4(sc, GEM_RESET, GEM_RESET_RX);
        GEM_BANK2_BARRIER(sc, GEM_RESET, 4,
            BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);
@@ -724,6 +724,16 @@ gem_reset_rx(struct gem_softc *sc)
                device_printf(sc->sc_dev, "cannot reset receiver\n");
                return (1);
        }
+
+       /* Finally, reset RX MAC. */
+       GEM_BANK1_WRITE_4(sc, GEM_MAC_RXRESET, 1);
+       GEM_BANK1_BARRIER(sc, GEM_MAC_RXRESET, 4,
+           BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);
+       if (!GEM_BANK1_BITWAIT(sc, GEM_MAC_RXRESET, 1, 0)) {
+               device_printf(sc->sc_dev, "cannot reset RX MAC\n");
+               return (1);
+       }
+
        return (0);
 }
 
@@ -759,7 +769,7 @@ gem_reset_rxdma(struct gem_softc *sc)
            GEM_RX_CONFIG_CXM_START_SHFT) |
            (GEM_THRSH_1024 << GEM_RX_CONFIG_FIFO_THRS_SHIFT) |
            (ETHER_ALIGN << GEM_RX_CONFIG_FBOFF_SHFT));
-       /* Adjust for the SBus clock probably isn't worth the fuzz. */
+       /* Adjusting for the SBus clock probably isn't worth the fuzz. */
        GEM_BANK1_WRITE_4(sc, GEM_RX_BLANKING,
            ((6 * (sc->sc_flags & GEM_PCI66) != 0 ? 2 : 1) <<
            GEM_RX_BLANKING_TIME_SHIFT) | 6);
@@ -770,8 +780,11 @@ gem_reset_rxdma(struct gem_softc *sc)
            GEM_BANK1_READ_4(sc, GEM_RX_CONFIG) | GEM_RX_CONFIG_RXDMA_EN);
        GEM_BANK1_WRITE_4(sc, GEM_MAC_RX_MASK,
            GEM_MAC_RX_DONE | GEM_MAC_RX_FRAME_CNT);
-       GEM_BANK1_WRITE_4(sc, GEM_MAC_RX_CONFIG,
-           GEM_BANK1_READ_4(sc, GEM_MAC_RX_CONFIG) | GEM_MAC_RX_ENABLE);
+       /*
+        * Clear the RX filter and reprogram it.  This will also set the
+        * current RX MAC configuration and enable it.
+        */
+       gem_setladrf(sc);
 }
 
 static int
@@ -782,7 +795,7 @@ gem_reset_tx(struct gem_softc *sc)
         * Resetting while DMA is in progress can cause a bus hang, so we
         * disable DMA first.
         */
-       gem_disable_tx(sc);
+       (void)gem_disable_tx(sc);
        GEM_BANK1_WRITE_4(sc, GEM_TX_CONFIG, 0);
        GEM_BANK1_BARRIER(sc, GEM_TX_CONFIG, 4,
            BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);
@@ -812,8 +825,10 @@ gem_disable_rx(struct gem_softc *sc)
            GEM_BANK1_READ_4(sc, GEM_MAC_RX_CONFIG) & ~GEM_MAC_RX_ENABLE);
        GEM_BANK1_BARRIER(sc, GEM_MAC_RX_CONFIG, 4,
            BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);
-       return (GEM_BANK1_BITWAIT(sc, GEM_MAC_RX_CONFIG, GEM_MAC_RX_ENABLE,
-           0));
+       if (GEM_BANK1_BITWAIT(sc, GEM_MAC_RX_CONFIG, GEM_MAC_RX_ENABLE, 0))
+               return (1);
+       device_printf(sc->sc_dev, "cannot disable RX MAC\n");
+       return (0);
 }
 
 static int
@@ -824,8 +839,10 @@ gem_disable_tx(struct gem_softc *sc)
            GEM_BANK1_READ_4(sc, GEM_MAC_TX_CONFIG) & ~GEM_MAC_TX_ENABLE);
        GEM_BANK1_BARRIER(sc, GEM_MAC_TX_CONFIG, 4,
            BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);
-       return (GEM_BANK1_BITWAIT(sc, GEM_MAC_TX_CONFIG, GEM_MAC_TX_ENABLE,
-           0));
+       if (GEM_BANK1_BITWAIT(sc, GEM_MAC_TX_CONFIG, GEM_MAC_TX_ENABLE, 0))
+               return (1);
+       device_printf(sc->sc_dev, "cannot disable TX MAC\n");
+       return (0);
 }
 
 static int
@@ -960,7 +977,6 @@ gem_init_locked(struct gem_softc *sc)
        gem_init_regs(sc);
 
        /* step 5.  RX MAC registers & counters */
-       gem_setladrf(sc);
 
        /* step 6 & 7.  Program Descriptor Ring Base Addresses. */
        /* NOTE: we use only 32-bit DMA addresses here. */
@@ -1032,7 +1048,7 @@ gem_init_locked(struct gem_softc *sc)
            (ETHER_ALIGN << GEM_RX_CONFIG_FBOFF_SHFT) |
            GEM_RX_CONFIG_RXDMA_EN);
 
-       /* Adjust for the SBus clock probably isn't worth the fuzz. */
+       /* Adjusting for the SBus clock probably isn't worth the fuzz. */
        GEM_BANK1_WRITE_4(sc, GEM_RX_BLANKING,
            ((6 * (sc->sc_flags & GEM_PCI66) != 0 ? 2 : 1) <<
            GEM_RX_BLANKING_TIME_SHIFT) | 6);
@@ -1049,22 +1065,19 @@ gem_init_locked(struct gem_softc *sc)
 
        /* step 12.  RX_MAC Configuration Register */
        v = GEM_BANK1_READ_4(sc, GEM_MAC_RX_CONFIG);
-       v |= GEM_MAC_RX_ENABLE | GEM_MAC_RX_STRIP_CRC;
-       GEM_BANK1_WRITE_4(sc, GEM_MAC_RX_CONFIG, 0);
-       GEM_BANK1_BARRIER(sc, GEM_MAC_RX_CONFIG, 4,
-           BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);
-       if (!GEM_BANK1_BITWAIT(sc, GEM_MAC_RX_CONFIG, GEM_MAC_RX_ENABLE, 0))
-               device_printf(sc->sc_dev, "cannot configure RX MAC\n");
-       GEM_BANK1_WRITE_4(sc, GEM_MAC_RX_CONFIG, v);
+       v &= ~GEM_MAC_RX_ENABLE;
+       v |= GEM_MAC_RX_STRIP_CRC;
+       sc->sc_mac_rxcfg = v;
+       /*
+        * Clear the RX filter and reprogram it.  This will also set the
+        * current RX MAC configuration and enable it.
+        */
+       gem_setladrf(sc);
 
        /* step 13.  TX_MAC Configuration Register */
        v = GEM_BANK1_READ_4(sc, GEM_MAC_TX_CONFIG);
        v |= GEM_MAC_TX_ENABLE;
-       GEM_BANK1_WRITE_4(sc, GEM_MAC_TX_CONFIG, 0);
-       GEM_BANK1_BARRIER(sc, GEM_MAC_TX_CONFIG, 4,
-           BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);
-       if (!GEM_BANK1_BITWAIT(sc, GEM_MAC_TX_CONFIG, GEM_MAC_TX_ENABLE, 0))
-               device_printf(sc->sc_dev, "cannot configure TX MAC\n");
+       (void)gem_disable_tx(sc);
        GEM_BANK1_WRITE_4(sc, GEM_MAC_TX_CONFIG, v);
 
        /* step 14.  Issue Transmit Pending command. */
@@ -1588,7 +1601,7 @@ gem_rint(struct gem_softc *sc)
                 * the buffer that's already attached to this descriptor.
                 */
                if (gem_add_rxbuf(sc, sc->sc_rxptr) != 0) {
-                       ifp->if_ierrors++;
+                       ifp->if_iqdrops++;
                        GEM_INIT_RXDESC(sc, sc->sc_rxptr);
                        m = NULL;
                }
@@ -2028,8 +2041,8 @@ gem_mii_statchg(device_t dev)
         * the GEM Gigabit Ethernet ASIC Specification.
         */
 
-       rxcfg = GEM_BANK1_READ_4(sc, GEM_MAC_RX_CONFIG);
-       rxcfg &= ~(GEM_MAC_RX_CARR_EXTEND | GEM_MAC_RX_ENABLE);
+       rxcfg = sc->sc_mac_rxcfg;
+       rxcfg &= ~GEM_MAC_RX_CARR_EXTEND;
        txcfg = GEM_MAC_TX_ENA_IPG0 | GEM_MAC_TX_NGU | GEM_MAC_TX_NGU_LIMIT;
        if ((IFM_OPTIONS(sc->sc_mii->mii_media_active) & IFM_FDX) != 0)
                txcfg |= GEM_MAC_TX_IGN_CARRIER | GEM_MAC_TX_IGN_COLLIS;
@@ -2037,17 +2050,9 @@ gem_mii_statchg(device_t dev)
                rxcfg |= GEM_MAC_RX_CARR_EXTEND;
                txcfg |= GEM_MAC_TX_CARR_EXTEND;
        }
-       GEM_BANK1_WRITE_4(sc, GEM_MAC_TX_CONFIG, 0);
-       GEM_BANK1_BARRIER(sc, GEM_MAC_TX_CONFIG, 4,
-           BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);
-       if (!GEM_BANK1_BITWAIT(sc, GEM_MAC_TX_CONFIG, GEM_MAC_TX_ENABLE, 0))
-               device_printf(sc->sc_dev, "cannot disable TX MAC\n");
+       (void)gem_disable_tx(sc);
        GEM_BANK1_WRITE_4(sc, GEM_MAC_TX_CONFIG, txcfg);
-       GEM_BANK1_WRITE_4(sc, GEM_MAC_RX_CONFIG, 0);
-       GEM_BANK1_BARRIER(sc, GEM_MAC_RX_CONFIG, 4,
-           BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);
-       if (!GEM_BANK1_BITWAIT(sc, GEM_MAC_RX_CONFIG, GEM_MAC_RX_ENABLE, 0))
-               device_printf(sc->sc_dev, "cannot disable RX MAC\n");
+       (void)gem_disable_rx(sc);
        GEM_BANK1_WRITE_4(sc, GEM_MAC_RX_CONFIG, rxcfg);
 
        v = GEM_BANK1_READ_4(sc, GEM_MAC_CONTROL_CONFIG) &
@@ -2092,6 +2097,7 @@ gem_mii_statchg(device_t dev)
                v |= GEM_MAC_XIF_FDPLX_LED;
        GEM_BANK1_WRITE_4(sc, GEM_MAC_XIF_CONFIG, v);
 
+       sc->sc_mac_rxcfg = rxcfg;
        if ((sc->sc_ifp->if_drv_flags & IFF_DRV_RUNNING) != 0 &&
            (sc->sc_flags & GEM_LINK) != 0) {
                GEM_BANK1_WRITE_4(sc, GEM_MAC_TX_CONFIG,
@@ -2164,7 +2170,8 @@ gem_ioctl(struct ifnet *ifp, u_long cmd,
        case SIOCADDMULTI:
        case SIOCDELMULTI:
                GEM_LOCK(sc);
-               gem_setladrf(sc);
+               if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0)
+                       gem_setladrf(sc);
                GEM_UNLOCK(sc);
                break;
        case SIOCGIFMEDIA:
@@ -2199,24 +2206,20 @@ gem_setladrf(struct gem_softc *sc)
 
        GEM_LOCK_ASSERT(sc, MA_OWNED);
 
-       /* Get the current RX configuration. */
-       v = GEM_BANK1_READ_4(sc, GEM_MAC_RX_CONFIG);
-
        /*
-        * Turn off promiscuous mode, promiscuous group mode (all multicast),
-        * and hash filter.  Depending on the case, the right bit will be
-        * enabled.
+        * Turn off the RX MAC and the hash filter as required by the Sun GEM
+        * programming restrictions.
         */
-       v &= ~(GEM_MAC_RX_PROMISCUOUS | GEM_MAC_RX_HASH_FILTER |
-           GEM_MAC_RX_PROMISC_GRP);
-
+       v = sc->sc_mac_rxcfg & GEM_MAC_RX_HASH_FILTER;
        GEM_BANK1_WRITE_4(sc, GEM_MAC_RX_CONFIG, v);
        GEM_BANK1_BARRIER(sc, GEM_MAC_RX_CONFIG, 4,
            BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);
-       if (!GEM_BANK1_BITWAIT(sc, GEM_MAC_RX_CONFIG, GEM_MAC_RX_HASH_FILTER,
-           0))
-               device_printf(sc->sc_dev, "cannot disable RX hash filter\n");
+       if (!GEM_BANK1_BITWAIT(sc, GEM_MAC_RX_CONFIG, GEM_MAC_RX_HASH_FILTER |
+           GEM_MAC_RX_ENABLE, 0))
+               device_printf(sc->sc_dev,
+                   "cannot disable RX MAC or hash filter\n");
 
+       v &= ~(GEM_MAC_RX_PROMISCUOUS | GEM_MAC_RX_PROMISC_GRP);
        if ((ifp->if_flags & IFF_PROMISC) != 0) {
                v |= GEM_MAC_RX_PROMISCUOUS;
                goto chipit;
@@ -2262,5 +2265,6 @@ gem_setladrf(struct gem_softc *sc)
                    hash[i]);
 
  chipit:
-       GEM_BANK1_WRITE_4(sc, GEM_MAC_RX_CONFIG, v);
+       sc->sc_mac_rxcfg = v;
+       GEM_BANK1_WRITE_4(sc, GEM_MAC_RX_CONFIG, v | GEM_MAC_RX_ENABLE);
 }

Modified: stable/7/sys/dev/gem/if_gemvar.h
==============================================================================
--- stable/7/sys/dev/gem/if_gemvar.h    Mon Jul 25 18:29:35 2011        
(r224365)
+++ stable/7/sys/dev/gem/if_gemvar.h    Mon Jul 25 18:32:54 2011        
(r224366)
@@ -173,6 +173,8 @@ struct gem_softc {
        u_int           sc_rxptr;       /* next ready RX descriptor/state */
        u_int           sc_rxfifosize;  /* RX FIFO size (bytes) */
 
+       uint32_t        sc_mac_rxcfg;   /* RX MAC conf. % GEM_MAC_RX_ENABLE */
+
        int             sc_ifflags;
        u_long          sc_csum_features;
 };
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to