diff options
Diffstat (limited to 'sys/dev/gem/if_gem.c')
-rw-r--r-- | sys/dev/gem/if_gem.c | 124 |
1 files changed, 66 insertions, 58 deletions
diff --git a/sys/dev/gem/if_gem.c b/sys/dev/gem/if_gem.c index 9ee43f2..d75e1ab 100644 --- a/sys/dev/gem/if_gem.c +++ b/sys/dev/gem/if_gem.c @@ -626,7 +626,9 @@ gem_reset(struct gem_softc *sc) gem_reset_tx(sc); /* Do a full reset. */ - GEM_BANK2_WRITE_4(sc, GEM_RESET, GEM_RESET_RX | GEM_RESET_TX); + GEM_BANK2_WRITE_4(sc, GEM_RESET, GEM_RESET_RX | GEM_RESET_TX | + (sc->sc_variant == GEM_SUN_ERI ? GEM_ERI_CACHE_LINE_SIZE << + GEM_RESET_CLSZ_SHFT : 0)); GEM_BANK2_BARRIER(sc, GEM_RESET, 4, BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); if (!GEM_BANK2_BITWAIT(sc, GEM_RESET, GEM_RESET_RX | GEM_RESET_TX, 0)) @@ -705,7 +707,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,15 +717,26 @@ gem_reset_rx(struct gem_softc *sc) /* Wait 5ms extra. */ DELAY(5000); - /* Finally, reset the ERX. */ - GEM_BANK2_WRITE_4(sc, GEM_RESET, GEM_RESET_RX); + /* Reset the ERX. */ + GEM_BANK2_WRITE_4(sc, GEM_RESET, GEM_RESET_RX | + (sc->sc_variant == GEM_SUN_ERI ? GEM_ERI_CACHE_LINE_SIZE << + GEM_RESET_CLSZ_SHFT : 0)); GEM_BANK2_BARRIER(sc, GEM_RESET, 4, BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); - if (!GEM_BANK2_BITWAIT(sc, GEM_RESET, GEM_RESET_RX | GEM_RESET_TX, - 0)) { + if (!GEM_BANK2_BITWAIT(sc, GEM_RESET, GEM_RESET_RX, 0)) { 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 +772,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 +783,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 +798,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); @@ -793,11 +809,12 @@ gem_reset_tx(struct gem_softc *sc) DELAY(5000); /* Finally, reset the ETX. */ - GEM_BANK2_WRITE_4(sc, GEM_RESET, GEM_RESET_TX); + GEM_BANK2_WRITE_4(sc, GEM_RESET, GEM_RESET_TX | + (sc->sc_variant == GEM_SUN_ERI ? GEM_ERI_CACHE_LINE_SIZE << + GEM_RESET_CLSZ_SHFT : 0)); GEM_BANK2_BARRIER(sc, GEM_RESET, 4, BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); - if (!GEM_BANK2_BITWAIT(sc, GEM_RESET, GEM_RESET_RX | GEM_RESET_TX, - 0)) { + if (!GEM_BANK2_BITWAIT(sc, GEM_RESET, GEM_RESET_TX, 0)) { device_printf(sc->sc_dev, "cannot reset transmitter\n"); return (1); } @@ -812,8 +829,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 +843,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 +981,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 +1052,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 +1069,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 +1605,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 +2045,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 +2054,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 +2101,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 +2174,8 @@ gem_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) 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 +2210,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 +2269,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); } |