diff options
-rw-r--r-- | sys/conf/files | 5 | ||||
-rw-r--r-- | sys/dev/ic/ti.c (renamed from sys/dev/pci/if_ti.c) | 177 | ||||
-rw-r--r-- | sys/dev/ic/tireg.h (renamed from sys/dev/pci/if_tireg.h) | 3 | ||||
-rw-r--r-- | sys/dev/ic/tivar.h (renamed from sys/dev/pci/if_tivar.h) | 5 | ||||
-rw-r--r-- | sys/dev/pci/files.pci | 7 | ||||
-rw-r--r-- | sys/dev/pci/if_ti_pci.c | 181 |
6 files changed, 255 insertions, 123 deletions
diff --git a/sys/conf/files b/sys/conf/files index 2278bd9c91b..7b5b5741fd6 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -1,4 +1,4 @@ -# $OpenBSD: files,v 1.472 2009/08/25 16:16:34 jsg Exp $ +# $OpenBSD: files,v 1.473 2009/08/29 21:12:55 kettenis Exp $ # $NetBSD: files,v 1.87 1996/05/19 17:17:50 jonathan Exp $ # @(#)files.newconf 7.5 (Berkeley) 5/10/93 @@ -301,6 +301,9 @@ file dev/ic/i82596.c ie & (ie_pci | ie_eisa | ie_gsc) device gem: ether, ifnet, ifmedia, mii file dev/ic/gem.c gem +device ti: ether, ifnet, ifmedia, mii, firmload +file dev/ic/ti.c ti + # 8250/16[45]50-based "com" ports device com: tty file dev/ic/com.c com & (com | com_cardbus | com_gsc | diff --git a/sys/dev/pci/if_ti.c b/sys/dev/ic/ti.c index 187dd8b25ef..996071fb1c0 100644 --- a/sys/dev/pci/if_ti.c +++ b/sys/dev/ic/ti.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_ti.c,v 1.98 2009/08/13 14:24:47 jasper Exp $ */ +/* $OpenBSD: ti.c,v 1.1 2009/08/29 21:12:55 kettenis Exp $ */ /* * Copyright (c) 1997, 1998, 1999 @@ -107,19 +107,11 @@ #include <net/if_vlan_var.h> #endif -#include <dev/pci/pcireg.h> -#include <dev/pci/pcivar.h> -#include <dev/pci/pcidevs.h> - -#include <dev/pci/if_tireg.h> -#include <dev/pci/if_tivar.h> - -int ti_probe(struct device *, void *, void *); -void ti_attach(struct device *, struct device *, void *); +#include <machine/bus.h> -struct cfattach ti_ca = { - sizeof(struct ti_softc), ti_probe, ti_attach -}; +#include <dev/ic/tireg.h> +#include <dev/ic/tivar.h> +#include <dev/pci/pcireg.h> struct cfdriver ti_cd = { NULL, "ti", DV_IFNET @@ -177,18 +169,10 @@ int ti_init_tx_ring(struct ti_softc *); int ti_64bitslot_war(struct ti_softc *); int ti_chipinit(struct ti_softc *); +void ti_chipinit_pci(struct ti_softc *); +void ti_chipinit_sbus(struct ti_softc *); int ti_gibinit(struct ti_softc *); -const struct pci_matchid ti_devices[] = { - { PCI_VENDOR_NETGEAR, PCI_PRODUCT_NETGEAR_GA620 }, - { PCI_VENDOR_NETGEAR, PCI_PRODUCT_NETGEAR_GA620T }, - { PCI_VENDOR_ALTEON, PCI_PRODUCT_ALTEON_ACENIC }, - { PCI_VENDOR_ALTEON, PCI_PRODUCT_ALTEON_ACENICT }, - { PCI_VENDOR_3COM, PCI_PRODUCT_3COM_3C985 }, - { PCI_VENDOR_SGI, PCI_PRODUCT_SGI_TIGON }, - { PCI_VENDOR_DEC, PCI_PRODUCT_DEC_PN9000SX } -}; - /* * Send an instruction or address to the EEPROM, check for ACK. */ @@ -1261,8 +1245,6 @@ ti_64bitslot_war(struct ti_softc *sc) int ti_chipinit(struct ti_softc *sc) { - u_int32_t cacheline; - u_int32_t pci_writemax = 0; u_int32_t chip_rev; /* Initialize link to down state. */ @@ -1305,8 +1287,32 @@ ti_chipinit(struct ti_softc *sc) TI_SETBIT(sc, TI_MISC_CONF, TI_MCR_SRAM_SYNCHRONOUS); } + if (sc->ti_sbus) + ti_chipinit_sbus(sc); + else + ti_chipinit_pci(sc); + + /* Recommended settings from Tigon manual. */ + CSR_WRITE_4(sc, TI_GCR_DMA_WRITECFG, TI_DMA_STATE_THRESH_8W); + CSR_WRITE_4(sc, TI_GCR_DMA_READCFG, TI_DMA_STATE_THRESH_8W); + + if (ti_64bitslot_war(sc)) { + printf("%s: bios thinks we're in a 64 bit slot, " + "but we aren't", sc->sc_dv.dv_xname); + return (EINVAL); + } + + return (0); +} + +void +ti_chipinit_pci(struct ti_softc *sc) +{ + u_int32_t cacheline; + u_int32_t pci_writemax = 0; + /* Set up the PCI state register. */ - CSR_WRITE_4(sc, TI_PCI_STATE, TI_PCI_READ_CMD|TI_PCI_WRITE_CMD); + CSR_WRITE_4(sc, TI_PCI_STATE, TI_PCI_READ_CMD | TI_PCI_WRITE_CMD); if (sc->ti_hwrev == TI_HWREV_TIGON_II) TI_SETBIT(sc, TI_PCI_STATE, TI_PCISTATE_USE_MEM_RD_MULT); @@ -1360,18 +1366,22 @@ ti_chipinit(struct ti_softc *sc) CSR_WRITE_4(sc, TI_GCR_OPMODE, TI_DMA_SWAP_OPTIONS | TI_OPMODE_WARN_ENB | TI_OPMODE_FATAL_ENB | TI_OPMODE_DONT_FRAG_JUMBO); +} - /* Recommended settings from Tigon manual. */ - CSR_WRITE_4(sc, TI_GCR_DMA_WRITECFG, TI_DMA_STATE_THRESH_8W); - CSR_WRITE_4(sc, TI_GCR_DMA_READCFG, TI_DMA_STATE_THRESH_8W); - - if (ti_64bitslot_war(sc)) { - printf("%s: bios thinks we're in a 64 bit slot, " - "but we aren't", sc->sc_dv.dv_xname); - return (EINVAL); - } +void +ti_chipinit_sbus(struct ti_softc *sc) +{ + /* Set up the PCI state register. */ + CSR_WRITE_4(sc, TI_PCI_STATE, TI_PCI_READ_CMD | TI_PCI_WRITE_CMD | + TI_PCISTATE_NO_SWAP_READ_DMA | TI_PCISTATE_NO_SWAP_WRITE_DMA | + TI_PCI_WRITEMAX_64 | TI_PCI_READMAX_64 | + TI_PCISTATE_PROVIDE_LEN); - return (0); + /* Configure DMA variables. */ + CSR_WRITE_4(sc, TI_GCR_OPMODE, TI_OPMODE_WORDSWAP_BD | + TI_OPMODE_1_DMA_ACTIVE | TI_OPMODE_SBUS | + TI_OPMODE_WARN_ENB | TI_OPMODE_FATAL_ENB | + TI_OPMODE_DONT_FRAG_JUMBO); } /* @@ -1539,60 +1549,17 @@ ti_gibinit(struct ti_softc *sc) return (0); } -/* - * Probe for a Tigon chip. Check the PCI vendor and device IDs - * against our list and return its name if we find a match. - */ int -ti_probe(struct device *parent, void *match, void *aux) +ti_attach(struct ti_softc *sc) { - return (pci_matchbyid((struct pci_attach_args *)aux, ti_devices, - sizeof(ti_devices)/sizeof(ti_devices[0]))); -} - -void -ti_attach(struct device *parent, struct device *self, void *aux) -{ - struct ti_softc *sc = (struct ti_softc *)self; - struct pci_attach_args *pa = aux; - pci_chipset_tag_t pc = pa->pa_pc; - pci_intr_handle_t ih; - const char *intrstr = NULL; - bus_size_t size; bus_dma_segment_t seg; int rseg; struct ifnet *ifp; caddr_t kva; - /* - * Map control/status registers. - */ - - if (pci_mapreg_map(pa, TI_PCI_LOMEM, - PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT, 0, - &sc->ti_btag, &sc->ti_bhandle, NULL, &size, 0)) { - printf(": can't map mem space\n"); - return; - } - - if (pci_intr_map(pa, &ih)) { - printf(": couldn't map interrupt\n"); - goto fail_1; - } - intrstr = pci_intr_string(pc, ih); - sc->ti_intrhand = pci_intr_establish(pc, ih, IPL_NET, ti_intr, sc, - self->dv_xname); - if (sc->ti_intrhand == NULL) { - printf(": couldn't establish interrupt"); - if (intrstr != NULL) - printf(" at %s", intrstr); - printf("\n"); - goto fail_1; - } - if (ti_chipinit(sc)) { printf("%s: chip initialization failed\n", sc->sc_dv.dv_xname); - goto fail_2; + return (1); } /* Zero out the NIC's on-board SRAM. */ @@ -1601,7 +1568,7 @@ ti_attach(struct device *parent, struct device *self, void *aux) /* Init again -- zeroing memory may have clobbered some registers. */ if (ti_chipinit(sc)) { printf("%s: chip initialization failed\n", sc->sc_dv.dv_xname); - goto fail_2; + return (1); } /* @@ -1615,38 +1582,35 @@ ti_attach(struct device *parent, struct device *self, void *aux) TI_EE_MAC_OFFSET + 2, ETHER_ADDR_LEN)) { printf("%s: failed to read station address\n", sc->sc_dv.dv_xname); - free(sc, M_DEVBUF); - goto fail_2; + return (1); } /* * A Tigon chip was detected. Inform the world. */ - printf(": %s, address %s\n", intrstr, - ether_sprintf(sc->arpcom.ac_enaddr)); + printf(", address %s\n", ether_sprintf(sc->arpcom.ac_enaddr)); /* Allocate the general information block and ring buffers. */ - sc->sc_dmatag = pa->pa_dmat; if (bus_dmamem_alloc(sc->sc_dmatag, sizeof(struct ti_ring_data), PAGE_SIZE, 0, &seg, 1, &rseg, BUS_DMA_NOWAIT)) { printf("%s: can't alloc rx buffers\n", sc->sc_dv.dv_xname); - goto fail_2; + return (1); } if (bus_dmamem_map(sc->sc_dmatag, &seg, rseg, sizeof(struct ti_ring_data), &kva, BUS_DMA_NOWAIT)) { printf("%s: can't map dma buffers (%d bytes)\n", sc->sc_dv.dv_xname, sizeof(struct ti_ring_data)); - goto fail_3; + goto fail_1; } if (bus_dmamap_create(sc->sc_dmatag, sizeof(struct ti_ring_data), 1, sizeof(struct ti_ring_data), 0, BUS_DMA_NOWAIT, &sc->ti_ring_map)) { printf("%s: can't create dma map\n", sc->sc_dv.dv_xname); - goto fail_4; + goto fail_2; } if (bus_dmamap_load(sc->sc_dmatag, sc->ti_ring_map, kva, sizeof(struct ti_ring_data), NULL, BUS_DMA_NOWAIT)) { - goto fail_5; + goto fail_3; } sc->ti_rdata = (struct ti_ring_data *)kva; bzero(sc->ti_rdata, sizeof(struct ti_ring_data)); @@ -1655,24 +1619,9 @@ ti_attach(struct device *parent, struct device *self, void *aux) if (ti_alloc_jumbo_mem(sc)) { printf("%s: jumbo buffer allocation failed\n", sc->sc_dv.dv_xname); - goto fail_5; + goto fail_3; } - /* - * We really need a better way to tell a 1000baseTX card - * from a 1000baseSX one, since in theory there could be - * OEMed 1000baseTX cards from lame vendors who aren't - * clever enough to change the PCI ID. For the moment - * though, the AceNIC is the only copper card available. - */ - if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_ALTEON && - PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_ALTEON_ACENICT) - sc->ti_copper = 1; - /* Ok, it's not the only copper card available */ - if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_NETGEAR && - PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_NETGEAR_GA620T) - sc->ti_copper = 1; - /* Set default tuneable values. */ sc->ti_stat_ticks = 2 * TI_TICKS_PER_SEC; sc->ti_rx_coal_ticks = TI_TICKS_PER_SEC / 5000; @@ -1735,23 +1684,19 @@ ti_attach(struct device *parent, struct device *self, void *aux) ether_ifattach(ifp); shutdownhook_establish(ti_shutdown, sc); - return; + return (0); -fail_5: +fail_3: bus_dmamap_destroy(sc->sc_dmatag, sc->ti_ring_map); -fail_4: +fail_2: bus_dmamem_unmap(sc->sc_dmatag, kva, sizeof(struct ti_ring_data)); -fail_3: +fail_1: bus_dmamem_free(sc->sc_dmatag, &seg, rseg); -fail_2: - pci_intr_disestablish(pc, sc->ti_intrhand); - -fail_1: - bus_space_unmap(sc->ti_btag, sc->ti_bhandle, size); + return (1); } /* diff --git a/sys/dev/pci/if_tireg.h b/sys/dev/ic/tireg.h index c76b1a99fb0..1b2a8ff1a28 100644 --- a/sys/dev/pci/if_tireg.h +++ b/sys/dev/ic/tireg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: if_tireg.h,v 1.25 2006/08/16 02:37:00 brad Exp $ */ +/* $OpenBSD: tireg.h,v 1.1 2009/08/29 21:12:55 kettenis Exp $ */ /* * Copyright (c) 1997, 1998, 1999 @@ -1113,6 +1113,7 @@ struct ti_softc { void * ti_intrhand; struct ifmedia ifmedia; /* media info */ u_int8_t ti_hwrev; /* Tigon rev (1 or 2) */ + u_int8_t ti_sbus; /* SBus card */ u_int8_t ti_copper; /* 1000baseTX card */ u_int8_t ti_linkstat; /* Link state */ bus_dma_tag_t sc_dmatag; diff --git a/sys/dev/pci/if_tivar.h b/sys/dev/ic/tivar.h index 5c3c37e943e..492c0a63f23 100644 --- a/sys/dev/pci/if_tivar.h +++ b/sys/dev/ic/tivar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: if_tivar.h,v 1.2 2004/11/22 21:23:57 deraadt Exp $ */ +/* $OpenBSD: tivar.h,v 1.1 2009/08/29 21:12:55 kettenis Exp $ */ /* * Copyright (c) 2004 Theo de Raadt <deraadt@openbsd.org> @@ -41,3 +41,6 @@ struct tigon_firmware { u_char data[1]; }; + +int ti_attach(struct ti_softc *sc); +int ti_intr(void *); diff --git a/sys/dev/pci/files.pci b/sys/dev/pci/files.pci index 0e25bdbee70..930e01243cd 100644 --- a/sys/dev/pci/files.pci +++ b/sys/dev/pci/files.pci @@ -1,4 +1,4 @@ -# $OpenBSD: files.pci,v 1.262 2009/08/08 09:31:13 kevlo Exp $ +# $OpenBSD: files.pci,v 1.263 2009/08/29 21:12:55 kettenis Exp $ # $NetBSD: files.pci,v 1.20 1996/09/24 17:47:15 christos Exp $ # # Config file and device description for machine-independent PCI code. @@ -400,9 +400,8 @@ attach epic at pci with epic_pci file dev/pci/if_epic_pci.c epic_pci # Alteon Tigon I & II -device ti: ether, ifnet, ifmedia, firmload -attach ti at pci -file dev/pci/if_ti.c ti +attach ti at pci with ti_pci +file dev/pci/if_ti_pci.c ti_pci # NE2000-compatible PCI Ethernet cards attach ne at pci with ne_pci: rtl80x9 diff --git a/sys/dev/pci/if_ti_pci.c b/sys/dev/pci/if_ti_pci.c new file mode 100644 index 00000000000..12260f686a3 --- /dev/null +++ b/sys/dev/pci/if_ti_pci.c @@ -0,0 +1,181 @@ +/* $OpenBSD: if_ti_pci.c,v 1.1 2009/08/29 21:12:55 kettenis Exp $ */ + +/* + * Copyright (c) 1997, 1998, 1999 + * Bill Paul <wpaul@ctr.columbia.edu>. All rights reserved. + * + * 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 Bill Paul. + * 4. Neither the name of the author nor the names of any co-contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY Bill Paul 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 Bill Paul OR THE VOICES IN HIS HEAD + * 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. + * + * $FreeBSD: src/sys/pci/if_ti.c,v 1.25 2000/01/18 00:26:29 wpaul Exp $ + */ + +/* + * Alteon Networks Tigon PCI gigabit ethernet driver for OpenBSD. + * + * Written by Bill Paul <wpaul@ctr.columbia.edu> + * Electrical Engineering Department + * Columbia University, New York City + */ + +/* + * The Alteon Networks Tigon chip contains an embedded R4000 CPU, + * gigabit MAC, dual DMA channels and a PCI interface unit. NICs + * using the Tigon may have anywhere from 512K to 2MB of SRAM. The + * Tigon supports hardware IP, TCP and UCP checksumming, multicast + * filtering and jumbo (9014 byte) frames. The hardware is largely + * controlled by firmware, which must be loaded into the NIC during + * initialization. + * + * The Tigon 2 contains 2 R4000 CPUs and requires a newer firmware + * revision, which supports new features such as extended commands, + * extended jumbo receive ring desciptors and a mini receive ring. + * + * Alteon Networks is to be commended for releasing such a vast amount + * of development material for the Tigon NIC without requiring an NDA + * (although they really should have done it a long time ago). With + * any luck, the other vendors will finally wise up and follow Alteon's + * stellar example. + * + * The following people deserve special thanks: + * - Terry Murphy of 3Com, for providing a 3c985 Tigon 1 board + * for testing + * - Raymond Lee of Netgear, for providing a pair of Netgear + * GA620 Tigon 2 boards for testing + * - Ulf Zimmermann, for bringing the GA260 to my attention and + * convincing me to write this driver. + * - Andrew Gallatin for providing FreeBSD/Alpha support. + */ + +#include <sys/param.h> +#include <sys/device.h> +#include <sys/socket.h> +#include <sys/systm.h> + +#include <net/if.h> +#include <net/if_dl.h> +#include <net/if_media.h> + +#ifdef INET +#include <netinet/in.h> +#include <netinet/in_systm.h> +#include <netinet/in_var.h> +#include <netinet/ip.h> +#include <netinet/if_ether.h> +#endif + +#include <dev/pci/pcireg.h> +#include <dev/pci/pcivar.h> +#include <dev/pci/pcidevs.h> + +#include <dev/ic/tireg.h> +#include <dev/ic/tivar.h> + +int ti_pci_match(struct device *, void *, void *); +void ti_pci_attach(struct device *, struct device *, void *); + +struct cfattach ti_pci_ca = { + sizeof(struct ti_softc), ti_pci_match, ti_pci_attach +}; + +const struct pci_matchid ti_devices[] = { + { PCI_VENDOR_NETGEAR, PCI_PRODUCT_NETGEAR_GA620 }, + { PCI_VENDOR_NETGEAR, PCI_PRODUCT_NETGEAR_GA620T }, + { PCI_VENDOR_ALTEON, PCI_PRODUCT_ALTEON_ACENIC }, + { PCI_VENDOR_ALTEON, PCI_PRODUCT_ALTEON_ACENICT }, + { PCI_VENDOR_3COM, PCI_PRODUCT_3COM_3C985 }, + { PCI_VENDOR_SGI, PCI_PRODUCT_SGI_TIGON }, + { PCI_VENDOR_DEC, PCI_PRODUCT_DEC_PN9000SX } +}; + +int +ti_pci_match(struct device *parent, void *match, void *aux) +{ + return (pci_matchbyid(aux, ti_devices, nitems(ti_devices))); +} + +void +ti_pci_attach(struct device *parent, struct device *self, void *aux) +{ + struct ti_softc *sc = (struct ti_softc *)self; + struct pci_attach_args *pa = aux; + pci_chipset_tag_t pc = pa->pa_pc; + pci_intr_handle_t ih; + const char *intrstr = NULL; + bus_size_t size; + + /* + * Map control/status registers. + */ + if (pci_mapreg_map(pa, TI_PCI_LOMEM, + PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT, 0, + &sc->ti_btag, &sc->ti_bhandle, NULL, &size, 0)) { + printf(": can't map registers\n"); + return; + } + + sc->sc_dmatag = pa->pa_dmat; + + if (pci_intr_map(pa, &ih)) { + printf(": can't map interrupt\n"); + goto unmap; + } + intrstr = pci_intr_string(pc, ih); + sc->ti_intrhand = pci_intr_establish(pc, ih, IPL_NET, ti_intr, sc, + self->dv_xname); + if (sc->ti_intrhand == NULL) { + printf(": can't establish interrupt"); + if (intrstr != NULL) + printf(" at %s", intrstr); + printf("\n"); + goto unmap; + } + printf(": %s", intrstr); + + /* + * We really need a better way to tell a 1000baseTX card + * from a 1000baseSX one, since in theory there could be + * OEMed 1000baseTX cards from lame vendors who aren't + * clever enough to change the PCI ID. For the moment + * though, the AceNIC is the only copper card available. + */ + if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_ALTEON && + PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_ALTEON_ACENICT) + sc->ti_copper = 1; + /* Ok, it's not the only copper card available */ + if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_NETGEAR && + PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_NETGEAR_GA620T) + sc->ti_copper = 1; + + if (ti_attach(sc) == 0) + return; + + pci_intr_disestablish(pc, sc->ti_intrhand); + +unmap: + bus_space_unmap(sc->ti_btag, sc->ti_bhandle, size); +} |