summaryrefslogtreecommitdiff
path: root/sys/dev/pci/if_cas.c
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2007-11-26 17:15:33 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2007-11-26 17:15:33 +0000
commit81f74d908d1f26a7c15904beb330b8b96e3172f7 (patch)
tree63bcafc211885f2c6d8ae55940a6f1460c59281e /sys/dev/pci/if_cas.c
parent1c8d182d996ce78179d1c611b6cb57cc4f2a7449 (diff)
Make Cassini+ work; remove some unused macros while I'm there.
Diffstat (limited to 'sys/dev/pci/if_cas.c')
-rw-r--r--sys/dev/pci/if_cas.c26
1 files changed, 24 insertions, 2 deletions
diff --git a/sys/dev/pci/if_cas.c b/sys/dev/pci/if_cas.c
index 522eb6193ab..faf64140c8e 100644
--- a/sys/dev/pci/if_cas.c
+++ b/sys/dev/pci/if_cas.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_cas.c,v 1.11 2007/11/26 15:55:59 kettenis Exp $ */
+/* $OpenBSD: if_cas.c,v 1.12 2007/11/26 17:15:32 kettenis Exp $ */
/*
*
@@ -32,6 +32,14 @@
/*
* Driver for Sun Cassini ethernet controllers.
+ *
+ * There are basically two variants of this chip: Cassini and
+ * Cassini+. We can distinguish between the two by revision: 0x10 and
+ * up are Cassini+. The most important difference is that Cassini+
+ * has a second RX descriptor ring. Cassini+ will not work without
+ * configuring that second ring. However, since we don't use it we
+ * don't actually fill the descriptors, and only hand off the first
+ * four to the chip.
*/
#include "bpfilter.h"
@@ -304,6 +312,7 @@ cas_attach(struct device *parent, struct device *self, void *aux)
bus_size_t size;
int gotenaddr = 0;
+ sc->sc_rev = PCI_REVISION(pa->pa_class);
sc->sc_dmatag = pa->pa_dmat;
#define PCI_CAS_BASEADDR 0x10
@@ -412,6 +421,8 @@ cas_config(struct cas_softc *sc)
goto fail_3;
}
+ bzero(sc->sc_control_data, sizeof(struct cas_control_data));
+
/*
* Create the receive buffer DMA maps.
*/
@@ -927,7 +938,6 @@ cas_cringsize(int sz)
int
cas_init(struct ifnet *ifp)
{
-
struct cas_softc *sc = (struct cas_softc *)ifp->if_softc;
bus_space_tag_t t = sc->sc_memt;
bus_space_handle_t h = sc->sc_memh;
@@ -981,6 +991,14 @@ cas_init(struct ifnet *ifp)
(((uint64_t)CAS_CDRXCADDR(sc,0)) >> 32));
bus_space_write_4(t, h, CAS_RX_CRING_PTR_LO, CAS_CDRXCADDR(sc, 0));
+ if (CAS_PLUS(sc)) {
+ KASSERT((CAS_CDRXADDR2(sc, 0) & 0x1fff) == 0);
+ bus_space_write_4(t, h, CAS_RX_DRING_PTR_HI2,
+ (((uint64_t)CAS_CDRXADDR2(sc,0)) >> 32));
+ bus_space_write_4(t, h, CAS_RX_DRING_PTR_LO2,
+ CAS_CDRXADDR2(sc, 0));
+ }
+
/* step 8. Global Configuration & Interrupt Mask */
bus_space_write_4(t, h, CAS_INTMASK,
~(CAS_INTR_TX_INTME|CAS_INTR_TX_EMPTY|
@@ -1007,6 +1025,8 @@ cas_init(struct ifnet *ifp)
/* Encode Receive Descriptor ring size */
v = cas_ringsize(CAS_NRXDESC) << CAS_RX_CONFIG_RXDRNG_SZ_SHIFT;
+ if (CAS_PLUS(sc))
+ v |= cas_ringsize(32) << CAS_RX_CONFIG_RXDRNG2_SZ_SHIFT;
/* Encode Receive Completion ring size */
v |= cas_cringsize(CAS_NRXCOMP) << CAS_RX_CONFIG_RXCRNG_SZ_SHIFT;
@@ -1036,6 +1056,8 @@ cas_init(struct ifnet *ifp)
/* step 15. Give the receiver a swift kick */
bus_space_write_4(t, h, CAS_RX_KICK, CAS_NRXDESC-4);
+ if (CAS_PLUS(sc))
+ bus_space_write_4(t, h, CAS_RX_KICK2, 4);
/* Start the one second timer. */
timeout_add(&sc->sc_tick_ch, hz);