summaryrefslogtreecommitdiff
path: root/sys/dev/pci
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2009-08-29 21:12:56 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2009-08-29 21:12:56 +0000
commit6bed2bd2bebb3bc2213623236ef2874fc2fb9141 (patch)
tree317a2723279afbc8469e3f5a171eb42572736f36 /sys/dev/pci
parentbd1d57e1e7d32857956f0496b2bc2f60338a7a0a (diff)
Split the ti(4) driver into mostly bus-agnostic code and PCI-specific
attachment. Add SBus support to the bus-agnostic code.
Diffstat (limited to 'sys/dev/pci')
-rw-r--r--sys/dev/pci/files.pci7
-rw-r--r--sys/dev/pci/if_ti.c2624
-rw-r--r--sys/dev/pci/if_ti_pci.c181
-rw-r--r--sys/dev/pci/if_tireg.h1175
-rw-r--r--sys/dev/pci/if_tivar.h43
5 files changed, 184 insertions, 3846 deletions
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.c b/sys/dev/pci/if_ti.c
deleted file mode 100644
index 187dd8b25ef..00000000000
--- a/sys/dev/pci/if_ti.c
+++ /dev/null
@@ -1,2624 +0,0 @@
-/* $OpenBSD: if_ti.c,v 1.98 2009/08/13 14:24:47 jasper 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 "bpfilter.h"
-#include "vlan.h"
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/sockio.h>
-#include <sys/mbuf.h>
-#include <sys/malloc.h>
-#include <sys/kernel.h>
-#include <sys/socket.h>
-#include <sys/device.h>
-#include <sys/queue.h>
-
-#include <net/if.h>
-#include <net/if_dl.h>
-#include <net/if_types.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 <net/if_media.h>
-
-#if NBPFILTER > 0
-#include <net/bpf.h>
-#endif
-
-#if NVLAN > 0
-#include <net/if_types.h>
-#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 *);
-
-struct cfattach ti_ca = {
- sizeof(struct ti_softc), ti_probe, ti_attach
-};
-
-struct cfdriver ti_cd = {
- NULL, "ti", DV_IFNET
-};
-
-void ti_txeof_tigon1(struct ti_softc *);
-void ti_txeof_tigon2(struct ti_softc *);
-void ti_rxeof(struct ti_softc *);
-
-void ti_stats_update(struct ti_softc *);
-int ti_encap_tigon1(struct ti_softc *, struct mbuf *, u_int32_t *);
-int ti_encap_tigon2(struct ti_softc *, struct mbuf *, u_int32_t *);
-
-int ti_intr(void *);
-void ti_start(struct ifnet *);
-int ti_ioctl(struct ifnet *, u_long, caddr_t);
-void ti_init(void *);
-void ti_init2(struct ti_softc *);
-void ti_stop(struct ti_softc *);
-void ti_watchdog(struct ifnet *);
-void ti_shutdown(void *);
-int ti_ifmedia_upd(struct ifnet *);
-void ti_ifmedia_sts(struct ifnet *, struct ifmediareq *);
-
-u_int32_t ti_eeprom_putbyte(struct ti_softc *, int);
-u_int8_t ti_eeprom_getbyte(struct ti_softc *, int, u_int8_t *);
-int ti_read_eeprom(struct ti_softc *, caddr_t, int, int);
-
-void ti_add_mcast(struct ti_softc *, struct ether_addr *);
-void ti_del_mcast(struct ti_softc *, struct ether_addr *);
-void ti_setmulti(struct ti_softc *);
-
-void ti_mem_read(struct ti_softc *, u_int32_t, u_int32_t, void *);
-void ti_mem_write(struct ti_softc *, u_int32_t, u_int32_t, const void*);
-void ti_mem_set(struct ti_softc *, u_int32_t, u_int32_t);
-void ti_loadfw(struct ti_softc *);
-void ti_cmd(struct ti_softc *, struct ti_cmd_desc *);
-void ti_cmd_ext(struct ti_softc *, struct ti_cmd_desc *,
- caddr_t, int);
-void ti_handle_events(struct ti_softc *);
-int ti_alloc_jumbo_mem(struct ti_softc *);
-void *ti_jalloc(struct ti_softc *);
-void ti_jfree(caddr_t, u_int, void *);
-int ti_newbuf_std(struct ti_softc *, int, struct mbuf *, bus_dmamap_t);
-int ti_newbuf_mini(struct ti_softc *, int, struct mbuf *, bus_dmamap_t);
-int ti_newbuf_jumbo(struct ti_softc *, int, struct mbuf *);
-int ti_init_rx_ring_std(struct ti_softc *);
-void ti_free_rx_ring_std(struct ti_softc *);
-int ti_init_rx_ring_jumbo(struct ti_softc *);
-void ti_free_rx_ring_jumbo(struct ti_softc *);
-int ti_init_rx_ring_mini(struct ti_softc *);
-void ti_free_rx_ring_mini(struct ti_softc *);
-void ti_free_tx_ring(struct ti_softc *);
-int ti_init_tx_ring(struct ti_softc *);
-
-int ti_64bitslot_war(struct ti_softc *);
-int ti_chipinit(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.
- */
-u_int32_t
-ti_eeprom_putbyte(struct ti_softc *sc, int byte)
-{
- int i, ack = 0;
-
- /*
- * Make sure we're in TX mode.
- */
- TI_SETBIT(sc, TI_MISC_LOCAL_CTL, TI_MLC_EE_TXEN);
-
- /*
- * Feed in each bit and strobe the clock.
- */
- for (i = 0x80; i; i >>= 1) {
- if (byte & i)
- TI_SETBIT(sc, TI_MISC_LOCAL_CTL, TI_MLC_EE_DOUT);
- else
- TI_CLRBIT(sc, TI_MISC_LOCAL_CTL, TI_MLC_EE_DOUT);
- DELAY(1);
- TI_SETBIT(sc, TI_MISC_LOCAL_CTL, TI_MLC_EE_CLK);
- DELAY(1);
- TI_CLRBIT(sc, TI_MISC_LOCAL_CTL, TI_MLC_EE_CLK);
- }
-
- /*
- * Turn off TX mode.
- */
- TI_CLRBIT(sc, TI_MISC_LOCAL_CTL, TI_MLC_EE_TXEN);
-
- /*
- * Check for ack.
- */
- TI_SETBIT(sc, TI_MISC_LOCAL_CTL, TI_MLC_EE_CLK);
- ack = CSR_READ_4(sc, TI_MISC_LOCAL_CTL) & TI_MLC_EE_DIN;
- TI_CLRBIT(sc, TI_MISC_LOCAL_CTL, TI_MLC_EE_CLK);
-
- return (ack);
-}
-
-/*
- * Read a byte of data stored in the EEPROM at address 'addr.'
- * We have to send two address bytes since the EEPROM can hold
- * more than 256 bytes of data.
- */
-u_int8_t
-ti_eeprom_getbyte(struct ti_softc *sc, int addr, u_int8_t *dest)
-{
- int i;
- u_int8_t byte = 0;
-
- EEPROM_START;
-
- /*
- * Send write control code to EEPROM.
- */
- if (ti_eeprom_putbyte(sc, EEPROM_CTL_WRITE)) {
- printf("%s: failed to send write command, status: %x\n",
- sc->sc_dv.dv_xname, CSR_READ_4(sc, TI_MISC_LOCAL_CTL));
- return (1);
- }
-
- /*
- * Send first byte of address of byte we want to read.
- */
- if (ti_eeprom_putbyte(sc, (addr >> 8) & 0xFF)) {
- printf("%s: failed to send address, status: %x\n",
- sc->sc_dv.dv_xname, CSR_READ_4(sc, TI_MISC_LOCAL_CTL));
- return (1);
- }
- /*
- * Send second byte address of byte we want to read.
- */
- if (ti_eeprom_putbyte(sc, addr & 0xFF)) {
- printf("%s: failed to send address, status: %x\n",
- sc->sc_dv.dv_xname, CSR_READ_4(sc, TI_MISC_LOCAL_CTL));
- return (1);
- }
-
- EEPROM_STOP;
- EEPROM_START;
- /*
- * Send read control code to EEPROM.
- */
- if (ti_eeprom_putbyte(sc, EEPROM_CTL_READ)) {
- printf("%s: failed to send read command, status: %x\n",
- sc->sc_dv.dv_xname, CSR_READ_4(sc, TI_MISC_LOCAL_CTL));
- return (1);
- }
-
- /*
- * Start reading bits from EEPROM.
- */
- TI_CLRBIT(sc, TI_MISC_LOCAL_CTL, TI_MLC_EE_TXEN);
- for (i = 0x80; i; i >>= 1) {
- TI_SETBIT(sc, TI_MISC_LOCAL_CTL, TI_MLC_EE_CLK);
- DELAY(1);
- if (CSR_READ_4(sc, TI_MISC_LOCAL_CTL) & TI_MLC_EE_DIN)
- byte |= i;
- TI_CLRBIT(sc, TI_MISC_LOCAL_CTL, TI_MLC_EE_CLK);
- DELAY(1);
- }
-
- EEPROM_STOP;
-
- /*
- * No ACK generated for read, so just return byte.
- */
-
- *dest = byte;
-
- return (0);
-}
-
-/*
- * Read a sequence of bytes from the EEPROM.
- */
-int
-ti_read_eeprom(struct ti_softc *sc, caddr_t dest, int off, int cnt)
-{
- int err = 0, i;
- u_int8_t byte = 0;
-
- for (i = 0; i < cnt; i++) {
- err = ti_eeprom_getbyte(sc, off + i, &byte);
- if (err)
- break;
- *(dest + i) = byte;
- }
-
- return (err ? 1 : 0);
-}
-
-/*
- * NIC memory read function.
- * Can be used to copy data from NIC local memory.
- */
-void
-ti_mem_read(struct ti_softc *sc, u_int32_t addr, u_int32_t len, void *buf)
-{
- int segptr, segsize, cnt;
- caddr_t ptr;
-
- segptr = addr;
- cnt = len;
- ptr = buf;
-
- while(cnt) {
- if (cnt < TI_WINLEN)
- segsize = cnt;
- else
- segsize = TI_WINLEN - (segptr % TI_WINLEN);
- CSR_WRITE_4(sc, TI_WINBASE, (segptr & ~(TI_WINLEN - 1)));
- bus_space_read_region_4(sc->ti_btag, sc->ti_bhandle,
- TI_WINDOW + (segptr & (TI_WINLEN - 1)), (u_int32_t *)ptr,
- segsize / 4);
- ptr += segsize;
- segptr += segsize;
- cnt -= segsize;
- }
-}
-
-/*
- * NIC memory write function.
- * Can be used to copy data into NIC local memory.
- */
-void
-ti_mem_write(struct ti_softc *sc, u_int32_t addr, u_int32_t len,
- const void *buf)
-{
- int segptr, segsize, cnt;
- const char *ptr;
-
- segptr = addr;
- cnt = len;
- ptr = buf;
-
- while(cnt) {
- if (cnt < TI_WINLEN)
- segsize = cnt;
- else
- segsize = TI_WINLEN - (segptr % TI_WINLEN);
- CSR_WRITE_4(sc, TI_WINBASE, (segptr & ~(TI_WINLEN - 1)));
- bus_space_write_region_4(sc->ti_btag, sc->ti_bhandle,
- TI_WINDOW + (segptr & (TI_WINLEN - 1)), (u_int32_t *)ptr,
- segsize / 4);
- ptr += segsize;
- segptr += segsize;
- cnt -= segsize;
- }
-}
-
-/*
- * NIC memory write function.
- * Can be used to clear a section of NIC local memory.
- */
-void
-ti_mem_set(struct ti_softc *sc, u_int32_t addr, u_int32_t len)
-{
- int segptr, segsize, cnt;
-
- segptr = addr;
- cnt = len;
-
- while(cnt) {
- if (cnt < TI_WINLEN)
- segsize = cnt;
- else
- segsize = TI_WINLEN - (segptr % TI_WINLEN);
- CSR_WRITE_4(sc, TI_WINBASE, (segptr & ~(TI_WINLEN - 1)));
- bus_space_set_region_4(sc->ti_btag, sc->ti_bhandle,
- TI_WINDOW + (segptr & (TI_WINLEN - 1)), 0, segsize / 4);
- segptr += segsize;
- cnt -= segsize;
- }
-}
-
-/*
- * Load firmware image into the NIC. Check that the firmware revision
- * is acceptable and see if we want the firmware for the Tigon 1 or
- * Tigon 2.
- */
-void
-ti_loadfw(struct ti_softc *sc)
-{
- struct tigon_firmware *tf;
- u_char *buf = NULL;
- u_int32_t *b;
- size_t buflen, i, cnt;
- char *name;
- int error;
-
- switch(sc->ti_hwrev) {
- case TI_HWREV_TIGON:
- name = "tigon1";
- break;
- case TI_HWREV_TIGON_II:
- name = "tigon2";
- break;
- default:
- printf("%s: can't load firmware: unknown hardware rev\n",
- sc->sc_dv.dv_xname);
- return;
- }
-
- error = loadfirmware(name, &buf, &buflen);
- if (error)
- return;
- /* convert firmware to host byte order */
- b = (u_int32_t *)buf;
- cnt = buflen / sizeof(u_int32_t);
- for (i = 0; i < cnt; i++)
- b[i] = letoh32(b[i]);
-
- tf = (struct tigon_firmware *)buf;
- if (tf->FwReleaseMajor != TI_FIRMWARE_MAJOR ||
- tf->FwReleaseMinor != TI_FIRMWARE_MINOR ||
- tf->FwReleaseFix != TI_FIRMWARE_FIX) {
- printf("%s: firmware revision mismatch; want "
- "%d.%d.%d, got %d.%d.%d\n", sc->sc_dv.dv_xname,
- TI_FIRMWARE_MAJOR, TI_FIRMWARE_MINOR,
- TI_FIRMWARE_FIX, tf->FwReleaseMajor,
- tf->FwReleaseMinor, tf->FwReleaseFix);
- free(buf, M_DEVBUF);
- return;
- }
- ti_mem_write(sc, tf->FwTextAddr, tf->FwTextLen,
- (caddr_t)&tf->data[tf->FwTextOffset]);
- ti_mem_write(sc, tf->FwRodataAddr, tf->FwRodataLen,
- (caddr_t)&tf->data[tf->FwRodataOffset]);
- ti_mem_write(sc, tf->FwDataAddr, tf->FwDataLen,
- (caddr_t)&tf->data[tf->FwDataOffset]);
- ti_mem_set(sc, tf->FwBssAddr, tf->FwBssLen);
- ti_mem_set(sc, tf->FwSbssAddr, tf->FwSbssLen);
- CSR_WRITE_4(sc, TI_CPU_PROGRAM_COUNTER, tf->FwStartAddr);
- free(buf, M_DEVBUF);
-}
-
-/*
- * Send the NIC a command via the command ring.
- */
-void
-ti_cmd(struct ti_softc *sc, struct ti_cmd_desc *cmd)
-{
- u_int32_t index;
-
- index = sc->ti_cmd_saved_prodidx;
- CSR_WRITE_4(sc, TI_GCR_CMDRING + (index * 4), *(u_int32_t *)(cmd));
- TI_INC(index, TI_CMD_RING_CNT);
- CSR_WRITE_4(sc, TI_MB_CMDPROD_IDX, index);
- sc->ti_cmd_saved_prodidx = index;
-}
-
-/*
- * Send the NIC an extended command. The 'len' parameter specifies the
- * number of command slots to include after the initial command.
- */
-void
-ti_cmd_ext(struct ti_softc *sc, struct ti_cmd_desc *cmd, caddr_t arg,
- int len)
-{
- u_int32_t index;
- int i;
-
- index = sc->ti_cmd_saved_prodidx;
- CSR_WRITE_4(sc, TI_GCR_CMDRING + (index * 4), *(u_int32_t *)(cmd));
- TI_INC(index, TI_CMD_RING_CNT);
- for (i = 0; i < len; i++) {
- CSR_WRITE_4(sc, TI_GCR_CMDRING + (index * 4),
- *(u_int32_t *)(&arg[i * 4]));
- TI_INC(index, TI_CMD_RING_CNT);
- }
- CSR_WRITE_4(sc, TI_MB_CMDPROD_IDX, index);
- sc->ti_cmd_saved_prodidx = index;
-}
-
-/*
- * Handle events that have triggered interrupts.
- */
-void
-ti_handle_events(struct ti_softc *sc)
-{
- struct ti_event_desc *e;
- struct ifnet *ifp = &sc->arpcom.ac_if;
-
- if (sc->ti_rdata->ti_event_ring == NULL)
- return;
-
- while (sc->ti_ev_saved_considx != sc->ti_ev_prodidx.ti_idx) {
- e = &sc->ti_rdata->ti_event_ring[sc->ti_ev_saved_considx];
- switch (TI_EVENT_EVENT(e)) {
- case TI_EV_LINKSTAT_CHANGED:
- sc->ti_linkstat = TI_EVENT_CODE(e);
- switch (sc->ti_linkstat) {
- case TI_EV_CODE_LINK_UP:
- case TI_EV_CODE_GIG_LINK_UP:
- {
- struct ifmediareq ifmr;
-
- bzero(&ifmr, sizeof(ifmr));
- ti_ifmedia_sts(ifp, &ifmr);
- if (ifmr.ifm_active & IFM_FDX) {
- ifp->if_link_state =
- LINK_STATE_FULL_DUPLEX;
- } else {
- ifp->if_link_state =
- LINK_STATE_HALF_DUPLEX;
- }
- if_link_state_change(ifp);
- ifp->if_baudrate =
- ifmedia_baudrate(ifmr.ifm_active);
- break;
- }
- case TI_EV_CODE_LINK_DOWN:
- ifp->if_link_state = LINK_STATE_DOWN;
- if_link_state_change(ifp);
- ifp->if_baudrate = 0;
- break;
- default:
- printf("%s: unknown link state code %d\n",
- sc->sc_dv.dv_xname, sc->ti_linkstat);
- }
- break;
- case TI_EV_ERROR:
- if (TI_EVENT_CODE(e) == TI_EV_CODE_ERR_INVAL_CMD)
- printf("%s: invalid command\n",
- sc->sc_dv.dv_xname);
- else if (TI_EVENT_CODE(e) == TI_EV_CODE_ERR_UNIMP_CMD)
- printf("%s: unknown command\n",
- sc->sc_dv.dv_xname);
- else if (TI_EVENT_CODE(e) == TI_EV_CODE_ERR_BADCFG)
- printf("%s: bad config data\n",
- sc->sc_dv.dv_xname);
- break;
- case TI_EV_FIRMWARE_UP:
- ti_init2(sc);
- break;
- case TI_EV_STATS_UPDATED:
- ti_stats_update(sc);
- break;
- case TI_EV_RESET_JUMBO_RING:
- case TI_EV_MCAST_UPDATED:
- /* Who cares. */
- break;
- default:
- printf("%s: unknown event: %d\n", sc->sc_dv.dv_xname,
- TI_EVENT_EVENT(e));
- break;
- }
- /* Advance the consumer index. */
- TI_INC(sc->ti_ev_saved_considx, TI_EVENT_RING_CNT);
- CSR_WRITE_4(sc, TI_GCR_EVENTCONS_IDX, sc->ti_ev_saved_considx);
- }
-}
-
-/*
- * Memory management for the jumbo receive ring is a pain in the
- * butt. We need to allocate at least 9018 bytes of space per frame,
- * _and_ it has to be contiguous (unless you use the extended
- * jumbo descriptor format). Using malloc() all the time won't
- * work: malloc() allocates memory in powers of two, which means we
- * would end up wasting a considerable amount of space by allocating
- * 9K chunks. We don't have a jumbo mbuf cluster pool. Thus, we have
- * to do our own memory management.
- *
- * The driver needs to allocate a contiguous chunk of memory at boot
- * time. We then chop this up ourselves into 9K pieces and use them
- * as external mbuf storage.
- *
- * One issue here is how much memory to allocate. The jumbo ring has
- * 256 slots in it, but at 9K per slot than can consume over 2MB of
- * RAM. This is a bit much, especially considering we also need
- * RAM for the standard ring and mini ring (on the Tigon 2). To
- * save space, we only actually allocate enough memory for 64 slots
- * by default, which works out to between 500 and 600K. This can
- * be tuned by changing a #define in if_tireg.h.
- */
-
-int
-ti_alloc_jumbo_mem(struct ti_softc *sc)
-{
- caddr_t ptr, kva;
- bus_dma_segment_t seg;
- int i, rseg, state, error;
- struct ti_jpool_entry *entry;
-
- state = error = 0;
-
- /* Grab a big chunk o' storage. */
- if (bus_dmamem_alloc(sc->sc_dmatag, TI_JMEM, PAGE_SIZE, 0,
- &seg, 1, &rseg, BUS_DMA_NOWAIT)) {
- printf("%s: can't alloc rx buffers\n", sc->sc_dv.dv_xname);
- return (ENOBUFS);
- }
-
- state = 1;
- if (bus_dmamem_map(sc->sc_dmatag, &seg, rseg, TI_JMEM, &kva,
- BUS_DMA_NOWAIT)) {
- printf("%s: can't map dma buffers (%d bytes)\n",
- sc->sc_dv.dv_xname, TI_JMEM);
- error = ENOBUFS;
- goto out;
- }
-
- state = 2;
- if (bus_dmamap_create(sc->sc_dmatag, TI_JMEM, 1, TI_JMEM, 0,
- BUS_DMA_NOWAIT, &sc->ti_cdata.ti_rx_jumbo_map)) {
- printf("%s: can't create dma map\n", sc->sc_dv.dv_xname);
- error = ENOBUFS;
- goto out;
- }
-
- state = 3;
- if (bus_dmamap_load(sc->sc_dmatag, sc->ti_cdata.ti_rx_jumbo_map, kva,
- TI_JMEM, NULL, BUS_DMA_NOWAIT)) {
- printf("%s: can't load dma map\n", sc->sc_dv.dv_xname);
- error = ENOBUFS;
- goto out;
- }
-
- state = 4;
- sc->ti_cdata.ti_jumbo_buf = (caddr_t)kva;
-
- SLIST_INIT(&sc->ti_jfree_listhead);
- SLIST_INIT(&sc->ti_jinuse_listhead);
-
- /*
- * Now divide it up into 9K pieces and save the addresses
- * in an array.
- */
- ptr = sc->ti_cdata.ti_jumbo_buf;
- for (i = 0; i < TI_JSLOTS; i++) {
- sc->ti_cdata.ti_jslots[i].ti_buf = ptr;
- sc->ti_cdata.ti_jslots[i].ti_inuse = 0;
- ptr += TI_JLEN;
- entry = malloc(sizeof(struct ti_jpool_entry),
- M_DEVBUF, M_NOWAIT);
- if (entry == NULL) {
- sc->ti_cdata.ti_jumbo_buf = NULL;
- printf("%s: no memory for jumbo buffer queue\n",
- sc->sc_dv.dv_xname);
- error = ENOBUFS;
- goto out;
- }
- entry->slot = i;
- SLIST_INSERT_HEAD(&sc->ti_jfree_listhead, entry, jpool_entries);
- }
-out:
- if (error != 0) {
- switch (state) {
- case 4:
- bus_dmamap_unload(sc->sc_dmatag,
- sc->ti_cdata.ti_rx_jumbo_map);
- case 3:
- bus_dmamap_destroy(sc->sc_dmatag,
- sc->ti_cdata.ti_rx_jumbo_map);
- case 2:
- bus_dmamem_unmap(sc->sc_dmatag, kva, TI_JMEM);
- case 1:
- bus_dmamem_free(sc->sc_dmatag, &seg, rseg);
- break;
- default:
- break;
- }
- }
-
- return (error);
-}
-
-/*
- * Allocate a jumbo buffer.
- */
-void *
-ti_jalloc(struct ti_softc *sc)
-{
- struct ti_jpool_entry *entry;
-
- entry = SLIST_FIRST(&sc->ti_jfree_listhead);
-
- if (entry == NULL)
- return (NULL);
-
- SLIST_REMOVE_HEAD(&sc->ti_jfree_listhead, jpool_entries);
- SLIST_INSERT_HEAD(&sc->ti_jinuse_listhead, entry, jpool_entries);
- sc->ti_cdata.ti_jslots[entry->slot].ti_inuse = 1;
- return (sc->ti_cdata.ti_jslots[entry->slot].ti_buf);
-}
-
-/*
- * Release a jumbo buffer.
- */
-void
-ti_jfree(caddr_t buf, u_int size, void *arg)
-{
- struct ti_softc *sc;
- int i;
- struct ti_jpool_entry *entry;
-
- /* Extract the softc struct pointer. */
- sc = (struct ti_softc *)arg;
-
- if (sc == NULL)
- panic("ti_jfree: can't find softc pointer!");
-
- /* calculate the slot this buffer belongs to */
- i = ((vaddr_t)buf - (vaddr_t)sc->ti_cdata.ti_jumbo_buf) / TI_JLEN;
-
- if ((i < 0) || (i >= TI_JSLOTS))
- panic("ti_jfree: asked to free buffer that we don't manage!");
- else if (sc->ti_cdata.ti_jslots[i].ti_inuse == 0)
- panic("ti_jfree: buffer already free!");
-
- sc->ti_cdata.ti_jslots[i].ti_inuse--;
- if(sc->ti_cdata.ti_jslots[i].ti_inuse == 0) {
- entry = SLIST_FIRST(&sc->ti_jinuse_listhead);
- if (entry == NULL)
- panic("ti_jfree: buffer not in use!");
- entry->slot = i;
- SLIST_REMOVE_HEAD(&sc->ti_jinuse_listhead, jpool_entries);
- SLIST_INSERT_HEAD(&sc->ti_jfree_listhead,
- entry, jpool_entries);
- }
-}
-
-/*
- * Intialize a standard receive ring descriptor.
- */
-int
-ti_newbuf_std(struct ti_softc *sc, int i, struct mbuf *m,
- bus_dmamap_t dmamap)
-{
- struct mbuf *m_new = NULL;
- struct ti_rx_desc *r;
-
- if (dmamap == NULL) {
- /* if (m) panic() */
-
- if (bus_dmamap_create(sc->sc_dmatag, MCLBYTES, 1, MCLBYTES,
- 0, BUS_DMA_NOWAIT, &dmamap)) {
- printf("%s: can't create recv map\n",
- sc->sc_dv.dv_xname);
- return (ENOMEM);
- }
- } else if (m == NULL)
- bus_dmamap_unload(sc->sc_dmatag, dmamap);
-
- sc->ti_cdata.ti_rx_std_map[i] = dmamap;
-
- if (m == NULL) {
- MGETHDR(m_new, M_DONTWAIT, MT_DATA);
- if (m_new == NULL)
- return (ENOBUFS);
-
- MCLGET(m_new, M_DONTWAIT);
- if (!(m_new->m_flags & M_EXT)) {
- m_freem(m_new);
- return (ENOBUFS);
- }
- m_new->m_len = m_new->m_pkthdr.len = MCLBYTES;
-
- m_adj(m_new, ETHER_ALIGN);
-
- if (bus_dmamap_load_mbuf(sc->sc_dmatag, dmamap, m_new,
- BUS_DMA_NOWAIT))
- return (ENOBUFS);
-
- } else {
- /*
- * We're re-using a previously allocated mbuf;
- * be sure to re-init pointers and lengths to
- * default values.
- */
- m_new = m;
- m_new->m_len = m_new->m_pkthdr.len = MCLBYTES;
- m_new->m_data = m_new->m_ext.ext_buf;
- m_adj(m_new, ETHER_ALIGN);
- }
-
- sc->ti_cdata.ti_rx_std_chain[i] = m_new;
- r = &sc->ti_rdata->ti_rx_std_ring[i];
- TI_HOSTADDR(r->ti_addr) = dmamap->dm_segs[0].ds_addr;
- r->ti_type = TI_BDTYPE_RECV_BD;
- r->ti_flags = TI_BDFLAG_IP_CKSUM;
- r->ti_len = dmamap->dm_segs[0].ds_len;
- r->ti_idx = i;
-
- if ((dmamap->dm_segs[0].ds_addr & ~(MCLBYTES - 1)) !=
- ((dmamap->dm_segs[0].ds_addr + dmamap->dm_segs[0].ds_len - 1) &
- ~(MCLBYTES - 1)))
- panic("%s: overwritten!!!", sc->sc_dv.dv_xname);
-
- return (0);
-}
-
-/*
- * Intialize a mini receive ring descriptor. This only applies to
- * the Tigon 2.
- */
-int
-ti_newbuf_mini(struct ti_softc *sc, int i, struct mbuf *m,
- bus_dmamap_t dmamap)
-{
- struct mbuf *m_new = NULL;
- struct ti_rx_desc *r;
-
- if (dmamap == NULL) {
- /* if (m) panic() */
-
- if (bus_dmamap_create(sc->sc_dmatag, MHLEN, 1, MHLEN,
- 0, BUS_DMA_NOWAIT, &dmamap)) {
- printf("%s: can't create recv map\n",
- sc->sc_dv.dv_xname);
- return (ENOMEM);
- }
- } else if (m == NULL)
- bus_dmamap_unload(sc->sc_dmatag, dmamap);
-
- sc->ti_cdata.ti_rx_mini_map[i] = dmamap;
-
- if (m == NULL) {
- MGETHDR(m_new, M_DONTWAIT, MT_DATA);
- if (m_new == NULL)
- return (ENOBUFS);
- m_new->m_len = m_new->m_pkthdr.len = MHLEN;
- m_adj(m_new, ETHER_ALIGN);
-
- if (bus_dmamap_load_mbuf(sc->sc_dmatag, dmamap, m_new,
- BUS_DMA_NOWAIT))
- return (ENOBUFS);
-
- } else {
- /*
- * We're re-using a previously allocated mbuf;
- * be sure to re-init pointers and lengths to
- * default values.
- */
- m_new = m;
- m_new->m_data = m_new->m_pktdat;
- m_new->m_len = m_new->m_pkthdr.len = MHLEN;
- }
-
- r = &sc->ti_rdata->ti_rx_mini_ring[i];
- sc->ti_cdata.ti_rx_mini_chain[i] = m_new;
- TI_HOSTADDR(r->ti_addr) = dmamap->dm_segs[0].ds_addr;
- r->ti_type = TI_BDTYPE_RECV_BD;
- r->ti_flags = TI_BDFLAG_MINI_RING | TI_BDFLAG_IP_CKSUM;
- r->ti_len = dmamap->dm_segs[0].ds_len;
- r->ti_idx = i;
-
- return (0);
-}
-
-/*
- * Initialize a jumbo receive ring descriptor. This allocates
- * a jumbo buffer from the pool managed internally by the driver.
- */
-int
-ti_newbuf_jumbo(struct ti_softc *sc, int i, struct mbuf *m)
-{
- struct mbuf *m_new = NULL;
- struct ti_rx_desc *r;
-
- if (m == NULL) {
- caddr_t buf = NULL;
-
- /* Allocate the mbuf. */
- MGETHDR(m_new, M_DONTWAIT, MT_DATA);
- if (m_new == NULL)
- return (ENOBUFS);
-
- /* Allocate the jumbo buffer */
- buf = ti_jalloc(sc);
- if (buf == NULL) {
- m_freem(m_new);
- return (ENOBUFS);
- }
-
- /* Attach the buffer to the mbuf. */
- m_new->m_len = m_new->m_pkthdr.len = TI_JUMBO_FRAMELEN;
- MEXTADD(m_new, buf, TI_JUMBO_FRAMELEN, 0, ti_jfree, sc);
- } else {
- /*
- * We're re-using a previously allocated mbuf;
- * be sure to re-init pointers and lengths to
- * default values.
- */
- m_new = m;
- m_new->m_data = m_new->m_ext.ext_buf;
- m_new->m_ext.ext_size = TI_JUMBO_FRAMELEN;
- }
-
- m_adj(m_new, ETHER_ALIGN);
- /* Set up the descriptor. */
- r = &sc->ti_rdata->ti_rx_jumbo_ring[i];
- sc->ti_cdata.ti_rx_jumbo_chain[i] = m_new;
- TI_HOSTADDR(r->ti_addr) = TI_JUMBO_DMA_ADDR(sc, m_new);
- r->ti_type = TI_BDTYPE_RECV_JUMBO_BD;
- r->ti_flags = TI_BDFLAG_JUMBO_RING | TI_BDFLAG_IP_CKSUM;
- r->ti_len = m_new->m_len;
- r->ti_idx = i;
-
- return (0);
-}
-
-/*
- * The standard receive ring has 512 entries in it. At 2K per mbuf cluster,
- * that's 1MB of memory, which is a lot. For now, we fill only the first
- * 256 ring entries and hope that our CPU is fast enough to keep up with
- * the NIC.
- */
-int
-ti_init_rx_ring_std(struct ti_softc *sc)
-{
- int i;
- struct ti_cmd_desc cmd;
-
- for (i = 0; i < TI_SSLOTS; i++) {
- if (ti_newbuf_std(sc, i, NULL, 0) == ENOBUFS)
- return (ENOBUFS);
- }
-
- TI_UPDATE_STDPROD(sc, i - 1);
- sc->ti_std = i - 1;
-
- return (0);
-}
-
-void
-ti_free_rx_ring_std(struct ti_softc *sc)
-{
- int i;
-
- for (i = 0; i < TI_STD_RX_RING_CNT; i++) {
- if (sc->ti_cdata.ti_rx_std_chain[i] != NULL) {
- m_freem(sc->ti_cdata.ti_rx_std_chain[i]);
- sc->ti_cdata.ti_rx_std_chain[i] = NULL;
- bus_dmamap_destroy(sc->sc_dmatag,
- sc->ti_cdata.ti_rx_std_map[i]);
- sc->ti_cdata.ti_rx_std_map[i] = 0;
- }
- bzero((char *)&sc->ti_rdata->ti_rx_std_ring[i],
- sizeof(struct ti_rx_desc));
- }
-}
-
-int
-ti_init_rx_ring_jumbo(struct ti_softc *sc)
-{
- int i;
- struct ti_cmd_desc cmd;
-
- for (i = 0; i < TI_JUMBO_RX_RING_CNT; i++) {
- if (ti_newbuf_jumbo(sc, i, NULL) == ENOBUFS)
- return (ENOBUFS);
- };
-
- TI_UPDATE_JUMBOPROD(sc, i - 1);
- sc->ti_jumbo = i - 1;
-
- return (0);
-}
-
-void
-ti_free_rx_ring_jumbo(struct ti_softc *sc)
-{
- int i;
-
- for (i = 0; i < TI_JUMBO_RX_RING_CNT; i++) {
- if (sc->ti_cdata.ti_rx_jumbo_chain[i] != NULL) {
- m_freem(sc->ti_cdata.ti_rx_jumbo_chain[i]);
- sc->ti_cdata.ti_rx_jumbo_chain[i] = NULL;
- }
- bzero((char *)&sc->ti_rdata->ti_rx_jumbo_ring[i],
- sizeof(struct ti_rx_desc));
- }
-}
-
-int
-ti_init_rx_ring_mini(struct ti_softc *sc)
-{
- int i;
-
- for (i = 0; i < TI_MSLOTS; i++) {
- if (ti_newbuf_mini(sc, i, NULL, 0) == ENOBUFS)
- return (ENOBUFS);
- };
-
- TI_UPDATE_MINIPROD(sc, i - 1);
- sc->ti_mini = i - 1;
-
- return (0);
-}
-
-void
-ti_free_rx_ring_mini(struct ti_softc *sc)
-{
- int i;
-
- for (i = 0; i < TI_MINI_RX_RING_CNT; i++) {
- if (sc->ti_cdata.ti_rx_mini_chain[i] != NULL) {
- m_freem(sc->ti_cdata.ti_rx_mini_chain[i]);
- sc->ti_cdata.ti_rx_mini_chain[i] = NULL;
- bus_dmamap_destroy(sc->sc_dmatag,
- sc->ti_cdata.ti_rx_mini_map[i]);
- sc->ti_cdata.ti_rx_mini_map[i] = 0;
- }
- bzero((char *)&sc->ti_rdata->ti_rx_mini_ring[i],
- sizeof(struct ti_rx_desc));
- }
-}
-
-void
-ti_free_tx_ring(struct ti_softc *sc)
-{
- int i;
- struct ti_txmap_entry *entry;
-
- if (sc->ti_rdata->ti_tx_ring == NULL)
- return;
-
- for (i = 0; i < TI_TX_RING_CNT; i++) {
- if (sc->ti_cdata.ti_tx_chain[i] != NULL) {
- m_freem(sc->ti_cdata.ti_tx_chain[i]);
- sc->ti_cdata.ti_tx_chain[i] = NULL;
- SLIST_INSERT_HEAD(&sc->ti_tx_map_listhead,
- sc->ti_cdata.ti_tx_map[i], link);
- sc->ti_cdata.ti_tx_map[i] = 0;
- }
- bzero((char *)&sc->ti_rdata->ti_tx_ring[i],
- sizeof(struct ti_tx_desc));
- }
-
- while ((entry = SLIST_FIRST(&sc->ti_tx_map_listhead))) {
- SLIST_REMOVE_HEAD(&sc->ti_tx_map_listhead, link);
- bus_dmamap_destroy(sc->sc_dmatag, entry->dmamap);
- free(entry, M_DEVBUF);
- }
-}
-
-int
-ti_init_tx_ring(struct ti_softc *sc)
-{
- int i;
- bus_dmamap_t dmamap;
- struct ti_txmap_entry *entry;
-
- sc->ti_txcnt = 0;
- sc->ti_tx_saved_considx = 0;
- sc->ti_tx_saved_prodidx = 0;
- CSR_WRITE_4(sc, TI_MB_SENDPROD_IDX, 0);
-
- SLIST_INIT(&sc->ti_tx_map_listhead);
- for (i = 0; i < TI_TX_RING_CNT; i++) {
- if (bus_dmamap_create(sc->sc_dmatag, TI_JUMBO_FRAMELEN,
- TI_NTXSEG, MCLBYTES, 0, BUS_DMA_NOWAIT, &dmamap))
- return (ENOBUFS);
-
- entry = malloc(sizeof(*entry), M_DEVBUF, M_NOWAIT);
- if (!entry) {
- bus_dmamap_destroy(sc->sc_dmatag, dmamap);
- return (ENOBUFS);
- }
- entry->dmamap = dmamap;
- SLIST_INSERT_HEAD(&sc->ti_tx_map_listhead, entry, link);
- }
-
- return (0);
-}
-
-/*
- * The Tigon 2 firmware has a new way to add/delete multicast addresses,
- * but we have to support the old way too so that Tigon 1 cards will
- * work.
- */
-void
-ti_add_mcast(struct ti_softc *sc, struct ether_addr *addr)
-{
- struct ti_cmd_desc cmd;
- u_int16_t *m;
- u_int32_t ext[2] = {0, 0};
-
- m = (u_int16_t *)&addr->ether_addr_octet[0];
-
- switch(sc->ti_hwrev) {
- case TI_HWREV_TIGON:
- CSR_WRITE_4(sc, TI_GCR_MAR0, htons(m[0]));
- CSR_WRITE_4(sc, TI_GCR_MAR1, (htons(m[1]) << 16) | htons(m[2]));
- TI_DO_CMD(TI_CMD_ADD_MCAST_ADDR, 0, 0);
- break;
- case TI_HWREV_TIGON_II:
- ext[0] = htons(m[0]);
- ext[1] = (htons(m[1]) << 16) | htons(m[2]);
- TI_DO_CMD_EXT(TI_CMD_EXT_ADD_MCAST, 0, 0, (caddr_t)&ext, 2);
- break;
- default:
- printf("%s: unknown hwrev\n", sc->sc_dv.dv_xname);
- break;
- }
-}
-
-void
-ti_del_mcast(struct ti_softc *sc, struct ether_addr *addr)
-{
- struct ti_cmd_desc cmd;
- u_int16_t *m;
- u_int32_t ext[2] = {0, 0};
-
- m = (u_int16_t *)&addr->ether_addr_octet[0];
-
- switch(sc->ti_hwrev) {
- case TI_HWREV_TIGON:
- CSR_WRITE_4(sc, TI_GCR_MAR0, htons(m[0]));
- CSR_WRITE_4(sc, TI_GCR_MAR1, (htons(m[1]) << 16) | htons(m[2]));
- TI_DO_CMD(TI_CMD_DEL_MCAST_ADDR, 0, 0);
- break;
- case TI_HWREV_TIGON_II:
- ext[0] = htons(m[0]);
- ext[1] = (htons(m[1]) << 16) | htons(m[2]);
- TI_DO_CMD_EXT(TI_CMD_EXT_DEL_MCAST, 0, 0, (caddr_t)&ext, 2);
- break;
- default:
- printf("%s: unknown hwrev\n", sc->sc_dv.dv_xname);
- break;
- }
-}
-
-/*
- * Configure the Tigon's multicast address filter.
- *
- * The actual multicast table management is a bit of a pain, thanks to
- * slight brain damage on the part of both Alteon and us. With our
- * multicast code, we are only alerted when the multicast address table
- * changes and at that point we only have the current list of addresses:
- * we only know the current state, not the previous state, so we don't
- * actually know what addresses were removed or added. The firmware has
- * state, but we can't get our grubby mits on it, and there is no 'delete
- * all multicast addresses' command. Hence, we have to maintain our own
- * state so we know what addresses have been programmed into the NIC at
- * any given time.
- */
-void
-ti_setmulti(struct ti_softc *sc)
-{
- struct ifnet *ifp;
- struct arpcom *ac = &sc->arpcom;
- struct ether_multi *enm;
- struct ether_multistep step;
- struct ti_cmd_desc cmd;
- struct ti_mc_entry *mc;
- u_int32_t intrs;
-
- ifp = &sc->arpcom.ac_if;
-
-allmulti:
- if (ifp->if_flags & IFF_ALLMULTI) {
- TI_DO_CMD(TI_CMD_SET_ALLMULTI, TI_CMD_CODE_ALLMULTI_ENB, 0);
- return;
- } else {
- TI_DO_CMD(TI_CMD_SET_ALLMULTI, TI_CMD_CODE_ALLMULTI_DIS, 0);
- }
-
- /* Disable interrupts. */
- intrs = CSR_READ_4(sc, TI_MB_HOSTINTR);
- CSR_WRITE_4(sc, TI_MB_HOSTINTR, 1);
-
- /* First, zot all the existing filters. */
- while (SLIST_FIRST(&sc->ti_mc_listhead) != NULL) {
- mc = SLIST_FIRST(&sc->ti_mc_listhead);
- ti_del_mcast(sc, &mc->mc_addr);
- SLIST_REMOVE_HEAD(&sc->ti_mc_listhead, mc_entries);
- free(mc, M_DEVBUF);
- }
-
- /* Now program new ones. */
- ETHER_FIRST_MULTI(step, ac, enm);
- while (enm != NULL) {
- if (bcmp(enm->enm_addrlo, enm->enm_addrhi, ETHER_ADDR_LEN)) {
- /* Re-enable interrupts. */
- CSR_WRITE_4(sc, TI_MB_HOSTINTR, intrs);
-
- ifp->if_flags |= IFF_ALLMULTI;
- goto allmulti;
- }
- mc = malloc(sizeof(struct ti_mc_entry), M_DEVBUF, M_NOWAIT);
- if (mc == NULL)
- panic("ti_setmulti");
- bcopy(enm->enm_addrlo, (char *)&mc->mc_addr, ETHER_ADDR_LEN);
- SLIST_INSERT_HEAD(&sc->ti_mc_listhead, mc, mc_entries);
- ti_add_mcast(sc, &mc->mc_addr);
- ETHER_NEXT_MULTI(step, enm);
- }
-
- /* Re-enable interrupts. */
- CSR_WRITE_4(sc, TI_MB_HOSTINTR, intrs);
-}
-
-/*
- * Check to see if the BIOS has configured us for a 64 bit slot when
- * we aren't actually in one. If we detect this condition, we can work
- * around it on the Tigon 2 by setting a bit in the PCI state register,
- * but for the Tigon 1 we must give up and abort the interface attach.
- */
-int
-ti_64bitslot_war(struct ti_softc *sc)
-{
- if (!(CSR_READ_4(sc, TI_PCI_STATE) & TI_PCISTATE_32BIT_BUS)) {
- CSR_WRITE_4(sc, 0x600, 0);
- CSR_WRITE_4(sc, 0x604, 0);
- CSR_WRITE_4(sc, 0x600, 0x5555AAAA);
- if (CSR_READ_4(sc, 0x604) == 0x5555AAAA) {
- if (sc->ti_hwrev == TI_HWREV_TIGON)
- return (EINVAL);
- else {
- TI_SETBIT(sc, TI_PCI_STATE,
- TI_PCISTATE_32BIT_BUS);
- return (0);
- }
- }
- }
-
- return (0);
-}
-
-/*
- * Do endian, PCI and DMA initialization. Also check the on-board ROM
- * self-test results.
- */
-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. */
- sc->ti_linkstat = TI_EV_CODE_LINK_DOWN;
-
- /* Set endianness before we access any non-PCI registers. */
- CSR_WRITE_4(sc, TI_MISC_HOST_CTL,
- TI_MHC_LITTLEENDIAN_INIT | (TI_MHC_LITTLEENDIAN_INIT << 24));
-
- /* Check the ROM failed bit to see if self-tests passed. */
- if (CSR_READ_4(sc, TI_CPU_STATE) & TI_CPUSTATE_ROMFAIL) {
- printf("%s: board self-diagnostics failed!\n",
- sc->sc_dv.dv_xname);
- return (ENODEV);
- }
-
- /* Halt the CPU. */
- TI_SETBIT(sc, TI_CPU_STATE, TI_CPUSTATE_HALT);
-
- /* Figure out the hardware revision. */
- chip_rev = CSR_READ_4(sc, TI_MISC_HOST_CTL) & TI_MHC_CHIP_REV_MASK;
- switch(chip_rev) {
- case TI_REV_TIGON_I:
- sc->ti_hwrev = TI_HWREV_TIGON;
- break;
- case TI_REV_TIGON_II:
- sc->ti_hwrev = TI_HWREV_TIGON_II;
- break;
- default:
- printf("\n");
- printf("%s: unsupported chip revision: %x\n",
- sc->sc_dv.dv_xname, chip_rev);
- return (ENODEV);
- }
-
- /* Do special setup for Tigon 2. */
- if (sc->ti_hwrev == TI_HWREV_TIGON_II) {
- TI_SETBIT(sc, TI_CPU_CTL_B, TI_CPUSTATE_HALT);
- TI_SETBIT(sc, TI_MISC_LOCAL_CTL, TI_MLC_SRAM_BANK_512K);
- TI_SETBIT(sc, TI_MISC_CONF, TI_MCR_SRAM_SYNCHRONOUS);
- }
-
- /* Set up the PCI state register. */
- 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);
-
- /* Clear the read/write max DMA parameters. */
- TI_CLRBIT(sc, TI_PCI_STATE, (TI_PCISTATE_WRITE_MAXDMA|
- TI_PCISTATE_READ_MAXDMA));
-
- /* Get cache line size. */
- cacheline = CSR_READ_4(sc, TI_PCI_BIST) & 0xFF;
-
- /*
- * If the system has set enabled the PCI memory write
- * and invalidate command in the command register, set
- * the write max parameter accordingly. This is necessary
- * to use MWI with the Tigon 2.
- */
- if (CSR_READ_4(sc, TI_PCI_CMDSTAT) & PCI_COMMAND_INVALIDATE_ENABLE) {
- switch(cacheline) {
- case 1:
- case 4:
- case 8:
- case 16:
- case 32:
- case 64:
- break;
- default:
- /* Disable PCI memory write and invalidate. */
- CSR_WRITE_4(sc, TI_PCI_CMDSTAT, CSR_READ_4(sc,
- TI_PCI_CMDSTAT) & ~PCI_COMMAND_INVALIDATE_ENABLE);
- break;
- }
- }
-
-#ifdef __brokenalpha__
- /*
- * From the Alteon sample driver:
- * Must insure that we do not cross an 8K (bytes) boundary
- * for DMA reads. Our highest limit is 1K bytes. This is a
- * restriction on some ALPHA platforms with early revision
- * 21174 PCI chipsets, such as the AlphaPC 164lx
- */
- TI_SETBIT(sc, TI_PCI_STATE, pci_writemax|TI_PCI_READMAX_1024);
-#else
- TI_SETBIT(sc, TI_PCI_STATE, pci_writemax);
-#endif
-
- /* This sets the min dma param all the way up (0xff). */
- TI_SETBIT(sc, TI_PCI_STATE, TI_PCISTATE_MINDMA);
-
- /* Configure DMA variables. */
- 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);
- }
-
- return (0);
-}
-
-/*
- * Initialize the general information block and firmware, and
- * start the CPU(s) running.
- */
-int
-ti_gibinit(struct ti_softc *sc)
-{
- struct ti_rcb *rcb;
- int i;
- struct ifnet *ifp;
-
- ifp = &sc->arpcom.ac_if;
-
- /* Disable interrupts for now. */
- CSR_WRITE_4(sc, TI_MB_HOSTINTR, 1);
-
- /*
- * Tell the chip where to find the general information block.
- * While this struct could go into >4GB memory, we allocate it in a
- * single slab with the other descriptors, and those don't seem to
- * support being located in a 64-bit region.
- */
- CSR_WRITE_4(sc, TI_GCR_GENINFO_HI, 0);
- CSR_WRITE_4(sc, TI_GCR_GENINFO_LO,
- TI_RING_DMA_ADDR(sc, ti_info) & 0xffffffff);
-
- /* Load the firmware into SRAM. */
- ti_loadfw(sc);
-
- /* Set up the contents of the general info and ring control blocks. */
-
- /* Set up the event ring and producer pointer. */
- rcb = &sc->ti_rdata->ti_info.ti_ev_rcb;
-
- TI_HOSTADDR(rcb->ti_hostaddr) = TI_RING_DMA_ADDR(sc, ti_event_ring);
- rcb->ti_flags = 0;
- TI_HOSTADDR(sc->ti_rdata->ti_info.ti_ev_prodidx_ptr) =
- TI_RING_DMA_ADDR(sc, ti_ev_prodidx_r);
- sc->ti_ev_prodidx.ti_idx = 0;
- CSR_WRITE_4(sc, TI_GCR_EVENTCONS_IDX, 0);
- sc->ti_ev_saved_considx = 0;
-
- /* Set up the command ring and producer mailbox. */
- rcb = &sc->ti_rdata->ti_info.ti_cmd_rcb;
-
- TI_HOSTADDR(rcb->ti_hostaddr) = TI_GCR_NIC_ADDR(TI_GCR_CMDRING);
- rcb->ti_flags = 0;
- rcb->ti_max_len = 0;
- for (i = 0; i < TI_CMD_RING_CNT; i++) {
- CSR_WRITE_4(sc, TI_GCR_CMDRING + (i * 4), 0);
- }
- CSR_WRITE_4(sc, TI_GCR_CMDCONS_IDX, 0);
- CSR_WRITE_4(sc, TI_MB_CMDPROD_IDX, 0);
- sc->ti_cmd_saved_prodidx = 0;
-
- /*
- * Assign the address of the stats refresh buffer.
- * We re-use the current stats buffer for this to
- * conserve memory.
- */
- TI_HOSTADDR(sc->ti_rdata->ti_info.ti_refresh_stats_ptr) =
- TI_RING_DMA_ADDR(sc, ti_info.ti_stats);
-
- /* Set up the standard receive ring. */
- rcb = &sc->ti_rdata->ti_info.ti_std_rx_rcb;
- TI_HOSTADDR(rcb->ti_hostaddr) =
- TI_RING_DMA_ADDR(sc, ti_rx_std_ring);
- rcb->ti_max_len = ETHER_MAX_LEN;
- rcb->ti_flags = 0;
- rcb->ti_flags |= TI_RCB_FLAG_IP_CKSUM | TI_RCB_FLAG_NO_PHDR_CKSUM;
-#if NVLAN > 0
- if (ifp->if_capabilities & IFCAP_VLAN_HWTAGGING)
- rcb->ti_flags |= TI_RCB_FLAG_VLAN_ASSIST;
-#endif
-
- /* Set up the jumbo receive ring. */
- rcb = &sc->ti_rdata->ti_info.ti_jumbo_rx_rcb;
- TI_HOSTADDR(rcb->ti_hostaddr) = TI_RING_DMA_ADDR(sc, ti_rx_jumbo_ring);
- rcb->ti_max_len = TI_JUMBO_FRAMELEN;
- rcb->ti_flags = 0;
- rcb->ti_flags |= TI_RCB_FLAG_IP_CKSUM | TI_RCB_FLAG_NO_PHDR_CKSUM;
-#if NVLAN > 0
- if (ifp->if_capabilities & IFCAP_VLAN_HWTAGGING)
- rcb->ti_flags |= TI_RCB_FLAG_VLAN_ASSIST;
-#endif
-
- /*
- * Set up the mini ring. Only activated on the
- * Tigon 2 but the slot in the config block is
- * still there on the Tigon 1.
- */
- rcb = &sc->ti_rdata->ti_info.ti_mini_rx_rcb;
- TI_HOSTADDR(rcb->ti_hostaddr) = TI_RING_DMA_ADDR(sc, ti_rx_mini_ring);
- rcb->ti_max_len = MHLEN - ETHER_ALIGN;
- if (sc->ti_hwrev == TI_HWREV_TIGON)
- rcb->ti_flags = TI_RCB_FLAG_RING_DISABLED;
- else
- rcb->ti_flags = 0;
- rcb->ti_flags |= TI_RCB_FLAG_IP_CKSUM | TI_RCB_FLAG_NO_PHDR_CKSUM;
-#if NVLAN > 0
- if (ifp->if_capabilities & IFCAP_VLAN_HWTAGGING)
- rcb->ti_flags |= TI_RCB_FLAG_VLAN_ASSIST;
-#endif
-
- /*
- * Set up the receive return ring.
- */
- rcb = &sc->ti_rdata->ti_info.ti_return_rcb;
- TI_HOSTADDR(rcb->ti_hostaddr) = TI_RING_DMA_ADDR(sc,ti_rx_return_ring);
- rcb->ti_flags = 0;
- rcb->ti_max_len = TI_RETURN_RING_CNT;
- TI_HOSTADDR(sc->ti_rdata->ti_info.ti_return_prodidx_ptr) =
- TI_RING_DMA_ADDR(sc, ti_return_prodidx_r);
-
- /*
- * Set up the tx ring. Note: for the Tigon 2, we have the option
- * of putting the transmit ring in the host's address space and
- * letting the chip DMA it instead of leaving the ring in the NIC's
- * memory and accessing it through the shared memory region. We
- * do this for the Tigon 2, but it doesn't work on the Tigon 1,
- * so we have to revert to the shared memory scheme if we detect
- * a Tigon 1 chip.
- */
- CSR_WRITE_4(sc, TI_WINBASE, TI_TX_RING_BASE);
- bzero((char *)sc->ti_rdata->ti_tx_ring,
- TI_TX_RING_CNT * sizeof(struct ti_tx_desc));
- rcb = &sc->ti_rdata->ti_info.ti_tx_rcb;
- if (sc->ti_hwrev == TI_HWREV_TIGON)
- rcb->ti_flags = 0;
- else
- rcb->ti_flags = TI_RCB_FLAG_HOST_RING;
- rcb->ti_flags |= TI_RCB_FLAG_IP_CKSUM | TI_RCB_FLAG_NO_PHDR_CKSUM;
-#if NVLAN > 0
- if (ifp->if_capabilities & IFCAP_VLAN_HWTAGGING)
- rcb->ti_flags |= TI_RCB_FLAG_VLAN_ASSIST;
-#endif
- rcb->ti_max_len = TI_TX_RING_CNT;
- if (sc->ti_hwrev == TI_HWREV_TIGON)
- TI_HOSTADDR(rcb->ti_hostaddr) = TI_TX_RING_BASE;
- else
- TI_HOSTADDR(rcb->ti_hostaddr) =
- TI_RING_DMA_ADDR(sc, ti_tx_ring);
- TI_HOSTADDR(sc->ti_rdata->ti_info.ti_tx_considx_ptr) =
- TI_RING_DMA_ADDR(sc, ti_tx_considx_r);
-
- TI_RING_DMASYNC(sc, ti_info, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
-
- /* Set up tuneables */
- CSR_WRITE_4(sc, TI_GCR_RX_COAL_TICKS, (sc->ti_rx_coal_ticks / 10));
- CSR_WRITE_4(sc, TI_GCR_TX_COAL_TICKS, sc->ti_tx_coal_ticks);
- CSR_WRITE_4(sc, TI_GCR_STAT_TICKS, sc->ti_stat_ticks);
- CSR_WRITE_4(sc, TI_GCR_RX_MAX_COAL_BD, sc->ti_rx_max_coal_bds);
- CSR_WRITE_4(sc, TI_GCR_TX_MAX_COAL_BD, sc->ti_tx_max_coal_bds);
- CSR_WRITE_4(sc, TI_GCR_TX_BUFFER_RATIO, sc->ti_tx_buf_ratio);
-
- /* Turn interrupts on. */
- CSR_WRITE_4(sc, TI_GCR_MASK_INTRS, 0);
- CSR_WRITE_4(sc, TI_MB_HOSTINTR, 0);
-
- /* Start CPU. */
- TI_CLRBIT(sc, TI_CPU_STATE, (TI_CPUSTATE_HALT|TI_CPUSTATE_STEP));
-
- 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)
-{
- 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;
- }
-
- /* Zero out the NIC's on-board SRAM. */
- ti_mem_set(sc, 0x2000, 0x100000 - 0x2000);
-
- /* 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;
- }
-
- /*
- * Get station address from the EEPROM. Note: the manual states
- * that the MAC address is at offset 0x8c, however the data is
- * stored as two longwords (since that's how it's loaded into
- * the NIC). This means the MAC address is actually preceded
- * by two zero bytes. We need to skip over those.
- */
- if (ti_read_eeprom(sc, (caddr_t)&sc->arpcom.ac_enaddr,
- 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;
- }
-
- /*
- * A Tigon chip was detected. Inform the world.
- */
- printf(": %s, address %s\n", intrstr,
- 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;
- }
- 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;
- }
- 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;
- }
- if (bus_dmamap_load(sc->sc_dmatag, sc->ti_ring_map, kva,
- sizeof(struct ti_ring_data), NULL, BUS_DMA_NOWAIT)) {
- goto fail_5;
- }
- sc->ti_rdata = (struct ti_ring_data *)kva;
- bzero(sc->ti_rdata, sizeof(struct ti_ring_data));
-
- /* Try to allocate memory for jumbo buffers. */
- if (ti_alloc_jumbo_mem(sc)) {
- printf("%s: jumbo buffer allocation failed\n",
- sc->sc_dv.dv_xname);
- goto fail_5;
- }
-
- /*
- * 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;
- sc->ti_tx_coal_ticks = TI_TICKS_PER_SEC / 500;
- sc->ti_rx_max_coal_bds = 64;
- sc->ti_tx_max_coal_bds = 128;
- sc->ti_tx_buf_ratio = 21;
-
- /* Set up ifnet structure */
- ifp = &sc->arpcom.ac_if;
- ifp->if_softc = sc;
- ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
- ifp->if_ioctl = ti_ioctl;
- ifp->if_start = ti_start;
- ifp->if_watchdog = ti_watchdog;
- ifp->if_hardmtu = TI_JUMBO_FRAMELEN - ETHER_HDR_LEN;
- IFQ_SET_MAXLEN(&ifp->if_snd, TI_TX_RING_CNT - 1);
- IFQ_SET_READY(&ifp->if_snd);
- bcopy(sc->sc_dv.dv_xname, ifp->if_xname, IFNAMSIZ);
-
- ifp->if_capabilities = IFCAP_VLAN_MTU;
-
-#if NVLAN > 0
- ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING;
-#endif
-
- /* Set up ifmedia support. */
- ifmedia_init(&sc->ifmedia, IFM_IMASK, ti_ifmedia_upd, ti_ifmedia_sts);
- if (sc->ti_copper) {
- /*
- * Copper cards allow manual 10/100 mode selection,
- * but not manual 1000baseTX mode selection. Why?
- * Because currently there's no way to specify the
- * master/slave setting through the firmware interface,
- * so Alteon decided to just bag it and handle it
- * via autonegotiation.
- */
- ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_10_T, 0, NULL);
- ifmedia_add(&sc->ifmedia,
- IFM_ETHER|IFM_10_T|IFM_FDX, 0, NULL);
- ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_100_TX, 0, NULL);
- ifmedia_add(&sc->ifmedia,
- IFM_ETHER|IFM_100_TX|IFM_FDX, 0, NULL);
- ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_1000_T, 0, NULL);
- ifmedia_add(&sc->ifmedia,
- IFM_ETHER|IFM_1000_T|IFM_FDX, 0, NULL);
- } else {
- /* Fiber cards don't support 10/100 modes. */
- ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_1000_SX, 0, NULL);
- ifmedia_add(&sc->ifmedia,
- IFM_ETHER|IFM_1000_SX|IFM_FDX, 0, NULL);
- }
- ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_AUTO, 0, NULL);
- ifmedia_set(&sc->ifmedia, IFM_ETHER|IFM_AUTO);
-
- /*
- * Call MI attach routines.
- */
- if_attach(ifp);
- ether_ifattach(ifp);
-
- shutdownhook_establish(ti_shutdown, sc);
- return;
-
-fail_5:
- bus_dmamap_destroy(sc->sc_dmatag, sc->ti_ring_map);
-
-fail_4:
- bus_dmamem_unmap(sc->sc_dmatag, kva,
- sizeof(struct ti_ring_data));
-
-fail_3:
- 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);
-}
-
-/*
- * Frame reception handling. This is called if there's a frame
- * on the receive return list.
- *
- * Note: we have to be able to handle three possibilities here:
- * 1) the frame is from the mini receive ring (can only happen)
- * on Tigon 2 boards)
- * 2) the frame is from the jumbo receive ring
- * 3) the frame is from the standard receive ring
- */
-
-void
-ti_rxeof(struct ti_softc *sc)
-{
- struct ifnet *ifp;
- struct ti_cmd_desc cmd;
-
- ifp = &sc->arpcom.ac_if;
-
- while(sc->ti_rx_saved_considx != sc->ti_return_prodidx.ti_idx) {
- struct ti_rx_desc *cur_rx;
- u_int32_t rxidx;
- struct mbuf *m = NULL;
- bus_dmamap_t dmamap;
-
- cur_rx =
- &sc->ti_rdata->ti_rx_return_ring[sc->ti_rx_saved_considx];
- rxidx = cur_rx->ti_idx;
- TI_INC(sc->ti_rx_saved_considx, TI_RETURN_RING_CNT);
-
- if (cur_rx->ti_flags & TI_BDFLAG_JUMBO_RING) {
- TI_INC(sc->ti_jumbo, TI_JUMBO_RX_RING_CNT);
- m = sc->ti_cdata.ti_rx_jumbo_chain[rxidx];
- sc->ti_cdata.ti_rx_jumbo_chain[rxidx] = NULL;
- if (cur_rx->ti_flags & TI_BDFLAG_ERROR) {
- ifp->if_ierrors++;
- ti_newbuf_jumbo(sc, sc->ti_jumbo, m);
- continue;
- }
- if (ti_newbuf_jumbo(sc, sc->ti_jumbo, NULL)
- == ENOBUFS) {
- struct mbuf *m0;
- m0 = m_devget(mtod(m, char *), cur_rx->ti_len,
- ETHER_ALIGN, ifp, NULL);
- ti_newbuf_jumbo(sc, sc->ti_jumbo, m);
- if (m0 == NULL) {
- ifp->if_ierrors++;
- continue;
- }
- m = m0;
- }
- } else if (cur_rx->ti_flags & TI_BDFLAG_MINI_RING) {
- TI_INC(sc->ti_mini, TI_MINI_RX_RING_CNT);
- m = sc->ti_cdata.ti_rx_mini_chain[rxidx];
- sc->ti_cdata.ti_rx_mini_chain[rxidx] = NULL;
- dmamap = sc->ti_cdata.ti_rx_mini_map[rxidx];
- sc->ti_cdata.ti_rx_mini_map[rxidx] = 0;
- if (cur_rx->ti_flags & TI_BDFLAG_ERROR) {
- ifp->if_ierrors++;
- ti_newbuf_mini(sc, sc->ti_mini, m, dmamap);
- continue;
- }
- if (ti_newbuf_mini(sc, sc->ti_mini, NULL, dmamap)
- == ENOBUFS) {
- ifp->if_ierrors++;
- ti_newbuf_mini(sc, sc->ti_mini, m, dmamap);
- continue;
- }
- } else {
- TI_INC(sc->ti_std, TI_STD_RX_RING_CNT);
- m = sc->ti_cdata.ti_rx_std_chain[rxidx];
- sc->ti_cdata.ti_rx_std_chain[rxidx] = NULL;
- dmamap = sc->ti_cdata.ti_rx_std_map[rxidx];
- sc->ti_cdata.ti_rx_std_map[rxidx] = 0;
- if (cur_rx->ti_flags & TI_BDFLAG_ERROR) {
- ifp->if_ierrors++;
- ti_newbuf_std(sc, sc->ti_std, m, dmamap);
- continue;
- }
- if (ti_newbuf_std(sc, sc->ti_std, NULL, dmamap)
- == ENOBUFS) {
- ifp->if_ierrors++;
- ti_newbuf_std(sc, sc->ti_std, m, dmamap);
- continue;
- }
- }
-
- if (m == NULL)
- panic("%s: couldn't get mbuf", sc->sc_dv.dv_xname);
-
- m->m_pkthdr.len = m->m_len = cur_rx->ti_len;
- ifp->if_ipackets++;
- m->m_pkthdr.rcvif = ifp;
-
-#if NVLAN > 0
- if (cur_rx->ti_flags & TI_BDFLAG_VLAN_TAG) {
- m->m_pkthdr.ether_vtag = cur_rx->ti_vlan_tag;
- m->m_flags |= M_VLANTAG;
- }
-#endif
-
-#if NBPFILTER > 0
- /*
- * Handle BPF listeners. Let the BPF user see the packet.
- */
- if (ifp->if_bpf)
- bpf_mtap_ether(ifp->if_bpf, m, BPF_DIRECTION_IN);
-#endif
-
- if ((cur_rx->ti_ip_cksum ^ 0xffff) == 0)
- m->m_pkthdr.csum_flags |= M_IPV4_CSUM_IN_OK;
-
- ether_input_mbuf(ifp, m);
- }
-
- /* Only necessary on the Tigon 1. */
- if (sc->ti_hwrev == TI_HWREV_TIGON)
- CSR_WRITE_4(sc, TI_GCR_RXRETURNCONS_IDX,
- sc->ti_rx_saved_considx);
-
- TI_UPDATE_STDPROD(sc, sc->ti_std);
- TI_UPDATE_MINIPROD(sc, sc->ti_mini);
- TI_UPDATE_JUMBOPROD(sc, sc->ti_jumbo);
-}
-
-void
-ti_txeof_tigon1(struct ti_softc *sc)
-{
- struct ifnet *ifp;
- struct ti_txmap_entry *entry;
- int active = 1;
-
- ifp = &sc->arpcom.ac_if;
-
- /*
- * Go through our tx ring and free mbufs for those
- * frames that have been sent.
- */
- while (sc->ti_tx_saved_considx != sc->ti_tx_considx.ti_idx) {
- u_int32_t idx = 0;
- struct ti_tx_desc txdesc;
-
- idx = sc->ti_tx_saved_considx;
- ti_mem_read(sc, TI_TX_RING_BASE + idx * sizeof(txdesc),
- sizeof(txdesc), (caddr_t)&txdesc);
-
- if (txdesc.ti_flags & TI_BDFLAG_END)
- ifp->if_opackets++;
-
- if (sc->ti_cdata.ti_tx_chain[idx] != NULL) {
- m_freem(sc->ti_cdata.ti_tx_chain[idx]);
- sc->ti_cdata.ti_tx_chain[idx] = NULL;
-
- entry = sc->ti_cdata.ti_tx_map[idx];
- bus_dmamap_sync(sc->sc_dmatag, entry->dmamap, 0,
- entry->dmamap->dm_mapsize, BUS_DMASYNC_POSTWRITE);
-
- bus_dmamap_unload(sc->sc_dmatag, entry->dmamap);
- SLIST_INSERT_HEAD(&sc->ti_tx_map_listhead, entry,
- link);
- sc->ti_cdata.ti_tx_map[idx] = NULL;
-
- }
- sc->ti_txcnt--;
- TI_INC(sc->ti_tx_saved_considx, TI_TX_RING_CNT);
- ifp->if_timer = 0;
-
- active = 0;
- }
-
- if (!active)
- ifp->if_flags &= ~IFF_OACTIVE;
-}
-
-void
-ti_txeof_tigon2(struct ti_softc *sc)
-{
- struct ti_tx_desc *cur_tx = NULL;
- struct ifnet *ifp;
- struct ti_txmap_entry *entry;
-
- ifp = &sc->arpcom.ac_if;
-
- /*
- * Go through our tx ring and free mbufs for those
- * frames that have been sent.
- */
- while (sc->ti_tx_saved_considx != sc->ti_tx_considx.ti_idx) {
- u_int32_t idx = 0;
-
- idx = sc->ti_tx_saved_considx;
- cur_tx = &sc->ti_rdata->ti_tx_ring[idx];
-
- if (cur_tx->ti_flags & TI_BDFLAG_END)
- ifp->if_opackets++;
- if (sc->ti_cdata.ti_tx_chain[idx] != NULL) {
- m_freem(sc->ti_cdata.ti_tx_chain[idx]);
- sc->ti_cdata.ti_tx_chain[idx] = NULL;
-
- entry = sc->ti_cdata.ti_tx_map[idx];
- bus_dmamap_sync(sc->sc_dmatag, entry->dmamap, 0,
- entry->dmamap->dm_mapsize, BUS_DMASYNC_POSTWRITE);
-
- bus_dmamap_unload(sc->sc_dmatag, entry->dmamap);
- SLIST_INSERT_HEAD(&sc->ti_tx_map_listhead, entry,
- link);
- sc->ti_cdata.ti_tx_map[idx] = NULL;
-
- }
- sc->ti_txcnt--;
- TI_INC(sc->ti_tx_saved_considx, TI_TX_RING_CNT);
- ifp->if_timer = 0;
- }
-
- if (cur_tx != NULL)
- ifp->if_flags &= ~IFF_OACTIVE;
-}
-
-int
-ti_intr(void *xsc)
-{
- struct ti_softc *sc;
- struct ifnet *ifp;
-
- sc = xsc;
- ifp = &sc->arpcom.ac_if;
-
- /* XXX checking this register is expensive. */
- /* Make sure this is really our interrupt. */
- if (!(CSR_READ_4(sc, TI_MISC_HOST_CTL) & TI_MHC_INTSTATE))
- return (0);
-
- /* Ack interrupt and stop others from occurring. */
- CSR_WRITE_4(sc, TI_MB_HOSTINTR, 1);
-
- if (ifp->if_flags & IFF_RUNNING) {
- /* Check RX return ring producer/consumer */
- ti_rxeof(sc);
-
- /* Check TX ring producer/consumer */
- if (sc->ti_hwrev == TI_HWREV_TIGON)
- ti_txeof_tigon1(sc);
- else
- ti_txeof_tigon2(sc);
- }
-
- ti_handle_events(sc);
-
- /* Re-enable interrupts. */
- CSR_WRITE_4(sc, TI_MB_HOSTINTR, 0);
-
- if (ifp->if_flags & IFF_RUNNING && !IFQ_IS_EMPTY(&ifp->if_snd))
- ti_start(ifp);
-
- return (1);
-}
-
-void
-ti_stats_update(struct ti_softc *sc)
-{
- struct ifnet *ifp;
- struct ti_stats *stats = &sc->ti_rdata->ti_info.ti_stats;
-
- ifp = &sc->arpcom.ac_if;
-
- TI_RING_DMASYNC(sc, ti_info.ti_stats, BUS_DMASYNC_POSTREAD);
-
- ifp->if_collisions += stats->dot3StatsSingleCollisionFrames +
- stats->dot3StatsMultipleCollisionFrames +
- stats->dot3StatsExcessiveCollisions +
- stats->dot3StatsLateCollisions -
- ifp->if_collisions;
-
- TI_RING_DMASYNC(sc, ti_info.ti_stats, BUS_DMASYNC_PREREAD);
-}
-
-/*
- * Encapsulate an mbuf chain in the tx ring by coupling the mbuf data
- * pointers to descriptors.
- */
-int
-ti_encap_tigon1(struct ti_softc *sc, struct mbuf *m_head, u_int32_t *txidx)
-{
- u_int32_t frag, cur;
- struct ti_txmap_entry *entry;
- bus_dmamap_t txmap;
- struct ti_tx_desc txdesc;
- int i = 0;
-
- entry = SLIST_FIRST(&sc->ti_tx_map_listhead);
- if (entry == NULL)
- return (ENOBUFS);
- txmap = entry->dmamap;
-
- cur = frag = *txidx;
-
- /*
- * Start packing the mbufs in this chain into
- * the fragment pointers. Stop when we run out
- * of fragments or hit the end of the mbuf chain.
- */
- if (bus_dmamap_load_mbuf(sc->sc_dmatag, txmap, m_head,
- BUS_DMA_NOWAIT))
- return (ENOBUFS);
-
- /*
- * Sanity check: avoid coming within 16 descriptors
- * of the end of the ring.
- */
- if (txmap->dm_nsegs > (TI_TX_RING_CNT - sc->ti_txcnt - 16))
- goto fail_unload;
-
- for (i = 0; i < txmap->dm_nsegs; i++) {
- if (sc->ti_cdata.ti_tx_chain[frag] != NULL)
- break;
-
- memset(&txdesc, 0, sizeof(txdesc));
-
- TI_HOSTADDR(txdesc.ti_addr) = txmap->dm_segs[i].ds_addr;
- txdesc.ti_len = txmap->dm_segs[i].ds_len & 0xffff;
- txdesc.ti_flags = 0;
- txdesc.ti_vlan_tag = 0;
-
-#if NVLAN > 0
- if (m_head->m_flags & M_VLANTAG) {
- txdesc.ti_flags |= TI_BDFLAG_VLAN_TAG;
- txdesc.ti_vlan_tag = m_head->m_pkthdr.ether_vtag;
- }
-#endif
-
- ti_mem_write(sc, TI_TX_RING_BASE + frag * sizeof(txdesc),
- sizeof(txdesc), (caddr_t)&txdesc);
-
- cur = frag;
- TI_INC(frag, TI_TX_RING_CNT);
- }
-
- if (frag == sc->ti_tx_saved_considx)
- goto fail_unload;
-
- txdesc.ti_flags |= TI_BDFLAG_END;
- ti_mem_write(sc, TI_TX_RING_BASE + cur * sizeof(txdesc),
- sizeof(txdesc), (caddr_t)&txdesc);
-
- bus_dmamap_sync(sc->sc_dmatag, txmap, 0, txmap->dm_mapsize,
- BUS_DMASYNC_PREWRITE);
-
- sc->ti_cdata.ti_tx_chain[cur] = m_head;
- SLIST_REMOVE_HEAD(&sc->ti_tx_map_listhead, link);
- sc->ti_cdata.ti_tx_map[cur] = entry;
- sc->ti_txcnt += txmap->dm_nsegs;
-
- *txidx = frag;
-
- return (0);
-
-fail_unload:
- bus_dmamap_unload(sc->sc_dmatag, txmap);
-
- return (ENOBUFS);
-}
-
-/*
- * Encapsulate an mbuf chain in the tx ring by coupling the mbuf data
- * pointers to descriptors.
- */
-int
-ti_encap_tigon2(struct ti_softc *sc, struct mbuf *m_head, u_int32_t *txidx)
-{
- struct ti_tx_desc *f = NULL;
- u_int32_t frag, cur;
- struct ti_txmap_entry *entry;
- bus_dmamap_t txmap;
- int i = 0;
-
- entry = SLIST_FIRST(&sc->ti_tx_map_listhead);
- if (entry == NULL)
- return (ENOBUFS);
- txmap = entry->dmamap;
-
- cur = frag = *txidx;
-
- /*
- * Start packing the mbufs in this chain into
- * the fragment pointers. Stop when we run out
- * of fragments or hit the end of the mbuf chain.
- */
- if (bus_dmamap_load_mbuf(sc->sc_dmatag, txmap, m_head,
- BUS_DMA_NOWAIT))
- return (ENOBUFS);
-
- /*
- * Sanity check: avoid coming within 16 descriptors
- * of the end of the ring.
- */
- if (txmap->dm_nsegs > (TI_TX_RING_CNT - sc->ti_txcnt - 16))
- goto fail_unload;
-
- for (i = 0; i < txmap->dm_nsegs; i++) {
- f = &sc->ti_rdata->ti_tx_ring[frag];
-
- if (sc->ti_cdata.ti_tx_chain[frag] != NULL)
- break;
-
- TI_HOSTADDR(f->ti_addr) = txmap->dm_segs[i].ds_addr;
- f->ti_len = txmap->dm_segs[i].ds_len & 0xffff;
- f->ti_flags = 0;
- f->ti_vlan_tag = 0;
-
-#if NVLAN > 0
- if (m_head->m_flags & M_VLANTAG) {
- f->ti_flags |= TI_BDFLAG_VLAN_TAG;
- f->ti_vlan_tag = m_head->m_pkthdr.ether_vtag;
- }
-#endif
-
- cur = frag;
- TI_INC(frag, TI_TX_RING_CNT);
- }
-
- if (frag == sc->ti_tx_saved_considx)
- goto fail_unload;
-
- sc->ti_rdata->ti_tx_ring[cur].ti_flags |= TI_BDFLAG_END;
-
- bus_dmamap_sync(sc->sc_dmatag, txmap, 0, txmap->dm_mapsize,
- BUS_DMASYNC_PREWRITE);
-
- TI_RING_DMASYNC(sc, ti_tx_ring[cur], BUS_DMASYNC_POSTREAD);
-
- sc->ti_cdata.ti_tx_chain[cur] = m_head;
- SLIST_REMOVE_HEAD(&sc->ti_tx_map_listhead, link);
- sc->ti_cdata.ti_tx_map[cur] = entry;
- sc->ti_txcnt += txmap->dm_nsegs;
-
- *txidx = frag;
-
- return (0);
-
-fail_unload:
- bus_dmamap_unload(sc->sc_dmatag, txmap);
-
- return (ENOBUFS);
-}
-
-/*
- * Main transmit routine. To avoid having to do mbuf copies, we put pointers
- * to the mbuf data regions directly in the transmit descriptors.
- */
-void
-ti_start(struct ifnet *ifp)
-{
- struct ti_softc *sc;
- struct mbuf *m_head = NULL;
- u_int32_t prodidx;
- int pkts = 0, error;
-
- sc = ifp->if_softc;
-
- prodidx = sc->ti_tx_saved_prodidx;
-
- while(sc->ti_cdata.ti_tx_chain[prodidx] == NULL) {
- IFQ_POLL(&ifp->if_snd, m_head);
- if (m_head == NULL)
- break;
-
- /*
- * Pack the data into the transmit ring. If we
- * don't have room, set the OACTIVE flag and wait
- * for the NIC to drain the ring.
- */
- if (sc->ti_hwrev == TI_HWREV_TIGON)
- error = ti_encap_tigon1(sc, m_head, &prodidx);
- else
- error = ti_encap_tigon2(sc, m_head, &prodidx);
-
- if (error) {
- ifp->if_flags |= IFF_OACTIVE;
- break;
- }
-
- /* now we are committed to transmit the packet */
- IFQ_DEQUEUE(&ifp->if_snd, m_head);
- pkts++;
-
- /*
- * If there's a BPF listener, bounce a copy of this frame
- * to him.
- */
-#if NBPFILTER > 0
- if (ifp->if_bpf)
- bpf_mtap_ether(ifp->if_bpf, m_head, BPF_DIRECTION_OUT);
-#endif
- }
- if (pkts == 0)
- return;
-
- /* Transmit */
- sc->ti_tx_saved_prodidx = prodidx;
- CSR_WRITE_4(sc, TI_MB_SENDPROD_IDX, prodidx);
-
- /*
- * Set a timeout in case the chip goes out to lunch.
- */
- ifp->if_timer = 5;
-}
-
-void
-ti_init(void *xsc)
-{
- struct ti_softc *sc = xsc;
- int s;
-
- s = splnet();
-
- /* Cancel pending I/O and flush buffers. */
- ti_stop(sc);
-
- /* Init the gen info block, ring control blocks and firmware. */
- if (ti_gibinit(sc)) {
- printf("%s: initialization failure\n", sc->sc_dv.dv_xname);
- splx(s);
- return;
- }
-
- splx(s);
-}
-
-void
-ti_init2(struct ti_softc *sc)
-{
- struct ti_cmd_desc cmd;
- struct ifnet *ifp;
- u_int16_t *m;
- struct ifmedia *ifm;
- int tmp;
-
- ifp = &sc->arpcom.ac_if;
-
- /* Specify MTU and interface index. */
- CSR_WRITE_4(sc, TI_GCR_IFINDEX, sc->sc_dv.dv_unit);
- CSR_WRITE_4(sc, TI_GCR_IFMTU,
- TI_JUMBO_FRAMELEN + ETHER_VLAN_ENCAP_LEN);
- TI_DO_CMD(TI_CMD_UPDATE_GENCOM, 0, 0);
-
- /* Load our MAC address. */
- m = (u_int16_t *)&sc->arpcom.ac_enaddr[0];
- CSR_WRITE_4(sc, TI_GCR_PAR0, htons(m[0]));
- CSR_WRITE_4(sc, TI_GCR_PAR1, (htons(m[1]) << 16) | htons(m[2]));
- TI_DO_CMD(TI_CMD_SET_MAC_ADDR, 0, 0);
-
- /* Enable or disable promiscuous mode as needed. */
- if (ifp->if_flags & IFF_PROMISC) {
- TI_DO_CMD(TI_CMD_SET_PROMISC_MODE, TI_CMD_CODE_PROMISC_ENB, 0);
- } else {
- TI_DO_CMD(TI_CMD_SET_PROMISC_MODE, TI_CMD_CODE_PROMISC_DIS, 0);
- }
-
- /* Program multicast filter. */
- ti_setmulti(sc);
-
- /*
- * If this is a Tigon 1, we should tell the
- * firmware to use software packet filtering.
- */
- if (sc->ti_hwrev == TI_HWREV_TIGON) {
- TI_DO_CMD(TI_CMD_FDR_FILTERING, TI_CMD_CODE_FILT_ENB, 0);
- }
-
- /* Init RX ring. */
- if (ti_init_rx_ring_std(sc) == ENOBUFS)
- panic("not enough mbufs for rx ring");
-
- /* Init jumbo RX ring. */
- ti_init_rx_ring_jumbo(sc);
-
- /*
- * If this is a Tigon 2, we can also configure the
- * mini ring.
- */
- if (sc->ti_hwrev == TI_HWREV_TIGON_II)
- ti_init_rx_ring_mini(sc);
-
- CSR_WRITE_4(sc, TI_GCR_RXRETURNCONS_IDX, 0);
- sc->ti_rx_saved_considx = 0;
-
- /* Init TX ring. */
- ti_init_tx_ring(sc);
-
- /* Tell firmware we're alive. */
- TI_DO_CMD(TI_CMD_HOST_STATE, TI_CMD_CODE_STACK_UP, 0);
-
- /* Enable host interrupts. */
- CSR_WRITE_4(sc, TI_MB_HOSTINTR, 0);
-
- ifp->if_flags |= IFF_RUNNING;
- ifp->if_flags &= ~IFF_OACTIVE;
-
- /*
- * Make sure to set media properly. We have to do this
- * here since we have to issue commands in order to set
- * the link negotiation and we can't issue commands until
- * the firmware is running.
- */
- ifm = &sc->ifmedia;
- tmp = ifm->ifm_media;
- ifm->ifm_media = ifm->ifm_cur->ifm_media;
- ti_ifmedia_upd(ifp);
- ifm->ifm_media = tmp;
-}
-
-/*
- * Set media options.
- */
-int
-ti_ifmedia_upd(struct ifnet *ifp)
-{
- struct ti_softc *sc;
- struct ifmedia *ifm;
- struct ti_cmd_desc cmd;
-
- sc = ifp->if_softc;
- ifm = &sc->ifmedia;
-
- if (IFM_TYPE(ifm->ifm_media) != IFM_ETHER)
- return(EINVAL);
-
- switch(IFM_SUBTYPE(ifm->ifm_media)) {
- case IFM_AUTO:
- CSR_WRITE_4(sc, TI_GCR_GLINK, TI_GLNK_PREF|TI_GLNK_1000MB|
- TI_GLNK_FULL_DUPLEX|TI_GLNK_RX_FLOWCTL_Y|
- TI_GLNK_AUTONEGENB|TI_GLNK_ENB);
- CSR_WRITE_4(sc, TI_GCR_LINK, TI_LNK_100MB|TI_LNK_10MB|
- TI_LNK_FULL_DUPLEX|TI_LNK_HALF_DUPLEX|
- TI_LNK_AUTONEGENB|TI_LNK_ENB);
- TI_DO_CMD(TI_CMD_LINK_NEGOTIATION,
- TI_CMD_CODE_NEGOTIATE_BOTH, 0);
- break;
- case IFM_1000_SX:
- case IFM_1000_T:
- CSR_WRITE_4(sc, TI_GCR_GLINK, TI_GLNK_PREF|TI_GLNK_1000MB|
- TI_GLNK_RX_FLOWCTL_Y|TI_GLNK_ENB);
- CSR_WRITE_4(sc, TI_GCR_LINK, 0);
- if ((ifm->ifm_media & IFM_GMASK) == IFM_FDX) {
- TI_SETBIT(sc, TI_GCR_GLINK, TI_GLNK_FULL_DUPLEX);
- }
- TI_DO_CMD(TI_CMD_LINK_NEGOTIATION,
- TI_CMD_CODE_NEGOTIATE_GIGABIT, 0);
- break;
- case IFM_100_FX:
- case IFM_10_FL:
- case IFM_100_TX:
- case IFM_10_T:
- CSR_WRITE_4(sc, TI_GCR_GLINK, 0);
- CSR_WRITE_4(sc, TI_GCR_LINK, TI_LNK_ENB|TI_LNK_PREF);
- if (IFM_SUBTYPE(ifm->ifm_media) == IFM_100_FX ||
- IFM_SUBTYPE(ifm->ifm_media) == IFM_100_TX) {
- TI_SETBIT(sc, TI_GCR_LINK, TI_LNK_100MB);
- } else {
- TI_SETBIT(sc, TI_GCR_LINK, TI_LNK_10MB);
- }
- if ((ifm->ifm_media & IFM_GMASK) == IFM_FDX) {
- TI_SETBIT(sc, TI_GCR_LINK, TI_LNK_FULL_DUPLEX);
- } else {
- TI_SETBIT(sc, TI_GCR_LINK, TI_LNK_HALF_DUPLEX);
- }
- TI_DO_CMD(TI_CMD_LINK_NEGOTIATION,
- TI_CMD_CODE_NEGOTIATE_10_100, 0);
- break;
- }
-
- return (0);
-}
-
-/*
- * Report current media status.
- */
-void
-ti_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
-{
- struct ti_softc *sc;
- u_int32_t media = 0;
-
- sc = ifp->if_softc;
-
- ifmr->ifm_status = IFM_AVALID;
- ifmr->ifm_active = IFM_ETHER;
-
- if (sc->ti_linkstat == TI_EV_CODE_LINK_DOWN) {
- ifmr->ifm_active |= IFM_NONE;
- return;
- }
-
- ifmr->ifm_status |= IFM_ACTIVE;
-
- if (sc->ti_linkstat == TI_EV_CODE_GIG_LINK_UP) {
- media = CSR_READ_4(sc, TI_GCR_GLINK_STAT);
- if (sc->ti_copper)
- ifmr->ifm_active |= IFM_1000_T;
- else
- ifmr->ifm_active |= IFM_1000_SX;
- if (media & TI_GLNK_FULL_DUPLEX)
- ifmr->ifm_active |= IFM_FDX;
- else
- ifmr->ifm_active |= IFM_HDX;
- } else if (sc->ti_linkstat == TI_EV_CODE_LINK_UP) {
- media = CSR_READ_4(sc, TI_GCR_LINK_STAT);
- if (sc->ti_copper) {
- if (media & TI_LNK_100MB)
- ifmr->ifm_active |= IFM_100_TX;
- if (media & TI_LNK_10MB)
- ifmr->ifm_active |= IFM_10_T;
- } else {
- if (media & TI_LNK_100MB)
- ifmr->ifm_active |= IFM_100_FX;
- if (media & TI_LNK_10MB)
- ifmr->ifm_active |= IFM_10_FL;
- }
- if (media & TI_LNK_FULL_DUPLEX)
- ifmr->ifm_active |= IFM_FDX;
- if (media & TI_LNK_HALF_DUPLEX)
- ifmr->ifm_active |= IFM_HDX;
- }
-}
-
-int
-ti_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
-{
- struct ti_softc *sc = ifp->if_softc;
- struct ifaddr *ifa = (struct ifaddr *)data;
- struct ifreq *ifr = (struct ifreq *)data;
- int s, error = 0;
- struct ti_cmd_desc cmd;
-
- s = splnet();
-
- switch(command) {
- case SIOCSIFADDR:
- ifp->if_flags |= IFF_UP;
- if ((ifp->if_flags & IFF_RUNNING) == 0)
- ti_init(sc);
-#ifdef INET
- if (ifa->ifa_addr->sa_family == AF_INET)
- arp_ifinit(&sc->arpcom, ifa);
-#endif /* INET */
- break;
-
- case SIOCSIFFLAGS:
- if (ifp->if_flags & IFF_UP) {
- /*
- * If only the state of the PROMISC flag changed,
- * then just use the 'set promisc mode' command
- * instead of reinitializing the entire NIC. Doing
- * a full re-init means reloading the firmware and
- * waiting for it to start up, which may take a
- * second or two.
- */
- if (ifp->if_flags & IFF_RUNNING &&
- ifp->if_flags & IFF_PROMISC &&
- !(sc->ti_if_flags & IFF_PROMISC)) {
- TI_DO_CMD(TI_CMD_SET_PROMISC_MODE,
- TI_CMD_CODE_PROMISC_ENB, 0);
- } else if (ifp->if_flags & IFF_RUNNING &&
- !(ifp->if_flags & IFF_PROMISC) &&
- sc->ti_if_flags & IFF_PROMISC) {
- TI_DO_CMD(TI_CMD_SET_PROMISC_MODE,
- TI_CMD_CODE_PROMISC_DIS, 0);
- } else {
- if ((ifp->if_flags & IFF_RUNNING) == 0)
- ti_init(sc);
- }
- } else {
- if (ifp->if_flags & IFF_RUNNING)
- ti_stop(sc);
- }
- sc->ti_if_flags = ifp->if_flags;
- break;
-
- case SIOCSIFMEDIA:
- case SIOCGIFMEDIA:
- error = ifmedia_ioctl(ifp, ifr, &sc->ifmedia, command);
- break;
-
- default:
- error = ether_ioctl(ifp, &sc->arpcom, command, data);
- }
-
- if (error == ENETRESET) {
- if (ifp->if_flags & IFF_RUNNING)
- ti_setmulti(sc);
- error = 0;
- }
-
- splx(s);
- return (error);
-}
-
-void
-ti_watchdog(struct ifnet *ifp)
-{
- struct ti_softc *sc;
-
- sc = ifp->if_softc;
-
- printf("%s: watchdog timeout -- resetting\n", sc->sc_dv.dv_xname);
- ti_stop(sc);
- ti_init(sc);
-
- ifp->if_oerrors++;
-}
-
-/*
- * Stop the adapter and free any mbufs allocated to the
- * RX and TX lists.
- */
-void
-ti_stop(struct ti_softc *sc)
-{
- struct ifnet *ifp;
- struct ti_cmd_desc cmd;
-
- ifp = &sc->arpcom.ac_if;
-
- ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
-
- /* Disable host interrupts. */
- CSR_WRITE_4(sc, TI_MB_HOSTINTR, 1);
- /*
- * Tell firmware we're shutting down.
- */
- TI_DO_CMD(TI_CMD_HOST_STATE, TI_CMD_CODE_STACK_DOWN, 0);
-
- /* Halt and reinitialize. */
- ti_chipinit(sc);
- ti_mem_set(sc, 0x2000, 0x100000 - 0x2000);
- ti_chipinit(sc);
-
- /* Free the RX lists. */
- ti_free_rx_ring_std(sc);
-
- /* Free jumbo RX list. */
- ti_free_rx_ring_jumbo(sc);
-
- /* Free mini RX list. */
- ti_free_rx_ring_mini(sc);
-
- /* Free TX buffers. */
- ti_free_tx_ring(sc);
-
- sc->ti_ev_prodidx.ti_idx = 0;
- sc->ti_return_prodidx.ti_idx = 0;
- sc->ti_tx_considx.ti_idx = 0;
- sc->ti_tx_saved_considx = TI_TXCONS_UNSET;
-}
-
-/*
- * Stop all chip I/O so that the kernel's probe routines don't
- * get confused by errant DMAs when rebooting.
- */
-void
-ti_shutdown(void *xsc)
-{
- struct ti_softc *sc;
-
- sc = xsc;
-
- ti_chipinit(sc);
-}
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);
+}
diff --git a/sys/dev/pci/if_tireg.h b/sys/dev/pci/if_tireg.h
deleted file mode 100644
index c76b1a99fb0..00000000000
--- a/sys/dev/pci/if_tireg.h
+++ /dev/null
@@ -1,1175 +0,0 @@
-/* $OpenBSD: if_tireg.h,v 1.25 2006/08/16 02:37:00 brad 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_tireg.h,v 1.12 2000/01/18 00:26:29 wpaul Exp $
- */
-
-/*
- * Tigon register offsets. These are memory mapped registers
- * which can be accessed with the CSR_READ_4()/CSR_WRITE_4() macros.
- * Each register must be accessed using 32 bit operations.
- *
- * All reegisters are accessed through a 16K shared memory block.
- * The first group of registers are actually copies of the PCI
- * configuration space registers.
- */
-
-#define TI_PCI_ID PCI_ID_REG /* PCI device/vendor ID */
-#define TI_PCI_CMDSTAT PCI_COMMAND_STATUS_REG
-#define TI_PCI_CLASSCODE PCI_CLASS_REG
-#define TI_PCI_BIST PCI_BHLC_REG
-#define TI_PCI_LOMEM PCI_MAPS /* Shared memory base address */
-#define TI_PCI_SUBSYS PCI_SUBVEND_0
-#define TI_PCI_ROMBASE 0x030
-#define TI_PCI_INT PCI_INTLINE
-
-/*
- * Tigon configuration and control registers.
- */
-#define TI_MISC_HOST_CTL 0x040
-#define TI_MISC_LOCAL_CTL 0x044
-#define TI_SEM_AB 0x048 /* Tigon 2 only */
-#define TI_MISC_CONF 0x050 /* Tigon 2 only */
-#define TI_TIMER_BITS 0x054
-#define TI_TIMERREF 0x058
-#define TI_PCI_STATE 0x05C
-#define TI_MAIN_EVENT_A 0x060
-#define TI_MAILBOX_EVENT_A 0x064
-#define TI_WINBASE 0x068
-#define TI_WINDATA 0x06C
-#define TI_MAIN_EVENT_B 0x070 /* Tigon 2 only */
-#define TI_MAILBOX_EVENT_B 0x074 /* Tigon 2 only */
-#define TI_TIMERREF_B 0x078 /* Tigon 2 only */
-#define TI_SERIAL 0x07C
-
-/*
- * Misc host control bits.
- */
-#define TI_MHC_INTSTATE 0x00000001
-#define TI_MHC_CLEARINT 0x00000002
-#define TI_MHC_RESET 0x00000008
-#define TI_MHC_BYTE_SWAP_ENB 0x00000010
-#define TI_MHC_WORD_SWAP_ENB 0x00000020
-#define TI_MHC_MASK_INTS 0x00000040
-#define TI_MHC_CHIP_REV_MASK 0xF0000000
-
-#define TI_MHC_BIGENDIAN_INIT \
- (TI_MHC_BYTE_SWAP_ENB|TI_MHC_WORD_SWAP_ENB|TI_MHC_CLEARINT)
-
-#define TI_MHC_LITTLEENDIAN_INIT \
- (TI_MHC_WORD_SWAP_ENB|TI_MHC_CLEARINT)
-
-/*
- * Tigon chip rev values. Rev 4 is the Tigon 1. Rev 6 is the Tigon 2.
- * Rev 5 is also the Tigon 2, but is a broken version which was never
- * used in any actual hardware, so we ignore it.
- */
-#define TI_REV_TIGON_I 0x40000000
-#define TI_REV_TIGON_II 0x60000000
-
-/*
- * Firmware revision that we want.
- */
-#define TI_FIRMWARE_MAJOR 0xc
-#define TI_FIRMWARE_MINOR 0x4
-#define TI_FIRMWARE_FIX 0xd
-
-/*
- * Miscelaneous Local Control register.
- */
-#define TI_MLC_EE_WRITE_ENB 0x00000010
-#define TI_MLC_SRAM_BANK_SIZE 0x00000300 /* Tigon 2 only */
-#define TI_MLC_LOCALADDR_21 0x00004000
-#define TI_MLC_LOCALADDR_22 0x00008000
-#define TI_MLC_SBUS_WRITEERR 0x00080000
-#define TI_MLC_EE_CLK 0x00100000
-#define TI_MLC_EE_TXEN 0x00200000
-#define TI_MLC_EE_DOUT 0x00400000
-#define TI_MLC_EE_DIN 0x00800000
-
-/* Possible memory sizes. */
-#define TI_MLC_SRAM_BANK_DISA 0x00000000
-#define TI_MLC_SRAM_BANK_1024K 0x00000100
-#define TI_MLC_SRAM_BANK_512K 0x00000200
-#define TI_MLC_SRAM_BANK_256K 0x00000300
-
-/*
- * Offset of MAC address inside EEPROM.
- */
-#define TI_EE_MAC_OFFSET 0x8c
-
-#define TI_DMA_ASSIST 0x11C
-#define TI_CPU_STATE 0x140
-#define TI_CPU_PROGRAM_COUNTER 0x144
-#define TI_SRAM_ADDR 0x154
-#define TI_SRAM_DATA 0x158
-#define TI_GEN_0 0x180
-#define TI_GEN_X 0x1FC
-#define TI_MAC_TX_STATE 0x200
-#define TI_MAC_RX_STATE 0x220
-#define TI_CPU_CTL_B 0x240 /* Tigon 2 only */
-#define TI_CPU_PROGRAM_COUNTER_B 0x244 /* Tigon 2 only */
-#define TI_SRAM_ADDR_B 0x254 /* Tigon 2 only */
-#define TI_SRAM_DATA_B 0x258 /* Tigon 2 only */
-#define TI_GEN_B_0 0x280 /* Tigon 2 only */
-#define TI_GEN_B_X 0x2FC /* Tigon 2 only */
-
-/*
- * Misc config register.
- */
-#define TI_MCR_SRAM_SYNCHRONOUS 0x00100000 /* Tigon 2 only */
-
-/*
- * PCI state register.
- */
-#define TI_PCISTATE_FORCE_RESET 0x00000001
-#define TI_PCISTATE_PROVIDE_LEN 0x00000002
-#define TI_PCISTATE_READ_MAXDMA 0x0000001C
-#define TI_PCISTATE_WRITE_MAXDMA 0x000000E0
-#define TI_PCISTATE_MINDMA 0x0000FF00
-#define TI_PCISTATE_FIFO_RETRY_ENB 0x00010000
-#define TI_PCISTATE_USE_MEM_RD_MULT 0x00020000
-#define TI_PCISTATE_NO_SWAP_READ_DMA 0x00040000
-#define TI_PCISTATE_NO_SWAP_WRITE_DMA 0x00080000
-#define TI_PCISTATE_66MHZ_BUS 0x00080000 /* Tigon 2 only */
-#define TI_PCISTATE_32BIT_BUS 0x00100000 /* Tigon 2 only */
-#define TI_PCISTATE_ENB_BYTE_ENABLES 0x00800000 /* Tigon 2 only */
-#define TI_PCISTATE_READ_CMD 0x0F000000
-#define TI_PCISTATE_WRITE_CMD 0xF0000000
-
-#define TI_PCI_READMAX_4 0x04
-#define TI_PCI_READMAX_16 0x08
-#define TI_PCI_READMAX_32 0x0C
-#define TI_PCI_READMAX_64 0x10
-#define TI_PCI_READMAX_128 0x14
-#define TI_PCI_READMAX_256 0x18
-#define TI_PCI_READMAX_1024 0x1C
-
-#define TI_PCI_WRITEMAX_4 0x20
-#define TI_PCI_WRITEMAX_16 0x40
-#define TI_PCI_WRITEMAX_32 0x60
-#define TI_PCI_WRITEMAX_64 0x80
-#define TI_PCI_WRITEMAX_128 0xA0
-#define TI_PCI_WRITEMAX_256 0xC0
-#define TI_PCI_WRITEMAX_1024 0xE0
-
-#define TI_PCI_READ_CMD 0x06000000
-#define TI_PCI_WRITE_CMD 0x70000000
-
-/*
- * DMA state register.
- */
-#define TI_DMASTATE_ENABLE 0x00000001
-#define TI_DMASTATE_PAUSE 0x00000002
-
-/*
- * CPU state register.
- */
-#define TI_CPUSTATE_RESET 0x00000001
-#define TI_CPUSTATE_STEP 0x00000002
-#define TI_CPUSTATE_ROMFAIL 0x00000010
-#define TI_CPUSTATE_HALT 0x00010000
-/*
- * MAC TX state register
- */
-#define TI_TXSTATE_RESET 0x00000001
-#define TI_TXSTATE_ENB 0x00000002
-#define TI_TXSTATE_STOP 0x00000004
-
-/*
- * MAC RX state register
- */
-#define TI_RXSTATE_RESET 0x00000001
-#define TI_RXSTATE_ENB 0x00000002
-#define TI_RXSTATE_STOP 0x00000004
-
-/*
- * Tigon 2 mailbox registers. The mailbox area consists of 256 bytes
- * split into 64 bit registers. Only the lower 32 bits of each mailbox
- * are used.
- */
-#define TI_MB_HOSTINTR_HI 0x500
-#define TI_MB_HOSTINTR_LO 0x504
-#define TI_MB_HOSTINTR TI_MB_HOSTINTR_LO
-#define TI_MB_CMDPROD_IDX_HI 0x508
-#define TI_MB_CMDPROD_IDX_LO 0x50C
-#define TI_MB_CMDPROD_IDX TI_MB_CMDPROD_IDX_LO
-#define TI_MB_SENDPROD_IDX_HI 0x510
-#define TI_MB_SENDPROD_IDX_LO 0x514
-#define TI_MB_SENDPROD_IDX TI_MB_SENDPROD_IDX_LO
-#define TI_MB_STDRXPROD_IDX_HI 0x518 /* Tigon 2 only */
-#define TI_MB_STDRXPROD_IDX_LO 0x51C /* Tigon 2 only */
-#define TI_MB_STDRXPROD_IDX TI_MB_STDRXPROD_IDX_LO
-#define TI_MB_JUMBORXPROD_IDX_HI 0x520 /* Tigon 2 only */
-#define TI_MB_JUMBORXPROD_IDX_LO 0x524 /* Tigon 2 only */
-#define TI_MB_JUMBORXPROD_IDX TI_MB_JUMBORXPROD_IDX_LO
-#define TI_MB_MINIRXPROD_IDX_HI 0x528 /* Tigon 2 only */
-#define TI_MB_MINIRXPROD_IDX_LO 0x52C /* Tigon 2 only */
-#define TI_MB_MINIRXPROD_IDX TI_MB_MINIRXPROD_IDX_LO
-#define TI_MB_RSVD 0x530
-
-/*
- * Tigon 2 general communication registers. These are 64 and 32 bit
- * registers which are only valid after the firmware has been
- * loaded and started. They actually exist in NIC memory but are
- * mapped into the host memory via the shared memory region.
- *
- * The NIC internally maps these registers starting at address 0,
- * so to determine the NIC address of any of these registers, we
- * subtract 0x600 (the address of the first register).
- */
-
-#define TI_GCR_BASE 0x600
-#define TI_GCR_MACADDR 0x600
-#define TI_GCR_PAR0 0x600
-#define TI_GCR_PAR1 0x604
-#define TI_GCR_GENINFO_HI 0x608
-#define TI_GCR_GENINFO_LO 0x60C
-#define TI_GCR_MCASTADDR 0x610 /* obsolete */
-#define TI_GCR_MAR0 0x610 /* obsolete */
-#define TI_GCR_MAR1 0x614 /* obsolete */
-#define TI_GCR_OPMODE 0x618
-#define TI_GCR_DMA_READCFG 0x61C
-#define TI_GCR_DMA_WRITECFG 0x620
-#define TI_GCR_TX_BUFFER_RATIO 0x624
-#define TI_GCR_EVENTCONS_IDX 0x628
-#define TI_GCR_CMDCONS_IDX 0x62C
-#define TI_GCR_TUNEPARMS 0x630
-#define TI_GCR_RX_COAL_TICKS 0x630
-#define TI_GCR_TX_COAL_TICKS 0x634
-#define TI_GCR_STAT_TICKS 0x638
-#define TI_GCR_TX_MAX_COAL_BD 0x63C
-#define TI_GCR_RX_MAX_COAL_BD 0x640
-#define TI_GCR_NIC_TRACING 0x644
-#define TI_GCR_GLINK 0x648
-#define TI_GCR_LINK 0x64C
-#define TI_GCR_NICTRACE_PTR 0x650
-#define TI_GCR_NICTRACE_START 0x654
-#define TI_GCR_NICTRACE_LEN 0x658
-#define TI_GCR_IFINDEX 0x65C
-#define TI_GCR_IFMTU 0x660
-#define TI_GCR_MASK_INTRS 0x664
-#define TI_GCR_GLINK_STAT 0x668
-#define TI_GCR_LINK_STAT 0x66C
-#define TI_GCR_RXRETURNCONS_IDX 0x680
-#define TI_GCR_CMDRING 0x700
-
-#define TI_GCR_NIC_ADDR(x) (x - TI_GCR_BASE)
-
-/*
- * Local memory window. The local memory window is a 2K shared
- * memory region which can be used to access the NIC's internal
- * SRAM. The window can be mapped to a given 2K region using
- * the TI_WINDOW_BASE register.
- */
-#define TI_WINDOW 0x800
-#define TI_WINLEN 0x800
-
-#define TI_TICKS_PER_SEC 1000000
-
-/*
- * Operation mode register.
- */
-#define TI_OPMODE_BYTESWAP_BD 0x00000002
-#define TI_OPMODE_WORDSWAP_BD 0x00000004
-#define TI_OPMODE_WARN_ENB 0x00000008 /* not yet implemented */
-#define TI_OPMODE_BYTESWAP_DATA 0x00000010
-#define TI_OPMODE_1_DMA_ACTIVE 0x00000040
-#define TI_OPMODE_SBUS 0x00000100
-#define TI_OPMODE_DONT_FRAG_JUMBO 0x00000200
-#define TI_OPMODE_INCLUDE_CRC 0x00000400
-#define TI_OPMODE_RX_BADFRAMES 0x00000800
-#define TI_OPMODE_NO_EVENT_INTRS 0x00001000
-#define TI_OPMODE_NO_TX_INTRS 0x00002000
-#define TI_OPMODE_NO_RX_INTRS 0x00004000
-#define TI_OPMODE_FATAL_ENB 0x40000000 /* not yet implemented */
-
-#if BYTE_ORDER == BIG_ENDIAN
-#define TI_DMA_SWAP_OPTIONS \
- TI_OPMODE_BYTESWAP_DATA| \
- TI_OPMODE_BYTESWAP_BD|TI_OPMODE_WORDSWAP_BD
-#else
-#define TI_DMA_SWAP_OPTIONS \
- TI_OPMODE_BYTESWAP_DATA
-#endif
-
-/*
- * DMA configuration thresholds.
- */
-#define TI_DMA_STATE_THRESH_16W 0x00000100
-#define TI_DMA_STATE_THRESH_8W 0x00000080
-#define TI_DMA_STATE_THRESH_4W 0x00000040
-#define TI_DMA_STATE_THRESH_2W 0x00000020
-#define TI_DMA_STATE_THRESH_1W 0x00000010
-
-#define TI_DMA_STATE_FORCE_32_BIT 0x00000008
-
-/*
- * Gigabit link status bits.
- */
-#define TI_GLNK_SENSE_NO_BEG 0x00002000
-#define TI_GLNK_LOOPBACK 0x00004000
-#define TI_GLNK_PREF 0x00008000
-#define TI_GLNK_1000MB 0x00040000
-#define TI_GLNK_FULL_DUPLEX 0x00080000
-#define TI_GLNK_TX_FLOWCTL_Y 0x00200000 /* Tigon 2 only */
-#define TI_GLNK_RX_FLOWCTL_Y 0x00800000
-#define TI_GLNK_AUTONEGENB 0x20000000
-#define TI_GLNK_ENB 0x40000000
-
-/*
- * Link status bits.
- */
-#define TI_LNK_LOOPBACK 0x00004000
-#define TI_LNK_PREF 0x00008000
-#define TI_LNK_10MB 0x00010000
-#define TI_LNK_100MB 0x00020000
-#define TI_LNK_1000MB 0x00040000
-#define TI_LNK_FULL_DUPLEX 0x00080000
-#define TI_LNK_HALF_DUPLEX 0x00100000
-#define TI_LNK_TX_FLOWCTL_Y 0x00200000 /* Tigon 2 only */
-#define TI_LNK_RX_FLOWCTL_Y 0x00800000
-#define TI_LNK_AUTONEGENB 0x20000000
-#define TI_LNK_ENB 0x40000000
-
-/*
- * Ring size constants.
- */
-#define TI_EVENT_RING_CNT 256
-#define TI_CMD_RING_CNT 64
-#define TI_STD_RX_RING_CNT 512
-#define TI_JUMBO_RX_RING_CNT 256
-#define TI_MINI_RX_RING_CNT 1024
-#define TI_RETURN_RING_CNT 2048
-
-/*
- * Possible TX ring sizes.
- */
-#define TI_TX_RING_CNT_128 128
-#define TI_TX_RING_BASE_128 0x3800
-
-#define TI_TX_RING_CNT_256 256
-#define TI_TX_RING_BASE_256 0x3000
-
-#define TI_TX_RING_CNT_512 512
-#define TI_TX_RING_BASE_512 0x2000
-
-#define TI_TX_RING_CNT TI_TX_RING_CNT_512
-#define TI_TX_RING_BASE TI_TX_RING_BASE_512
-
-/*
- * The Tigon can have up to 8MB of external SRAM, however the Tigon 1
- * is limited to 2MB total, and in general I think most adapters have
- * around 1MB. We use this value for zeroing the NIC's SRAM, so to
- * be safe we use the largest possible value (zeroing memory that
- * isn't there doesn't hurt anything).
- */
-#define TI_MEM_MAX 0x7FFFFF
-
-/*
- * Even on the alpha, pci addresses are 32-bit quantities
- */
-
-typedef struct {
- u_int32_t ti_addr_hi;
- u_int32_t ti_addr_lo;
-} ti_hostaddr;
-#define TI_HOSTADDR(x) x.ti_addr_lo
-
-/*
- * Ring control block structure. The rules for the max_len field
- * are as follows:
- *
- * For the send ring, max_len indicates the number of entries in the
- * ring (128, 256 or 512).
- *
- * For the standard receive ring, max_len indicates the threshold
- * used to decide when a frame should be put in the jumbo receive ring
- * instead of the standard one.
- *
- * For the mini ring, max_len indicates the size of the buffers in the
- * ring. This is the value used to decide when a frame is small enough
- * to be placed in the mini ring.
- *
- * For the return receive ring, max_len indicates the number of entries
- * in the ring. It can be one of 2048, 1024 or 0 (which is the same as
- * 2048 for backwards compatibility). The value 1024 can only be used
- * if the mini ring is disabled.
- */
-struct ti_rcb {
- ti_hostaddr ti_hostaddr;
-#if BYTE_ORDER == BIG_ENDIAN
- u_int16_t ti_max_len;
- u_int16_t ti_flags;
-#else
- u_int16_t ti_flags;
- u_int16_t ti_max_len;
-#endif
- u_int32_t ti_unused;
-};
-
-#define TI_RCB_FLAG_TCP_UDP_CKSUM 0x00000001
-#define TI_RCB_FLAG_IP_CKSUM 0x00000002
-#define TI_RCB_FLAG_NO_PHDR_CKSUM 0x00000008
-#define TI_RCB_FLAG_VLAN_ASSIST 0x00000010
-#define TI_RCB_FLAG_COAL_UPD_ONLY 0x00000020
-#define TI_RCB_FLAG_HOST_RING 0x00000040
-#define TI_RCB_FLAG_IEEE_SNAP_CKSUM 0x00000080
-#define TI_RCB_FLAG_USE_EXT_RX_BD 0x00000100
-#define TI_RCB_FLAG_RING_DISABLED 0x00000200
-
-struct ti_producer {
- u_int32_t ti_idx;
- u_int32_t ti_unused;
-};
-
-/*
- * Tigon statistics counters.
- */
-struct ti_stats {
- /*
- * MAC stats, taken from RFC 1643, ethernet-like MIB
- */
- volatile u_int32_t dot3StatsAlignmentErrors; /* 0 */
- volatile u_int32_t dot3StatsFCSErrors; /* 1 */
- volatile u_int32_t dot3StatsSingleCollisionFrames; /* 2 */
- volatile u_int32_t dot3StatsMultipleCollisionFrames; /* 3 */
- volatile u_int32_t dot3StatsSQETestErrors; /* 4 */
- volatile u_int32_t dot3StatsDeferredTransmissions; /* 5 */
- volatile u_int32_t dot3StatsLateCollisions; /* 6 */
- volatile u_int32_t dot3StatsExcessiveCollisions; /* 7 */
- volatile u_int32_t dot3StatsInternalMacTransmitErrors; /* 8 */
- volatile u_int32_t dot3StatsCarrierSenseErrors; /* 9 */
- volatile u_int32_t dot3StatsFrameTooLongs; /* 10 */
- volatile u_int32_t dot3StatsInternalMacReceiveErrors; /* 11 */
- /*
- * interface stats, taken from RFC 1213, MIB-II, interfaces group
- */
- volatile u_int32_t ifIndex; /* 12 */
- volatile u_int32_t ifType; /* 13 */
- volatile u_int32_t ifMtu; /* 14 */
- volatile u_int32_t ifSpeed; /* 15 */
- volatile u_int32_t ifAdminStatus; /* 16 */
-#define IF_ADMIN_STATUS_UP 1
-#define IF_ADMIN_STATUS_DOWN 2
-#define IF_ADMIN_STATUS_TESTING 3
- volatile u_int32_t ifOperStatus; /* 17 */
-#define IF_OPER_STATUS_UP 1
-#define IF_OPER_STATUS_DOWN 2
-#define IF_OPER_STATUS_TESTING 3
-#define IF_OPER_STATUS_UNKNOWN 4
-#define IF_OPER_STATUS_DORMANT 5
- volatile u_int32_t ifLastChange; /* 18 */
- volatile u_int32_t ifInDiscards; /* 19 */
- volatile u_int32_t ifInErrors; /* 20 */
- volatile u_int32_t ifInUnknownProtos; /* 21 */
- volatile u_int32_t ifOutDiscards; /* 22 */
- volatile u_int32_t ifOutErrors; /* 23 */
- volatile u_int32_t ifOutQLen; /* deprecated */ /* 24 */
- volatile u_int8_t ifPhysAddress[8]; /* 8 bytes */ /* 25 - 26 */
- volatile u_int8_t ifDescr[32]; /* 27 - 34 */
- u_int32_t alignIt; /* align to 64 bit for u_int64_ts following */
- /*
- * more interface stats, taken from RFC 1573, MIB-IIupdate,
- * interfaces group
- */
- volatile u_int64_t ifHCInOctets; /* 36 - 37 */
- volatile u_int64_t ifHCInUcastPkts; /* 38 - 39 */
- volatile u_int64_t ifHCInMulticastPkts; /* 40 - 41 */
- volatile u_int64_t ifHCInBroadcastPkts; /* 42 - 43 */
- volatile u_int64_t ifHCOutOctets; /* 44 - 45 */
- volatile u_int64_t ifHCOutUcastPkts; /* 46 - 47 */
- volatile u_int64_t ifHCOutMulticastPkts; /* 48 - 49 */
- volatile u_int64_t ifHCOutBroadcastPkts; /* 50 - 51 */
- volatile u_int32_t ifLinkUpDownTrapEnable; /* 52 */
- volatile u_int32_t ifHighSpeed; /* 53 */
- volatile u_int32_t ifPromiscuousMode; /* 54 */
- volatile u_int32_t ifConnectorPresent; /* follow link state 55 */
- /*
- * Host Commands
- */
- volatile u_int32_t nicCmdsHostState; /* 56 */
- volatile u_int32_t nicCmdsFDRFiltering; /* 57 */
- volatile u_int32_t nicCmdsSetRecvProdIndex; /* 58 */
- volatile u_int32_t nicCmdsUpdateGencommStats; /* 59 */
- volatile u_int32_t nicCmdsResetJumboRing; /* 60 */
- volatile u_int32_t nicCmdsAddMCastAddr; /* 61 */
- volatile u_int32_t nicCmdsDelMCastAddr; /* 62 */
- volatile u_int32_t nicCmdsSetPromiscMode; /* 63 */
- volatile u_int32_t nicCmdsLinkNegotiate; /* 64 */
- volatile u_int32_t nicCmdsSetMACAddr; /* 65 */
- volatile u_int32_t nicCmdsClearProfile; /* 66 */
- volatile u_int32_t nicCmdsSetMulticastMode; /* 67 */
- volatile u_int32_t nicCmdsClearStats; /* 68 */
- volatile u_int32_t nicCmdsSetRecvJumboProdIndex; /* 69 */
- volatile u_int32_t nicCmdsSetRecvMiniProdIndex; /* 70 */
- volatile u_int32_t nicCmdsRefreshStats; /* 71 */
- volatile u_int32_t nicCmdsUnknown; /* 72 */
- /*
- * NIC Events
- */
- volatile u_int32_t nicEventsNICFirmwareOperational; /* 73 */
- volatile u_int32_t nicEventsStatsUpdated; /* 74 */
- volatile u_int32_t nicEventsLinkStateChanged; /* 75 */
- volatile u_int32_t nicEventsError; /* 76 */
- volatile u_int32_t nicEventsMCastListUpdated; /* 77 */
- volatile u_int32_t nicEventsResetJumboRing; /* 78 */
- /*
- * Ring manipulation
- */
- volatile u_int32_t nicRingSetSendProdIndex; /* 79 */
- volatile u_int32_t nicRingSetSendConsIndex; /* 80 */
- volatile u_int32_t nicRingSetRecvReturnProdIndex; /* 81 */
- /*
- * Interrupts
- */
- volatile u_int32_t nicInterrupts; /* 82 */
- volatile u_int32_t nicAvoidedInterrupts; /* 83 */
- /*
- * BD Coalessing Thresholds
- */
- volatile u_int32_t nicEventThresholdHit; /* 84 */
- volatile u_int32_t nicSendThresholdHit; /* 85 */
- volatile u_int32_t nicRecvThresholdHit; /* 86 */
- /*
- * DMA Attentions
- */
- volatile u_int32_t nicDmaRdOverrun; /* 87 */
- volatile u_int32_t nicDmaRdUnderrun; /* 88 */
- volatile u_int32_t nicDmaWrOverrun; /* 89 */
- volatile u_int32_t nicDmaWrUnderrun; /* 90 */
- volatile u_int32_t nicDmaWrMasterAborts; /* 91 */
- volatile u_int32_t nicDmaRdMasterAborts; /* 92 */
- /*
- * NIC Resources
- */
- volatile u_int32_t nicDmaWriteRingFull; /* 93 */
- volatile u_int32_t nicDmaReadRingFull; /* 94 */
- volatile u_int32_t nicEventRingFull; /* 95 */
- volatile u_int32_t nicEventProducerRingFull; /* 96 */
- volatile u_int32_t nicTxMacDescrRingFull; /* 97 */
- volatile u_int32_t nicOutOfTxBufSpaceFrameRetry; /* 98 */
- volatile u_int32_t nicNoMoreWrDMADescriptors; /* 99 */
- volatile u_int32_t nicNoMoreRxBDs; /* 100 */
- volatile u_int32_t nicNoSpaceInReturnRing; /* 101 */
- volatile u_int32_t nicSendBDs; /* current count 102 */
- volatile u_int32_t nicRecvBDs; /* current count 103 */
- volatile u_int32_t nicJumboRecvBDs; /* current count 104 */
- volatile u_int32_t nicMiniRecvBDs; /* current count 105 */
- volatile u_int32_t nicTotalRecvBDs; /* current count 106 */
- volatile u_int32_t nicTotalSendBDs; /* current count 107 */
- volatile u_int32_t nicJumboSpillOver; /* 108 */
- volatile u_int32_t nicSbusHangCleared; /* 109 */
- volatile u_int32_t nicEnqEventDelayed; /* 110 */
- /*
- * Stats from MAC rx completion
- */
- volatile u_int32_t nicMacRxLateColls; /* 111 */
- volatile u_int32_t nicMacRxLinkLostDuringPkt; /* 112 */
- volatile u_int32_t nicMacRxPhyDecodeErr; /* 113 */
- volatile u_int32_t nicMacRxMacAbort; /* 114 */
- volatile u_int32_t nicMacRxTruncNoResources; /* 115 */
- /*
- * Stats from the mac_stats area
- */
- volatile u_int32_t nicMacRxDropUla; /* 116 */
- volatile u_int32_t nicMacRxDropMcast; /* 117 */
- volatile u_int32_t nicMacRxFlowControl; /* 118 */
- volatile u_int32_t nicMacRxDropSpace; /* 119 */
- volatile u_int32_t nicMacRxColls; /* 120 */
- /*
- * MAC RX Attentions
- */
- volatile u_int32_t nicMacRxTotalAttns; /* 121 */
- volatile u_int32_t nicMacRxLinkAttns; /* 122 */
- volatile u_int32_t nicMacRxSyncAttns; /* 123 */
- volatile u_int32_t nicMacRxConfigAttns; /* 124 */
- volatile u_int32_t nicMacReset; /* 125 */
- volatile u_int32_t nicMacRxBufDescrAttns; /* 126 */
- volatile u_int32_t nicMacRxBufAttns; /* 127 */
- volatile u_int32_t nicMacRxZeroFrameCleanup; /* 128 */
- volatile u_int32_t nicMacRxOneFrameCleanup; /* 129 */
- volatile u_int32_t nicMacRxMultipleFrameCleanup; /* 130 */
- volatile u_int32_t nicMacRxTimerCleanup; /* 131 */
- volatile u_int32_t nicMacRxDmaCleanup; /* 132 */
- /*
- * Stats from the mac_stats area
- */
- volatile u_int32_t nicMacTxCollisionHistogram[15]; /* 133 */
- /*
- * MAC TX Attentions
- */
- volatile u_int32_t nicMacTxTotalAttns; /* 134 */
- /*
- * NIC Profile
- */
- volatile u_int32_t nicProfile[32]; /* 135 */
- /*
- * Pat to 1024 bytes.
- */
- u_int32_t pad[75];
-};
-/*
- * Tigon general information block. This resides in host memory
- * and contains the status counters, ring control blocks and
- * producer pointers.
- */
-
-struct ti_gib {
- struct ti_stats ti_stats;
- struct ti_rcb ti_ev_rcb;
- struct ti_rcb ti_cmd_rcb;
- struct ti_rcb ti_tx_rcb;
- struct ti_rcb ti_std_rx_rcb;
- struct ti_rcb ti_jumbo_rx_rcb;
- struct ti_rcb ti_mini_rx_rcb;
- struct ti_rcb ti_return_rcb;
- ti_hostaddr ti_ev_prodidx_ptr;
- ti_hostaddr ti_return_prodidx_ptr;
- ti_hostaddr ti_tx_considx_ptr;
- ti_hostaddr ti_refresh_stats_ptr;
-};
-
-/*
- * Buffer descriptor structures. There are basically three types
- * of structures: normal receive descriptors, extended receive
- * descriptors and transmit descriptors. The extended receive
- * descriptors are optionally used only for the jumbo receive ring.
- */
-
-struct ti_rx_desc {
- ti_hostaddr ti_addr;
-#if BYTE_ORDER == BIG_ENDIAN
- u_int16_t ti_idx;
- u_int16_t ti_len;
-#else
- u_int16_t ti_len;
- u_int16_t ti_idx;
-#endif
-#if BYTE_ORDER == BIG_ENDIAN
- u_int16_t ti_type;
- u_int16_t ti_flags;
-#else
- u_int16_t ti_flags;
- u_int16_t ti_type;
-#endif
-#if BYTE_ORDER == BIG_ENDIAN
- u_int16_t ti_ip_cksum;
- u_int16_t ti_tcp_udp_cksum;
-#else
- u_int16_t ti_tcp_udp_cksum;
- u_int16_t ti_ip_cksum;
-#endif
-#if BYTE_ORDER == BIG_ENDIAN
- u_int16_t ti_error_flags;
- u_int16_t ti_vlan_tag;
-#else
- u_int16_t ti_vlan_tag;
- u_int16_t ti_error_flags;
-#endif
- u_int32_t ti_rsvd;
- u_int32_t ti_opaque;
-};
-
-struct ti_rx_desc_ext {
- ti_hostaddr ti_addr1;
- ti_hostaddr ti_addr2;
- ti_hostaddr ti_addr3;
-#if BYTE_ORDER == BIG_ENDIAN
- u_int16_t ti_len1;
- u_int16_t ti_len2;
-#else
- u_int16_t ti_len2;
- u_int16_t ti_len1;
-#endif
-#if BYTE_ORDER == BIG_ENDIAN
- u_int16_t ti_len3;
- u_int16_t ti_rsvd0;
-#else
- u_int16_t ti_rsvd0;
- u_int16_t ti_len3;
-#endif
- ti_hostaddr ti_addr0;
-#if BYTE_ORDER == BIG_ENDIAN
- u_int16_t ti_idx;
- u_int16_t ti_len0;
-#else
- u_int16_t ti_len0;
- u_int16_t ti_idx;
-#endif
-#if BYTE_ORDER == BIG_ENDIAN
- u_int16_t ti_type;
- u_int16_t ti_flags;
-#else
- u_int16_t ti_flags;
- u_int16_t ti_type;
-#endif
-#if BYTE_ORDER == BIG_ENDIAN
- u_int16_t ti_ip_cksum;
- u_int16_t ti_tcp_udp_cksum;
-#else
- u_int16_t ti_tcp_udp_cksum;
- u_int16_t ti_ip_cksum;
-#endif
-#if BYTE_ORDER == BIG_ENDIAN
- u_int16_t ti_error_flags;
- u_int16_t ti_vlan_tag;
-#else
- u_int16_t ti_vlan_tag;
- u_int16_t ti_error_flags;
-#endif
- u_int32_t ti_rsvd1;
- u_int32_t ti_opaque;
-};
-
-/*
- * Transmit descriptors are, mercifully, very small.
- */
-struct ti_tx_desc {
- ti_hostaddr ti_addr;
-#if BYTE_ORDER == BIG_ENDIAN
- u_int16_t ti_len;
- u_int16_t ti_flags;
-#else
- u_int16_t ti_flags;
- u_int16_t ti_len;
-#endif
-#if BYTE_ORDER == BIG_ENDIAN
- u_int16_t ti_rsvd;
- u_int16_t ti_vlan_tag;
-#else
- u_int16_t ti_vlan_tag;
- u_int16_t ti_rsvd;
-#endif
-};
-
-/*
- * NOTE! On the Alpha, we have an alignment constraint.
- * The first thing in the packet is a 14-byte Ethernet header.
- * This means that the packet is misaligned. To compensate,
- * we actually offset the data 2 bytes into the cluster. This
- * alignes the packet after the Ethernet header at a 32-bit
- * boundary.
- */
-
-#define TI_JUMBO_FRAMELEN 9018
-#define TI_JUMBO_MTU (TI_JUMBO_FRAMELEN - ETHER_HDR_LEN - ETHER_CRC_LEN)
-#define TI_PAGE_SIZE PAGE_SIZE
-
-/*
- * Buffer descriptor error flags.
- */
-#define TI_BDERR_CRC 0x0001
-#define TI_BDERR_COLLDETECT 0x0002
-#define TI_BDERR_LINKLOST 0x0004
-#define TI_BDERR_DECODE 0x0008
-#define TI_BDERR_ODD_NIBBLES 0x0010
-#define TI_BDERR_MAC_ABRT 0x0020
-#define TI_BDERR_RUNT 0x0040
-#define TI_BDERR_TRUNC 0x0080
-#define TI_BDERR_GIANT 0x0100
-
-/*
- * Buffer descriptor flags.
- */
-#define TI_BDFLAG_TCP_UDP_CKSUM 0x0001
-#define TI_BDFLAG_IP_CKSUM 0x0002
-#define TI_BDFLAG_END 0x0004
-#define TI_BDFLAG_MORE 0x0008
-#define TI_BDFLAG_JUMBO_RING 0x0010
-#define TI_BDFLAG_UCAST_PKT 0x0020
-#define TI_BDFLAG_MCAST_PKT 0x0040
-#define TI_BDFLAG_BCAST_PKT 0x0060
-#define TI_BDFLAG_IP_FRAG 0x0080
-#define TI_BDFLAG_IP_FRAG_END 0x0100
-#define TI_BDFLAG_VLAN_TAG 0x0200
-#define TI_BDFLAG_ERROR 0x0400
-#define TI_BDFLAG_COAL_NOW 0x0800
-#define TI_BDFLAG_MINI_RING 0x1000
-
-/*
- * Descriptor type flags. I think these only have meaning for
- * the Tigon 1. I had to extract them from the sample driver source
- * since they aren't in the manual.
- */
-#define TI_BDTYPE_TYPE_NULL 0x0000
-#define TI_BDTYPE_SEND_BD 0x0001
-#define TI_BDTYPE_RECV_BD 0x0002
-#define TI_BDTYPE_RECV_JUMBO_BD 0x0003
-#define TI_BDTYPE_RECV_BD_LAST 0x0004
-#define TI_BDTYPE_SEND_DATA 0x0005
-#define TI_BDTYPE_SEND_DATA_LAST 0x0006
-#define TI_BDTYPE_RECV_DATA 0x0007
-#define TI_BDTYPE_RECV_DATA_LAST 0x000b
-#define TI_BDTYPE_EVENT_RUPT 0x000c
-#define TI_BDTYPE_EVENT_NO_RUPT 0x000d
-#define TI_BDTYPE_ODD_START 0x000e
-#define TI_BDTYPE_UPDATE_STATS 0x000f
-#define TI_BDTYPE_SEND_DUMMY_DMA 0x0010
-#define TI_BDTYPE_EVENT_PROD 0x0011
-#define TI_BDTYPE_TX_CONS 0x0012
-#define TI_BDTYPE_RX_PROD 0x0013
-#define TI_BDTYPE_REFRESH_STATS 0x0014
-#define TI_BDTYPE_SEND_DATA_LAST_VLAN 0x0015
-#define TI_BDTYPE_SEND_DATA_COAL 0x0016
-#define TI_BDTYPE_SEND_DATA_LAST_COAL 0x0017
-#define TI_BDTYPE_SEND_DATA_LAST_VLAN_COAL 0x0018
-#define TI_BDTYPE_TX_CONS_NO_INTR 0x0019
-
-/*
- * Tigon command structure.
- */
-struct ti_cmd_desc {
- u_int32_t ti_cmdx;
-};
-
-#define TI_CMD_CMD(cmd) (((((cmd)->ti_cmdx)) >> 24) & 0xff)
-#define TI_CMD_CODE(cmd) (((((cmd)->ti_cmdx)) >> 12) & 0xfff)
-#define TI_CMD_IDX(cmd) ((((cmd)->ti_cmdx)) & 0xfff)
-
-#define TI_CMD_HOST_STATE 0x01
-#define TI_CMD_CODE_STACK_UP 0x01
-#define TI_CMD_CODE_STACK_DOWN 0x02
-
-/*
- * This command enables software address filtering. It's a workaround
- * for a bug in the Tigon 1 and not implemented for the Tigon 2.
- */
-#define TI_CMD_FDR_FILTERING 0x02
-#define TI_CMD_CODE_FILT_ENB 0x01
-#define TI_CMD_CODE_FILT_DIS 0x02
-
-#define TI_CMD_SET_RX_PROD_IDX 0x03 /* obsolete */
-#define TI_CMD_UPDATE_GENCOM 0x04
-#define TI_CMD_RESET_JUMBO_RING 0x05
-#define TI_CMD_SET_PARTIAL_RX_CNT 0x06
-#define TI_CMD_ADD_MCAST_ADDR 0x08 /* obsolete */
-#define TI_CMD_DEL_MCAST_ADDR 0x09 /* obsolete */
-
-#define TI_CMD_SET_PROMISC_MODE 0x0A
-#define TI_CMD_CODE_PROMISC_ENB 0x01
-#define TI_CMD_CODE_PROMISC_DIS 0x02
-
-#define TI_CMD_LINK_NEGOTIATION 0x0B
-#define TI_CMD_CODE_NEGOTIATE_BOTH 0x00
-#define TI_CMD_CODE_NEGOTIATE_GIGABIT 0x01
-#define TI_CMD_CODE_NEGOTIATE_10_100 0x02
-
-#define TI_CMD_SET_MAC_ADDR 0x0C
-#define TI_CMD_CLR_PROFILE 0x0D
-
-#define TI_CMD_SET_ALLMULTI 0x0E
-#define TI_CMD_CODE_ALLMULTI_ENB 0x01
-#define TI_CMD_CODE_ALLMULTI_DIS 0x02
-
-#define TI_CMD_CLR_STATS 0x0F
-#define TI_CMD_SET_RX_JUMBO_PROD_IDX 0x10 /* obsolete */
-#define TI_CMD_RFRSH_STATS 0x11
-
-#define TI_CMD_EXT_ADD_MCAST 0x12
-#define TI_CMD_EXT_DEL_MCAST 0x13
-
-/*
- * Utility macros to make issuing commands a little simpler. Assumes
- * that 'sc' and 'cmd' are in local scope.
- */
-#define TI_DO_CMD(x, y, z) \
- cmd.ti_cmdx = (((x) << 24) | ((y) << 12) | ((z))); \
- ti_cmd(sc, &cmd);
-
-#define TI_DO_CMD_EXT(x, y, z, v, w) \
- cmd.ti_cmdx = (((x) << 24) | ((y) << 12) | ((z))); \
- ti_cmd_ext(sc, &cmd, v, w);
-
-/*
- * Other utility macros.
- */
-#define TI_INC(x, y) (x) = (x + 1) % y
-
-#define TI_UPDATE_JUMBOPROD(x, y) \
- if (x->ti_hwrev == TI_HWREV_TIGON) { \
- TI_DO_CMD(TI_CMD_SET_RX_JUMBO_PROD_IDX, 0, y); \
- } else { \
- CSR_WRITE_4(x, TI_MB_JUMBORXPROD_IDX, y); \
- }
-
-#define TI_UPDATE_MINIPROD(x, y) \
- CSR_WRITE_4(x, TI_MB_MINIRXPROD_IDX, y);
-
-#define TI_UPDATE_STDPROD(x, y) \
- if (x->ti_hwrev == TI_HWREV_TIGON) { \
- TI_DO_CMD(TI_CMD_SET_RX_PROD_IDX, 0, y); \
- } else { \
- CSR_WRITE_4(x, TI_MB_STDRXPROD_IDX, y); \
- }
-
-
-/*
- * Tigon event structure.
- */
-struct ti_event_desc {
- u_int32_t ti_eventx;
- u_int32_t ti_rsvd;
-};
-
-#define TI_EVENT_EVENT(e) (((((e)->ti_eventx)) >> 24) & 0xff)
-#define TI_EVENT_CODE(e) (((((e)->ti_eventx)) >> 12) & 0xfff)
-#define TI_EVENT_IDX(e) (((((e)->ti_eventx))) & 0xfff)
-
-/*
- * Tigon events.
- */
-#define TI_EV_FIRMWARE_UP 0x01
-#define TI_EV_STATS_UPDATED 0x04
-
-#define TI_EV_LINKSTAT_CHANGED 0x06
-#define TI_EV_CODE_GIG_LINK_UP 0x01
-#define TI_EV_CODE_LINK_DOWN 0x02
-#define TI_EV_CODE_LINK_UP 0x03
-
-#define TI_EV_ERROR 0x07
-#define TI_EV_CODE_ERR_INVAL_CMD 0x01
-#define TI_EV_CODE_ERR_UNIMP_CMD 0x02
-#define TI_EV_CODE_ERR_BADCFG 0x03
-
-#define TI_EV_MCAST_UPDATED 0x08
-#define TI_EV_CODE_MCAST_ADD 0x01
-#define TI_EV_CODE_MCAST_DEL 0x02
-
-#define TI_EV_RESET_JUMBO_RING 0x09
-/*
- * Register access macros. The Tigon always uses memory mapped register
- * accesses and all registers must be accessed with 32 bit operations.
- */
-
-#define CSR_WRITE_4(sc, reg, val) \
- bus_space_write_4(sc->ti_btag, sc->ti_bhandle, (reg), (val))
-
-#define CSR_READ_4(sc, reg) \
- bus_space_read_4(sc->ti_btag, sc->ti_bhandle, (reg))
-
-#define TI_SETBIT(sc, reg, x) \
- CSR_WRITE_4(sc, (reg), (CSR_READ_4(sc, (reg)) | (x)))
-#define TI_CLRBIT(sc, reg, x) \
- CSR_WRITE_4(sc, (reg), (CSR_READ_4(sc, (reg)) & ~(x)))
-
-/*
- * Memory management stuff. Note: the SSLOTS, MSLOTS and JSLOTS
- * values are tuneable. They control the actual amount of buffers
- * allocated for the standard, mini and jumbo receive rings.
- */
-
-#define TI_SSLOTS 256
-#define TI_MSLOTS 256
-#define TI_JSLOTS 384
-
-#define TI_JRAWLEN (TI_JUMBO_FRAMELEN + ETHER_ALIGN)
-#define TI_JLEN (TI_JRAWLEN + (sizeof(u_int64_t) - \
- (TI_JRAWLEN % sizeof(u_int64_t))))
-#define TI_JPAGESZ PAGE_SIZE
-#define TI_RESID (TI_JPAGESZ - (TI_JLEN * TI_JSLOTS) % TI_JPAGESZ)
-#define TI_JMEM ((TI_JLEN * TI_JSLOTS) + TI_RESID)
-
-struct ti_jslot {
- caddr_t ti_buf;
- int ti_inuse;
-};
-
-/*
- * Ring structures. Most of these reside in host memory and we tell
- * the NIC where they are via the ring control blocks. The exceptions
- * are the tx and command rings, which live in NIC memory and which
- * we access via the shared memory window.
- */
-struct ti_ring_data {
- struct ti_rx_desc ti_rx_std_ring[TI_STD_RX_RING_CNT];
- struct ti_rx_desc ti_rx_jumbo_ring[TI_JUMBO_RX_RING_CNT];
- struct ti_rx_desc ti_rx_mini_ring[TI_MINI_RX_RING_CNT];
- struct ti_rx_desc ti_rx_return_ring[TI_RETURN_RING_CNT];
- struct ti_event_desc ti_event_ring[TI_EVENT_RING_CNT];
- struct ti_tx_desc ti_tx_ring[TI_TX_RING_CNT];
-
- /*
- * Make sure producer structures are aligned on 32-byte cache
- * line boundaries.
- */
- struct ti_producer ti_ev_prodidx_r;
- u_int32_t ti_pad0[6];
- struct ti_producer ti_return_prodidx_r;
- u_int32_t ti_pad1[6];
- struct ti_producer ti_tx_considx_r;
- u_int32_t ti_pad2[6];
- struct ti_gib ti_info;
-};
-
-#define TI_RING_DMA_ADDR(sc, offset) \
- ((sc)->ti_ring_map->dm_segs[0].ds_addr + \
- offsetof(struct ti_ring_data, offset))
-
-#define TI_RING_DMASYNC(sc, offset, op) \
- bus_dmamap_sync((sc)->sc_dmatag, (sc)->ti_ring_map, \
- offsetof(struct ti_ring_data, offset), \
- sizeof(((struct ti_ring_data *)0)->offset), (op))
-
-/*
- * Number of DMA segments in a TxCB. Note that this is carefully
- * chosen to make the total struct size an even power of two. It's
- * critical that no TxCB be split across a page boundry since
- * no attempt is made to allocate physically contiguous memory.
- *
- */
-#ifdef __LP64__
-#define TI_NTXSEG 30
-#else
-#define TI_NTXSEG 31
-#endif
-
-struct ti_txmap_entry {
- bus_dmamap_t dmamap;
- SLIST_ENTRY(ti_txmap_entry) link;
-};
-
-/*
- * Mbuf pointers. We need these to keep track of the virtual addresses
- * of our mbuf chains since we can only convert from physical to virtual,
- * not the other way around.
- */
-struct ti_chain_data {
- struct mbuf *ti_tx_chain[TI_TX_RING_CNT];
- struct mbuf *ti_rx_std_chain[TI_STD_RX_RING_CNT];
- struct mbuf *ti_rx_jumbo_chain[TI_JUMBO_RX_RING_CNT];
- struct mbuf *ti_rx_mini_chain[TI_MINI_RX_RING_CNT];
-
- struct ti_txmap_entry *ti_tx_map[TI_TX_RING_CNT];
- bus_dmamap_t ti_rx_std_map[TI_STD_RX_RING_CNT];
- bus_dmamap_t ti_rx_jumbo_map;
- bus_dmamap_t ti_rx_mini_map[TI_MINI_RX_RING_CNT];
-
- /* Stick the jumbo mem management stuff here too. */
- struct ti_jslot ti_jslots[TI_JSLOTS];
- void *ti_jumbo_buf;
-};
-
-#define TI_JUMBO_DMA_ADDR(sc, m) \
- ((sc)->ti_cdata.ti_rx_jumbo_map->dm_segs[0].ds_addr + \
- (mtod((m), char *) - (char *)(sc)->ti_cdata.ti_jumbo_buf))
-
-struct ti_type {
- u_int16_t ti_vid;
- u_int16_t ti_did;
- char *ti_name;
-};
-
-#define TI_HWREV_TIGON 0x01
-#define TI_HWREV_TIGON_II 0x02
-#define TI_TIMEOUT 1000
-#define TI_TXCONS_UNSET 0xFFFF /* impossible value */
-
-struct ti_mc_entry {
- struct ether_addr mc_addr;
- SLIST_ENTRY(ti_mc_entry) mc_entries;
-};
-
-struct ti_jpool_entry {
- int slot;
- SLIST_ENTRY(ti_jpool_entry) jpool_entries;
-};
-
-struct ti_softc {
- struct device sc_dv;
- struct arpcom arpcom; /* interface info */
- bus_space_handle_t ti_bhandle;
- bus_space_tag_t ti_btag;
- void * ti_intrhand;
- struct ifmedia ifmedia; /* media info */
- u_int8_t ti_hwrev; /* Tigon rev (1 or 2) */
- u_int8_t ti_copper; /* 1000baseTX card */
- u_int8_t ti_linkstat; /* Link state */
- bus_dma_tag_t sc_dmatag;
- struct ti_ring_data *ti_rdata; /* rings */
- struct ti_chain_data ti_cdata; /* mbufs */
-#define ti_ev_prodidx ti_rdata->ti_ev_prodidx_r
-#define ti_return_prodidx ti_rdata->ti_return_prodidx_r
-#define ti_tx_considx ti_rdata->ti_tx_considx_r
- struct ti_tx_desc *ti_tx_ring_nic;/* pointer to shared mem */
- bus_dmamap_t ti_ring_map;
- u_int16_t ti_tx_saved_prodidx;
- u_int16_t ti_tx_saved_considx;
- u_int16_t ti_rx_saved_considx;
- u_int16_t ti_ev_saved_considx;
- u_int16_t ti_cmd_saved_prodidx;
- u_int16_t ti_std; /* current std ring head */
- u_int16_t ti_mini; /* current mini ring head */
- u_int16_t ti_jumbo; /* current jumo ring head */
- SLIST_HEAD(__ti_mchead, ti_mc_entry) ti_mc_listhead;
- SLIST_HEAD(__ti_jfreehead, ti_jpool_entry) ti_jfree_listhead;
- SLIST_HEAD(__ti_jinusehead, ti_jpool_entry) ti_jinuse_listhead;
- SLIST_HEAD(__ti_txmaphead, ti_txmap_entry) ti_tx_map_listhead;
- u_int32_t ti_stat_ticks;
- u_int32_t ti_rx_coal_ticks;
- u_int32_t ti_tx_coal_ticks;
- u_int32_t ti_rx_max_coal_bds;
- u_int32_t ti_tx_max_coal_bds;
- u_int32_t ti_tx_buf_ratio;
- int ti_if_flags;
- int ti_txcnt;
-};
-
-/*
- * Microchip Technology 24Cxx EEPROM control bytes
- */
-#define EEPROM_CTL_READ 0xA1 /* 0101 0001 */
-#define EEPROM_CTL_WRITE 0xA0 /* 0101 0000 */
-
-/*
- * Note that EEPROM_START leaves transmission enabled.
- */
-#define EEPROM_START \
- TI_SETBIT(sc, TI_MISC_LOCAL_CTL, TI_MLC_EE_CLK); /* Pull clock pin high */\
- TI_SETBIT(sc, TI_MISC_LOCAL_CTL, TI_MLC_EE_DOUT); /* Set DATA bit to 1 */ \
- TI_SETBIT(sc, TI_MISC_LOCAL_CTL, TI_MLC_EE_TXEN); /* Enable xmit to write bit */\
- TI_CLRBIT(sc, TI_MISC_LOCAL_CTL, TI_MLC_EE_DOUT); /* Pull DATA bit to 0 again */\
- TI_CLRBIT(sc, TI_MISC_LOCAL_CTL, TI_MLC_EE_CLK); /* Pull clock low again */
-
-/*
- * EEPROM_STOP ends access to the EEPROM and clears the ETXEN bit so
- * that no further data can be written to the EEPROM I/O pin.
- */
-#define EEPROM_STOP \
- TI_CLRBIT(sc, TI_MISC_LOCAL_CTL, TI_MLC_EE_TXEN); /* Disable xmit */ \
- TI_CLRBIT(sc, TI_MISC_LOCAL_CTL, TI_MLC_EE_DOUT); /* Pull DATA to 0 */ \
- TI_SETBIT(sc, TI_MISC_LOCAL_CTL, TI_MLC_EE_CLK); /* Pull clock high */ \
- TI_SETBIT(sc, TI_MISC_LOCAL_CTL, TI_MLC_EE_TXEN); /* Enable xmit */ \
- TI_SETBIT(sc, TI_MISC_LOCAL_CTL, TI_MLC_EE_DOUT); /* Toggle DATA to 1 */ \
- TI_CLRBIT(sc, TI_MISC_LOCAL_CTL, TI_MLC_EE_TXEN); /* Disable xmit. */ \
- TI_CLRBIT(sc, TI_MISC_LOCAL_CTL, TI_MLC_EE_CLK); /* Pull clock low again */
diff --git a/sys/dev/pci/if_tivar.h b/sys/dev/pci/if_tivar.h
deleted file mode 100644
index 5c3c37e943e..00000000000
--- a/sys/dev/pci/if_tivar.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/* $OpenBSD: if_tivar.h,v 1.2 2004/11/22 21:23:57 deraadt Exp $ */
-
-/*
- * Copyright (c) 2004 Theo de Raadt <deraadt@openbsd.org>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-struct tigon_firmware {
- int FwReleaseMajor;
- int FwReleaseMinor;
- int FwReleaseFix;
- u_int32_t FwStartAddr;
-
- u_int32_t FwTextAddr;
- int FwTextLen;
- u_int32_t FwRodataAddr;
- int FwRodataLen;
-
- u_int32_t FwDataAddr;
- int FwDataLen;
- u_int32_t FwSbssAddr;
- int FwSbssLen;
-
- u_int32_t FwBssAddr;
- int FwBssLen;
-
- int FwTextOffset;
- int FwRodataOffset;
- int FwDataOffset;
-
- u_char data[1];
-};