Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev Add support for the Adaptec AIC-6915 10/100 Ethernet...
details: https://anonhg.NetBSD.org/src/rev/9ace0916a16e
branches: trunk
changeset: 511378:9ace0916a16e
user: thorpej <thorpej%NetBSD.org@localhost>
date: Mon Jun 18 22:05:35 2001 +0000
description:
Add support for the Adaptec AIC-6915 10/100 Ethernet. This is
a 64-bit PCI chip, available in 1, 2, and 4 port models.
diffstat:
sys/dev/ic/aic6915.c | 1469 +++++++++++++++++++++++++++++++++++++++++++++++
sys/dev/ic/aic6915reg.h | 686 +++++++++++++++++++++
sys/dev/ic/aic6915var.h | 200 ++++++
sys/dev/pci/if_sf_pci.c | 286 +++++++++
4 files changed, 2641 insertions(+), 0 deletions(-)
diffs (truncated from 2657 to 300 lines):
diff -r 802375f7deab -r 9ace0916a16e sys/dev/ic/aic6915.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/dev/ic/aic6915.c Mon Jun 18 22:05:35 2001 +0000
@@ -0,0 +1,1469 @@
+/* $NetBSD: aic6915.c,v 1.1 2001/06/18 22:05:35 thorpej Exp $ */
+
+/*-
+ * Copyright (c) 2001 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jason R. Thorpe.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Device driver for the Adaptec AIC-6915 (``Starfire'')
+ * 10/100 Ethernet controller.
+ */
+
+#include "bpfilter.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/callout.h>
+#include <sys/mbuf.h>
+#include <sys/malloc.h>
+#include <sys/kernel.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <sys/errno.h>
+#include <sys/device.h>
+
+#include <uvm/uvm_extern.h>
+
+#include <net/if.h>
+#include <net/if_dl.h>
+#include <net/if_media.h>
+#include <net/if_ether.h>
+
+#if NBPFILTER > 0
+#include <net/bpf.h>
+#endif
+
+#include <machine/bus.h>
+#include <machine/intr.h>
+
+#include <dev/mii/miivar.h>
+
+#include <dev/ic/aic6915reg.h>
+#include <dev/ic/aic6915var.h>
+
+void sf_start(struct ifnet *);
+void sf_watchdog(struct ifnet *);
+int sf_ioctl(struct ifnet *, u_long, caddr_t);
+int sf_init(struct ifnet *);
+void sf_stop(struct ifnet *, int);
+
+void sf_shutdown(void *);
+
+void sf_txintr(struct sf_softc *);
+void sf_rxintr(struct sf_softc *);
+void sf_stats_update(struct sf_softc *);
+
+void sf_reset(struct sf_softc *);
+void sf_macreset(struct sf_softc *);
+void sf_rxdrain(struct sf_softc *);
+int sf_add_rxbuf(struct sf_softc *, int);
+uint8_t sf_read_eeprom(struct sf_softc *, int);
+void sf_set_filter(struct sf_softc *);
+
+int sf_mii_read(struct device *, int, int);
+void sf_mii_write(struct device *, int, int, int);
+void sf_mii_statchg(struct device *);
+
+void sf_tick(void *);
+
+int sf_mediachange(struct ifnet *);
+void sf_mediastatus(struct ifnet *, struct ifmediareq *);
+
+int sf_copy_small = 0;
+
+#define sf_funcreg_read(sc, reg) \
+ bus_space_read_4((sc)->sc_st, (sc)->sc_sh_func, (reg))
+#define sf_funcreg_write(sc, reg, val) \
+ bus_space_write_4((sc)->sc_st, (sc)->sc_sh_func, (reg), (val))
+
+static __inline uint32_t
+sf_reg_read(struct sf_softc *sc, bus_addr_t reg)
+{
+
+ if (__predict_false(sc->sc_iomapped)) {
+ bus_space_write_4(sc->sc_st, sc->sc_sh, SF_IndirectIoAccess,
+ reg);
+ return (bus_space_read_4(sc->sc_st, sc->sc_sh,
+ SF_IndirectIoDataPort));
+ }
+
+ return (bus_space_read_4(sc->sc_st, sc->sc_sh, reg));
+}
+
+static __inline void
+sf_reg_write(struct sf_softc *sc, bus_addr_t reg, uint32_t val)
+{
+
+ if (__predict_false(sc->sc_iomapped)) {
+ bus_space_write_4(sc->sc_st, sc->sc_sh, SF_IndirectIoAccess,
+ reg);
+ bus_space_write_4(sc->sc_st, sc->sc_sh, SF_IndirectIoDataPort,
+ val);
+ return;
+ }
+
+ bus_space_write_4(sc->sc_st, sc->sc_sh, reg, val);
+}
+
+#define sf_genreg_read(sc, reg) \
+ sf_reg_read((sc), (reg) + SF_GENREG_OFFSET)
+#define sf_genreg_write(sc, reg, val) \
+ sf_reg_write((sc), (reg) + SF_GENREG_OFFSET, (val))
+
+/*
+ * sf_attach:
+ *
+ * Attach a Starfire interface to the system.
+ */
+void
+sf_attach(struct sf_softc *sc)
+{
+ struct ifnet *ifp = &sc->sc_ethercom.ec_if;
+ int i, rseg, error;
+ bus_dma_segment_t seg;
+ u_int8_t enaddr[ETHER_ADDR_LEN];
+
+ callout_init(&sc->sc_tick_callout);
+
+ /*
+ * If we're I/O mapped, the functional register handle is
+ * the same as the base handle. If we're memory mapped,
+ * carve off a chunk of the register space for the functional
+ * registers, to save on arithmetic later.
+ */
+ if (sc->sc_iomapped)
+ sc->sc_sh_func = sc->sc_sh;
+ else {
+ if ((error = bus_space_subregion(sc->sc_st, sc->sc_sh,
+ SF_GENREG_OFFSET, SF_FUNCREG_SIZE, &sc->sc_sh_func)) != 0) {
+ printf("%s: unable to sub-region functional "
+ "registers, error = %d\n", sc->sc_dev.dv_xname,
+ error);
+ return;
+ }
+ }
+
+ /*
+ * Initialize the transmit threshold for this interface. The
+ * manual describes the default as 4 * 16 bytes. We start out
+ * at 10 * 16 bytes, to avoid a bunch of initial underruns on
+ * several platforms.
+ */
+ sc->sc_txthresh = 10;
+
+ /*
+ * Allocate the control data structures, and create and load the
+ * DMA map for it.
+ */
+ if ((error = bus_dmamem_alloc(sc->sc_dmat,
+ sizeof(struct sf_control_data), PAGE_SIZE, 0, &seg, 1, &rseg,
+ BUS_DMA_NOWAIT)) != 0) {
+ printf("%s: unable to allocate control data, error = %d\n",
+ sc->sc_dev.dv_xname, error);
+ goto fail_0;
+ }
+
+ if ((error = bus_dmamem_map(sc->sc_dmat, &seg, rseg,
+ sizeof(struct sf_control_data), (caddr_t *)&sc->sc_control_data,
+ BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) != 0) {
+ printf("%s: unable to map control data, error = %d\n",
+ sc->sc_dev.dv_xname, error);
+ goto fail_1;
+ }
+
+ if ((error = bus_dmamap_create(sc->sc_dmat,
+ sizeof(struct sf_control_data), 1,
+ sizeof(struct sf_control_data), 0, BUS_DMA_NOWAIT,
+ &sc->sc_cddmamap)) != 0) {
+ printf("%s: unable to create control data DMA map, "
+ "error = %d\n", sc->sc_dev.dv_xname, error);
+ goto fail_2;
+ }
+
+ if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_cddmamap,
+ sc->sc_control_data, sizeof(struct sf_control_data), NULL,
+ BUS_DMA_NOWAIT)) != 0) {
+ printf("%s: unable to load control data DMA map, error = %d\n",
+ sc->sc_dev.dv_xname, error);
+ goto fail_3;
+ }
+
+ /*
+ * Create the transmit buffer DMA maps.
+ */
+ for (i = 0; i < SF_NTXDESC; i++) {
+ if ((error = bus_dmamap_create(sc->sc_dmat, MCLBYTES,
+ SF_NTXFRAGS, MCLBYTES, 0, BUS_DMA_NOWAIT,
+ &sc->sc_txsoft[i].ds_dmamap)) != 0) {
+ printf("%s: unable to create tx DMA map %d, "
+ "error = %d\n", sc->sc_dev.dv_xname, i, error);
+ goto fail_4;
+ }
+ }
+
+ /*
+ * Create the receive buffer DMA maps.
+ */
+ for (i = 0; i < SF_NRXDESC; i++) {
+ if ((error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1,
+ MCLBYTES, 0, BUS_DMA_NOWAIT,
+ &sc->sc_rxsoft[i].ds_dmamap)) != 0) {
+ printf("%s: unable to create rx DMA map %d, "
+ "error = %d\n", sc->sc_dev.dv_xname, i, error);
+ goto fail_5;
+ }
+ }
+
+ /*
+ * Reset the chip to a known state.
+ */
+ sf_reset(sc);
+
+ /*
+ * Read the Ethernet address from the EEPROM.
+ */
+ for (i = 0; i < ETHER_ADDR_LEN; i++)
+ enaddr[i] = sf_read_eeprom(sc, (15 + (ETHER_ADDR_LEN - 1)) - i);
+
+ printf("%s: Ethernet address %s\n", sc->sc_dev.dv_xname,
+ ether_sprintf(enaddr));
+
+ if (sf_funcreg_read(sc, SF_PciDeviceConfig) & PDC_System64)
+ printf("%s: 64-bit PCI slot detected\n", sc->sc_dev.dv_xname);
+
+ /*
+ * Initialize our media structures and probe the MII.
+ */
+ sc->sc_mii.mii_ifp = ifp;
+ sc->sc_mii.mii_readreg = sf_mii_read;
+ sc->sc_mii.mii_writereg = sf_mii_write;
+ sc->sc_mii.mii_statchg = sf_mii_statchg;
+ ifmedia_init(&sc->sc_mii.mii_media, 0, sf_mediachange,
+ sf_mediastatus);
+ mii_attach(&sc->sc_dev, &sc->sc_mii, 0xffffffff, MII_PHY_ANY,
+ MII_OFFSET_ANY, 0);
+ if (LIST_FIRST(&sc->sc_mii.mii_phys) == NULL) {
+ ifmedia_add(&sc->sc_mii.mii_media, IFM_ETHER|IFM_NONE, 0, NULL);
+ ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_NONE);
+ } else
+ ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_AUTO);
+
+ strcpy(ifp->if_xname, sc->sc_dev.dv_xname);
+ ifp->if_softc = sc;
+ ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
+ ifp->if_ioctl = sf_ioctl;
+ ifp->if_start = sf_start;
+ ifp->if_watchdog = sf_watchdog;
+ ifp->if_init = sf_init;
+ ifp->if_stop = sf_stop;
+ IFQ_SET_READY(&ifp->if_snd);
+
+ /*
+ * Attach the interface.
+ */
+ if_attach(ifp);
Home |
Main Index |
Thread Index |
Old Index