diff options
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/pci/if_cas.c | 26 | ||||
-rw-r--r-- | sys/dev/pci/if_casvar.h | 28 |
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) \ |