summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/pci/if_cas.c26
-rw-r--r--sys/dev/pci/if_casvar.h28
2 files changed, 36 insertions, 18 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);
diff --git a/sys/dev/pci/if_casvar.h b/sys/dev/pci/if_casvar.h
index f41fe3df7c5..fc6c4ee2748 100644
--- a/sys/dev/pci/if_casvar.h
+++ b/sys/dev/pci/if_casvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_casvar.h,v 1.4 2007/04/15 16:31:30 kettenis Exp $ */
+/* $OpenBSD: if_casvar.h,v 1.5 2007/11/26 17:15:32 kettenis Exp $ */
/*
*
@@ -98,11 +98,14 @@ struct cas_control_data {
* The receive descriptors.
*/
struct cas_desc ccd_rxdescs[CAS_NRXDESC];
+ char ccd_unused[CAS_PAGE_SIZE - CAS_NRXDESC * 16];
+ struct cas_desc ccd_rxdescs2[CAS_NRXDESC];
};
#define CAS_CDOFF(x) offsetof(struct cas_control_data, x)
#define CAS_CDTXOFF(x) CAS_CDOFF(ccd_txdescs[(x)])
#define CAS_CDRXOFF(x) CAS_CDOFF(ccd_rxdescs[(x)])
+#define CAS_CDRXOFF2(x) CAS_CDOFF(ccd_rxdescs2[(x)])
#define CAS_CDRXCOFF(x) CAS_CDOFF(ccd_rxcomps[(x)])
/*
@@ -152,6 +155,7 @@ struct cas_softc {
u_int32_t sc_tx_cnt, sc_tx_prod, sc_tx_cons;
struct cas_rxsoft sc_rxsoft[CAS_NRXDESC];
+ struct cas_rxsoft sc_rxsoft2[CAS_NRXDESC];
/*
* Control data structures.
@@ -159,38 +163,30 @@ struct cas_softc {
struct cas_control_data *sc_control_data;
#define sc_txdescs sc_control_data->ccd_txdescs
#define sc_rxdescs sc_control_data->ccd_rxdescs
+#define sc_rxdescs2 sc_control_data->ccd_rxdescs2
#define sc_rxcomps sc_control_data->ccd_rxcomps
int sc_rxptr; /* next ready RX descriptor/descsoft */
int sc_rxfifosize;
int sc_rxdptr;
- /* ========== */
+ int sc_rev;
int sc_inited;
int sc_debug;
void *sc_sh; /* shutdownhook cookie */
};
-#define CAS_DMA_READ(v) letoh64(v)
-#define CAS_DMA_WRITE(v) htole64(v)
-
/*
- * This macro returns the current media entry for *non-MII* media.
+ * This maccro determines whether we have a Cassini+.
*/
-#define CAS_CURRENT_MEDIA(sc) \
- (IFM_SUBTYPE((sc)->sc_mii.mii_media.ifm_cur->ifm_media) != IFM_AUTO ? \
- (sc)->sc_mii.mii_media.ifm_cur : (sc)->sc_nway_active)
+#define CAS_PLUS(sc) (sc->sc_rev > 0x10)
-/*
- * This macro determines if a change to media-related OPMODE bits requires
- * a chip reset.
- */
-#define CAS_MEDIA_NEEDSRESET(sc, newbits) \
- (((sc)->sc_opmode & OPMODE_MEDIA_BITS) != \
- ((newbits) & OPMODE_MEDIA_BITS))
+#define CAS_DMA_READ(v) letoh64(v)
+#define CAS_DMA_WRITE(v) htole64(v)
#define CAS_CDTXADDR(sc, x) ((sc)->sc_cddma + CAS_CDTXOFF((x)))
#define CAS_CDRXADDR(sc, x) ((sc)->sc_cddma + CAS_CDRXOFF((x)))
+#define CAS_CDRXADDR2(sc, x) ((sc)->sc_cddma + CAS_CDRXOFF2((x)))
#define CAS_CDRXCADDR(sc, x) ((sc)->sc_cddma + CAS_CDRXCOFF((x)))
#define CAS_CDTXSYNC(sc, x, n, ops) \