summaryrefslogtreecommitdiffstats
path: root/sys/dev/gem
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/gem')
-rw-r--r--sys/dev/gem/if_gem.c124
-rw-r--r--sys/dev/gem/if_gem_pci.c4
-rw-r--r--sys/dev/gem/if_gemreg.h23
-rw-r--r--sys/dev/gem/if_gemvar.h2
4 files changed, 86 insertions, 67 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);
}
diff --git a/sys/dev/gem/if_gem_pci.c b/sys/dev/gem/if_gem_pci.c
index cfea337..c5e1acd 100644
--- a/sys/dev/gem/if_gem_pci.c
+++ b/sys/dev/gem/if_gem_pci.c
@@ -177,6 +177,10 @@ gem_pci_attach(device_t dev)
if (pci_get_intpin(dev) == 0)
pci_set_intpin(dev, 1);
+ /* Set the PCI latency timer for Sun ERIs. */
+ if (sc->sc_variant == GEM_SUN_ERI)
+ pci_write_config(dev, PCIR_LATTIMER, GEM_ERI_LATENCY_TIMER, 1);
+
sc->sc_dev = dev;
sc->sc_flags |= GEM_PCI;
diff --git a/sys/dev/gem/if_gemreg.h b/sys/dev/gem/if_gemreg.h
index effcaf5..394fd90 100644
--- a/sys/dev/gem/if_gemreg.h
+++ b/sys/dev/gem/if_gemreg.h
@@ -35,7 +35,7 @@
/* register definitions for Apple GMAC, Sun ERI and Sun GEM */
/*
- * First bank: this registers live at the start of the PCI
+ * First bank: these registers live at the start of the PCI
* mapping, and at the start of the second bank of the SBus
* version.
*/
@@ -93,7 +93,7 @@
"b\x10MAC_CONTROL\0b\x11MIF\0b\x12IBERR\0\0"
/*
- * Second bank: this registers live at offset 0x1000 of the PCI
+ * Second bank: these registers live at offset 0x1000 of the PCI
* mapping, and at the start of the first bank of the SBus
* version.
*/
@@ -128,7 +128,7 @@
/* GEM_PCI_BIF_DIAG register bits */
#define GEN_PCI_BIF_DIAG_BC_SM 0x007f0000 /* burst ctrl. state machine */
-#define GEN_PCI_BIF_DIAG_SM 0xff000000 /* BIF state machine */
+#define GEN_PCI_BIF_DIAG_SM 0xff000000 /* BIF state machine */
/* Bits in GEM_SBUS_CONFIG register */
#define GEM_SBUS_CFG_BURST_32 0x00000001 /* 32 byte bursts */
@@ -147,6 +147,8 @@
#define GEM_RESET_TX 0x00000001 /* Reset TX half. */
#define GEM_RESET_RX 0x00000002 /* Reset RX half. */
#define GEM_RESET_PCI_RSTOUT 0x00000004 /* Force PCI RSTOUT#. */
+#define GEM_RESET_CLSZ_MASK 0x00ff0000 /* ERI cache line size */
+#define GEM_RESET_CLSZ_SHFT 16
/* The rest of the registers live in the first bank again. */
@@ -586,6 +588,10 @@
#define GEM_PHYAD_INTERNAL 1
#define GEM_PHYAD_EXTERNAL 0
+/* Miscellaneous */
+#define GEM_ERI_CACHE_LINE_SIZE 16
+#define GEM_ERI_LATENCY_TIMER 64
+
/*
* descriptor table structures
*/
@@ -594,7 +600,11 @@ struct gem_desc {
uint64_t gd_addr;
};
-/* Transmit flags */
+/*
+ * Transmit flags
+ * GEM_TD_CXSUM_ENABLE, GEM_TD_CXSUM_START, GEM_TD_CXSUM_STUFF and
+ * GEM_TD_INTERRUPT_ME only need to be set in the first descriptor of a group.
+ */
#define GEM_TD_BUFSIZE 0x0000000000007fffULL
#define GEM_TD_CXSUM_START 0x00000000001f8000ULL /* Cxsum start offset */
#define GEM_TD_CXSUM_STARTSHFT 15
@@ -605,10 +615,6 @@ struct gem_desc {
#define GEM_TD_START_OF_PACKET 0x0000000080000000ULL
#define GEM_TD_INTERRUPT_ME 0x0000000100000000ULL /* Interrupt me now */
#define GEM_TD_NO_CRC 0x0000000200000000ULL /* do not insert crc */
-/*
- * Only need to set GEM_TD_CXSUM_ENABLE, GEM_TD_CXSUM_STUFF,
- * GEM_TD_CXSUM_START, and GEM_TD_INTERRUPT_ME in 1st descriptor of a group.
- */
/* Receive flags */
#define GEM_RD_CHECKSUM 0x000000000000ffffULL /* is the complement */
@@ -618,7 +624,6 @@ struct gem_desc {
#define GEM_RD_HASH_PASS 0x1000000000000000ULL /* passed hash filter */
#define GEM_RD_ALTERNATE_MAC 0x2000000000000000ULL /* Alternate MAC adrs */
#define GEM_RD_BAD_CRC 0x4000000000000000ULL
-
#define GEM_RD_BUFSHIFT 16
#define GEM_RD_BUFLEN(x) (((x) & GEM_RD_BUFSIZE) >> GEM_RD_BUFSHIFT)
diff --git a/sys/dev/gem/if_gemvar.h b/sys/dev/gem/if_gemvar.h
index 59cb582..d89a322 100644
--- a/sys/dev/gem/if_gemvar.h
+++ b/sys/dev/gem/if_gemvar.h
@@ -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;
};
OpenPOWER on IntegriCloud