diff options
author | Brooks Davis <brooks@FreeBSD.org> | 2019-05-17 15:23:43 +0000 |
---|---|---|
committer | Brooks Davis <brooks@FreeBSD.org> | 2019-05-17 15:23:43 +0000 |
commit | 3b70dd81f56fd1d096f0bb6fc0092be425d6856c (patch) | |
tree | a4232713c57fca9334313a774f42b2df7e7e9ff9 | |
parent | 607790d10fdb97d25cdc0bbe9ed6eaae67383ae1 (diff) | |
download | src-3b70dd81f56f.tar.gz src-3b70dd81f56f.zip |
FCP-101: Remove sf(4).
Relnotes: yes
FCP: https://github.com/freebsd/fcp/blob/master/fcp-0101.md
Reviewed by: jhb, imp
Differential Revision: https://reviews.freebsd.org/D20230
Notes
Notes:
svn path=/head/; revision=347916
-rw-r--r-- | ObsoleteFiles.inc | 2 | ||||
-rw-r--r-- | share/man/man4/Makefile | 2 | ||||
-rw-r--r-- | share/man/man4/sf.4 | 217 | ||||
-rw-r--r-- | sys/amd64/conf/GENERIC | 1 | ||||
-rw-r--r-- | sys/conf/NOTES | 6 | ||||
-rw-r--r-- | sys/conf/files | 1 | ||||
-rw-r--r-- | sys/dev/sf/if_sf.c | 2740 | ||||
-rw-r--r-- | sys/dev/sf/if_sfreg.h | 1105 | ||||
-rw-r--r-- | sys/dev/sf/starfire_rx.h | 118 | ||||
-rw-r--r-- | sys/dev/sf/starfire_tx.h | 118 | ||||
-rw-r--r-- | sys/i386/conf/GENERIC | 1 | ||||
-rw-r--r-- | sys/modules/Makefile | 2 | ||||
-rw-r--r-- | sys/modules/sf/Makefile | 9 | ||||
-rw-r--r-- | sys/sparc64/conf/GENERIC | 1 |
14 files changed, 2 insertions, 4321 deletions
diff --git a/ObsoleteFiles.inc b/ObsoleteFiles.inc index 3e14d903413d..d5b944780df4 100644 --- a/ObsoleteFiles.inc +++ b/ObsoleteFiles.inc @@ -50,6 +50,8 @@ OLD_FILES+=usr/share/man/man4/ex.4 OLD_FILES+=usr/share/man/man4/fe.4 OLD_FILES+=usr/share/man/man4/pcn.4 OLD_FILES+=usr/share/man/man4/if_pcn.4 +OLD_FILES+=usr/share/man/man4/sf.4 +OLD_FILES+=usr/share/man/man4/if_sf.4 # 20190513: libcap_sysctl interface change OLD_FILES+=lib/casper/libcap_sysctl.1 # 20190509: tests/sys/opencrypto requires the net/py-dpkt package. diff --git a/share/man/man4/Makefile b/share/man/man4/Makefile index 798cc67cdd38..ac576378bc6a 100644 --- a/share/man/man4/Makefile +++ b/share/man/man4/Makefile @@ -451,7 +451,6 @@ MAN= aac.4 \ sem.4 \ send.4 \ ses.4 \ - sf.4 \ ${_sfxge.4} \ sge.4 \ siba.4 \ @@ -701,7 +700,6 @@ MLINKS+=scsi.4 CAM.4 \ scsi.4 cam.4 \ scsi.4 scbus.4 \ scsi.4 SCSI.4 -MLINKS+=sf.4 if_sf.4 MLINKS+=sge.4 if_sge.4 MLINKS+=sis.4 if_sis.4 MLINKS+=sk.4 if_sk.4 diff --git a/share/man/man4/sf.4 b/share/man/man4/sf.4 deleted file mode 100644 index 085ed9323ed7..000000000000 --- a/share/man/man4/sf.4 +++ /dev/null @@ -1,217 +0,0 @@ -.\" 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$ -.\" -.Dd October 24, 2018 -.Dt SF 4 -.Os -.Sh NAME -.Nm sf -.Nd "Adaptec AIC-6915" -.Qq Starfire -PCI Fast Ethernet adapter driver -.Sh SYNOPSIS -To compile this driver into the kernel, -place the following lines in your -kernel configuration file: -.Bd -ragged -offset indent -.Cd "device miibus" -.Cd "device sf" -.Ed -.Pp -Alternatively, to load the driver as a -module at boot time, place the following line in -.Xr loader.conf 5 : -.Bd -literal -offset indent -if_sf_load="YES" -.Ed -.Sh DEPRECATION NOTICE -The -.Nm -driver is not present in -.Fx 13.0 -and later. -See https://github.com/freebsd/fcp/blob/master/fcp-0101.md for more -information. -.Sh DESCRIPTION -The -.Nm -driver provides support for Adaptec Duralink Fast Ethernet adapters -based on the Adaptec AIC-6915 "Starfire" chipset. -.Pp -The AIC-6915 is a bus master controller with an MII interface. -It -supports high and low priority transmit and receive queues, TCP/IP -checksum offload, multiple DMA descriptor formats and both polling -and producer/consumer DMA models. -The AIC-6915 receive filtering -options include a 16 entry perfect filter, a 512-bit hash table -for multicast addresses, a 512-bit hash table for priority address -matching and VLAN filtering. -An external MII-compliant transceiver -is required for media interfacing. -.Pp -Multiport adapters consist of several AIC-6915 controllers connected -via a PCI to PCI bridge. -Each controller is treated as a separate -interface by the -.Nm -driver. -.Pp -The -.Nm -driver supports the following media types: -.Bl -tag -width xxxxxxxxxxxxxxxxxxxx -.It autoselect -Enable autoselection of the media type and options. -The user can manually override -the autoselected mode by adding media options to the -.Pa /etc/rc.conf -file. -.It 10baseT/UTP -Set 10Mbps operation. -The -.Ar mediaopt -option can also be used to select either -.Ar full-duplex -or -.Ar half-duplex -modes. -.It 100baseTX -Set 100Mbps (Fast Ethernet) operation. -The -.Ar mediaopt -option can also be used to select either -.Ar full-duplex -or -.Ar half-duplex -modes. -.El -.Pp -The -.Nm -driver supports the following media options: -.Bl -tag -width xxxxxxxxxxxxxxxxxxxx -.It full-duplex -Force full duplex operation -.It half-duplex -Force half duplex operation. -.El -.Pp -For more information on configuring this device, see -.Xr ifconfig 8 . -.Sh HARDWARE -Adapters supported by the -.Nm -driver include: -.Pp -.Bl -bullet -compact -.It -ANA-62011 64-bit single port 10/100baseTX adapter -.It -ANA-62022 64-bit dual port 10/100baseTX adapter -.It -ANA-62044 64-bit quad port 10/100baseTX adapter -.It -ANA-69011 32-bit single port 10/100baseTX adapter -.It -ANA-62020 64-bit single port 100baseFX adapter -.El -.Sh SYSCTL VARIABLES -The following variables are available as both -.Xr sysctl 8 -variables and -.Xr loader 8 -tunables: -.Bl -tag -width indent -.It Va dev.sf.%d.int_mod -Maximum amount of time to delay interrupt processing in units of -102.4us. -The accepted range is 0 to 31, the default value is 1 (102.4us). -Value 0 completely disables the interrupt moderation. -The interface does not need to be brought down and up again before -a change takes effect. -.It Va dev.sf.%d.stats -Display lots of useful MAC counters maintained in the driver. -.El -.Sh DIAGNOSTICS -.Bl -diag -.It "sf%d: couldn't map memory" -A fatal initialization error has occurred. -This may -happen if the PCI BIOS not configured the device, which may be because -the BIOS has been configured for a "Plug and Play" operating system. -The "Plug and Play OS" setting in the BIOS should be set to "no" or -"off" in order for PCI devices to work properly with -.Fx . -.It "sf%d: couldn't map ports" -A fatal initialization error has occurred. -This may -happen if the PCI BIOS not configured the device, which may be because -the BIOS has been configured for a "Plug and Play" operating system. -The "Plug and Play OS" setting in the BIOS should be set to "no" or -"off" in order for PCI devices to work properly with -.Fx . -.It "sf%d: couldn't map interrupt" -A fatal initialization error has occurred. -.It "sf%d: no memory for softc struct!" -The driver failed to allocate memory for per-device instance information -during initialization. -.It "sf%d: failed to enable I/O ports/memory mapping!" -The driver failed to initialize PCI I/O port or shared memory access. -This might happen if the card is not in a bus-master slot. -.It "sf%d: watchdog timeout" -The device has stopped responding to the network, or there is a problem with -the network connection (cable). -.El -.Sh SEE ALSO -.Xr altq 4 , -.Xr arp 4 , -.Xr miibus 4 , -.Xr netintro 4 , -.Xr ng_ether 4 , -.Xr polling 4 , -.Xr vlan 4 , -.Xr ifconfig 8 -.Rs -.%T The Adaptec AIC-6915 Programmer's Manual -.%U http://download.adaptec.com/pdfs/user_guides/aic6915_pg.pdf -.Re -.Sh HISTORY -The -.Nm -device driver first appeared in -.Fx 3.0 . -.Sh AUTHORS -The -.Nm -driver was written by -.An Bill Paul Aq Mt wpaul@ctr.columbia.edu . diff --git a/sys/amd64/conf/GENERIC b/sys/amd64/conf/GENERIC index 42f67f5aa90f..cf25c4764dc5 100644 --- a/sys/amd64/conf/GENERIC +++ b/sys/amd64/conf/GENERIC @@ -273,7 +273,6 @@ device nfe # nVidia nForce MCP on-board Ethernet device nge # NatSemi DP83820 gigabit Ethernet device re # RealTek 8139C+/8169/8169S/8110S device rl # RealTek 8129/8139 -device sf # Adaptec AIC-6915 (``Starfire'') device sge # Silicon Integrated Systems SiS190/191 device sis # Silicon Integrated Systems SiS 900/SiS 7016 device sk # SysKonnect SK-984x & SK-982x gigabit Ethernet diff --git a/sys/conf/NOTES b/sys/conf/NOTES index 2bf8bea40938..9b5c28c0a9f8 100644 --- a/sys/conf/NOTES +++ b/sys/conf/NOTES @@ -1977,11 +1977,6 @@ device xmphy # XaQti XMAC II # chipset and is supported by this driver, not the 'vr' driver. # rtwn: RealTek wireless adapters. # rtwnfw: RealTek wireless firmware. -# sf: Support for Adaptec Duralink PCI fast ethernet adapters based on the -# Adaptec AIC-6915 "starfire" controller. -# This includes dual and quad port cards, as well as one 100baseFX card. -# Most of these are 64-bit PCI devices, except for one single port -# card which is 32-bit. # sge: Silicon Integrated Systems SiS190/191 Fast/Gigabit Ethernet adapter # sis: Support for NICs based on the Silicon Integrated Systems SiS 900, # SiS 7016 and NS DP83815 PCI fast ethernet controller chips. @@ -2066,7 +2061,6 @@ device my # Myson Fast Ethernet (MTD80X, MTD89X) device nge # NatSemi DP83820 gigabit Ethernet device re # RealTek 8139C+/8169/8169S/8110S device rl # RealTek 8129/8139 -device sf # Adaptec AIC-6915 (``Starfire'') device sge # Silicon Integrated Systems SiS190/191 device sis # Silicon Integrated Systems SiS 900/SiS 7016 device sk # SysKonnect SK-984x & SK-982x gigabit Ethernet diff --git a/sys/conf/files b/sys/conf/files index 5a573611a988..f9aac8214689 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -3009,7 +3009,6 @@ dev/sdhci/sdhci_fdt_gpio.c optional sdhci fdt gpio dev/sdhci/sdhci_if.m optional sdhci dev/sdhci/sdhci_acpi.c optional sdhci acpi dev/sdhci/sdhci_pci.c optional sdhci pci -dev/sf/if_sf.c optional sf pci dev/sge/if_sge.c optional sge pci dev/siis/siis.c optional siis pci dev/sis/if_sis.c optional sis pci diff --git a/sys/dev/sf/if_sf.c b/sys/dev/sf/if_sf.c deleted file mode 100644 index 59ec14aa290f..000000000000 --- a/sys/dev/sf/if_sf.c +++ /dev/null @@ -1,2740 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-4-Clause - * - * 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. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -/* - * Adaptec AIC-6915 "Starfire" PCI fast ethernet driver for FreeBSD. - * Programming manual is available from: - * http://download.adaptec.com/pdfs/user_guides/aic6915_pg.pdf. - * - * Written by Bill Paul <wpaul@ctr.columbia.edu> - * Department of Electical Engineering - * Columbia University, New York City - */ -/* - * The Adaptec AIC-6915 "Starfire" is a 64-bit 10/100 PCI ethernet - * controller designed with flexibility and reducing CPU load in mind. - * The Starfire offers high and low priority buffer queues, a - * producer/consumer index mechanism and several different buffer - * queue and completion queue descriptor types. Any one of a number - * of different driver designs can be used, depending on system and - * OS requirements. This driver makes use of type2 transmit frame - * descriptors to take full advantage of fragmented packets buffers - * and two RX buffer queues prioritized on size (one queue for small - * frames that will fit into a single mbuf, another with full size - * mbuf clusters for everything else). The producer/consumer indexes - * and completion queues are also used. - * - * One downside to the Starfire has to do with alignment: buffer - * queues must be aligned on 256-byte boundaries, and receive buffers - * must be aligned on longword boundaries. The receive buffer alignment - * causes problems on the strict alignment architecture, where the - * packet payload should be longword aligned. There is no simple way - * around this. - * - * For receive filtering, the Starfire offers 16 perfect filter slots - * and a 512-bit hash table. - * - * The Starfire has no internal transceiver, relying instead on an - * external MII-based transceiver. Accessing registers on external - * PHYs is done through a special register map rather than with the - * usual bitbang MDIO method. - * - * Acesssing the registers on the Starfire is a little tricky. The - * Starfire has a 512K internal register space. When programmed for - * PCI memory mapped mode, the entire register space can be accessed - * directly. However in I/O space mode, only 256 bytes are directly - * mapped into PCI I/O space. The other registers can be accessed - * indirectly using the SF_INDIRECTIO_ADDR and SF_INDIRECTIO_DATA - * registers inside the 256-byte I/O window. - */ - -#ifdef HAVE_KERNEL_OPTION_HEADERS -#include "opt_device_polling.h" -#endif - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/bus.h> -#include <sys/endian.h> -#include <sys/kernel.h> -#include <sys/malloc.h> -#include <sys/mbuf.h> -#include <sys/rman.h> -#include <sys/module.h> -#include <sys/socket.h> -#include <sys/sockio.h> -#include <sys/sysctl.h> - -#include <net/bpf.h> -#include <net/if.h> -#include <net/if_var.h> -#include <net/if_arp.h> -#include <net/ethernet.h> -#include <net/if_dl.h> -#include <net/if_media.h> -#include <net/if_types.h> -#include <net/if_vlan_var.h> - -#include <dev/mii/mii.h> -#include <dev/mii/miivar.h> - -#include <dev/pci/pcireg.h> -#include <dev/pci/pcivar.h> - -#include <machine/bus.h> - -#include <dev/sf/if_sfreg.h> -#include <dev/sf/starfire_rx.h> -#include <dev/sf/starfire_tx.h> - -/* "device miibus" required. See GENERIC if you get errors here. */ -#include "miibus_if.h" - -MODULE_DEPEND(sf, pci, 1, 1, 1); -MODULE_DEPEND(sf, ether, 1, 1, 1); -MODULE_DEPEND(sf, miibus, 1, 1, 1); - -#undef SF_GFP_DEBUG -#define SF_CSUM_FEATURES (CSUM_TCP | CSUM_UDP) -/* Define this to activate partial TCP/UDP checksum offload. */ -#undef SF_PARTIAL_CSUM_SUPPORT - -static struct sf_type sf_devs[] = { - { AD_VENDORID, AD_DEVICEID_STARFIRE, "Adaptec AIC-6915 10/100BaseTX", - AD_SUBSYSID_62011_REV0, "Adaptec ANA-62011 (rev 0) 10/100BaseTX" }, - { AD_VENDORID, AD_DEVICEID_STARFIRE, "Adaptec AIC-6915 10/100BaseTX", - AD_SUBSYSID_62011_REV1, "Adaptec ANA-62011 (rev 1) 10/100BaseTX" }, - { AD_VENDORID, AD_DEVICEID_STARFIRE, "Adaptec AIC-6915 10/100BaseTX", - AD_SUBSYSID_62022, "Adaptec ANA-62022 10/100BaseTX" }, - { AD_VENDORID, AD_DEVICEID_STARFIRE, "Adaptec AIC-6915 10/100BaseTX", - AD_SUBSYSID_62044_REV0, "Adaptec ANA-62044 (rev 0) 10/100BaseTX" }, - { AD_VENDORID, AD_DEVICEID_STARFIRE, "Adaptec AIC-6915 10/100BaseTX", - AD_SUBSYSID_62044_REV1, "Adaptec ANA-62044 (rev 1) 10/100BaseTX" }, - { AD_VENDORID, AD_DEVICEID_STARFIRE, "Adaptec AIC-6915 10/100BaseTX", - AD_SUBSYSID_62020, "Adaptec ANA-62020 10/100BaseFX" }, - { AD_VENDORID, AD_DEVICEID_STARFIRE, "Adaptec AIC-6915 10/100BaseTX", - AD_SUBSYSID_69011, "Adaptec ANA-69011 10/100BaseTX" }, -}; - -static int sf_probe(device_t); -static int sf_attach(device_t); -static int sf_detach(device_t); -static int sf_shutdown(device_t); -static int sf_suspend(device_t); -static int sf_resume(device_t); -static void sf_intr(void *); -static void sf_tick(void *); -static void sf_stats_update(struct sf_softc *); -#ifndef __NO_STRICT_ALIGNMENT -static __inline void sf_fixup_rx(struct mbuf *); -#endif -static int sf_rxeof(struct sf_softc *); -static void sf_txeof(struct sf_softc *); -static int sf_encap(struct sf_softc *, struct mbuf **); -static void sf_start(struct ifnet *); -static void sf_start_locked(struct ifnet *); -static int sf_ioctl(struct ifnet *, u_long, caddr_t); -static void sf_download_fw(struct sf_softc *); -static void sf_init(void *); -static void sf_init_locked(struct sf_softc *); -static void sf_stop(struct sf_softc *); -static void sf_watchdog(struct sf_softc *); -static int sf_ifmedia_upd(struct ifnet *); -static int sf_ifmedia_upd_locked(struct ifnet *); -static void sf_ifmedia_sts(struct ifnet *, struct ifmediareq *); -static void sf_reset(struct sf_softc *); -static int sf_dma_alloc(struct sf_softc *); -static void sf_dma_free(struct sf_softc *); -static int sf_init_rx_ring(struct sf_softc *); -static void sf_init_tx_ring(struct sf_softc *); -static int sf_newbuf(struct sf_softc *, int); -static void sf_rxfilter(struct sf_softc *); -static int sf_setperf(struct sf_softc *, int, uint8_t *); -static int sf_sethash(struct sf_softc *, caddr_t, int); -#ifdef notdef -static int sf_setvlan(struct sf_softc *, int, uint32_t); -#endif - -static uint8_t sf_read_eeprom(struct sf_softc *, int); - -static int sf_miibus_readreg(device_t, int, int); -static int sf_miibus_writereg(device_t, int, int, int); -static void sf_miibus_statchg(device_t); -#ifdef DEVICE_POLLING -static int sf_poll(struct ifnet *ifp, enum poll_cmd cmd, int count); -#endif - -static uint32_t csr_read_4(struct sf_softc *, int); -static void csr_write_4(struct sf_softc *, int, uint32_t); -static void sf_txthresh_adjust(struct sf_softc *); -static int sf_sysctl_stats(SYSCTL_HANDLER_ARGS); -static int sysctl_int_range(SYSCTL_HANDLER_ARGS, int, int); -static int sysctl_hw_sf_int_mod(SYSCTL_HANDLER_ARGS); - -static device_method_t sf_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, sf_probe), - DEVMETHOD(device_attach, sf_attach), - DEVMETHOD(device_detach, sf_detach), - DEVMETHOD(device_shutdown, sf_shutdown), - DEVMETHOD(device_suspend, sf_suspend), - DEVMETHOD(device_resume, sf_resume), - - /* MII interface */ - DEVMETHOD(miibus_readreg, sf_miibus_readreg), - DEVMETHOD(miibus_writereg, sf_miibus_writereg), - DEVMETHOD(miibus_statchg, sf_miibus_statchg), - - DEVMETHOD_END -}; - -static driver_t sf_driver = { - "sf", - sf_methods, - sizeof(struct sf_softc), -}; - -static devclass_t sf_devclass; - -DRIVER_MODULE(sf, pci, sf_driver, sf_devclass, 0, 0); -DRIVER_MODULE(miibus, sf, miibus_driver, miibus_devclass, 0, 0); - -#define SF_SETBIT(sc, reg, x) \ - csr_write_4(sc, reg, csr_read_4(sc, reg) | (x)) - -#define SF_CLRBIT(sc, reg, x) \ - csr_write_4(sc, reg, csr_read_4(sc, reg) & ~(x)) - -static uint32_t -csr_read_4(struct sf_softc *sc, int reg) -{ - uint32_t val; - - if (sc->sf_restype == SYS_RES_MEMORY) - val = CSR_READ_4(sc, (reg + SF_RMAP_INTREG_BASE)); - else { - CSR_WRITE_4(sc, SF_INDIRECTIO_ADDR, reg + SF_RMAP_INTREG_BASE); - val = CSR_READ_4(sc, SF_INDIRECTIO_DATA); - } - - return (val); -} - -static uint8_t -sf_read_eeprom(struct sf_softc *sc, int reg) -{ - uint8_t val; - - val = (csr_read_4(sc, SF_EEADDR_BASE + - (reg & 0xFFFFFFFC)) >> (8 * (reg & 3))) & 0xFF; - - return (val); -} - -static void -csr_write_4(struct sf_softc *sc, int reg, uint32_t val) -{ - - if (sc->sf_restype == SYS_RES_MEMORY) - CSR_WRITE_4(sc, (reg + SF_RMAP_INTREG_BASE), val); - else { - CSR_WRITE_4(sc, SF_INDIRECTIO_ADDR, reg + SF_RMAP_INTREG_BASE); - CSR_WRITE_4(sc, SF_INDIRECTIO_DATA, val); - } -} - -/* - * Copy the address 'mac' into the perfect RX filter entry at - * offset 'idx.' The perfect filter only has 16 entries so do - * some sanity tests. - */ -static int -sf_setperf(struct sf_softc *sc, int idx, uint8_t *mac) -{ - - if (idx < 0 || idx > SF_RXFILT_PERFECT_CNT) - return (EINVAL); - - if (mac == NULL) - return (EINVAL); - - csr_write_4(sc, SF_RXFILT_PERFECT_BASE + - (idx * SF_RXFILT_PERFECT_SKIP) + 0, mac[5] | (mac[4] << 8)); - csr_write_4(sc, SF_RXFILT_PERFECT_BASE + - (idx * SF_RXFILT_PERFECT_SKIP) + 4, mac[3] | (mac[2] << 8)); - csr_write_4(sc, SF_RXFILT_PERFECT_BASE + - (idx * SF_RXFILT_PERFECT_SKIP) + 8, mac[1] | (mac[0] << 8)); - - return (0); -} - -/* - * Set the bit in the 512-bit hash table that corresponds to the - * specified mac address 'mac.' If 'prio' is nonzero, update the - * priority hash table instead of the filter hash table. - */ -static int -sf_sethash(struct sf_softc *sc, caddr_t mac, int prio) -{ - uint32_t h; - - if (mac == NULL) - return (EINVAL); - - h = ether_crc32_be(mac, ETHER_ADDR_LEN) >> 23; - - if (prio) { - SF_SETBIT(sc, SF_RXFILT_HASH_BASE + SF_RXFILT_HASH_PRIOOFF + - (SF_RXFILT_HASH_SKIP * (h >> 4)), (1 << (h & 0xF))); - } else { - SF_SETBIT(sc, SF_RXFILT_HASH_BASE + SF_RXFILT_HASH_ADDROFF + - (SF_RXFILT_HASH_SKIP * (h >> 4)), (1 << (h & 0xF))); - } - - return (0); -} - -#ifdef notdef -/* - * Set a VLAN tag in the receive filter. - */ -static int -sf_setvlan(struct sf_softc *sc, int idx, uint32_t vlan) -{ - - if (idx < 0 || idx >> SF_RXFILT_HASH_CNT) - return (EINVAL); - - csr_write_4(sc, SF_RXFILT_HASH_BASE + - (idx * SF_RXFILT_HASH_SKIP) + SF_RXFILT_HASH_VLANOFF, vlan); - - return (0); -} -#endif - -static int -sf_miibus_readreg(device_t dev, int phy, int reg) -{ - struct sf_softc *sc; - int i; - uint32_t val = 0; - - sc = device_get_softc(dev); - - for (i = 0; i < SF_TIMEOUT; i++) { - val = csr_read_4(sc, SF_PHY_REG(phy, reg)); - if ((val & SF_MII_DATAVALID) != 0) - break; - } - - if (i == SF_TIMEOUT) - return (0); - - val &= SF_MII_DATAPORT; - if (val == 0xffff) - return (0); - - return (val); -} - -static int -sf_miibus_writereg(device_t dev, int phy, int reg, int val) -{ - struct sf_softc *sc; - int i; - int busy; - - sc = device_get_softc(dev); - - csr_write_4(sc, SF_PHY_REG(phy, reg), val); - - for (i = 0; i < SF_TIMEOUT; i++) { - busy = csr_read_4(sc, SF_PHY_REG(phy, reg)); - if ((busy & SF_MII_BUSY) == 0) - break; - } - - return (0); -} - -static void -sf_miibus_statchg(device_t dev) -{ - struct sf_softc *sc; - struct mii_data *mii; - struct ifnet *ifp; - uint32_t val; - - sc = device_get_softc(dev); - mii = device_get_softc(sc->sf_miibus); - ifp = sc->sf_ifp; - if (mii == NULL || ifp == NULL || - (ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) - return; - - sc->sf_link = 0; - if ((mii->mii_media_status & (IFM_ACTIVE | IFM_AVALID)) == - (IFM_ACTIVE | IFM_AVALID)) { - switch (IFM_SUBTYPE(mii->mii_media_active)) { - case IFM_10_T: - case IFM_100_TX: - case IFM_100_FX: - sc->sf_link = 1; - break; - } - } - if (sc->sf_link == 0) - return; - - val = csr_read_4(sc, SF_MACCFG_1); - val &= ~SF_MACCFG1_FULLDUPLEX; - val &= ~(SF_MACCFG1_RX_FLOWENB | SF_MACCFG1_TX_FLOWENB); - if ((IFM_OPTIONS(mii->mii_media_active) & IFM_FDX) != 0) { - val |= SF_MACCFG1_FULLDUPLEX; - csr_write_4(sc, SF_BKTOBKIPG, SF_IPGT_FDX); -#ifdef notyet - /* Configure flow-control bits. */ - if ((IFM_OPTIONS(sc->sc_mii->mii_media_active) & - IFM_ETH_RXPAUSE) != 0) - val |= SF_MACCFG1_RX_FLOWENB; - if ((IFM_OPTIONS(sc->sc_mii->mii_media_active) & - IFM_ETH_TXPAUSE) != 0) - val |= SF_MACCFG1_TX_FLOWENB; -#endif - } else - csr_write_4(sc, SF_BKTOBKIPG, SF_IPGT_HDX); - - /* Make sure to reset MAC to take changes effect. */ - csr_write_4(sc, SF_MACCFG_1, val | SF_MACCFG1_SOFTRESET); - DELAY(1000); - csr_write_4(sc, SF_MACCFG_1, val); - - val = csr_read_4(sc, SF_TIMER_CTL); - if (IFM_SUBTYPE(mii->mii_media_active) == IFM_100_TX) - val |= SF_TIMER_TIMES_TEN; - else - val &= ~SF_TIMER_TIMES_TEN; - csr_write_4(sc, SF_TIMER_CTL, val); -} - -static void -sf_rxfilter(struct sf_softc *sc) -{ - struct ifnet *ifp; - int i; - struct ifmultiaddr *ifma; - uint8_t dummy[ETHER_ADDR_LEN] = { 0, 0, 0, 0, 0, 0 }; - uint32_t rxfilt; - - ifp = sc->sf_ifp; - - /* First zot all the existing filters. */ - for (i = 1; i < SF_RXFILT_PERFECT_CNT; i++) - sf_setperf(sc, i, dummy); - for (i = SF_RXFILT_HASH_BASE; i < (SF_RXFILT_HASH_MAX + 1); - i += sizeof(uint32_t)) - csr_write_4(sc, i, 0); - - rxfilt = csr_read_4(sc, SF_RXFILT); - rxfilt &= ~(SF_RXFILT_PROMISC | SF_RXFILT_ALLMULTI | SF_RXFILT_BROAD); - if ((ifp->if_flags & IFF_BROADCAST) != 0) - rxfilt |= SF_RXFILT_BROAD; - if ((ifp->if_flags & IFF_ALLMULTI) != 0 || - (ifp->if_flags & IFF_PROMISC) != 0) { - if ((ifp->if_flags & IFF_PROMISC) != 0) - rxfilt |= SF_RXFILT_PROMISC; - if ((ifp->if_flags & IFF_ALLMULTI) != 0) - rxfilt |= SF_RXFILT_ALLMULTI; - goto done; - } - - /* Now program new ones. */ - i = 1; - /* XXX how do we maintain reverse semantics without impl */ - if_maddr_rlock(ifp); - CK_STAILQ_FOREACH(ifma, &ifp->if_multiaddrs, - ifma_link) { - if (ifma->ifma_addr->sa_family != AF_LINK) - continue; - /* - * Program the first 15 multicast groups - * into the perfect filter. For all others, - * use the hash table. - */ - if (i < SF_RXFILT_PERFECT_CNT) { - sf_setperf(sc, i, - LLADDR((struct sockaddr_dl *)ifma->ifma_addr)); - i++; - continue; - } - - sf_sethash(sc, - LLADDR((struct sockaddr_dl *)ifma->ifma_addr), 0); - } - if_maddr_runlock(ifp); - -done: - csr_write_4(sc, SF_RXFILT, rxfilt); -} - -/* - * Set media options. - */ -static int -sf_ifmedia_upd(struct ifnet *ifp) -{ - struct sf_softc *sc; - int error; - - sc = ifp->if_softc; - SF_LOCK(sc); - error = sf_ifmedia_upd_locked(ifp); - SF_UNLOCK(sc); - return (error); -} - -static int -sf_ifmedia_upd_locked(struct ifnet *ifp) -{ - struct sf_softc *sc; - struct mii_data *mii; - struct mii_softc *miisc; - - sc = ifp->if_softc; - mii = device_get_softc(sc->sf_miibus); - LIST_FOREACH(miisc, &mii->mii_phys, mii_list) - PHY_RESET(miisc); - return (mii_mediachg(mii)); -} - -/* - * Report current media status. - */ -static void -sf_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr) -{ - struct sf_softc *sc; - struct mii_data *mii; - - sc = ifp->if_softc; - SF_LOCK(sc); - if ((ifp->if_flags & IFF_UP) == 0) { - SF_UNLOCK(sc); - return; - } - - mii = device_get_softc(sc->sf_miibus); - mii_pollstat(mii); - ifmr->ifm_active = mii->mii_media_active; - ifmr->ifm_status = mii->mii_media_status; - SF_UNLOCK(sc); -} - -static int -sf_ioctl(struct ifnet *ifp, u_long command, caddr_t data) -{ - struct sf_softc *sc; - struct ifreq *ifr; - struct mii_data *mii; - int error, mask; - - sc = ifp->if_softc; - ifr = (struct ifreq *)data; - error = 0; - - switch (command) { - case SIOCSIFFLAGS: - SF_LOCK(sc); - if (ifp->if_flags & IFF_UP) { - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) { - if ((ifp->if_flags ^ sc->sf_if_flags) & - (IFF_PROMISC | IFF_ALLMULTI)) - sf_rxfilter(sc); - } else { - if (sc->sf_detach == 0) - sf_init_locked(sc); - } - } else { - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) - sf_stop(sc); - } - sc->sf_if_flags = ifp->if_flags; - SF_UNLOCK(sc); - break; - case SIOCADDMULTI: - case SIOCDELMULTI: - SF_LOCK(sc); - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) - sf_rxfilter(sc); - SF_UNLOCK(sc); - break; - case SIOCGIFMEDIA: - case SIOCSIFMEDIA: - mii = device_get_softc(sc->sf_miibus); - error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, command); - break; - case SIOCSIFCAP: - mask = ifr->ifr_reqcap ^ ifp->if_capenable; -#ifdef DEVICE_POLLING - if ((mask & IFCAP_POLLING) != 0) { - if ((ifr->ifr_reqcap & IFCAP_POLLING) != 0) { - error = ether_poll_register(sf_poll, ifp); - if (error != 0) - break; - SF_LOCK(sc); - /* Disable interrupts. */ - csr_write_4(sc, SF_IMR, 0); - ifp->if_capenable |= IFCAP_POLLING; - SF_UNLOCK(sc); - } else { - error = ether_poll_deregister(ifp); - /* Enable interrupts. */ - SF_LOCK(sc); - csr_write_4(sc, SF_IMR, SF_INTRS); - ifp->if_capenable &= ~IFCAP_POLLING; - SF_UNLOCK(sc); - } - } -#endif /* DEVICE_POLLING */ - if ((mask & IFCAP_TXCSUM) != 0) { - if ((IFCAP_TXCSUM & ifp->if_capabilities) != 0) { - SF_LOCK(sc); - ifp->if_capenable ^= IFCAP_TXCSUM; - if ((IFCAP_TXCSUM & ifp->if_capenable) != 0) { - ifp->if_hwassist |= SF_CSUM_FEATURES; - SF_SETBIT(sc, SF_GEN_ETH_CTL, - SF_ETHCTL_TXGFP_ENB); - } else { - ifp->if_hwassist &= ~SF_CSUM_FEATURES; - SF_CLRBIT(sc, SF_GEN_ETH_CTL, - SF_ETHCTL_TXGFP_ENB); - } - SF_UNLOCK(sc); - } - } - if ((mask & IFCAP_RXCSUM) != 0) { - if ((IFCAP_RXCSUM & ifp->if_capabilities) != 0) { - SF_LOCK(sc); - ifp->if_capenable ^= IFCAP_RXCSUM; - if ((IFCAP_RXCSUM & ifp->if_capenable) != 0) - SF_SETBIT(sc, SF_GEN_ETH_CTL, - SF_ETHCTL_RXGFP_ENB); - else - SF_CLRBIT(sc, SF_GEN_ETH_CTL, - SF_ETHCTL_RXGFP_ENB); - SF_UNLOCK(sc); - } - } - break; - default: - error = ether_ioctl(ifp, command, data); - break; - } - - return (error); -} - -static void -sf_reset(struct sf_softc *sc) -{ - int i; - - csr_write_4(sc, SF_GEN_ETH_CTL, 0); - SF_SETBIT(sc, SF_MACCFG_1, SF_MACCFG1_SOFTRESET); - DELAY(1000); - SF_CLRBIT(sc, SF_MACCFG_1, SF_MACCFG1_SOFTRESET); - - SF_SETBIT(sc, SF_PCI_DEVCFG, SF_PCIDEVCFG_RESET); - - for (i = 0; i < SF_TIMEOUT; i++) { - DELAY(10); - if (!(csr_read_4(sc, SF_PCI_DEVCFG) & SF_PCIDEVCFG_RESET)) - break; - } - - if (i == SF_TIMEOUT) - device_printf(sc->sf_dev, "reset never completed!\n"); - - /* Wait a little while for the chip to get its brains in order. */ - DELAY(1000); -} - -/* - * Probe for an Adaptec AIC-6915 chip. Check the PCI vendor and device - * IDs against our list and return a device name if we find a match. - * We also check the subsystem ID so that we can identify exactly which - * NIC has been found, if possible. - */ -static int -sf_probe(device_t dev) -{ - struct sf_type *t; - uint16_t vid; - uint16_t did; - uint16_t sdid; - int i; - - vid = pci_get_vendor(dev); - did = pci_get_device(dev); - sdid = pci_get_subdevice(dev); - - t = sf_devs; - for (i = 0; i < nitems(sf_devs); i++, t++) { - if (vid == t->sf_vid && did == t->sf_did) { - if (sdid == t->sf_sdid) { - device_set_desc(dev, t->sf_sname); - return (BUS_PROBE_DEFAULT); - } - } - } - - if (vid == AD_VENDORID && did == AD_DEVICEID_STARFIRE) { - /* unknown subdevice */ - device_set_desc(dev, sf_devs[0].sf_name); - return (BUS_PROBE_DEFAULT); - } - - return (ENXIO); -} - -/* - * Attach the interface. Allocate softc structures, do ifmedia - * setup and ethernet/BPF attach. - */ -static int -sf_attach(device_t dev) -{ - int i; - struct sf_softc *sc; - struct ifnet *ifp; - uint32_t reg; - int rid, error = 0; - uint8_t eaddr[ETHER_ADDR_LEN]; - - sc = device_get_softc(dev); - sc->sf_dev = dev; - - mtx_init(&sc->sf_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK, - MTX_DEF); - callout_init_mtx(&sc->sf_co, &sc->sf_mtx, 0); - - /* - * Map control/status registers. - */ - pci_enable_busmaster(dev); - - /* - * Prefer memory space register mapping over I/O space as the - * hardware requires lots of register access to get various - * producer/consumer index during Tx/Rx operation. However this - * requires large memory space(512K) to map the entire register - * space. - */ - sc->sf_rid = PCIR_BAR(0); - sc->sf_restype = SYS_RES_MEMORY; - sc->sf_res = bus_alloc_resource_any(dev, sc->sf_restype, &sc->sf_rid, - RF_ACTIVE); - if (sc->sf_res == NULL) { - reg = pci_read_config(dev, PCIR_BAR(0), 4); - if ((reg & PCIM_BAR_MEM_64) == PCIM_BAR_MEM_64) - sc->sf_rid = PCIR_BAR(2); - else - sc->sf_rid = PCIR_BAR(1); - sc->sf_restype = SYS_RES_IOPORT; - sc->sf_res = bus_alloc_resource_any(dev, sc->sf_restype, - &sc->sf_rid, RF_ACTIVE); - if (sc->sf_res == NULL) { - device_printf(dev, "couldn't allocate resources\n"); - mtx_destroy(&sc->sf_mtx); - return (ENXIO); - } - } - if (bootverbose) - device_printf(dev, "using %s space register mapping\n", - sc->sf_restype == SYS_RES_MEMORY ? "memory" : "I/O"); - - reg = pci_read_config(dev, PCIR_CACHELNSZ, 1); - if (reg == 0) { - /* - * If cache line size is 0, MWI is not used at all, so set - * reasonable default. AIC-6915 supports 0, 4, 8, 16, 32 - * and 64. - */ - reg = 16; - device_printf(dev, "setting PCI cache line size to %u\n", reg); - pci_write_config(dev, PCIR_CACHELNSZ, reg, 1); - } else { - if (bootverbose) - device_printf(dev, "PCI cache line size : %u\n", reg); - } - /* Enable MWI. */ - reg = pci_read_config(dev, PCIR_COMMAND, 2); - reg |= PCIM_CMD_MWRICEN; - pci_write_config(dev, PCIR_COMMAND, reg, 2); - - /* Allocate interrupt. */ - rid = 0; - sc->sf_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, - RF_SHAREABLE | RF_ACTIVE); - - if (sc->sf_irq == NULL) { - device_printf(dev, "couldn't map interrupt\n"); - error = ENXIO; - goto fail; - } - - SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), - SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), - OID_AUTO, "stats", CTLTYPE_INT | CTLFLAG_RW, sc, 0, - sf_sysctl_stats, "I", "Statistics"); - - SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), - SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), - OID_AUTO, "int_mod", CTLTYPE_INT | CTLFLAG_RW, - &sc->sf_int_mod, 0, sysctl_hw_sf_int_mod, "I", - "sf interrupt moderation"); - /* Pull in device tunables. */ - sc->sf_int_mod = SF_IM_DEFAULT; - error = resource_int_value(device_get_name(dev), device_get_unit(dev), - "int_mod", &sc->sf_int_mod); - if (error == 0) { - if (sc->sf_int_mod < SF_IM_MIN || - sc->sf_int_mod > SF_IM_MAX) { - device_printf(dev, "int_mod value out of range; " - "using default: %d\n", SF_IM_DEFAULT); - sc->sf_int_mod = SF_IM_DEFAULT; - } - } - - /* Reset the adapter. */ - sf_reset(sc); - - /* - * Get station address from the EEPROM. - */ - for (i = 0; i < ETHER_ADDR_LEN; i++) - eaddr[i] = - sf_read_eeprom(sc, SF_EE_NODEADDR + ETHER_ADDR_LEN - i); - - /* Allocate DMA resources. */ - if (sf_dma_alloc(sc) != 0) { - error = ENOSPC; - goto fail; - } - - sc->sf_txthresh = SF_MIN_TX_THRESHOLD; - - ifp = sc->sf_ifp = if_alloc(IFT_ETHER); - if (ifp == NULL) { - device_printf(dev, "can not allocate ifnet structure\n"); - error = ENOSPC; - goto fail; - } - - /* Do MII setup. */ - error = mii_attach(dev, &sc->sf_miibus, ifp, sf_ifmedia_upd, - sf_ifmedia_sts, BMSR_DEFCAPMASK, MII_PHY_ANY, MII_OFFSET_ANY, 0); - if (error != 0) { - device_printf(dev, "attaching PHYs failed\n"); - goto fail; - } - - ifp->if_softc = sc; - if_initname(ifp, device_get_name(dev), device_get_unit(dev)); - ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; - ifp->if_ioctl = sf_ioctl; - ifp->if_start = sf_start; - ifp->if_init = sf_init; - IFQ_SET_MAXLEN(&ifp->if_snd, SF_TX_DLIST_CNT - 1); - ifp->if_snd.ifq_drv_maxlen = SF_TX_DLIST_CNT - 1; - IFQ_SET_READY(&ifp->if_snd); - /* - * With the help of firmware, AIC-6915 supports - * Tx/Rx TCP/UDP checksum offload. - */ - ifp->if_hwassist = SF_CSUM_FEATURES; - ifp->if_capabilities = IFCAP_HWCSUM; - - /* - * Call MI attach routine. - */ - ether_ifattach(ifp, eaddr); - - /* VLAN capability setup. */ - ifp->if_capabilities |= IFCAP_VLAN_MTU; - ifp->if_capenable = ifp->if_capabilities; -#ifdef DEVICE_POLLING - ifp->if_capabilities |= IFCAP_POLLING; -#endif - /* - * Tell the upper layer(s) we support long frames. - * Must appear after the call to ether_ifattach() because - * ether_ifattach() sets ifi_hdrlen to the default value. - */ - ifp->if_hdrlen = sizeof(struct ether_vlan_header); - - /* Hook interrupt last to avoid having to lock softc */ - error = bus_setup_intr(dev, sc->sf_irq, INTR_TYPE_NET | INTR_MPSAFE, - NULL, sf_intr, sc, &sc->sf_intrhand); - - if (error) { - device_printf(dev, "couldn't set up irq\n"); - ether_ifdetach(ifp); - goto fail; - } - - gone_by_fcp101_dev(dev); - -fail: - if (error) - sf_detach(dev); - - return (error); -} - -/* - * Shutdown hardware and free up resources. This can be called any - * time after the mutex has been initialized. It is called in both - * the error case in attach and the normal detach case so it needs - * to be careful about only freeing resources that have actually been - * allocated. - */ -static int -sf_detach(device_t dev) -{ - struct sf_softc *sc; - struct ifnet *ifp; - - sc = device_get_softc(dev); - ifp = sc->sf_ifp; - -#ifdef DEVICE_POLLING - if (ifp != NULL && ifp->if_capenable & IFCAP_POLLING) - ether_poll_deregister(ifp); -#endif - - /* These should only be active if attach succeeded */ - if (device_is_attached(dev)) { - SF_LOCK(sc); - sc->sf_detach = 1; - sf_stop(sc); - SF_UNLOCK(sc); - callout_drain(&sc->sf_co); - if (ifp != NULL) - ether_ifdetach(ifp); - } - if (sc->sf_miibus) { - device_delete_child(dev, sc->sf_miibus); - sc->sf_miibus = NULL; - } - bus_generic_detach(dev); - - if (sc->sf_intrhand != NULL) - bus_teardown_intr(dev, sc->sf_irq, sc->sf_intrhand); - if (sc->sf_irq != NULL) - bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sf_irq); - if (sc->sf_res != NULL) - bus_release_resource(dev, sc->sf_restype, sc->sf_rid, - sc->sf_res); - - sf_dma_free(sc); - if (ifp != NULL) - if_free(ifp); - - mtx_destroy(&sc->sf_mtx); - - return (0); -} - -struct sf_dmamap_arg { - bus_addr_t sf_busaddr; -}; - -static void -sf_dmamap_cb(void *arg, bus_dma_segment_t *segs, int nseg, int error) -{ - struct sf_dmamap_arg *ctx; - - if (error != 0) - return; - ctx = arg; - ctx->sf_busaddr = segs[0].ds_addr; -} - -static int -sf_dma_alloc(struct sf_softc *sc) -{ - struct sf_dmamap_arg ctx; - struct sf_txdesc *txd; - struct sf_rxdesc *rxd; - bus_addr_t lowaddr; - bus_addr_t rx_ring_end, rx_cring_end; - bus_addr_t tx_ring_end, tx_cring_end; - int error, i; - - lowaddr = BUS_SPACE_MAXADDR; - -again: - /* Create parent DMA tag. */ - error = bus_dma_tag_create( - bus_get_dma_tag(sc->sf_dev), /* parent */ - 1, 0, /* alignment, boundary */ - lowaddr, /* lowaddr */ - BUS_SPACE_MAXADDR, /* highaddr */ - NULL, NULL, /* filter, filterarg */ - BUS_SPACE_MAXSIZE_32BIT, /* maxsize */ - 0, /* nsegments */ - BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */ - 0, /* flags */ - NULL, NULL, /* lockfunc, lockarg */ - &sc->sf_cdata.sf_parent_tag); - if (error != 0) { - device_printf(sc->sf_dev, "failed to create parent DMA tag\n"); - goto fail; - } - /* Create tag for Tx ring. */ - error = bus_dma_tag_create(sc->sf_cdata.sf_parent_tag,/* parent */ - SF_RING_ALIGN, 0, /* alignment, boundary */ - BUS_SPACE_MAXADDR, /* lowaddr */ - BUS_SPACE_MAXADDR, /* highaddr */ - NULL, NULL, /* filter, filterarg */ - SF_TX_DLIST_SIZE, /* maxsize */ - 1, /* nsegments */ - SF_TX_DLIST_SIZE, /* maxsegsize */ - 0, /* flags */ - NULL, NULL, /* lockfunc, lockarg */ - &sc->sf_cdata.sf_tx_ring_tag); - if (error != 0) { - device_printf(sc->sf_dev, "failed to create Tx ring DMA tag\n"); - goto fail; - } - - /* Create tag for Tx completion ring. */ - error = bus_dma_tag_create(sc->sf_cdata.sf_parent_tag,/* parent */ - SF_RING_ALIGN, 0, /* alignment, boundary */ - BUS_SPACE_MAXADDR, /* lowaddr */ - BUS_SPACE_MAXADDR, /* highaddr */ - NULL, NULL, /* filter, filterarg */ - SF_TX_CLIST_SIZE, /* maxsize */ - 1, /* nsegments */ - SF_TX_CLIST_SIZE, /* maxsegsize */ - 0, /* flags */ - NULL, NULL, /* lockfunc, lockarg */ - &sc->sf_cdata.sf_tx_cring_tag); - if (error != 0) { - device_printf(sc->sf_dev, - "failed to create Tx completion ring DMA tag\n"); - goto fail; - } - - /* Create tag for Rx ring. */ - error = bus_dma_tag_create(sc->sf_cdata.sf_parent_tag,/* parent */ - SF_RING_ALIGN, 0, /* alignment, boundary */ - BUS_SPACE_MAXADDR, /* lowaddr */ - BUS_SPACE_MAXADDR, /* highaddr */ - NULL, NULL, /* filter, filterarg */ - SF_RX_DLIST_SIZE, /* maxsize */ - 1, /* nsegments */ - SF_RX_DLIST_SIZE, /* maxsegsize */ - 0, /* flags */ - NULL, NULL, /* lockfunc, lockarg */ - &sc->sf_cdata.sf_rx_ring_tag); - if (error != 0) { - device_printf(sc->sf_dev, - "failed to create Rx ring DMA tag\n"); - goto fail; - } - - /* Create tag for Rx completion ring. */ - error = bus_dma_tag_create(sc->sf_cdata.sf_parent_tag,/* parent */ - SF_RING_ALIGN, 0, /* alignment, boundary */ - BUS_SPACE_MAXADDR, /* lowaddr */ - BUS_SPACE_MAXADDR, /* highaddr */ - NULL, NULL, /* filter, filterarg */ - SF_RX_CLIST_SIZE, /* maxsize */ - 1, /* nsegments */ - SF_RX_CLIST_SIZE, /* maxsegsize */ - 0, /* flags */ - NULL, NULL, /* lockfunc, lockarg */ - &sc->sf_cdata.sf_rx_cring_tag); - if (error != 0) { - device_printf(sc->sf_dev, - "failed to create Rx completion ring DMA tag\n"); - goto fail; - } - - /* Create tag for Tx buffers. */ - error = bus_dma_tag_create(sc->sf_cdata.sf_parent_tag,/* parent */ - 1, 0, /* alignment, boundary */ - BUS_SPACE_MAXADDR, /* lowaddr */ - BUS_SPACE_MAXADDR, /* highaddr */ - NULL, NULL, /* filter, filterarg */ - MCLBYTES * SF_MAXTXSEGS, /* maxsize */ - SF_MAXTXSEGS, /* nsegments */ - MCLBYTES, /* maxsegsize */ - 0, /* flags */ - NULL, NULL, /* lockfunc, lockarg */ - &sc->sf_cdata.sf_tx_tag); - if (error != 0) { - device_printf(sc->sf_dev, "failed to create Tx DMA tag\n"); - goto fail; - } - - /* Create tag for Rx buffers. */ - error = bus_dma_tag_create(sc->sf_cdata.sf_parent_tag,/* parent */ - SF_RX_ALIGN, 0, /* alignment, boundary */ - BUS_SPACE_MAXADDR, /* lowaddr */ - BUS_SPACE_MAXADDR, /* highaddr */ - NULL, NULL, /* filter, filterarg */ - MCLBYTES, /* maxsize */ - 1, /* nsegments */ - MCLBYTES, /* maxsegsize */ - 0, /* flags */ - NULL, NULL, /* lockfunc, lockarg */ - &sc->sf_cdata.sf_rx_tag); - if (error != 0) { - device_printf(sc->sf_dev, "failed to create Rx DMA tag\n"); - goto fail; - } - - /* Allocate DMA'able memory and load the DMA map for Tx ring. */ - error = bus_dmamem_alloc(sc->sf_cdata.sf_tx_ring_tag, - (void **)&sc->sf_rdata.sf_tx_ring, BUS_DMA_WAITOK | - BUS_DMA_COHERENT | BUS_DMA_ZERO, &sc->sf_cdata.sf_tx_ring_map); - if (error != 0) { - device_printf(sc->sf_dev, - "failed to allocate DMA'able memory for Tx ring\n"); - goto fail; - } - - ctx.sf_busaddr = 0; - error = bus_dmamap_load(sc->sf_cdata.sf_tx_ring_tag, - sc->sf_cdata.sf_tx_ring_map, sc->sf_rdata.sf_tx_ring, - SF_TX_DLIST_SIZE, sf_dmamap_cb, &ctx, 0); - if (error != 0 || ctx.sf_busaddr == 0) { - device_printf(sc->sf_dev, - "failed to load DMA'able memory for Tx ring\n"); - goto fail; - } - sc->sf_rdata.sf_tx_ring_paddr = ctx.sf_busaddr; - - /* - * Allocate DMA'able memory and load the DMA map for Tx completion ring. - */ - error = bus_dmamem_alloc(sc->sf_cdata.sf_tx_cring_tag, - (void **)&sc->sf_rdata.sf_tx_cring, BUS_DMA_WAITOK | - BUS_DMA_COHERENT | BUS_DMA_ZERO, &sc->sf_cdata.sf_tx_cring_map); - if (error != 0) { - device_printf(sc->sf_dev, - "failed to allocate DMA'able memory for " - "Tx completion ring\n"); - goto fail; - } - - ctx.sf_busaddr = 0; - error = bus_dmamap_load(sc->sf_cdata.sf_tx_cring_tag, - sc->sf_cdata.sf_tx_cring_map, sc->sf_rdata.sf_tx_cring, - SF_TX_CLIST_SIZE, sf_dmamap_cb, &ctx, 0); - if (error != 0 || ctx.sf_busaddr == 0) { - device_printf(sc->sf_dev, - "failed to load DMA'able memory for Tx completion ring\n"); - goto fail; - } - sc->sf_rdata.sf_tx_cring_paddr = ctx.sf_busaddr; - - /* Allocate DMA'able memory and load the DMA map for Rx ring. */ - error = bus_dmamem_alloc(sc->sf_cdata.sf_rx_ring_tag, - (void **)&sc->sf_rdata.sf_rx_ring, BUS_DMA_WAITOK | - BUS_DMA_COHERENT | BUS_DMA_ZERO, &sc->sf_cdata.sf_rx_ring_map); - if (error != 0) { - device_printf(sc->sf_dev, - "failed to allocate DMA'able memory for Rx ring\n"); - goto fail; - } - - ctx.sf_busaddr = 0; - error = bus_dmamap_load(sc->sf_cdata.sf_rx_ring_tag, - sc->sf_cdata.sf_rx_ring_map, sc->sf_rdata.sf_rx_ring, - SF_RX_DLIST_SIZE, sf_dmamap_cb, &ctx, 0); - if (error != 0 || ctx.sf_busaddr == 0) { - device_printf(sc->sf_dev, - "failed to load DMA'able memory for Rx ring\n"); - goto fail; - } - sc->sf_rdata.sf_rx_ring_paddr = ctx.sf_busaddr; - - /* - * Allocate DMA'able memory and load the DMA map for Rx completion ring. - */ - error = bus_dmamem_alloc(sc->sf_cdata.sf_rx_cring_tag, - (void **)&sc->sf_rdata.sf_rx_cring, BUS_DMA_WAITOK | - BUS_DMA_COHERENT | BUS_DMA_ZERO, &sc->sf_cdata.sf_rx_cring_map); - if (error != 0) { - device_printf(sc->sf_dev, - "failed to allocate DMA'able memory for " - "Rx completion ring\n"); - goto fail; - } - - ctx.sf_busaddr = 0; - error = bus_dmamap_load(sc->sf_cdata.sf_rx_cring_tag, - sc->sf_cdata.sf_rx_cring_map, sc->sf_rdata.sf_rx_cring, - SF_RX_CLIST_SIZE, sf_dmamap_cb, &ctx, 0); - if (error != 0 || ctx.sf_busaddr == 0) { - device_printf(sc->sf_dev, - "failed to load DMA'able memory for Rx completion ring\n"); - goto fail; - } - sc->sf_rdata.sf_rx_cring_paddr = ctx.sf_busaddr; - - /* - * Tx desciptor ring and Tx completion ring should be addressed in - * the same 4GB space. The same rule applys to Rx ring and Rx - * completion ring. Unfortunately there is no way to specify this - * boundary restriction with bus_dma(9). So just try to allocate - * without the restriction and check the restriction was satisfied. - * If not, fall back to 32bit dma addressing mode which always - * guarantees the restriction. - */ - tx_ring_end = sc->sf_rdata.sf_tx_ring_paddr + SF_TX_DLIST_SIZE; - tx_cring_end = sc->sf_rdata.sf_tx_cring_paddr + SF_TX_CLIST_SIZE; - rx_ring_end = sc->sf_rdata.sf_rx_ring_paddr + SF_RX_DLIST_SIZE; - rx_cring_end = sc->sf_rdata.sf_rx_cring_paddr + SF_RX_CLIST_SIZE; - if ((SF_ADDR_HI(sc->sf_rdata.sf_tx_ring_paddr) != - SF_ADDR_HI(tx_cring_end)) || - (SF_ADDR_HI(sc->sf_rdata.sf_tx_cring_paddr) != - SF_ADDR_HI(tx_ring_end)) || - (SF_ADDR_HI(sc->sf_rdata.sf_rx_ring_paddr) != - SF_ADDR_HI(rx_cring_end)) || - (SF_ADDR_HI(sc->sf_rdata.sf_rx_cring_paddr) != - SF_ADDR_HI(rx_ring_end))) { - device_printf(sc->sf_dev, - "switching to 32bit DMA mode\n"); - sf_dma_free(sc); - /* Limit DMA address space to 32bit and try again. */ - lowaddr = BUS_SPACE_MAXADDR_32BIT; - goto again; - } - - /* Create DMA maps for Tx buffers. */ - for (i = 0; i < SF_TX_DLIST_CNT; i++) { - txd = &sc->sf_cdata.sf_txdesc[i]; - txd->tx_m = NULL; - txd->ndesc = 0; - txd->tx_dmamap = NULL; - error = bus_dmamap_create(sc->sf_cdata.sf_tx_tag, 0, - &txd->tx_dmamap); - if (error != 0) { - device_printf(sc->sf_dev, - "failed to create Tx dmamap\n"); - goto fail; - } - } - /* Create DMA maps for Rx buffers. */ - if ((error = bus_dmamap_create(sc->sf_cdata.sf_rx_tag, 0, - &sc->sf_cdata.sf_rx_sparemap)) != 0) { - device_printf(sc->sf_dev, - "failed to create spare Rx dmamap\n"); - goto fail; - } - for (i = 0; i < SF_RX_DLIST_CNT; i++) { - rxd = &sc->sf_cdata.sf_rxdesc[i]; - rxd->rx_m = NULL; - rxd->rx_dmamap = NULL; - error = bus_dmamap_create(sc->sf_cdata.sf_rx_tag, 0, - &rxd->rx_dmamap); - if (error != 0) { - device_printf(sc->sf_dev, - "failed to create Rx dmamap\n"); - goto fail; - } - } - -fail: - return (error); -} - -static void -sf_dma_free(struct sf_softc *sc) -{ - struct sf_txdesc *txd; - struct sf_rxdesc *rxd; - int i; - - /* Tx ring. */ - if (sc->sf_cdata.sf_tx_ring_tag) { - if (sc->sf_rdata.sf_tx_ring_paddr) - bus_dmamap_unload(sc->sf_cdata.sf_tx_ring_tag, - sc->sf_cdata.sf_tx_ring_map); - if (sc->sf_rdata.sf_tx_ring) - bus_dmamem_free(sc->sf_cdata.sf_tx_ring_tag, - sc->sf_rdata.sf_tx_ring, - sc->sf_cdata.sf_tx_ring_map); - sc->sf_rdata.sf_tx_ring = NULL; - sc->sf_rdata.sf_tx_ring_paddr = 0; - bus_dma_tag_destroy(sc->sf_cdata.sf_tx_ring_tag); - sc->sf_cdata.sf_tx_ring_tag = NULL; - } - /* Tx completion ring. */ - if (sc->sf_cdata.sf_tx_cring_tag) { - if (sc->sf_rdata.sf_tx_cring_paddr) - bus_dmamap_unload(sc->sf_cdata.sf_tx_cring_tag, - sc->sf_cdata.sf_tx_cring_map); - if (sc->sf_rdata.sf_tx_cring) - bus_dmamem_free(sc->sf_cdata.sf_tx_cring_tag, - sc->sf_rdata.sf_tx_cring, - sc->sf_cdata.sf_tx_cring_map); - sc->sf_rdata.sf_tx_cring = NULL; - sc->sf_rdata.sf_tx_cring_paddr = 0; - bus_dma_tag_destroy(sc->sf_cdata.sf_tx_cring_tag); - sc->sf_cdata.sf_tx_cring_tag = NULL; - } - /* Rx ring. */ - if (sc->sf_cdata.sf_rx_ring_tag) { - if (sc->sf_rdata.sf_rx_ring_paddr) - bus_dmamap_unload(sc->sf_cdata.sf_rx_ring_tag, - sc->sf_cdata.sf_rx_ring_map); - if (sc->sf_rdata.sf_rx_ring) - bus_dmamem_free(sc->sf_cdata.sf_rx_ring_tag, - sc->sf_rdata.sf_rx_ring, - sc->sf_cdata.sf_rx_ring_map); - sc->sf_rdata.sf_rx_ring = NULL; - sc->sf_rdata.sf_rx_ring_paddr = 0; - bus_dma_tag_destroy(sc->sf_cdata.sf_rx_ring_tag); - sc->sf_cdata.sf_rx_ring_tag = NULL; - } - /* Rx completion ring. */ - if (sc->sf_cdata.sf_rx_cring_tag) { - if (sc->sf_rdata.sf_rx_cring_paddr) - bus_dmamap_unload(sc->sf_cdata.sf_rx_cring_tag, - sc->sf_cdata.sf_rx_cring_map); - if (sc->sf_rdata.sf_rx_cring) - bus_dmamem_free(sc->sf_cdata.sf_rx_cring_tag, - sc->sf_rdata.sf_rx_cring, - sc->sf_cdata.sf_rx_cring_map); - sc->sf_rdata.sf_rx_cring = NULL; - sc->sf_rdata.sf_rx_cring_paddr = 0; - bus_dma_tag_destroy(sc->sf_cdata.sf_rx_cring_tag); - sc->sf_cdata.sf_rx_cring_tag = NULL; - } - /* Tx buffers. */ - if (sc->sf_cdata.sf_tx_tag) { - for (i = 0; i < SF_TX_DLIST_CNT; i++) { - txd = &sc->sf_cdata.sf_txdesc[i]; - if (txd->tx_dmamap) { - bus_dmamap_destroy(sc->sf_cdata.sf_tx_tag, - txd->tx_dmamap); - txd->tx_dmamap = NULL; - } - } - bus_dma_tag_destroy(sc->sf_cdata.sf_tx_tag); - sc->sf_cdata.sf_tx_tag = NULL; - } - /* Rx buffers. */ - if (sc->sf_cdata.sf_rx_tag) { - for (i = 0; i < SF_RX_DLIST_CNT; i++) { - rxd = &sc->sf_cdata.sf_rxdesc[i]; - if (rxd->rx_dmamap) { - bus_dmamap_destroy(sc->sf_cdata.sf_rx_tag, - rxd->rx_dmamap); - rxd->rx_dmamap = NULL; - } - } - if (sc->sf_cdata.sf_rx_sparemap) { - bus_dmamap_destroy(sc->sf_cdata.sf_rx_tag, - sc->sf_cdata.sf_rx_sparemap); - sc->sf_cdata.sf_rx_sparemap = 0; - } - bus_dma_tag_destroy(sc->sf_cdata.sf_rx_tag); - sc->sf_cdata.sf_rx_tag = NULL; - } - - if (sc->sf_cdata.sf_parent_tag) { - bus_dma_tag_destroy(sc->sf_cdata.sf_parent_tag); - sc->sf_cdata.sf_parent_tag = NULL; - } -} - -static int -sf_init_rx_ring(struct sf_softc *sc) -{ - struct sf_ring_data *rd; - int i; - - sc->sf_cdata.sf_rxc_cons = 0; - - rd = &sc->sf_rdata; - bzero(rd->sf_rx_ring, SF_RX_DLIST_SIZE); - bzero(rd->sf_rx_cring, SF_RX_CLIST_SIZE); - - for (i = 0; i < SF_RX_DLIST_CNT; i++) { - if (sf_newbuf(sc, i) != 0) - return (ENOBUFS); - } - - bus_dmamap_sync(sc->sf_cdata.sf_rx_cring_tag, - sc->sf_cdata.sf_rx_cring_map, - BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); - bus_dmamap_sync(sc->sf_cdata.sf_rx_ring_tag, - sc->sf_cdata.sf_rx_ring_map, - BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); - - return (0); -} - -static void -sf_init_tx_ring(struct sf_softc *sc) -{ - struct sf_ring_data *rd; - int i; - - sc->sf_cdata.sf_tx_prod = 0; - sc->sf_cdata.sf_tx_cnt = 0; - sc->sf_cdata.sf_txc_cons = 0; - - rd = &sc->sf_rdata; - bzero(rd->sf_tx_ring, SF_TX_DLIST_SIZE); - bzero(rd->sf_tx_cring, SF_TX_CLIST_SIZE); - for (i = 0; i < SF_TX_DLIST_CNT; i++) { - rd->sf_tx_ring[i].sf_tx_ctrl = htole32(SF_TX_DESC_ID); - sc->sf_cdata.sf_txdesc[i].tx_m = NULL; - sc->sf_cdata.sf_txdesc[i].ndesc = 0; - } - rd->sf_tx_ring[i].sf_tx_ctrl |= htole32(SF_TX_DESC_END); - - bus_dmamap_sync(sc->sf_cdata.sf_tx_ring_tag, - sc->sf_cdata.sf_tx_ring_map, - BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); - bus_dmamap_sync(sc->sf_cdata.sf_tx_cring_tag, - sc->sf_cdata.sf_tx_cring_map, - BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); -} - -/* - * Initialize an RX descriptor and attach an MBUF cluster. - */ -static int -sf_newbuf(struct sf_softc *sc, int idx) -{ - struct sf_rx_rdesc *desc; - struct sf_rxdesc *rxd; - struct mbuf *m; - bus_dma_segment_t segs[1]; - bus_dmamap_t map; - int nsegs; - - m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR); - if (m == NULL) - return (ENOBUFS); - m->m_len = m->m_pkthdr.len = MCLBYTES; - m_adj(m, sizeof(uint32_t)); - - if (bus_dmamap_load_mbuf_sg(sc->sf_cdata.sf_rx_tag, - sc->sf_cdata.sf_rx_sparemap, m, segs, &nsegs, 0) != 0) { - m_freem(m); - return (ENOBUFS); - } - KASSERT(nsegs == 1, ("%s: %d segments returned!", __func__, nsegs)); - - rxd = &sc->sf_cdata.sf_rxdesc[idx]; - if (rxd->rx_m != NULL) { - bus_dmamap_sync(sc->sf_cdata.sf_rx_tag, rxd->rx_dmamap, - BUS_DMASYNC_POSTREAD); - bus_dmamap_unload(sc->sf_cdata.sf_rx_tag, rxd->rx_dmamap); - } - map = rxd->rx_dmamap; - rxd->rx_dmamap = sc->sf_cdata.sf_rx_sparemap; - sc->sf_cdata.sf_rx_sparemap = map; - bus_dmamap_sync(sc->sf_cdata.sf_rx_tag, rxd->rx_dmamap, - BUS_DMASYNC_PREREAD); - rxd->rx_m = m; - desc = &sc->sf_rdata.sf_rx_ring[idx]; - desc->sf_addr = htole64(segs[0].ds_addr); - - return (0); -} - -#ifndef __NO_STRICT_ALIGNMENT -static __inline void -sf_fixup_rx(struct mbuf *m) -{ - int i; - uint16_t *src, *dst; - - src = mtod(m, uint16_t *); - dst = src - 1; - - for (i = 0; i < (m->m_len / sizeof(uint16_t) + 1); i++) - *dst++ = *src++; - - m->m_data -= ETHER_ALIGN; -} -#endif - -/* - * The starfire is programmed to use 'normal' mode for packet reception, - * which means we use the consumer/producer model for both the buffer - * descriptor queue and the completion descriptor queue. The only problem - * with this is that it involves a lot of register accesses: we have to - * read the RX completion consumer and producer indexes and the RX buffer - * producer index, plus the RX completion consumer and RX buffer producer - * indexes have to be updated. It would have been easier if Adaptec had - * put each index in a separate register, especially given that the damn - * NIC has a 512K register space. - * - * In spite of all the lovely features that Adaptec crammed into the 6915, - * it is marred by one truly stupid design flaw, which is that receive - * buffer addresses must be aligned on a longword boundary. This forces - * the packet payload to be unaligned, which is suboptimal on the x86 and - * completely unusable on the Alpha. Our only recourse is to copy received - * packets into properly aligned buffers before handing them off. - */ -static int -sf_rxeof(struct sf_softc *sc) -{ - struct mbuf *m; - struct ifnet *ifp; - struct sf_rxdesc *rxd; - struct sf_rx_rcdesc *cur_cmp; - int cons, eidx, prog, rx_npkts; - uint32_t status, status2; - - SF_LOCK_ASSERT(sc); - - ifp = sc->sf_ifp; - rx_npkts = 0; - - bus_dmamap_sync(sc->sf_cdata.sf_rx_ring_tag, - sc->sf_cdata.sf_rx_ring_map, - BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); - bus_dmamap_sync(sc->sf_cdata.sf_rx_cring_tag, - sc->sf_cdata.sf_rx_cring_map, - BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); - - /* - * To reduce register access, directly read Receive completion - * queue entry. - */ - eidx = 0; - prog = 0; - for (cons = sc->sf_cdata.sf_rxc_cons; - (ifp->if_drv_flags & IFF_DRV_RUNNING) != 0; - SF_INC(cons, SF_RX_CLIST_CNT)) { - cur_cmp = &sc->sf_rdata.sf_rx_cring[cons]; - status = le32toh(cur_cmp->sf_rx_status1); - if (status == 0) - break; -#ifdef DEVICE_POLLING - if ((ifp->if_capenable & IFCAP_POLLING) != 0) { - if (sc->rxcycles <= 0) - break; - sc->rxcycles--; - } -#endif - prog++; - eidx = (status & SF_RX_CMPDESC_EIDX) >> 16; - rxd = &sc->sf_cdata.sf_rxdesc[eidx]; - m = rxd->rx_m; - - /* - * Note, IFCOUNTER_IPACKETS and IFCOUNTER_IERRORS - * are handled in sf_stats_update(). - */ - if ((status & SF_RXSTAT1_OK) == 0) { - cur_cmp->sf_rx_status1 = 0; - continue; - } - - if (sf_newbuf(sc, eidx) != 0) { - if_inc_counter(ifp, IFCOUNTER_IQDROPS, 1); - cur_cmp->sf_rx_status1 = 0; - continue; - } - - /* AIC-6915 supports TCP/UDP checksum offload. */ - if ((ifp->if_capenable & IFCAP_RXCSUM) != 0) { - status2 = le32toh(cur_cmp->sf_rx_status2); - /* - * Sometimes AIC-6915 generates an interrupt to - * warn RxGFP stall with bad checksum bit set - * in status word. I'm not sure what conditioan - * triggers it but recevied packet's checksum - * was correct even though AIC-6915 does not - * agree on this. This may be an indication of - * firmware bug. To fix the issue, do not rely - * on bad checksum bit in status word and let - * upper layer verify integrity of received - * frame. - * Another nice feature of AIC-6915 is hardware - * assistance of checksum calculation by - * providing partial checksum value for received - * frame. The partial checksum value can be used - * to accelerate checksum computation for - * fragmented TCP/UDP packets. Upper network - * stack already takes advantage of the partial - * checksum value in IP reassembly stage. But - * I'm not sure the correctness of the partial - * hardware checksum assistance as frequent - * RxGFP stalls are seen on non-fragmented - * frames. Due to the nature of the complexity - * of checksum computation code in firmware it's - * possible to see another bug in RxGFP so - * ignore checksum assistance for fragmented - * frames. This can be changed in future. - */ - if ((status2 & SF_RXSTAT2_FRAG) == 0) { - if ((status2 & (SF_RXSTAT2_TCP | - SF_RXSTAT2_UDP)) != 0) { - if ((status2 & SF_RXSTAT2_CSUM_OK)) { - m->m_pkthdr.csum_flags = - CSUM_DATA_VALID | - CSUM_PSEUDO_HDR; - m->m_pkthdr.csum_data = 0xffff; - } - } - } -#ifdef SF_PARTIAL_CSUM_SUPPORT - else if ((status2 & SF_RXSTAT2_FRAG) != 0) { - if ((status2 & (SF_RXSTAT2_TCP | - SF_RXSTAT2_UDP)) != 0) { - if ((status2 & SF_RXSTAT2_PCSUM_OK)) { - m->m_pkthdr.csum_flags = - CSUM_DATA_VALID; - m->m_pkthdr.csum_data = - (status & - SF_RX_CMPDESC_CSUM2); - } - } - } -#endif - } - - m->m_pkthdr.len = m->m_len = status & SF_RX_CMPDESC_LEN; -#ifndef __NO_STRICT_ALIGNMENT - sf_fixup_rx(m); -#endif - m->m_pkthdr.rcvif = ifp; - - SF_UNLOCK(sc); - (*ifp->if_input)(ifp, m); - SF_LOCK(sc); - rx_npkts++; - - /* Clear completion status. */ - cur_cmp->sf_rx_status1 = 0; - } - - if (prog > 0) { - sc->sf_cdata.sf_rxc_cons = cons; - bus_dmamap_sync(sc->sf_cdata.sf_rx_ring_tag, - sc->sf_cdata.sf_rx_ring_map, - BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); - bus_dmamap_sync(sc->sf_cdata.sf_rx_cring_tag, - sc->sf_cdata.sf_rx_cring_map, - BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); - - /* Update Rx completion Q1 consumer index. */ - csr_write_4(sc, SF_CQ_CONSIDX, - (csr_read_4(sc, SF_CQ_CONSIDX) & ~SF_CQ_CONSIDX_RXQ1) | - (cons & SF_CQ_CONSIDX_RXQ1)); - /* Update Rx descriptor Q1 ptr. */ - csr_write_4(sc, SF_RXDQ_PTR_Q1, - (csr_read_4(sc, SF_RXDQ_PTR_Q1) & ~SF_RXDQ_PRODIDX) | - (eidx & SF_RXDQ_PRODIDX)); - } - return (rx_npkts); -} - -/* - * Read the transmit status from the completion queue and release - * mbufs. Note that the buffer descriptor index in the completion - * descriptor is an offset from the start of the transmit buffer - * descriptor list in bytes. This is important because the manual - * gives the impression that it should match the producer/consumer - * index, which is the offset in 8 byte blocks. - */ -static void -sf_txeof(struct sf_softc *sc) -{ - struct sf_txdesc *txd; - struct sf_tx_rcdesc *cur_cmp; - struct ifnet *ifp; - uint32_t status; - int cons, idx, prod; - - SF_LOCK_ASSERT(sc); - - ifp = sc->sf_ifp; - - bus_dmamap_sync(sc->sf_cdata.sf_tx_cring_tag, - sc->sf_cdata.sf_tx_cring_map, - BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); - - cons = sc->sf_cdata.sf_txc_cons; - prod = (csr_read_4(sc, SF_CQ_PRODIDX) & SF_TXDQ_PRODIDX_HIPRIO) >> 16; - if (prod == cons) - return; - - for (; cons != prod; SF_INC(cons, SF_TX_CLIST_CNT)) { - cur_cmp = &sc->sf_rdata.sf_tx_cring[cons]; - status = le32toh(cur_cmp->sf_tx_status1); - if (status == 0) - break; - switch (status & SF_TX_CMPDESC_TYPE) { - case SF_TXCMPTYPE_TX: - /* Tx complete entry. */ - break; - case SF_TXCMPTYPE_DMA: - /* DMA complete entry. */ - idx = status & SF_TX_CMPDESC_IDX; - idx = idx / sizeof(struct sf_tx_rdesc); - /* - * We don't need to check Tx status here. - * SF_ISR_TX_LOFIFO intr would handle this. - * Note, IFCOUNTER_OPACKETS, IFCOUNTER_COLLISIONS - * and IFCOUNTER_OERROR are handled in - * sf_stats_update(). - */ - txd = &sc->sf_cdata.sf_txdesc[idx]; - if (txd->tx_m != NULL) { - bus_dmamap_sync(sc->sf_cdata.sf_tx_tag, - txd->tx_dmamap, - BUS_DMASYNC_POSTWRITE); - bus_dmamap_unload(sc->sf_cdata.sf_tx_tag, - txd->tx_dmamap); - m_freem(txd->tx_m); - txd->tx_m = NULL; - } - sc->sf_cdata.sf_tx_cnt -= txd->ndesc; - KASSERT(sc->sf_cdata.sf_tx_cnt >= 0, - ("%s: Active Tx desc counter was garbled\n", - __func__)); - txd->ndesc = 0; - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - break; - default: - /* It should not happen. */ - device_printf(sc->sf_dev, - "unknown Tx completion type : 0x%08x : %d : %d\n", - status, cons, prod); - break; - } - cur_cmp->sf_tx_status1 = 0; - } - - sc->sf_cdata.sf_txc_cons = cons; - bus_dmamap_sync(sc->sf_cdata.sf_tx_cring_tag, - sc->sf_cdata.sf_tx_cring_map, - BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); - - if (sc->sf_cdata.sf_tx_cnt == 0) - sc->sf_watchdog_timer = 0; - - /* Update Tx completion consumer index. */ - csr_write_4(sc, SF_CQ_CONSIDX, - (csr_read_4(sc, SF_CQ_CONSIDX) & 0xffff) | - ((cons << 16) & 0xffff0000)); -} - -static void -sf_txthresh_adjust(struct sf_softc *sc) -{ - uint32_t txfctl; - - device_printf(sc->sf_dev, "Tx underrun -- "); - if (sc->sf_txthresh < SF_MAX_TX_THRESHOLD) { - txfctl = csr_read_4(sc, SF_TX_FRAMCTL); - /* Increase Tx threshold 256 bytes. */ - sc->sf_txthresh += 16; - if (sc->sf_txthresh > SF_MAX_TX_THRESHOLD) - sc->sf_txthresh = SF_MAX_TX_THRESHOLD; - txfctl &= ~SF_TXFRMCTL_TXTHRESH; - txfctl |= sc->sf_txthresh; - printf("increasing Tx threshold to %d bytes\n", - sc->sf_txthresh * SF_TX_THRESHOLD_UNIT); - csr_write_4(sc, SF_TX_FRAMCTL, txfctl); - } else - printf("\n"); -} - -#ifdef DEVICE_POLLING -static int -sf_poll(struct ifnet *ifp, enum poll_cmd cmd, int count) -{ - struct sf_softc *sc; - uint32_t status; - int rx_npkts; - - sc = ifp->if_softc; - rx_npkts = 0; - SF_LOCK(sc); - - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { - SF_UNLOCK(sc); - return (rx_npkts); - } - - sc->rxcycles = count; - rx_npkts = sf_rxeof(sc); - sf_txeof(sc); - if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) - sf_start_locked(ifp); - - if (cmd == POLL_AND_CHECK_STATUS) { - /* Reading the ISR register clears all interrrupts. */ - status = csr_read_4(sc, SF_ISR); - - if ((status & SF_ISR_ABNORMALINTR) != 0) { - if ((status & SF_ISR_STATSOFLOW) != 0) - sf_stats_update(sc); - else if ((status & SF_ISR_TX_LOFIFO) != 0) - sf_txthresh_adjust(sc); - else if ((status & SF_ISR_DMAERR) != 0) { - device_printf(sc->sf_dev, - "DMA error, resetting\n"); - ifp->if_drv_flags &= ~IFF_DRV_RUNNING; - sf_init_locked(sc); - SF_UNLOCK(sc); - return (rx_npkts); - } else if ((status & SF_ISR_NO_TX_CSUM) != 0) { - sc->sf_statistics.sf_tx_gfp_stall++; -#ifdef SF_GFP_DEBUG - device_printf(sc->sf_dev, - "TxGFP is not responding!\n"); -#endif - } else if ((status & SF_ISR_RXGFP_NORESP) != 0) { - sc->sf_statistics.sf_rx_gfp_stall++; -#ifdef SF_GFP_DEBUG - device_printf(sc->sf_dev, - "RxGFP is not responding!\n"); -#endif - } - } - } - - SF_UNLOCK(sc); - return (rx_npkts); -} -#endif /* DEVICE_POLLING */ - -static void -sf_intr(void *arg) -{ - struct sf_softc *sc; - struct ifnet *ifp; - uint32_t status; - int cnt; - - sc = (struct sf_softc *)arg; - SF_LOCK(sc); - - if (sc->sf_suspended != 0) - goto done_locked; - - /* Reading the ISR register clears all interrrupts. */ - status = csr_read_4(sc, SF_ISR); - if (status == 0 || status == 0xffffffff || - (status & SF_ISR_PCIINT_ASSERTED) == 0) - goto done_locked; - - ifp = sc->sf_ifp; -#ifdef DEVICE_POLLING - if ((ifp->if_capenable & IFCAP_POLLING) != 0) - goto done_locked; -#endif - - /* Disable interrupts. */ - csr_write_4(sc, SF_IMR, 0x00000000); - - for (cnt = 32; (status & SF_INTRS) != 0;) { - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) - break; - if ((status & SF_ISR_RXDQ1_DMADONE) != 0) - sf_rxeof(sc); - - if ((status & (SF_ISR_TX_TXDONE | SF_ISR_TX_DMADONE | - SF_ISR_TX_QUEUEDONE)) != 0) - sf_txeof(sc); - - if ((status & SF_ISR_ABNORMALINTR) != 0) { - if ((status & SF_ISR_STATSOFLOW) != 0) - sf_stats_update(sc); - else if ((status & SF_ISR_TX_LOFIFO) != 0) - sf_txthresh_adjust(sc); - else if ((status & SF_ISR_DMAERR) != 0) { - device_printf(sc->sf_dev, - "DMA error, resetting\n"); - ifp->if_drv_flags &= ~IFF_DRV_RUNNING; - sf_init_locked(sc); - SF_UNLOCK(sc); - return; - } else if ((status & SF_ISR_NO_TX_CSUM) != 0) { - sc->sf_statistics.sf_tx_gfp_stall++; -#ifdef SF_GFP_DEBUG - device_printf(sc->sf_dev, - "TxGFP is not responding!\n"); -#endif - } - else if ((status & SF_ISR_RXGFP_NORESP) != 0) { - sc->sf_statistics.sf_rx_gfp_stall++; -#ifdef SF_GFP_DEBUG - device_printf(sc->sf_dev, - "RxGFP is not responding!\n"); -#endif - } - } - if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) - sf_start_locked(ifp); - if (--cnt <= 0) - break; - /* Reading the ISR register clears all interrrupts. */ - status = csr_read_4(sc, SF_ISR); - } - - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) { - /* Re-enable interrupts. */ - csr_write_4(sc, SF_IMR, SF_INTRS); - } - -done_locked: - SF_UNLOCK(sc); -} - -static void -sf_download_fw(struct sf_softc *sc) -{ - uint32_t gfpinst; - int i, ndx; - uint8_t *p; - - /* - * A FP instruction is composed of 48bits so we have to - * write it with two parts. - */ - p = txfwdata; - ndx = 0; - for (i = 0; i < sizeof(txfwdata) / SF_GFP_INST_BYTES; i++) { - gfpinst = p[2] << 24 | p[3] << 16 | p[4] << 8 | p[5]; - csr_write_4(sc, SF_TXGFP_MEM_BASE + ndx * 4, gfpinst); - gfpinst = p[0] << 8 | p[1]; - csr_write_4(sc, SF_TXGFP_MEM_BASE + (ndx + 1) * 4, gfpinst); - p += SF_GFP_INST_BYTES; - ndx += 2; - } - if (bootverbose) - device_printf(sc->sf_dev, "%d Tx instructions downloaded\n", i); - - p = rxfwdata; - ndx = 0; - for (i = 0; i < sizeof(rxfwdata) / SF_GFP_INST_BYTES; i++) { - gfpinst = p[2] << 24 | p[3] << 16 | p[4] << 8 | p[5]; - csr_write_4(sc, SF_RXGFP_MEM_BASE + (ndx * 4), gfpinst); - gfpinst = p[0] << 8 | p[1]; - csr_write_4(sc, SF_RXGFP_MEM_BASE + (ndx + 1) * 4, gfpinst); - p += SF_GFP_INST_BYTES; - ndx += 2; - } - if (bootverbose) - device_printf(sc->sf_dev, "%d Rx instructions downloaded\n", i); -} - -static void -sf_init(void *xsc) -{ - struct sf_softc *sc; - - sc = (struct sf_softc *)xsc; - SF_LOCK(sc); - sf_init_locked(sc); - SF_UNLOCK(sc); -} - -static void -sf_init_locked(struct sf_softc *sc) -{ - struct ifnet *ifp; - uint8_t eaddr[ETHER_ADDR_LEN]; - bus_addr_t addr; - int i; - - SF_LOCK_ASSERT(sc); - ifp = sc->sf_ifp; - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) - return; - - sf_stop(sc); - /* Reset the hardware to a known state. */ - sf_reset(sc); - - /* Init all the receive filter registers */ - for (i = SF_RXFILT_PERFECT_BASE; - i < (SF_RXFILT_HASH_MAX + 1); i += sizeof(uint32_t)) - csr_write_4(sc, i, 0); - - /* Empty stats counter registers. */ - for (i = SF_STATS_BASE; i < (SF_STATS_END + 1); i += sizeof(uint32_t)) - csr_write_4(sc, i, 0); - - /* Init our MAC address. */ - bcopy(IF_LLADDR(sc->sf_ifp), eaddr, sizeof(eaddr)); - csr_write_4(sc, SF_PAR0, - eaddr[2] << 24 | eaddr[3] << 16 | eaddr[4] << 8 | eaddr[5]); - csr_write_4(sc, SF_PAR1, eaddr[0] << 8 | eaddr[1]); - sf_setperf(sc, 0, eaddr); - - if (sf_init_rx_ring(sc) == ENOBUFS) { - device_printf(sc->sf_dev, - "initialization failed: no memory for rx buffers\n"); - sf_stop(sc); - return; - } - - sf_init_tx_ring(sc); - - /* - * 16 perfect address filtering. - * Hash only multicast destination address, Accept matching - * frames regardless of VLAN ID. - */ - csr_write_4(sc, SF_RXFILT, SF_PERFMODE_NORMAL | SF_HASHMODE_ANYVLAN); - - /* - * Set Rx filter. - */ - sf_rxfilter(sc); - - /* Init the completion queue indexes. */ - csr_write_4(sc, SF_CQ_CONSIDX, 0); - csr_write_4(sc, SF_CQ_PRODIDX, 0); - - /* Init the RX completion queue. */ - addr = sc->sf_rdata.sf_rx_cring_paddr; - csr_write_4(sc, SF_CQ_ADDR_HI, SF_ADDR_HI(addr)); - csr_write_4(sc, SF_RXCQ_CTL_1, SF_ADDR_LO(addr) & SF_RXCQ_ADDR); - if (SF_ADDR_HI(addr) != 0) - SF_SETBIT(sc, SF_RXCQ_CTL_1, SF_RXCQ_USE_64BIT); - /* Set RX completion queue type 2. */ - SF_SETBIT(sc, SF_RXCQ_CTL_1, SF_RXCQTYPE_2); - csr_write_4(sc, SF_RXCQ_CTL_2, 0); - - /* - * Init RX DMA control. - * default RxHighPriority Threshold, - * default RxBurstSize, 128bytes. - */ - SF_SETBIT(sc, SF_RXDMA_CTL, - SF_RXDMA_REPORTBADPKTS | - (SF_RXDMA_HIGHPRIO_THRESH << 8) | - SF_RXDMA_BURST); - - /* Init the RX buffer descriptor queue. */ - addr = sc->sf_rdata.sf_rx_ring_paddr; - csr_write_4(sc, SF_RXDQ_ADDR_HI, SF_ADDR_HI(addr)); - csr_write_4(sc, SF_RXDQ_ADDR_Q1, SF_ADDR_LO(addr)); - - /* Set RX queue buffer length. */ - csr_write_4(sc, SF_RXDQ_CTL_1, - ((MCLBYTES - sizeof(uint32_t)) << 16) | - SF_RXDQCTL_64BITBADDR | SF_RXDQCTL_VARIABLE); - - if (SF_ADDR_HI(addr) != 0) - SF_SETBIT(sc, SF_RXDQ_CTL_1, SF_RXDQCTL_64BITDADDR); - csr_write_4(sc, SF_RXDQ_PTR_Q1, SF_RX_DLIST_CNT - 1); - csr_write_4(sc, SF_RXDQ_CTL_2, 0); - - /* Init the TX completion queue */ - addr = sc->sf_rdata.sf_tx_cring_paddr; - csr_write_4(sc, SF_TXCQ_CTL, SF_ADDR_LO(addr) & SF_TXCQ_ADDR); - if (SF_ADDR_HI(addr) != 0) - SF_SETBIT(sc, SF_TXCQ_CTL, SF_TXCQ_USE_64BIT); - - /* Init the TX buffer descriptor queue. */ - addr = sc->sf_rdata.sf_tx_ring_paddr; - csr_write_4(sc, SF_TXDQ_ADDR_HI, SF_ADDR_HI(addr)); - csr_write_4(sc, SF_TXDQ_ADDR_HIPRIO, 0); - csr_write_4(sc, SF_TXDQ_ADDR_LOPRIO, SF_ADDR_LO(addr)); - csr_write_4(sc, SF_TX_FRAMCTL, - SF_TXFRMCTL_CPLAFTERTX | sc->sf_txthresh); - csr_write_4(sc, SF_TXDQ_CTL, - SF_TXDMA_HIPRIO_THRESH << 24 | - SF_TXSKIPLEN_0BYTES << 16 | - SF_TXDDMA_BURST << 8 | - SF_TXBUFDESC_TYPE2 | SF_TXMINSPACE_UNLIMIT); - if (SF_ADDR_HI(addr) != 0) - SF_SETBIT(sc, SF_TXDQ_CTL, SF_TXDQCTL_64BITADDR); - - /* Set VLAN Type register. */ - csr_write_4(sc, SF_VLANTYPE, ETHERTYPE_VLAN); - - /* Set TxPause Timer. */ - csr_write_4(sc, SF_TXPAUSETIMER, 0xffff); - - /* Enable autopadding of short TX frames. */ - SF_SETBIT(sc, SF_MACCFG_1, SF_MACCFG1_AUTOPAD); - SF_SETBIT(sc, SF_MACCFG_2, SF_MACCFG2_AUTOVLANPAD); - /* Make sure to reset MAC to take changes effect. */ - SF_SETBIT(sc, SF_MACCFG_1, SF_MACCFG1_SOFTRESET); - DELAY(1000); - SF_CLRBIT(sc, SF_MACCFG_1, SF_MACCFG1_SOFTRESET); - - /* Enable PCI bus master. */ - SF_SETBIT(sc, SF_PCI_DEVCFG, SF_PCIDEVCFG_PCIMEN); - - /* Load StarFire firmware. */ - sf_download_fw(sc); - - /* Intialize interrupt moderation. */ - csr_write_4(sc, SF_TIMER_CTL, SF_TIMER_IMASK_MODE | SF_TIMER_TIMES_TEN | - (sc->sf_int_mod & SF_TIMER_IMASK_INTERVAL)); - -#ifdef DEVICE_POLLING - /* Disable interrupts if we are polling. */ - if ((ifp->if_capenable & IFCAP_POLLING) != 0) - csr_write_4(sc, SF_IMR, 0x00000000); - else -#endif - /* Enable interrupts. */ - csr_write_4(sc, SF_IMR, SF_INTRS); - SF_SETBIT(sc, SF_PCI_DEVCFG, SF_PCIDEVCFG_INTR_ENB); - - /* Enable the RX and TX engines. */ - csr_write_4(sc, SF_GEN_ETH_CTL, - SF_ETHCTL_RX_ENB | SF_ETHCTL_RXDMA_ENB | - SF_ETHCTL_TX_ENB | SF_ETHCTL_TXDMA_ENB); - - if ((ifp->if_capenable & IFCAP_TXCSUM) != 0) - SF_SETBIT(sc, SF_GEN_ETH_CTL, SF_ETHCTL_TXGFP_ENB); - else - SF_CLRBIT(sc, SF_GEN_ETH_CTL, SF_ETHCTL_TXGFP_ENB); - if ((ifp->if_capenable & IFCAP_RXCSUM) != 0) - SF_SETBIT(sc, SF_GEN_ETH_CTL, SF_ETHCTL_RXGFP_ENB); - else - SF_CLRBIT(sc, SF_GEN_ETH_CTL, SF_ETHCTL_RXGFP_ENB); - - ifp->if_drv_flags |= IFF_DRV_RUNNING; - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - - sc->sf_link = 0; - sf_ifmedia_upd_locked(ifp); - - callout_reset(&sc->sf_co, hz, sf_tick, sc); -} - -static int -sf_encap(struct sf_softc *sc, struct mbuf **m_head) -{ - struct sf_txdesc *txd; - struct sf_tx_rdesc *desc; - struct mbuf *m; - bus_dmamap_t map; - bus_dma_segment_t txsegs[SF_MAXTXSEGS]; - int error, i, nsegs, prod, si; - int avail, nskip; - - SF_LOCK_ASSERT(sc); - - m = *m_head; - prod = sc->sf_cdata.sf_tx_prod; - txd = &sc->sf_cdata.sf_txdesc[prod]; - map = txd->tx_dmamap; - error = bus_dmamap_load_mbuf_sg(sc->sf_cdata.sf_tx_tag, map, - *m_head, txsegs, &nsegs, BUS_DMA_NOWAIT); - if (error == EFBIG) { - m = m_collapse(*m_head, M_NOWAIT, SF_MAXTXSEGS); - if (m == NULL) { - m_freem(*m_head); - *m_head = NULL; - return (ENOBUFS); - } - *m_head = m; - error = bus_dmamap_load_mbuf_sg(sc->sf_cdata.sf_tx_tag, - map, *m_head, txsegs, &nsegs, BUS_DMA_NOWAIT); - if (error != 0) { - m_freem(*m_head); - *m_head = NULL; - return (error); - } - } else if (error != 0) - return (error); - if (nsegs == 0) { - m_freem(*m_head); - *m_head = NULL; - return (EIO); - } - - /* Check number of available descriptors. */ - avail = (SF_TX_DLIST_CNT - 1) - sc->sf_cdata.sf_tx_cnt; - if (avail < nsegs) { - bus_dmamap_unload(sc->sf_cdata.sf_tx_tag, map); - return (ENOBUFS); - } - nskip = 0; - if (prod + nsegs >= SF_TX_DLIST_CNT) { - nskip = SF_TX_DLIST_CNT - prod - 1; - if (avail < nsegs + nskip) { - bus_dmamap_unload(sc->sf_cdata.sf_tx_tag, map); - return (ENOBUFS); - } - } - - bus_dmamap_sync(sc->sf_cdata.sf_tx_tag, map, BUS_DMASYNC_PREWRITE); - - si = prod; - for (i = 0; i < nsegs; i++) { - desc = &sc->sf_rdata.sf_tx_ring[prod]; - desc->sf_tx_ctrl = htole32(SF_TX_DESC_ID | - (txsegs[i].ds_len & SF_TX_DESC_FRAGLEN)); - desc->sf_tx_reserved = 0; - desc->sf_addr = htole64(txsegs[i].ds_addr); - if (i == 0 && prod + nsegs >= SF_TX_DLIST_CNT) { - /* Queue wraps! */ - desc->sf_tx_ctrl |= htole32(SF_TX_DESC_END); - prod = 0; - } else - SF_INC(prod, SF_TX_DLIST_CNT); - } - /* Update producer index. */ - sc->sf_cdata.sf_tx_prod = prod; - sc->sf_cdata.sf_tx_cnt += nsegs + nskip; - - desc = &sc->sf_rdata.sf_tx_ring[si]; - /* Check TDP/UDP checksum offload request. */ - if ((m->m_pkthdr.csum_flags & SF_CSUM_FEATURES) != 0) - desc->sf_tx_ctrl |= htole32(SF_TX_DESC_CALTCP); - desc->sf_tx_ctrl |= - htole32(SF_TX_DESC_CRCEN | SF_TX_DESC_INTR | (nsegs << 16)); - - txd->tx_dmamap = map; - txd->tx_m = m; - txd->ndesc = nsegs + nskip; - - return (0); -} - -static void -sf_start(struct ifnet *ifp) -{ - struct sf_softc *sc; - - sc = ifp->if_softc; - SF_LOCK(sc); - sf_start_locked(ifp); - SF_UNLOCK(sc); -} - -static void -sf_start_locked(struct ifnet *ifp) -{ - struct sf_softc *sc; - struct mbuf *m_head; - int enq; - - sc = ifp->if_softc; - SF_LOCK_ASSERT(sc); - - if ((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) != - IFF_DRV_RUNNING || sc->sf_link == 0) - return; - - /* - * Since we don't know when descriptor wrap occurrs in advance - * limit available number of active Tx descriptor counter to be - * higher than maximum number of DMA segments allowed in driver. - */ - for (enq = 0; !IFQ_DRV_IS_EMPTY(&ifp->if_snd) && - sc->sf_cdata.sf_tx_cnt < SF_TX_DLIST_CNT - SF_MAXTXSEGS; ) { - IFQ_DRV_DEQUEUE(&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 (sf_encap(sc, &m_head)) { - if (m_head == NULL) - break; - IFQ_DRV_PREPEND(&ifp->if_snd, m_head); - ifp->if_drv_flags |= IFF_DRV_OACTIVE; - break; - } - - enq++; - /* - * If there's a BPF listener, bounce a copy of this frame - * to him. - */ - ETHER_BPF_MTAP(ifp, m_head); - } - - if (enq > 0) { - bus_dmamap_sync(sc->sf_cdata.sf_tx_ring_tag, - sc->sf_cdata.sf_tx_ring_map, - BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); - /* Kick transmit. */ - csr_write_4(sc, SF_TXDQ_PRODIDX, - sc->sf_cdata.sf_tx_prod * (sizeof(struct sf_tx_rdesc) / 8)); - - /* Set a timeout in case the chip goes out to lunch. */ - sc->sf_watchdog_timer = 5; - } -} - -static void -sf_stop(struct sf_softc *sc) -{ - struct sf_txdesc *txd; - struct sf_rxdesc *rxd; - struct ifnet *ifp; - int i; - - SF_LOCK_ASSERT(sc); - - ifp = sc->sf_ifp; - - ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); - sc->sf_link = 0; - callout_stop(&sc->sf_co); - sc->sf_watchdog_timer = 0; - - /* Reading the ISR register clears all interrrupts. */ - csr_read_4(sc, SF_ISR); - /* Disable further interrupts. */ - csr_write_4(sc, SF_IMR, 0); - - /* Disable Tx/Rx egine. */ - csr_write_4(sc, SF_GEN_ETH_CTL, 0); - - /* Give hardware chance to drain active DMA cycles. */ - DELAY(1000); - - csr_write_4(sc, SF_CQ_CONSIDX, 0); - csr_write_4(sc, SF_CQ_PRODIDX, 0); - csr_write_4(sc, SF_RXDQ_ADDR_Q1, 0); - csr_write_4(sc, SF_RXDQ_CTL_1, 0); - csr_write_4(sc, SF_RXDQ_PTR_Q1, 0); - csr_write_4(sc, SF_TXCQ_CTL, 0); - csr_write_4(sc, SF_TXDQ_ADDR_HIPRIO, 0); - csr_write_4(sc, SF_TXDQ_CTL, 0); - - /* - * Free RX and TX mbufs still in the queues. - */ - for (i = 0; i < SF_RX_DLIST_CNT; i++) { - rxd = &sc->sf_cdata.sf_rxdesc[i]; - if (rxd->rx_m != NULL) { - bus_dmamap_sync(sc->sf_cdata.sf_rx_tag, - rxd->rx_dmamap, BUS_DMASYNC_POSTREAD); - bus_dmamap_unload(sc->sf_cdata.sf_rx_tag, - rxd->rx_dmamap); - m_freem(rxd->rx_m); - rxd->rx_m = NULL; - } - } - for (i = 0; i < SF_TX_DLIST_CNT; i++) { - txd = &sc->sf_cdata.sf_txdesc[i]; - if (txd->tx_m != NULL) { - bus_dmamap_sync(sc->sf_cdata.sf_tx_tag, - txd->tx_dmamap, BUS_DMASYNC_POSTWRITE); - bus_dmamap_unload(sc->sf_cdata.sf_tx_tag, - txd->tx_dmamap); - m_freem(txd->tx_m); - txd->tx_m = NULL; - txd->ndesc = 0; - } - } -} - -static void -sf_tick(void *xsc) -{ - struct sf_softc *sc; - struct mii_data *mii; - - sc = xsc; - SF_LOCK_ASSERT(sc); - mii = device_get_softc(sc->sf_miibus); - mii_tick(mii); - sf_stats_update(sc); - sf_watchdog(sc); - callout_reset(&sc->sf_co, hz, sf_tick, sc); -} - -/* - * Note: it is important that this function not be interrupted. We - * use a two-stage register access scheme: if we are interrupted in - * between setting the indirect address register and reading from the - * indirect data register, the contents of the address register could - * be changed out from under us. - */ -static void -sf_stats_update(struct sf_softc *sc) -{ - struct ifnet *ifp; - struct sf_stats now, *stats, *nstats; - int i; - - SF_LOCK_ASSERT(sc); - - ifp = sc->sf_ifp; - stats = &now; - - stats->sf_tx_frames = - csr_read_4(sc, SF_STATS_BASE + SF_STATS_TX_FRAMES); - stats->sf_tx_single_colls = - csr_read_4(sc, SF_STATS_BASE + SF_STATS_TX_SINGLE_COL); - stats->sf_tx_multi_colls = - csr_read_4(sc, SF_STATS_BASE + SF_STATS_TX_MULTI_COL); - stats->sf_tx_crcerrs = - csr_read_4(sc, SF_STATS_BASE + SF_STATS_TX_CRC_ERRS); - stats->sf_tx_bytes = - csr_read_4(sc, SF_STATS_BASE + SF_STATS_TX_BYTES); - stats->sf_tx_deferred = - csr_read_4(sc, SF_STATS_BASE + SF_STATS_TX_DEFERRED); - stats->sf_tx_late_colls = - csr_read_4(sc, SF_STATS_BASE + SF_STATS_TX_LATE_COL); - stats->sf_tx_pause_frames = - csr_read_4(sc, SF_STATS_BASE + SF_STATS_TX_PAUSE); - stats->sf_tx_control_frames = - csr_read_4(sc, SF_STATS_BASE + SF_STATS_TX_CTL_FRAME); - stats->sf_tx_excess_colls = - csr_read_4(sc, SF_STATS_BASE + SF_STATS_TX_EXCESS_COL); - stats->sf_tx_excess_defer = - csr_read_4(sc, SF_STATS_BASE + SF_STATS_TX_EXCESS_DEF); - stats->sf_tx_mcast_frames = - csr_read_4(sc, SF_STATS_BASE + SF_STATS_TX_MULTI); - stats->sf_tx_bcast_frames = - csr_read_4(sc, SF_STATS_BASE + SF_STATS_TX_BCAST); - stats->sf_tx_frames_lost = - csr_read_4(sc, SF_STATS_BASE + SF_STATS_TX_FRAME_LOST); - stats->sf_rx_frames = - csr_read_4(sc, SF_STATS_BASE + SF_STATS_RX_FRAMES); - stats->sf_rx_crcerrs = - csr_read_4(sc, SF_STATS_BASE + SF_STATS_RX_CRC_ERRS); - stats->sf_rx_alignerrs = - csr_read_4(sc, SF_STATS_BASE + SF_STATS_RX_ALIGN_ERRS); - stats->sf_rx_bytes = - csr_read_4(sc, SF_STATS_BASE + SF_STATS_RX_BYTES); - stats->sf_rx_pause_frames = - csr_read_4(sc, SF_STATS_BASE + SF_STATS_RX_PAUSE); - stats->sf_rx_control_frames = - csr_read_4(sc, SF_STATS_BASE + SF_STATS_RX_CTL_FRAME); - stats->sf_rx_unsup_control_frames = - csr_read_4(sc, SF_STATS_BASE + SF_STATS_RX_UNSUP_FRAME); - stats->sf_rx_giants = - csr_read_4(sc, SF_STATS_BASE + SF_STATS_RX_GIANTS); - stats->sf_rx_runts = - csr_read_4(sc, SF_STATS_BASE + SF_STATS_RX_RUNTS); - stats->sf_rx_jabbererrs = - csr_read_4(sc, SF_STATS_BASE + SF_STATS_RX_JABBER); - stats->sf_rx_fragments = - csr_read_4(sc, SF_STATS_BASE + SF_STATS_RX_FRAGMENTS); - stats->sf_rx_pkts_64 = - csr_read_4(sc, SF_STATS_BASE + SF_STATS_RX_64); - stats->sf_rx_pkts_65_127 = - csr_read_4(sc, SF_STATS_BASE + SF_STATS_RX_65_127); - stats->sf_rx_pkts_128_255 = - csr_read_4(sc, SF_STATS_BASE + SF_STATS_RX_128_255); - stats->sf_rx_pkts_256_511 = - csr_read_4(sc, SF_STATS_BASE + SF_STATS_RX_256_511); - stats->sf_rx_pkts_512_1023 = - csr_read_4(sc, SF_STATS_BASE + SF_STATS_RX_512_1023); - stats->sf_rx_pkts_1024_1518 = - csr_read_4(sc, SF_STATS_BASE + SF_STATS_RX_1024_1518); - stats->sf_rx_frames_lost = - csr_read_4(sc, SF_STATS_BASE + SF_STATS_RX_FRAME_LOST); - /* Lower 16bits are valid. */ - stats->sf_tx_underruns = - (csr_read_4(sc, SF_STATS_BASE + SF_STATS_TX_UNDERRUN) & 0xffff); - - /* Empty stats counter registers. */ - for (i = SF_STATS_BASE; i < (SF_STATS_END + 1); i += sizeof(uint32_t)) - csr_write_4(sc, i, 0); - - if_inc_counter(ifp, IFCOUNTER_OPACKETS, (u_long)stats->sf_tx_frames); - - if_inc_counter(ifp, IFCOUNTER_COLLISIONS, - (u_long)stats->sf_tx_single_colls + - (u_long)stats->sf_tx_multi_colls); - - if_inc_counter(ifp, IFCOUNTER_OERRORS, - (u_long)stats->sf_tx_excess_colls + - (u_long)stats->sf_tx_excess_defer + - (u_long)stats->sf_tx_frames_lost); - - if_inc_counter(ifp, IFCOUNTER_IPACKETS, (u_long)stats->sf_rx_frames); - - if_inc_counter(ifp, IFCOUNTER_IERRORS, - (u_long)stats->sf_rx_crcerrs + - (u_long)stats->sf_rx_alignerrs + - (u_long)stats->sf_rx_giants + - (u_long)stats->sf_rx_runts + - (u_long)stats->sf_rx_jabbererrs + - (u_long)stats->sf_rx_frames_lost); - - nstats = &sc->sf_statistics; - - nstats->sf_tx_frames += stats->sf_tx_frames; - nstats->sf_tx_single_colls += stats->sf_tx_single_colls; - nstats->sf_tx_multi_colls += stats->sf_tx_multi_colls; - nstats->sf_tx_crcerrs += stats->sf_tx_crcerrs; - nstats->sf_tx_bytes += stats->sf_tx_bytes; - nstats->sf_tx_deferred += stats->sf_tx_deferred; - nstats->sf_tx_late_colls += stats->sf_tx_late_colls; - nstats->sf_tx_pause_frames += stats->sf_tx_pause_frames; - nstats->sf_tx_control_frames += stats->sf_tx_control_frames; - nstats->sf_tx_excess_colls += stats->sf_tx_excess_colls; - nstats->sf_tx_excess_defer += stats->sf_tx_excess_defer; - nstats->sf_tx_mcast_frames += stats->sf_tx_mcast_frames; - nstats->sf_tx_bcast_frames += stats->sf_tx_bcast_frames; - nstats->sf_tx_frames_lost += stats->sf_tx_frames_lost; - nstats->sf_rx_frames += stats->sf_rx_frames; - nstats->sf_rx_crcerrs += stats->sf_rx_crcerrs; - nstats->sf_rx_alignerrs += stats->sf_rx_alignerrs; - nstats->sf_rx_bytes += stats->sf_rx_bytes; - nstats->sf_rx_pause_frames += stats->sf_rx_pause_frames; - nstats->sf_rx_control_frames += stats->sf_rx_control_frames; - nstats->sf_rx_unsup_control_frames += stats->sf_rx_unsup_control_frames; - nstats->sf_rx_giants += stats->sf_rx_giants; - nstats->sf_rx_runts += stats->sf_rx_runts; - nstats->sf_rx_jabbererrs += stats->sf_rx_jabbererrs; - nstats->sf_rx_fragments += stats->sf_rx_fragments; - nstats->sf_rx_pkts_64 += stats->sf_rx_pkts_64; - nstats->sf_rx_pkts_65_127 += stats->sf_rx_pkts_65_127; - nstats->sf_rx_pkts_128_255 += stats->sf_rx_pkts_128_255; - nstats->sf_rx_pkts_256_511 += stats->sf_rx_pkts_256_511; - nstats->sf_rx_pkts_512_1023 += stats->sf_rx_pkts_512_1023; - nstats->sf_rx_pkts_1024_1518 += stats->sf_rx_pkts_1024_1518; - nstats->sf_rx_frames_lost += stats->sf_rx_frames_lost; - nstats->sf_tx_underruns += stats->sf_tx_underruns; -} - -static void -sf_watchdog(struct sf_softc *sc) -{ - struct ifnet *ifp; - - SF_LOCK_ASSERT(sc); - - if (sc->sf_watchdog_timer == 0 || --sc->sf_watchdog_timer) - return; - - ifp = sc->sf_ifp; - - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); - if (sc->sf_link == 0) { - if (bootverbose) - if_printf(sc->sf_ifp, "watchdog timeout " - "(missed link)\n"); - } else - if_printf(ifp, "watchdog timeout, %d Tx descs are active\n", - sc->sf_cdata.sf_tx_cnt); - - ifp->if_drv_flags &= ~IFF_DRV_RUNNING; - sf_init_locked(sc); - - if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) - sf_start_locked(ifp); -} - -static int -sf_shutdown(device_t dev) -{ - struct sf_softc *sc; - - sc = device_get_softc(dev); - - SF_LOCK(sc); - sf_stop(sc); - SF_UNLOCK(sc); - - return (0); -} - -static int -sf_suspend(device_t dev) -{ - struct sf_softc *sc; - - sc = device_get_softc(dev); - - SF_LOCK(sc); - sf_stop(sc); - sc->sf_suspended = 1; - bus_generic_suspend(dev); - SF_UNLOCK(sc); - - return (0); -} - -static int -sf_resume(device_t dev) -{ - struct sf_softc *sc; - struct ifnet *ifp; - - sc = device_get_softc(dev); - - SF_LOCK(sc); - bus_generic_resume(dev); - ifp = sc->sf_ifp; - if ((ifp->if_flags & IFF_UP) != 0) - sf_init_locked(sc); - - sc->sf_suspended = 0; - SF_UNLOCK(sc); - - return (0); -} - -static int -sf_sysctl_stats(SYSCTL_HANDLER_ARGS) -{ - struct sf_softc *sc; - struct sf_stats *stats; - int error; - int result; - - result = -1; - error = sysctl_handle_int(oidp, &result, 0, req); - - if (error != 0 || req->newptr == NULL) - return (error); - - if (result != 1) - return (error); - - sc = (struct sf_softc *)arg1; - stats = &sc->sf_statistics; - - printf("%s statistics:\n", device_get_nameunit(sc->sf_dev)); - printf("Transmit good frames : %ju\n", - (uintmax_t)stats->sf_tx_frames); - printf("Transmit good octets : %ju\n", - (uintmax_t)stats->sf_tx_bytes); - printf("Transmit single collisions : %u\n", - stats->sf_tx_single_colls); - printf("Transmit multiple collisions : %u\n", - stats->sf_tx_multi_colls); - printf("Transmit late collisions : %u\n", - stats->sf_tx_late_colls); - printf("Transmit abort due to excessive collisions : %u\n", - stats->sf_tx_excess_colls); - printf("Transmit CRC errors : %u\n", - stats->sf_tx_crcerrs); - printf("Transmit deferrals : %u\n", - stats->sf_tx_deferred); - printf("Transmit abort due to excessive deferrals : %u\n", - stats->sf_tx_excess_defer); - printf("Transmit pause control frames : %u\n", - stats->sf_tx_pause_frames); - printf("Transmit control frames : %u\n", - stats->sf_tx_control_frames); - printf("Transmit good multicast frames : %u\n", - stats->sf_tx_mcast_frames); - printf("Transmit good broadcast frames : %u\n", - stats->sf_tx_bcast_frames); - printf("Transmit frames lost due to internal transmit errors : %u\n", - stats->sf_tx_frames_lost); - printf("Transmit FIFO underflows : %u\n", - stats->sf_tx_underruns); - printf("Transmit GFP stalls : %u\n", stats->sf_tx_gfp_stall); - printf("Receive good frames : %ju\n", - (uint64_t)stats->sf_rx_frames); - printf("Receive good octets : %ju\n", - (uint64_t)stats->sf_rx_bytes); - printf("Receive CRC errors : %u\n", - stats->sf_rx_crcerrs); - printf("Receive alignment errors : %u\n", - stats->sf_rx_alignerrs); - printf("Receive pause frames : %u\n", - stats->sf_rx_pause_frames); - printf("Receive control frames : %u\n", - stats->sf_rx_control_frames); - printf("Receive control frames with unsupported opcode : %u\n", - stats->sf_rx_unsup_control_frames); - printf("Receive frames too long : %u\n", - stats->sf_rx_giants); - printf("Receive frames too short : %u\n", - stats->sf_rx_runts); - printf("Receive frames jabber errors : %u\n", - stats->sf_rx_jabbererrs); - printf("Receive frames fragments : %u\n", - stats->sf_rx_fragments); - printf("Receive packets 64 bytes : %ju\n", - (uint64_t)stats->sf_rx_pkts_64); - printf("Receive packets 65 to 127 bytes : %ju\n", - (uint64_t)stats->sf_rx_pkts_65_127); - printf("Receive packets 128 to 255 bytes : %ju\n", - (uint64_t)stats->sf_rx_pkts_128_255); - printf("Receive packets 256 to 511 bytes : %ju\n", - (uint64_t)stats->sf_rx_pkts_256_511); - printf("Receive packets 512 to 1023 bytes : %ju\n", - (uint64_t)stats->sf_rx_pkts_512_1023); - printf("Receive packets 1024 to 1518 bytes : %ju\n", - (uint64_t)stats->sf_rx_pkts_1024_1518); - printf("Receive frames lost due to internal receive errors : %u\n", - stats->sf_rx_frames_lost); - printf("Receive GFP stalls : %u\n", stats->sf_rx_gfp_stall); - - return (error); -} - -static int -sysctl_int_range(SYSCTL_HANDLER_ARGS, int low, int high) -{ - int error, value; - - if (!arg1) - return (EINVAL); - value = *(int *)arg1; - error = sysctl_handle_int(oidp, &value, 0, req); - if (error || !req->newptr) - return (error); - if (value < low || value > high) - return (EINVAL); - *(int *)arg1 = value; - - return (0); -} - -static int -sysctl_hw_sf_int_mod(SYSCTL_HANDLER_ARGS) -{ - - return (sysctl_int_range(oidp, arg1, arg2, req, SF_IM_MIN, SF_IM_MAX)); -} diff --git a/sys/dev/sf/if_sfreg.h b/sys/dev/sf/if_sfreg.h deleted file mode 100644 index bec92f1c813c..000000000000 --- a/sys/dev/sf/if_sfreg.h +++ /dev/null @@ -1,1105 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-4-Clause - * - * 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$ - */ - -/* - * Registers for the Adaptec AIC-6915 Starfire. The Starfire has a 512K - * register space. These registers can be accessed in the following way: - * - PCI config registers are always accessible through PCI config space - * - Full 512K space mapped into memory using PCI memory mapped access - * - 256-byte I/O space mapped through PCI I/O access - * - Full 512K space mapped through indirect I/O using PCI I/O access - * It's possible to use either memory mapped mode or I/O mode to access - * the registers, but memory mapped is usually the easiest. All registers - * are 32 bits wide and must be accessed using 32-bit operations. - */ - -/* - * Adaptec PCI vendor ID. - */ -#define AD_VENDORID 0x9004 - -/* - * AIC-6915 PCI device ID. - */ -#define AD_DEVICEID_STARFIRE 0x6915 - -/* - * AIC-6915 subsystem IDs. Adaptec uses the subsystem ID to identify - * the exact kind of NIC on which the ASIC is mounted. Currently there - * are six different variations. Note: the Adaptec manual lists code 0x28 - * for two different NICs: the 62044 and the 69011/TX. This is a typo: - * the code for the 62044 is really 0x18. - * - * Note that there also appears to be an 0x19 code for a newer rev - * 62044 card. - */ -#define AD_SUBSYSID_62011_REV0 0x0008 /* single port 10/100baseTX 64-bit */ -#define AD_SUBSYSID_62011_REV1 0x0009 /* single port 10/100baseTX 64-bit */ -#define AD_SUBSYSID_62022 0x0010 /* dual port 10/100baseTX 64-bit */ -#define AD_SUBSYSID_62044_REV0 0x0018 /* quad port 10/100baseTX 64-bit */ -#define AD_SUBSYSID_62044_REV1 0x0019 /* quad port 10/100baseTX 64-bit */ -#define AD_SUBSYSID_62020 0x0020 /* single port 10/100baseFX 64-bit */ -#define AD_SUBSYSID_69011 0x0028 /* single port 10/100baseTX 32-bit */ - -/* - * Starfire internal register space map. The entire register space - * is available using PCI memory mapped mode. The SF_RMAP_INTREG - * space is available using PCI I/O mode. The entire space can be - * accessed using indirect I/O using the indirect I/O addr and - * indirect I/O data registers located within the SF_RMAP_INTREG space. - */ -#define SF_RMAP_ROMADDR_BASE 0x00000 /* Expansion ROM space */ -#define SF_RMAP_ROMADDR_MAX 0x3FFFF - -#define SF_RMAP_EXGPIO_BASE 0x40000 /* External general purpose regs */ -#define SF_RMAP_EXGPIO_MAX 0x3FFFF - -#define SF_RMAP_INTREG_BASE 0x50000 /* Internal functional registers */ -#define SF_RMAP_INTREG_MAX 0x500FF -#define SF_RMAP_GENREG_BASE 0x50100 /* General purpose registers */ -#define SF_RMAP_GENREG_MAX 0x5FFFF - -#define SF_RMAP_FIFO_BASE 0x60000 -#define SF_RMAP_FIFO_MAX 0x6FFFF - -#define SF_RMAP_STS_BASE 0x70000 -#define SF_RMAP_STS_MAX 0x70083 - -#define SF_RMAP_RSVD_BASE 0x70084 -#define SF_RMAP_RSVD_MAX 0x7FFFF - -/* - * PCI config header registers, 0x0000 to 0x003F - */ -#define SF_PCI_VENDOR_ID 0x0000 -#define SF_PCI_DEVICE_ID 0x0002 -#define SF_PCI_COMMAND 0x0004 -#define SF_PCI_STATUS 0x0006 -#define SF_PCI_REVID 0x0008 -#define SF_PCI_CLASSCODE 0x0009 -#define SF_PCI_CACHELEN 0x000C -#define SF_PCI_LATENCY_TIMER 0x000D -#define SF_PCI_HEADER_TYPE 0x000E -#define SF_PCI_LOMEM 0x0010 -#define SF_PCI_LOIO 0x0014 -#define SF_PCI_SUBVEN_ID 0x002C -#define SF_PCI_SYBSYS_ID 0x002E -#define SF_PCI_BIOSROM 0x0030 -#define SF_PCI_INTLINE 0x003C -#define SF_PCI_INTPIN 0x003D -#define SF_PCI_MINGNT 0x003E -#define SF_PCI_MINLAT 0x003F - -/* - * PCI registers, 0x0040 to 0x006F - */ -#define SF_PCI_DEVCFG 0x0040 -#define SF_BACCTL 0x0044 -#define SF_PCI_MON1 0x0048 -#define SF_PCI_MON2 0x004C -#define SF_PCI_CAPID 0x0050 /* 8 bits */ -#define SF_PCI_NEXTPTR 0x0051 /* 8 bits */ -#define SF_PCI_PWRMGMTCAP 0x0052 /* 16 bits */ -#define SF_PCI_PWRMGMTCTRL 0x0054 /* 16 bits */ -#define SF_PCI_PME_EVENT 0x0058 -#define SF_PCI_EECTL 0x0060 -#define SF_PCI_COMPLIANCE 0x0064 -#define SF_INDIRECTIO_ADDR 0x0068 -#define SF_INDIRECTIO_DATA 0x006C - -#define SF_PCIDEVCFG_RESET 0x00000001 -#define SF_PCIDEVCFG_FORCE64 0x00000002 -#define SF_PCIDEVCFG_SYSTEM64 0x00000004 -#define SF_PCIDEVCFG_RSVD0 0x00000008 -#define SF_PCIDEVCFG_INCR_INB 0x00000010 -#define SF_PCIDEVCFG_ABTONPERR 0x00000020 -#define SF_PCIDEVCFG_STPONPERR 0x00000040 -#define SF_PCIDEVCFG_MR_ENB 0x00000080 -#define SF_PCIDEVCFG_FIFOTHR 0x00000F00 -#define SF_PCIDEVCFG_STPONCA 0x00001000 -#define SF_PCIDEVCFG_PCIMEN 0x00002000 /* enable PCI bus master */ -#define SF_PCIDEVCFG_LATSTP 0x00004000 -#define SF_PCIDEVCFG_BYTE_ENB 0x00008000 -#define SF_PCIDEVCFG_EECSWIDTH 0x00070000 -#define SF_PCIDEVCFG_STPMWCA 0x00080000 -#define SF_PCIDEVCFG_REGCSWIDTH 0x00700000 -#define SF_PCIDEVCFG_INTR_ENB 0x00800000 -#define SF_PCIDEVCFG_DPR_ENB 0x01000000 -#define SF_PCIDEVCFG_RSVD1 0x02000000 -#define SF_PCIDEVCFG_RSVD2 0x04000000 -#define SF_PCIDEVCFG_STA_ENB 0x08000000 -#define SF_PCIDEVCFG_RTA_ENB 0x10000000 -#define SF_PCIDEVCFG_RMA_ENB 0x20000000 -#define SF_PCIDEVCFG_SSE_ENB 0x40000000 -#define SF_PCIDEVCFG_DPE_ENB 0x80000000 - -#define SF_BACCTL_BACDMA_ENB 0x00000001 -#define SF_BACCTL_PREFER_RXDMA 0x00000002 -#define SF_BACCTL_PREFER_TXDMA 0x00000004 -#define SF_BACCTL_SINGLE_DMA 0x00000008 -#define SF_BACCTL_SWAPMODE_DATA 0x00000030 -#define SF_BACCTL_SWAPMODE_DESC 0x000000C0 - -#define SF_SWAPMODE_LE 0x00000000 -#define SF_SWAPMODE_BE 0x00000010 - -#define SF_PSTATE_MASK 0x0003 -#define SF_PSTATE_D0 0x0000 -#define SF_PSTATE_D1 0x0001 -#define SF_PSTATE_D2 0x0002 -#define SF_PSTATE_D3 0x0003 -#define SF_PME_EN 0x0010 -#define SF_PME_STATUS 0x8000 - - -/* - * Ethernet registers 0x0070 to 0x00FF - */ -#define SF_GEN_ETH_CTL 0x0070 -#define SF_TIMER_CTL 0x0074 -#define SF_CURTIME 0x0078 -#define SF_ISR 0x0080 -#define SF_ISR_SHADOW 0x0084 -#define SF_IMR 0x0088 -#define SF_GPIO 0x008C -#define SF_TXDQ_CTL 0x0090 -#define SF_TXDQ_ADDR_HIPRIO 0x0094 -#define SF_TXDQ_ADDR_LOPRIO 0x0098 -#define SF_TXDQ_ADDR_HI 0x009C -#define SF_TXDQ_PRODIDX 0x00A0 -#define SF_TXDQ_CONSIDX 0x00A4 -#define SF_TXDMA_STS1 0x00A8 -#define SF_TXDMA_STS2 0x00AC -#define SF_TX_FRAMCTL 0x00B0 -#define SF_CQ_ADDR_HI 0x00B4 -#define SF_TXCQ_CTL 0x00B8 -#define SF_RXCQ_CTL_1 0x00BC -#define SF_RXCQ_CTL_2 0x00C0 -#define SF_CQ_CONSIDX 0x00C4 -#define SF_CQ_PRODIDX 0x00C8 -#define SF_CQ_RXQ2 0x00CC -#define SF_RXDMA_CTL 0x00D0 -#define SF_RXDQ_CTL_1 0x00D4 -#define SF_RXDQ_CTL_2 0x00D8 -#define SF_RXDQ_ADDR_HI 0x00DC -#define SF_RXDQ_ADDR_Q1 0x00E0 -#define SF_RXDQ_ADDR_Q2 0x00E4 -#define SF_RXDQ_PTR_Q1 0x00E8 -#define SF_RXDQ_PTR_Q2 0x00EC -#define SF_RXDMA_STS 0x00F0 -#define SF_RXFILT 0x00F4 -#define SF_RX_FRAMETEST_OUT 0x00F8 - -/* Ethernet control register */ -#define SF_ETHCTL_RX_ENB 0x00000001 -#define SF_ETHCTL_TX_ENB 0x00000002 -#define SF_ETHCTL_RXDMA_ENB 0x00000004 -#define SF_ETHCTL_TXDMA_ENB 0x00000008 -#define SF_ETHCTL_RXGFP_ENB 0x00000010 -#define SF_ETHCTL_TXGFP_ENB 0x00000020 -#define SF_ETHCTL_SOFTINTR 0x00000800 - -/* Timer control register */ -#define SF_TIMER_IMASK_INTERVAL 0x0000001F -#define SF_TIMER_IMASK_MODE 0x00000060 -#define SF_TIMER_SMALLFRAME_BYP 0x00000100 -#define SF_TIMER_SMALLRX_FRAME 0x00000600 -#define SF_TIMER_TIMES_TEN 0x00000800 -#define SF_TIMER_RXHIPRIO_BYP 0x00001000 -#define SF_TIMER_TX_DMADONE_DLY 0x00002000 -#define SF_TIMER_TX_QDONE_DLY 0x00004000 -#define SF_TIMER_TX_FRDONE_DLY 0x00008000 -#define SF_TIMER_GENTIMER 0x00FF0000 -#define SF_TIMER_ONESHOT 0x01000000 -#define SF_TIMER_GENTIMER_RES 0x02000000 -#define SF_TIMER_TIMEST_RES 0x04000000 -#define SF_TIMER_RXQ2DONE_DLY 0x10000000 -#define SF_TIMER_EARLYRX2_DLY 0x20000000 -#define SF_TIMER_RXQ1DONE_DLY 0x40000000 -#define SF_TIMER_EARLYRX1_DLY 0x80000000 - -/* Timer resolution is 0.8us * 128. */ -#define SF_IM_MIN 0 -#define SF_IM_MAX 0x1F /* 3.276ms */ -#define SF_IM_DEFAULT 1 /* 102.4us */ - -/* Interrupt status register */ -#define SF_ISR_PCIINT_ASSERTED 0x00000001 -#define SF_ISR_GFP_TX 0x00000002 -#define SF_ISR_GFP_RX 0x00000004 -#define SF_ISR_TX_BADID_HIPRIO 0x00000008 -#define SF_ISR_TX_BADID_LOPRIO 0x00000010 -#define SF_ISR_NO_TX_CSUM 0x00000020 -#define SF_ISR_RXDQ2_NOBUFS 0x00000040 -#define SF_ISR_RXGFP_NORESP 0x00000080 -#define SF_ISR_RXDQ1_DMADONE 0x00000100 -#define SF_ISR_RXDQ2_DMADONE 0x00000200 -#define SF_ISR_RXDQ1_EARLY 0x00000400 -#define SF_ISR_RXDQ2_EARLY 0x00000800 -#define SF_ISR_TX_QUEUEDONE 0x00001000 -#define SF_ISR_TX_DMADONE 0x00002000 -#define SF_ISR_TX_TXDONE 0x00004000 -#define SF_ISR_NORMALINTR 0x00008000 -#define SF_ISR_RXDQ1_NOBUFS 0x00010000 -#define SF_ISR_RXCQ2_NOBUFS 0x00020000 -#define SF_ISR_TX_LOFIFO 0x00040000 -#define SF_ISR_DMAERR 0x00080000 -#define SF_ISR_PCIINT 0x00100000 -#define SF_ISR_TXCQ_NOBUFS 0x00200000 -#define SF_ISR_RXCQ1_NOBUFS 0x00400000 -#define SF_ISR_SOFTINTR 0x00800000 -#define SF_ISR_GENTIMER 0x01000000 -#define SF_ISR_ABNORMALINTR 0x02000000 -#define SF_ISR_RSVD0 0x04000000 -#define SF_ISR_STATSOFLOW 0x08000000 -#define SF_ISR_GPIO 0xF0000000 - -/* - * Shadow interrupt status register. Unlike the normal IRQ register, - * reading bits here does not automatically cause them to reset. - */ -#define SF_SISR_PCIINT_ASSERTED 0x00000001 -#define SF_SISR_GFP_TX 0x00000002 -#define SF_SISR_GFP_RX 0x00000004 -#define SF_SISR_TX_BADID_HIPRIO 0x00000008 -#define SF_SISR_TX_BADID_LOPRIO 0x00000010 -#define SF_SISR_NO_TX_CSUM 0x00000020 -#define SF_SISR_RXDQ2_NOBUFS 0x00000040 -#define SF_SISR_RXGFP_NORESP 0x00000080 -#define SF_SISR_RXDQ1_DMADONE 0x00000100 -#define SF_SISR_RXDQ2_DMADONE 0x00000200 -#define SF_SISR_RXDQ1_EARLY 0x00000400 -#define SF_SISR_RXDQ2_EARLY 0x00000800 -#define SF_SISR_TX_QUEUEDONE 0x00001000 -#define SF_SISR_TX_DMADONE 0x00002000 -#define SF_SISR_TX_TXDONE 0x00004000 -#define SF_SISR_NORMALINTR 0x00008000 -#define SF_SISR_RXDQ1_NOBUFS 0x00010000 -#define SF_SISR_RXCQ2_NOBUFS 0x00020000 -#define SF_SISR_TX_LOFIFO 0x00040000 -#define SF_SISR_DMAERR 0x00080000 -#define SF_SISR_PCIINT 0x00100000 -#define SF_SISR_TXCQ_NOBUFS 0x00200000 -#define SF_SISR_RXCQ1_NOBUFS 0x00400000 -#define SF_SISR_SOFTINTR 0x00800000 -#define SF_SISR_GENTIMER 0x01000000 -#define SF_SISR_ABNORMALINTR 0x02000000 -#define SF_SISR_RSVD0 0x04000000 -#define SF_SISR_STATSOFLOW 0x08000000 -#define SF_SISR_GPIO 0xF0000000 - -/* Interrupt mask register */ -#define SF_IMR_PCIINT_ASSERTED 0x00000001 -#define SF_IMR_GFP_TX 0x00000002 -#define SF_IMR_GFP_RX 0x00000004 -#define SF_IMR_TX_BADID_HIPRIO 0x00000008 -#define SF_IMR_TX_BADID_LOPRIO 0x00000010 -#define SF_IMR_NO_TX_CSUM 0x00000020 -#define SF_IMR_RXDQ2_NOBUFS 0x00000040 -#define SF_IMR_RXGFP_NORESP 0x00000080 -#define SF_IMR_RXDQ1_DMADONE 0x00000100 -#define SF_IMR_RXDQ2_DMADONE 0x00000200 -#define SF_IMR_RXDQ1_EARLY 0x00000400 -#define SF_IMR_RXDQ2_EARLY 0x00000800 -#define SF_IMR_TX_QUEUEDONE 0x00001000 -#define SF_IMR_TX_DMADONE 0x00002000 -#define SF_IMR_TX_TXDONE 0x00004000 -#define SF_IMR_NORMALINTR 0x00008000 -#define SF_IMR_RXDQ1_NOBUFS 0x00010000 -#define SF_IMR_RXCQ2_NOBUFS 0x00020000 -#define SF_IMR_TX_LOFIFO 0x00040000 -#define SF_IMR_DMAERR 0x00080000 -#define SF_IMR_PCIINT 0x00100000 -#define SF_IMR_TXCQ_NOBUFS 0x00200000 -#define SF_IMR_RXCQ1_NOBUFS 0x00400000 -#define SF_IMR_SOFTINTR 0x00800000 -#define SF_IMR_GENTIMER 0x01000000 -#define SF_IMR_ABNORMALINTR 0x02000000 -#define SF_IMR_RSVD0 0x04000000 -#define SF_IMR_STATSOFLOW 0x08000000 -#define SF_IMR_GPIO 0xF0000000 - -#define SF_INTRS \ - (SF_IMR_RXDQ2_NOBUFS|SF_IMR_RXDQ1_DMADONE|SF_IMR_RXDQ2_DMADONE| \ - SF_IMR_TX_DMADONE|SF_IMR_RXDQ1_NOBUFS| \ - SF_IMR_NORMALINTR|SF_IMR_ABNORMALINTR|SF_IMR_TXCQ_NOBUFS| \ - SF_IMR_RXCQ1_NOBUFS|SF_IMR_RXCQ2_NOBUFS|SF_IMR_STATSOFLOW| \ - SF_IMR_TX_LOFIFO|SF_IMR_DMAERR|SF_IMR_RXGFP_NORESP| \ - SF_IMR_NO_TX_CSUM) - -/* TX descriptor queue control registers */ -#define SF_TXDQCTL_DESCTYPE 0x00000007 -#define SF_TXDQCTL_NODMACMP 0x00000008 -#define SF_TXDQCTL_MINSPACE 0x00000070 -#define SF_TXDQCTL_64BITADDR 0x00000080 -#define SF_TXDQCTL_BURSTLEN 0x00003F00 -#define SF_TXDQCTL_SKIPLEN 0x001F0000 -#define SF_TXDQCTL_HIPRIOTHRESH 0xFF000000 - -#define SF_TXDMA_HIPRIO_THRESH 2 -#define SF_TXDDMA_BURST (128 / 32) - -#define SF_TXBUFDESC_TYPE0 0x00000000 -#define SF_TXBUFDESC_TYPE1 0x00000001 -#define SF_TXBUFDESC_TYPE2 0x00000002 -#define SF_TXBUFDESC_TYPE3 0x00000003 -#define SF_TXBUFDESC_TYPE4 0x00000004 - -#define SF_TXMINSPACE_UNLIMIT 0x00000000 -#define SF_TXMINSPACE_32BYTES 0x00000010 -#define SF_TXMINSPACE_64BYTES 0x00000020 -#define SF_TXMINSPACE_128BYTES 0x00000030 -#define SF_TXMINSPACE_256BYTES 0x00000040 - -#define SF_TXSKIPLEN_0BYTES 0x00000000 -#define SF_TXSKIPLEN_8BYTES 0x00010000 -#define SF_TXSKIPLEN_16BYTES 0x00020000 -#define SF_TXSKIPLEN_24BYTES 0x00030000 -#define SF_TXSKIPLEN_32BYTES 0x00040000 - -/* TX frame control register */ -#define SF_TXFRMCTL_TXTHRESH 0x000000FF -#define SF_TXFRMCTL_CPLAFTERTX 0x00000100 -#define SF_TXFRMCRL_DEBUG 0x0000FE00 -#define SF_TXFRMCTL_STATUS 0x01FF0000 -#define SF_TXFRMCTL_MAC_TXIF 0xFE000000 - -/* TX completion queue control register */ -#define SF_TXCQ_THRESH 0x0000000F -#define SF_TXCQ_COMMON 0x00000010 -#define SF_TXCQ_SIZE 0x00000020 -#define SF_TXCQ_WRITEENB 0x00000040 -#define SF_TXCQ_USE_64BIT 0x00000080 -#define SF_TXCQ_ADDR 0xFFFFFF00 - -/* RX completion queue control register */ -#define SF_RXCQ_THRESH 0x0000000F -#define SF_RXCQ_TYPE 0x00000030 -#define SF_RXCQ_WRITEENB 0x00000040 -#define SF_RXCQ_USE_64BIT 0x00000080 -#define SF_RXCQ_ADDR 0xFFFFFF00 - -#define SF_RXCQTYPE_0 0x00000000 -#define SF_RXCQTYPE_1 0x00000010 -#define SF_RXCQTYPE_2 0x00000020 -#define SF_RXCQTYPE_3 0x00000030 - -/* TX descriptor queue producer index register */ -#define SF_TXDQ_PRODIDX_LOPRIO 0x000007FF -#define SF_TXDQ_PRODIDX_HIPRIO 0x07FF0000 - -/* TX descriptor queue consumer index register */ -#define SF_TXDQ_CONSIDX_LOPRIO 0x000007FF -#define SF_TXDQ_CONSIDX_HIPRIO 0x07FF0000 - -/* Completion queue consumer index register */ -#define SF_CQ_CONSIDX_RXQ1 0x000003FF -#define SF_CQ_CONSIDX_RXTHRMODE 0x00008000 -#define SF_CQ_CONSIDX_TXQ 0x03FF0000 -#define SF_CQ_CONSIDX_TXTHRMODE 0x80000000 - -/* Completion queue producer index register */ -#define SF_CQ_PRODIDX_RXQ1 0x000003FF -#define SF_CQ_PRODIDX_TXQ 0x03FF0000 - -/* RX completion queue 2 consumer/producer index register */ -#define SF_CQ_RXQ2_CONSIDX 0x000003FF -#define SF_CQ_RXQ2_RXTHRMODE 0x00008000 -#define SF_CQ_RXQ2_PRODIDX 0x03FF0000 - -#define SF_CQ_RXTHRMODE_INT_ON 0x00008000 -#define SF_CQ_RXTHRMODE_INT_OFF 0x00000000 -#define SF_CQ_TXTHRMODE_INT_ON 0x80000000 -#define SF_CQ_TXTHRMODE_INT_OFF 0x00000000 - -/* RX DMA control register */ -#define SF_RXDMA_BURSTSIZE 0x0000007F -#define SF_RXDMA_FPTESTMODE 0x00000080 -#define SF_RXDMA_HIPRIOTHRESH 0x00000F00 -#define SF_RXDMA_RXEARLYTHRESH 0x0001F000 -#define SF_RXDMA_DMACRC 0x00040000 -#define SF_RXDMA_USEBKUPQUEUE 0x00080000 -#define SF_RXDMA_QUEUEMODE 0x00700000 -#define SF_RXDMA_RXCQ2_ON 0x00800000 -#define SF_RXDMA_CSUMMODE 0x03000000 -#define SF_RXDMA_DMAPAUSEPKTS 0x04000000 -#define SF_RXDMA_DMACTLPKTS 0x08000000 -#define SF_RXDMA_DMACRXERRPKTS 0x10000000 -#define SF_RXDMA_DMABADPKTS 0x20000000 -#define SF_RXDMA_DMARUNTS 0x40000000 -#define SF_RXDMA_REPORTBADPKTS 0x80000000 -#define SF_RXDMA_HIGHPRIO_THRESH 6 -#define SF_RXDMA_BURST (64 / 32) - -#define SF_RXDQMODE_Q1ONLY 0x00100000 -#define SF_RXDQMODE_Q2_ON_FP 0x00200000 -#define SF_RXDQMODE_Q2_ON_SHORT 0x00300000 -#define SF_RXDQMODE_Q2_ON_PRIO 0x00400000 -#define SF_RXDQMODE_SPLITHDR 0x00500000 - -#define SF_RXCSUMMODE_IGNORE 0x00000000 -#define SF_RXCSUMMODE_REJECT_BAD_TCP 0x01000000 -#define SF_RXCSUMMODE_REJECT_BAD_TCPUDP 0x02000000 -#define SF_RXCSUMMODE_RSVD 0x03000000 - -/* RX descriptor queue control registers */ -#define SF_RXDQCTL_MINDESCTHR 0x0000007F -#define SF_RXDQCTL_Q1_WE 0x00000080 -#define SF_RXDQCTL_DESCSPACE 0x00000700 -#define SF_RXDQCTL_64BITDADDR 0x00000800 -#define SF_RXDQCTL_64BITBADDR 0x00001000 -#define SF_RXDQCTL_VARIABLE 0x00002000 -#define SF_RXDQCTL_ENTRIES 0x00004000 -#define SF_RXDQCTL_PREFETCH 0x00008000 -#define SF_RXDQCTL_BUFLEN 0xFFFF0000 - -#define SF_DESCSPACE_4BYTES 0x00000000 -#define SF_DESCSPACE_8BYTES 0x00000100 -#define SF_DESCSPACE_16BYTES 0x00000200 -#define SF_DESCSPACE_32BYTES 0x00000300 -#define SF_DESCSPACE_64BYTES 0x00000400 -#define SF_DESCSPACE_128_BYTES 0x00000500 - -/* RX buffer consumer/producer index registers */ -#define SF_RXDQ_PRODIDX 0x000007FF -#define SF_RXDQ_CONSIDX 0x07FF0000 - -/* RX filter control register */ -#define SF_RXFILT_PROMISC 0x00000001 -#define SF_RXFILT_ALLMULTI 0x00000002 -#define SF_RXFILT_BROAD 0x00000004 -#define SF_RXFILT_HASHPRIO 0x00000008 -#define SF_RXFILT_HASHMODE 0x00000030 -#define SF_RXFILT_PERFMODE 0x000000C0 -#define SF_RXFILT_VLANMODE 0x00000300 -#define SF_RXFILT_WAKEMODE 0x00000C00 -#define SF_RXFILT_MULTI_NOBROAD 0x00001000 -#define SF_RXFILT_MIN_VLANPRIO 0x0000E000 -#define SF_RXFILT_PEFECTPRIO 0xFFFF0000 - -/* Hash filtering mode */ -#define SF_HASHMODE_OFF 0x00000000 -#define SF_HASHMODE_WITHVLAN 0x00000010 -#define SF_HASHMODE_ANYVLAN 0x00000020 -#define SF_HASHMODE_ANY 0x00000030 - -/* Perfect filtering mode */ -#define SF_PERFMODE_OFF 0x00000000 -#define SF_PERFMODE_NORMAL 0x00000040 -#define SF_PERFMODE_INVERSE 0x00000080 -#define SF_PERFMODE_VLAN 0x000000C0 - -/* VLAN mode */ -#define SF_VLANMODE_OFF 0x00000000 -#define SF_VLANMODE_NOSTRIP 0x00000100 -#define SF_VLANMODE_STRIP 0x00000200 -#define SF_VLANMODE_RSVD 0x00000300 - -/* Wakeup mode */ -#define SF_WAKEMODE_OFF 0x00000000 -#define SF_WAKEMODE_FILTER 0x00000400 -#define SF_WAKEMODE_FP 0x00000800 -#define SF_WAKEMODE_HIPRIO 0x00000C00 - -/* - * Extra PCI registers 0x0100 to 0x0FFF - */ -#define SF_PCI_TARGSTAT 0x0100 -#define SF_PCI_MASTSTAT1 0x0104 -#define SF_PCI_MASTSTAT2 0x0108 -#define SF_PCI_DMAHOSTADDR_LO 0x010C -#define SF_BAC_DMADIAG0 0x0110 -#define SF_BAC_DMADIAG1 0x0114 -#define SF_BAC_DMADIAG2 0x0118 -#define SF_BAC_DMADIAG3 0x011C -#define SF_PAR0 0x0120 -#define SF_PAR1 0x0124 -#define SF_PCICB_FUNCEVENT 0x0130 -#define SF_PCICB_FUNCEVENT_MASK 0x0134 -#define SF_PCICB_FUNCSTATE 0x0138 -#define SF_PCICB_FUNCFORCE 0x013C - -/* - * Serial EEPROM registers 0x1000 to 0x1FFF - * Presumeably the EEPROM is mapped into this 8K window. - */ -#define SF_EEADDR_BASE 0x1000 -#define SF_EEADDR_MAX 0x1FFF - -#define SF_EE_NODEADDR 14 - -/* - * MII registers registers 0x2000 to 0x3FFF - * There are 32 sets of 32 registers, one set for each possible - * PHY address. Each 32 bit register is split into a 16-bit data - * port and a couple of status bits. - */ - -#define SF_MIIADDR_BASE 0x2000 -#define SF_MIIADDR_MAX 0x3FFF -#define SF_MII_BLOCKS 32 - -#define SF_MII_DATAVALID 0x80000000 -#define SF_MII_BUSY 0x40000000 -#define SF_MII_DATAPORT 0x0000FFFF - -#define SF_PHY_REG(phy, reg) \ - (SF_MIIADDR_BASE + ((phy) * SF_MII_BLOCKS * sizeof(uint32_t)) + \ - ((reg) * sizeof(uint32_t))) - -/* - * Ethernet extra registers 0x4000 to 0x4FFF - */ -#define SF_TESTMODE 0x4000 -#define SF_RX_FRAMEPROC_CTL 0x4004 -#define SF_TX_FRAMEPROC_CTL 0x4008 - -/* - * MAC registers 0x5000 to 0x5FFF - */ -#define SF_MACCFG_1 0x5000 -#define SF_MACCFG_2 0x5004 -#define SF_BKTOBKIPG 0x5008 -#define SF_NONBKTOBKIPG 0x500C -#define SF_COLRETRY 0x5010 -#define SF_MAXLEN 0x5014 -#define SF_TXNIBBLECNT 0x5018 -#define SF_TXBYTECNT 0x501C -#define SF_RETXCNT 0x5020 -#define SF_RANDNUM 0x5024 -#define SF_RANDNUM_MASK 0x5028 -#define SF_TOTALTXCNT 0x5034 -#define SF_RXBYTECNT 0x5040 -#define SF_TXPAUSETIMER 0x5060 -#define SF_VLANTYPE 0x5064 -#define SF_MIISTATUS 0x5070 - -#define SF_MACCFG1_HUGEFRAMES 0x00000001 -#define SF_MACCFG1_FULLDUPLEX 0x00000002 -#define SF_MACCFG1_AUTOPAD 0x00000004 -#define SF_MACCFG1_HDJAM 0x00000008 -#define SF_MACCFG1_DELAYCRC 0x00000010 -#define SF_MACCFG1_NOBACKOFF 0x00000020 -#define SF_MACCFG1_LENGTHCHECK 0x00000040 -#define SF_MACCFG1_PUREPREAMBLE 0x00000080 -#define SF_MACCFG1_PASSALLRX 0x00000100 -#define SF_MACCFG1_PREAM_DETCNT 0x00000200 -#define SF_MACCFG1_RX_FLOWENB 0x00000400 -#define SF_MACCFG1_TX_FLOWENB 0x00000800 -#define SF_MACCFG1_TESTMODE 0x00003000 -#define SF_MACCFG1_MIILOOPBK 0x00004000 -#define SF_MACCFG1_SOFTRESET 0x00008000 - -#define SF_MACCFG2_AUTOVLANPAD 0x00000020 - -/* - * There are the recommended IPG nibble counter settings - * specified in the Adaptec manual for full duplex and - * half duplex operation. - */ -#define SF_IPGT_FDX 0x15 -#define SF_IPGT_HDX 0x11 - -/* - * RX filter registers 0x6000 to 0x6FFF - */ -#define SF_RXFILT_PERFECT_BASE 0x6000 -#define SF_RXFILT_PERFECT_MAX 0x60FF -#define SF_RXFILT_PERFECT_SKIP 0x0010 -#define SF_RXFILT_PERFECT_CNT 0x0010 - -#define SF_RXFILT_HASH_BASE 0x6100 -#define SF_RXFILT_HASH_MAX 0x62FF -#define SF_RXFILT_HASH_SKIP 0x0010 -#define SF_RXFILT_HASH_CNT 0x001F -#define SF_RXFILT_HASH_ADDROFF 0x0000 -#define SF_RXFILT_HASH_PRIOOFF 0x0004 -#define SF_RXFILT_HASH_VLANOFF 0x0008 - -/* - * Statistics registers 0x7000 to 0x7FFF - */ -#define SF_STATS_BASE 0x7000 -#define SF_STATS_END 0x7FFF - -#define SF_STATS_TX_FRAMES 0x0000 -#define SF_STATS_TX_SINGLE_COL 0x0004 -#define SF_STATS_TX_MULTI_COL 0x0008 -#define SF_STATS_TX_CRC_ERRS 0x000C -#define SF_STATS_TX_BYTES 0x0010 -#define SF_STATS_TX_DEFERRED 0x0014 -#define SF_STATS_TX_LATE_COL 0x0018 -#define SF_STATS_TX_PAUSE 0x001C -#define SF_STATS_TX_CTL_FRAME 0x0020 -#define SF_STATS_TX_EXCESS_COL 0x0024 -#define SF_STATS_TX_EXCESS_DEF 0x0028 -#define SF_STATS_TX_MULTI 0x002C -#define SF_STATS_TX_BCAST 0x0030 -#define SF_STATS_TX_FRAME_LOST 0x0034 -#define SF_STATS_RX_FRAMES 0x0038 -#define SF_STATS_RX_CRC_ERRS 0x003C -#define SF_STATS_RX_ALIGN_ERRS 0x0040 -#define SF_STATS_RX_BYTES 0x0044 -#define SF_STATS_RX_PAUSE 0x0048 -#define SF_STATS_RX_CTL_FRAME 0x004C -#define SF_STATS_RX_UNSUP_FRAME 0x0050 -#define SF_STATS_RX_GIANTS 0x0054 -#define SF_STATS_RX_RUNTS 0x0058 -#define SF_STATS_RX_JABBER 0x005C -#define SF_STATS_RX_FRAGMENTS 0x0060 -#define SF_STATS_RX_64 0x0064 -#define SF_STATS_RX_65_127 0x0068 -#define SF_STATS_RX_128_255 0x006C -#define SF_STATS_RX_256_511 0x0070 -#define SF_STATS_RX_512_1023 0x0074 -#define SF_STATS_RX_1024_1518 0x0078 -#define SF_STATS_RX_FRAME_LOST 0x007C -#define SF_STATS_TX_UNDERRUN 0x0080 - -/* - * TX frame processor instruction space 0x8000 to 0x9FFF - */ -#define SF_TXGFP_MEM_BASE 0x8000 -#define SF_TXGFP_MEM_END 0x8FFF - -/* Number of bytes of an GFP instruction. */ -#define SF_GFP_INST_BYTES 6 -/* - * RX frame processor instruction space 0xA000 to 0xBFFF - */ -#define SF_RXGFP_MEM_BASE 0xA000 -#define SF_RXGFP_MEM_END 0xBFFF - -/* - * Ethernet FIFO access space 0xC000 to 0xDFFF - */ - -/* - * Reserved 0xE000 to 0xFFFF - */ - -/* - * Descriptor data structures. - */ - -/* - * RX buffer descriptor type 0, 32-bit addressing. - */ -struct sf_rx_bufdesc_type0 { - uint32_t sf_addrlo; -#define SF_RX_DESC_VALID 0x00000001 -#define SF_RX_DESC_END 0x00000002 -}; - -/* - * RX buffer descriptor type 1, 64-bit addressing. - */ -struct sf_rx_bufdesc_type1 { - uint64_t sf_addr; -}; - -/* - * RX completion descriptor, type 0 (short). - */ -struct sf_rx_cmpdesc_type0 { - uint32_t sf_rx_status1; -#define SF_RX_CMPDESC_LEN 0x0000ffff -#define SF_RX_CMPDESC_EIDX 0x07ff0000 -#define SF_RX_CMPDESC_STAT1 0x38000000 -#define SF_RX_CMPDESC_ID 0x40000000 -}; - -/* - * RX completion descriptor, type 1 (basic). Includes vlan ID - * if this is a vlan-addressed packet, plus extended status. - */ -struct sf_rx_cmpdesc_type1 { - uint32_t sf_rx_status1; - uint32_t sf_rx_status2; -#define SF_RX_CMPDESC_VLAN 0x0000ffff -#define SF_RX_CMPDESC_STAT2 0xffff0000 -}; - -/* - * RX completion descriptor, type 2 (checksum). Includes partial TCP/IP - * checksum instead of vlan tag, plus extended status. - */ -struct sf_rx_cmpdesc_type2 { - uint32_t sf_rx_status1; - uint32_t sf_rx_status2; -#define SF_RX_CMPDESC_CSUM2 0x0000ffff -}; - -/* - * RX completion descriptor type 3 (full). Includes timestamp, partial - * TCP/IP checksum, vlan tag plus priority, two extended status fields. - */ -struct sf_rx_cmpdesc_type3 { - uint32_t sf_rx_status1; - uint32_t sf_rx_status2; - uint32_t sf_rx_status3; -#define SF_RX_CMPDESC_CSUM3 0xffff0000 -#define SF_RX_CMPDESC_VLANPRI 0x0000ffff - uint32_t sf_rx_timestamp; -}; - -#define SF_RXSTAT1_QUEUE 0x08000000 -#define SF_RXSTAT1_FIFOFULL 0x10000000 -#define SF_RXSTAT1_OK 0x20000000 - -#define SF_RXSTAT2_FRAMETYPE_MASK 0x00070000 -#define SF_RXSTAT2_FRAMETYPE_UNKN 0x00000000 -#define SF_RXSTAT2_FRAMETYPE_IPV4 0x00010000 -#define SF_RXSTAT2_FRAMETYPE_IPV6 0x00020000 -#define SF_RXSTAT2_FRAMETYPE_IPX 0x00030000 -#define SF_RXSTAT2_FRAMETYPE_ICMP 0x00040000 -#define SF_RXSTAT2_FRAMETYPE_UNSPRT 0x00050000 -#define SF_RXSTAT2_UDP 0x00080000 -#define SF_RXSTAT2_TCP 0x00100000 -#define SF_RXSTAT2_FRAG 0x00200000 -#define SF_RXSTAT2_PCSUM_OK 0x00400000 /* partial checksum ok */ -#define SF_RXSTAT2_CSUM_BAD 0x00800000 /* TCP/IP checksum bad */ -#define SF_RXSTAT2_CSUM_OK 0x01000000 /* TCP/IP checksum ok */ -#define SF_RXSTAT2_VLAN 0x02000000 -#define SF_RXSTAT2_BADRXCODE 0x04000000 -#define SF_RXSTAT2_DRIBBLE 0x08000000 -#define SF_RXSTAT2_ISL_CRCERR 0x10000000 -#define SF_RXSTAT2_CRCERR 0x20000000 -#define SF_RXSTAT2_HASH 0x40000000 -#define SF_RXSTAT2_PERFECT 0x80000000 -#define SF_RXSTAT2_MASK 0xFFFF0000 - -#define SF_RXSTAT3_ISL 0x00008000 -#define SF_RXSTAT3_PAUSE 0x00004000 -#define SF_RXSTAT3_CONTROL 0x00002000 -#define SF_RXSTAT3_HEADER 0x00001000 -#define SF_RXSTAT3_TRAILER 0x00000800 -#define SF_RXSTAT3_START_IDX_MASK 0x000007FF - -struct sf_frag { - uint32_t sf_addr; - uint16_t sf_fraglen; - uint16_t sf_pktlen; -}; - -struct sf_frag_msdos { - uint16_t sf_pktlen; - uint16_t sf_fraglen; - uint32_t sf_addr; -}; - -/* - * TX frame descriptor type 0, 32-bit addressing. One descriptor can - * be used to map multiple packet fragments. Note that the number of - * fragments can be variable depending on how the descriptor spacing - * is specified in the TX descriptor queue control register. - * We always use a spacing of 128 bytes, and a skipfield length of 8 - * bytes: this means 16 bytes for the descriptor, including the skipfield, - * with 121 bytes left for fragment maps. Each fragment requires 8 bytes, - * which allows for 14 fragments per descriptor. The total size of the - * transmit buffer queue is limited to 16384 bytes, so with a spacing of - * 128 bytes per descriptor, we have room for 128 descriptors in the queue. - */ -struct sf_tx_bufdesc_type0 { - uint32_t sf_tx_ctrl; -#define SF_TX_DESC_CRCEN 0x01000000 -#define SF_TX_DESC_CALTCP 0x02000000 -#define SF_TX_DESC_END 0x04000000 -#define SF_TX_DESC_INTR 0x08000000 -#define SF_TX_DESC_ID 0xb0000000 - uint32_t sf_tx_frag; - /* - * Depending on descriptor spacing/skip field length it - * can have fixed number of struct sf_frag. - * struct sf_frag sf_frags[14]; - */ -}; - -/* - * TX buffer descriptor type 1, 32-bit addressing. Each descriptor - * maps a single fragment. - */ -struct sf_tx_bufdesc_type1 { - uint32_t sf_tx_ctrl; -#define SF_TX_DESC_FRAGLEN 0x0000ffff -#define SF_TX_DESC_FRAGCNT 0x00ff0000 - uint32_t sf_addrlo; -}; - -/* - * TX buffer descriptor type 2, 64-bit addressing. Each descriptor - * maps a single fragment. - */ -struct sf_tx_bufdesc_type2 { - uint32_t sf_tx_ctrl; - uint32_t sf_tx_reserved; - uint64_t sf_addr; -}; - -/* TX buffer descriptor type 3 is not defined. */ - -/* - * TX frame descriptor type 4, 32-bit addressing. This is a special - * case of the type 0 descriptor, identical except that the fragment - * address and length fields are ordered differently. This is done - * to optimize copies in MS-DOS and OS/2 drivers. - */ -struct sf_tx_bufdesc_type4 { - uint32_t sf_tx_ctrl; - uint32_t sf_tx_frag; - /* - * Depending on descriptor spacing/skip field length it - * can have fixed number of struct sf_frag_msdos. - * - * struct sf_frag_msdos sf_frags[14]; - */ -}; - -/* - * Transmit completion queue descriptor formats. - */ - -/* - * Transmit DMA completion descriptor, type 0. - */ -#define SF_TXCMPTYPE_DMA 0x80000000 -#define SF_TXCMPTYPE_TX 0xa0000000 -struct sf_tx_cmpdesc_type0 { - uint32_t sf_tx_status1; -#define SF_TX_CMPDESC_IDX 0x00007fff -#define SF_TX_CMPDESC_HIPRI 0x00008000 -#define SF_TX_CMPDESC_STAT 0x1fff0000 -#define SF_TX_CMPDESC_TYPE 0xe0000000 -}; - -/* - * Transmit completion descriptor, type 1. - */ -struct sf_tx_cmpdesc_type1 { - uint32_t sf_tx_status1; - uint32_t sf_tx_status2; -}; - -#define SF_TXSTAT_CRCERR 0x00010000 -#define SF_TXSTAT_LENCHECKERR 0x00020000 -#define SF_TXSTAT_LENRANGEERR 0x00040000 -#define SF_TXSTAT_TX_OK 0x00080000 -#define SF_TXSTAT_TX_DEFERED 0x00100000 -#define SF_TXSTAT_EXCESS_DEFER 0x00200000 -#define SF_TXSTAT_EXCESS_COLL 0x00400000 -#define SF_TXSTAT_LATE_COLL 0x00800000 -#define SF_TXSTAT_TOOBIG 0x01000000 -#define SF_TXSTAT_TX_UNDERRUN 0x02000000 -#define SF_TXSTAT_CTLFRAME_OK 0x04000000 -#define SF_TXSTAT_PAUSEFRAME_OK 0x08000000 -#define SF_TXSTAT_PAUSED 0x10000000 - -/* Statistics counters. */ -struct sf_stats { - uint64_t sf_tx_frames; - uint32_t sf_tx_single_colls; - uint32_t sf_tx_multi_colls; - uint32_t sf_tx_crcerrs; - uint64_t sf_tx_bytes; - uint32_t sf_tx_deferred; - uint32_t sf_tx_late_colls; - uint32_t sf_tx_pause_frames; - uint32_t sf_tx_control_frames; - uint32_t sf_tx_excess_colls; - uint32_t sf_tx_excess_defer; - uint32_t sf_tx_mcast_frames; - uint32_t sf_tx_bcast_frames; - uint32_t sf_tx_frames_lost; - uint64_t sf_rx_frames; - uint32_t sf_rx_crcerrs; - uint32_t sf_rx_alignerrs; - uint64_t sf_rx_bytes; - uint32_t sf_rx_pause_frames; - uint32_t sf_rx_control_frames; - uint32_t sf_rx_unsup_control_frames; - uint32_t sf_rx_giants; - uint32_t sf_rx_runts; - uint32_t sf_rx_jabbererrs; - uint32_t sf_rx_fragments; - uint64_t sf_rx_pkts_64; - uint64_t sf_rx_pkts_65_127; - uint64_t sf_rx_pkts_128_255; - uint64_t sf_rx_pkts_256_511; - uint64_t sf_rx_pkts_512_1023; - uint64_t sf_rx_pkts_1024_1518; - uint32_t sf_rx_frames_lost; - uint32_t sf_tx_underruns; - uint32_t sf_tx_gfp_stall; - uint32_t sf_rx_gfp_stall; -}; - -/* - * register space access macros - */ -#define CSR_WRITE_4(sc, reg, val) \ - bus_write_4((sc)->sf_res, reg, val) - -#define CSR_READ_4(sc, reg) \ - bus_read_4((sc)->sf_res, reg) - -#define CSR_READ_1(sc, reg) \ - bus_read_1((sc)->sf_res, reg) - - -struct sf_type { - uint16_t sf_vid; - uint16_t sf_did; - char *sf_name; - uint16_t sf_sdid; - char *sf_sname; -}; - -/* Use Tx descriptor type 2 : 64bit buffer descriptor */ -#define sf_tx_rdesc sf_tx_bufdesc_type2 -/* Use Rx descriptor type 1 : 64bit buffer descriptor */ -#define sf_rx_rdesc sf_rx_bufdesc_type1 -/* Use Tx completion type 0 */ -#define sf_tx_rcdesc sf_tx_cmpdesc_type0 -/* Use Rx completion type 2 : checksum */ -#define sf_rx_rcdesc sf_rx_cmpdesc_type2 - -#define SF_TX_DLIST_CNT 256 -#define SF_RX_DLIST_CNT 256 -#define SF_TX_CLIST_CNT 1024 -#define SF_RX_CLIST_CNT 1024 -#define SF_TX_DLIST_SIZE (sizeof(struct sf_tx_rdesc) * SF_TX_DLIST_CNT) -#define SF_TX_CLIST_SIZE (sizeof(struct sf_tx_rcdesc) * SF_TX_CLIST_CNT) -#define SF_RX_DLIST_SIZE (sizeof(struct sf_rx_rdesc) * SF_RX_DLIST_CNT) -#define SF_RX_CLIST_SIZE (sizeof(struct sf_rx_rcdesc) * SF_RX_CLIST_CNT) -#define SF_RING_ALIGN 256 -#define SF_RX_ALIGN sizeof(uint32_t) -#define SF_MAXTXSEGS 16 - -#define SF_ADDR_LO(x) ((uint64_t)(x) & 0xffffffff) -#define SF_ADDR_HI(x) ((uint64_t)(x) >> 32) -#define SF_TX_DLIST_ADDR(sc, i) \ - ((sc)->sf_rdata.sf_tx_ring_paddr + sizeof(struct sf_tx_rdesc) * (i)) -#define SF_TX_CLIST_ADDR(sc, i) \ - ((sc)->sf_rdata.sf_tx_cring_paddr + sizeof(struct sf_tx_crdesc) * (i)) -#define SF_RX_DLIST_ADDR(sc, i) \ - ((sc)->sf_rdata.sf_rx_ring_paddr + sizeof(struct sf_rx_rdesc) * (i)) -#define SF_RX_CLIST_ADDR(sc, i) \ - ((sc)->sf_rdata.sf_rx_cring_paddr + sizeof(struct sf_rx_rcdesc) * (i)) - -#define SF_INC(x, y) (x) = ((x) + 1) % y - -#define SF_MAX_FRAMELEN 1536 -#define SF_TX_THRESHOLD_UNIT 16 -#define SF_MAX_TX_THRESHOLD (SF_MAX_FRAMELEN / SF_TX_THRESHOLD_UNIT) -#define SF_MIN_TX_THRESHOLD (128 / SF_TX_THRESHOLD_UNIT) - -struct sf_txdesc { - struct mbuf *tx_m; - int ndesc; - bus_dmamap_t tx_dmamap; -}; - -struct sf_rxdesc { - struct mbuf *rx_m; - bus_dmamap_t rx_dmamap; -}; - -struct sf_chain_data { - bus_dma_tag_t sf_parent_tag; - bus_dma_tag_t sf_tx_tag; - struct sf_txdesc sf_txdesc[SF_TX_DLIST_CNT]; - bus_dma_tag_t sf_rx_tag; - struct sf_rxdesc sf_rxdesc[SF_RX_DLIST_CNT]; - bus_dma_tag_t sf_tx_ring_tag; - bus_dma_tag_t sf_rx_ring_tag; - bus_dma_tag_t sf_tx_cring_tag; - bus_dma_tag_t sf_rx_cring_tag; - bus_dmamap_t sf_tx_ring_map; - bus_dmamap_t sf_rx_ring_map; - bus_dmamap_t sf_rx_sparemap; - bus_dmamap_t sf_tx_cring_map; - bus_dmamap_t sf_rx_cring_map; - int sf_tx_prod; - int sf_tx_cnt; - int sf_txc_cons; - int sf_rxc_cons; -}; - -struct sf_ring_data { - struct sf_tx_rdesc *sf_tx_ring; - bus_addr_t sf_tx_ring_paddr; - struct sf_tx_rcdesc *sf_tx_cring; - bus_addr_t sf_tx_cring_paddr; - struct sf_rx_rdesc *sf_rx_ring; - bus_addr_t sf_rx_ring_paddr; - struct sf_rx_rcdesc *sf_rx_cring; - bus_addr_t sf_rx_cring_paddr; -}; - - -struct sf_softc { - struct ifnet *sf_ifp; /* interface info */ - device_t sf_dev; /* device info */ - void *sf_intrhand; /* interrupt handler cookie */ - struct resource *sf_irq; /* irq resource descriptor */ - struct resource *sf_res; /* mem/ioport resource */ - int sf_restype; - int sf_rid; - struct sf_type *sf_info; /* Starfire adapter info */ - device_t sf_miibus; - struct sf_chain_data sf_cdata; - struct sf_ring_data sf_rdata; - int sf_if_flags; - struct callout sf_co; - int sf_watchdog_timer; - int sf_link; - int sf_suspended; - int sf_detach; - uint32_t sf_txthresh; - int sf_int_mod; - struct sf_stats sf_statistics; - struct mtx sf_mtx; -#ifdef DEVICE_POLLING - int rxcycles; -#endif /* DEVICE_POLLING */ -}; - - -#define SF_LOCK(_sc) mtx_lock(&(_sc)->sf_mtx) -#define SF_UNLOCK(_sc) mtx_unlock(&(_sc)->sf_mtx) -#define SF_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->sf_mtx, MA_OWNED) - -#define SF_TIMEOUT 1000 diff --git a/sys/dev/sf/starfire_rx.h b/sys/dev/sf/starfire_rx.h deleted file mode 100644 index bc4153c1ab4b..000000000000 --- a/sys/dev/sf/starfire_rx.h +++ /dev/null @@ -1,118 +0,0 @@ -/* $FreeBSD$ */ -/* - * MODULE: GFP_RX.H - * - * (c)2001 Adaptec, Inc. By using this software you agree that it is - * licensed to you "AS IS" and that Adaptec makes no warranties, - * express or implied, regarding the Software. - * Any redistribution of this Software must include this disclaimer and - * copyright notice. - */ - -static unsigned char rxfwdata[624] = -{ - 0x00,0x00,0x01,0x00,0x03,0xdc, - 0x00,0x86,0x04,0x00,0x04,0x21, - 0x18,0x0e,0x80,0x00,0x00,0x15, - 0x66,0x64,0x81,0x00,0x00,0x15, - 0x0b,0x06,0x1a,0x00,0x40,0xab, - 0x00,0x00,0x14,0x20,0x00,0x11, - 0xaa,0xaa,0x14,0x20,0x40,0x22, - 0x03,0x00,0x14,0x20,0x40,0x22, - 0x00,0x00,0x14,0x20,0x40,0x22, - 0x0b,0x14,0x1a,0x00,0x40,0xab, - 0x00,0x00,0x14,0x20,0x00,0x11, - 0x00,0x02,0x83,0x00,0x00,0x15, - 0x00,0x00,0x04,0x00,0x00,0x21, - 0x00,0x00,0x00,0x00,0x00,0x10, - 0x00,0x87,0x04,0x00,0x04,0x21, - 0x00,0x00,0x00,0x00,0x00,0x10, - 0x00,0x00,0x00,0x00,0x00,0x10, - 0x00,0x00,0x00,0x00,0x80,0x15, - 0x00,0x00,0x00,0x00,0x00,0x3e, - 0x00,0x00,0x00,0x00,0x00,0x10, - 0x40,0x00,0x82,0x00,0x00,0x15, - 0x00,0x00,0x00,0x9e,0x80,0x50, - 0x00,0x00,0x03,0x00,0x80,0x15, - 0x00,0x00,0x86,0x00,0x80,0x15, - 0x80,0x00,0x82,0x00,0x00,0x15, - 0x00,0x00,0x01,0x00,0x00,0x1c, - 0x01,0x0c,0x00,0x00,0x50,0xa0, - 0x60,0x08,0x4e,0x20,0xd0,0x11, - 0x40,0x08,0x14,0x20,0xd0,0x12, - 0x70,0x00,0x00,0x00,0xf0,0x90, - 0x30,0x00,0x00,0x00,0xc8,0xb0, - 0x00,0x00,0x00,0x00,0x40,0x40, - 0x00,0x00,0x00,0x10,0x80,0x15, - 0x40,0x00,0x00,0xa2,0xc1,0x50, - 0x00,0x14,0x00,0xa4,0x00,0xb0, - 0x00,0x00,0x00,0x00,0x00,0x20, - 0x25,0x25,0x25,0x00,0x40,0x0d, - 0x31,0x00,0x00,0x04,0x72,0x20, - 0x00,0x00,0x00,0x93,0x40,0x70, - 0x00,0x00,0x00,0x00,0x00,0x20, - 0x01,0x84,0x00,0x92,0x44,0x60, - 0x00,0x00,0x2b,0x20,0xc0,0x11, - 0x05,0x40,0x00,0x00,0xc4,0x20, - 0x42,0x2d,0x36,0x01,0x40,0x18, - 0x00,0x00,0x14,0x20,0x00,0x11, - 0x01,0x83,0x00,0x92,0x44,0x60, - 0x00,0x34,0x32,0x00,0x00,0x1f, - 0x00,0x02,0x02,0xac,0x00,0x15, - 0x00,0x08,0x00,0xa6,0x01,0x10, - 0x00,0x00,0x42,0x20,0x00,0x11, - 0x01,0x03,0x00,0x92,0x40,0x60, - 0x00,0x00,0x00,0x00,0x00,0x1e, - 0x01,0x00,0x00,0x00,0x00,0x20, - 0x00,0x00,0x00,0x00,0x00,0x1e, - 0x00,0x86,0x00,0x92,0x44,0x60, - 0x00,0x00,0x00,0x00,0x40,0x80, - 0x00,0x00,0x00,0x92,0xc0,0x70, - 0x01,0x00,0x00,0x92,0x40,0x60, - 0x50,0x00,0x00,0x00,0xc8,0x90, - 0x00,0x00,0x00,0xa6,0xc1,0x10, - 0x00,0x12,0x00,0xb0,0xc0,0x90, - 0x00,0x00,0x02,0x1c,0x00,0x15, - 0x00,0x34,0x32,0x00,0x00,0x1f, - 0x05,0x10,0x00,0x92,0x44,0x60, - 0x00,0x00,0x44,0x21,0x00,0x11, - 0x00,0x00,0x42,0x00,0x00,0x11, - 0x00,0x40,0x83,0x00,0x00,0x15, - 0x05,0x08,0x00,0x92,0x44,0x60, - 0x45,0x45,0x45,0x01,0x40,0x18, - 0x00,0x00,0x00,0x80,0x80,0x50, - 0x00,0x40,0x83,0x00,0x00,0x15, - 0x00,0x00,0x62,0x20,0x80,0x12, - 0x08,0x00,0x82,0x00,0x00,0x15, - 0x00,0x00,0x15,0x20,0x00,0x11, - 0x00,0x00,0x00,0x00,0x00,0x10, - 0x00,0x00,0x00,0x00,0x00,0x10, - 0x00,0x00,0x00,0x00,0x00,0x10, - 0x00,0x00,0x00,0x00,0x00,0x10, - 0xee,0xa4,0x80,0x00,0x00,0x15, - 0x00,0x5f,0x81,0x00,0x00,0x15, - 0x00,0x00,0x00,0x00,0x00,0x60, - 0x00,0x00,0x00,0x00,0x41,0x20, - 0x40,0x00,0x00,0x00,0x4a,0x00, - 0x01,0x90,0x00,0x92,0x44,0x60, - 0x59,0x56,0x56,0x01,0x40,0x1a, - 0x00,0x00,0x14,0x00,0x00,0x11, - 0x00,0x18,0x00,0x93,0x40,0x50, - 0x00,0x18,0x00,0x93,0x00,0x50, - 0x00,0x2d,0x36,0x01,0x40,0x3a, - 0x00,0x00,0x00,0x06,0x43,0xa9, - 0x01,0x40,0x00,0x00,0xc4,0x20, - 0x59,0x56,0x56,0x01,0x40,0x1a, - 0x00,0x00,0x14,0x00,0x00,0x11, - 0x00,0x00,0x00,0x00,0x00,0x10, - 0x00,0x00,0x00,0x00,0x00,0x10, - 0x00,0x00,0x00,0x06,0x42,0xa9, - 0x01,0x83,0x00,0x02,0x44,0x20, - 0x59,0x56,0x56,0x01,0x40,0x1a, - 0x20,0x00,0x82,0x00,0x00,0x15, - 0x00,0x00,0x15,0x20,0x00,0x11, - 0x00,0x10,0x82,0x00,0x00,0x15, - 0x00,0x00,0x15,0x20,0x00,0x11, - 0x00,0x10,0x82,0x00,0x00,0x15, - 0x00,0x00,0x15,0x20,0x00,0x11 -}; diff --git a/sys/dev/sf/starfire_tx.h b/sys/dev/sf/starfire_tx.h deleted file mode 100644 index 2a4449b19316..000000000000 --- a/sys/dev/sf/starfire_tx.h +++ /dev/null @@ -1,118 +0,0 @@ -/* $FreeBSD$ */ -/* - * MODULE: GFP_TX.H - * - * (c)2001 Adaptec, Inc. By using this software you agree that it is - * licensed to you "AS IS" and that Adaptec makes no warranties, - * express or implied, regarding the Software. - * Any redistribution of this Software must include this disclaimer and - * copyright notice. - */ - -static unsigned char txfwdata[624] = -{ - 0x00,0x00,0x01,0x00,0x03,0xdc, - 0x00,0x86,0x04,0x00,0x04,0x21, - 0x18,0x0e,0x80,0x00,0x00,0x15, - 0x66,0x64,0x81,0x00,0x00,0x15, - 0x0b,0x06,0x1a,0x00,0x40,0xab, - 0x00,0x00,0x14,0x20,0x00,0x11, - 0xaa,0xaa,0x14,0x20,0x40,0x22, - 0x03,0x00,0x14,0x20,0x40,0x22, - 0x00,0x00,0x14,0x20,0x40,0x22, - 0x0b,0x14,0x1a,0x00,0x40,0xab, - 0x00,0x00,0x14,0x20,0x00,0x11, - 0x00,0x02,0x83,0x00,0x00,0x15, - 0x00,0x00,0x04,0x00,0x00,0x21, - 0x00,0x00,0x00,0x00,0x00,0x10, - 0x00,0x0c,0x14,0x20,0x40,0x22, - 0x00,0x87,0x04,0x00,0x04,0x21, - 0x00,0x00,0x00,0x00,0x00,0x10, - 0x00,0x00,0x00,0x00,0x80,0x15, - 0x00,0x00,0x00,0x00,0x00,0x3e, - 0x00,0x00,0x00,0x00,0x00,0x10, - 0x40,0x00,0x82,0x00,0x00,0x15, - 0x00,0x00,0x00,0x9e,0x80,0x50, - 0x00,0x00,0x03,0x00,0x80,0x15, - 0x00,0x00,0x86,0x00,0x80,0x15, - 0x80,0x00,0x82,0x00,0x00,0x15, - 0x00,0x00,0x01,0x00,0x00,0x1c, - 0x01,0x0c,0x00,0x00,0x50,0xa0, - 0x60,0x08,0x4e,0x20,0xd0,0x11, - 0x40,0x08,0x14,0x20,0xd0,0x12, - 0x70,0x00,0x00,0x00,0xf0,0x90, - 0x30,0x00,0x00,0x00,0xc8,0xb0, - 0x00,0x00,0x00,0x00,0x40,0x40, - 0x00,0x00,0x00,0x10,0x80,0x15, - 0x40,0x00,0x00,0xa2,0xc1,0x50, - 0x00,0x14,0x00,0xa4,0x00,0xb0, - 0x00,0x00,0x00,0x00,0x00,0x20, - 0x25,0x25,0x25,0x00,0x40,0x0d, - 0x31,0x00,0x00,0x04,0x72,0x20, - 0x00,0x00,0x00,0x93,0x40,0x70, - 0x00,0x00,0x00,0x00,0x00,0x20, - 0x01,0x84,0x00,0x92,0x44,0x60, - 0x00,0x00,0x2b,0x20,0xc0,0x11, - 0x05,0x40,0x00,0x00,0xc4,0x20, - 0x4b,0x2d,0x36,0x01,0x40,0x18, - 0x00,0x00,0x14,0x20,0x00,0x11, - 0x01,0x83,0x00,0x92,0x44,0x60, - 0x00,0x34,0x32,0x00,0x00,0x1f, - 0x00,0x02,0x02,0xac,0x00,0x15, - 0x00,0x08,0x00,0xa6,0x01,0x10, - 0x00,0x00,0x42,0x20,0x00,0x11, - 0x01,0x03,0x00,0x92,0x40,0x60, - 0x00,0x00,0x00,0x00,0x00,0x1e, - 0x01,0x00,0x00,0x00,0x00,0x20, - 0x00,0x00,0x00,0x00,0x00,0x1e, - 0x00,0x86,0x00,0x92,0x44,0x60, - 0x00,0x00,0x00,0x00,0x40,0x80, - 0x00,0x00,0x00,0x92,0xc0,0x70, - 0x01,0x00,0x00,0x92,0x40,0x60, - 0x50,0x00,0x00,0x00,0xc8,0x90, - 0x00,0x00,0x00,0xa6,0xc1,0x10, - 0x00,0x12,0x00,0xb0,0xc0,0x90, - 0x00,0x00,0x02,0x1c,0x00,0x15, - 0x00,0x34,0x32,0x00,0x00,0x1f, - 0x05,0x10,0x00,0x92,0x44,0x60, - 0x00,0x00,0x45,0x21,0x00,0x11, - 0x00,0x00,0x42,0x00,0x00,0x11, - 0x43,0x43,0x43,0x01,0x40,0x18, - 0x00,0x40,0x83,0x00,0x00,0x15, - 0x05,0x08,0x00,0x92,0x44,0x60, - 0x00,0x00,0x00,0x80,0x80,0x50, - 0x00,0x00,0x62,0x20,0x80,0x12, - 0x08,0x00,0x82,0x00,0x00,0x15, - 0x00,0x00,0x15,0x20,0x00,0x11, - 0x00,0x00,0x00,0x00,0x00,0x10, - 0x00,0x00,0x00,0x00,0x00,0x10, - 0x00,0x00,0x00,0x00,0x00,0x50, - 0x00,0x00,0x00,0x07,0x00,0x50, - 0x42,0x2d,0x36,0x01,0x40,0x18, - 0xee,0xa4,0x80,0x00,0x00,0x15, - 0x00,0x5f,0x81,0x00,0x00,0x15, - 0x00,0x00,0x00,0x00,0x00,0x60, - 0x00,0x00,0x00,0x00,0x41,0x20, - 0x40,0x00,0x00,0x00,0x4a,0x00, - 0x01,0x90,0x00,0x92,0x44,0x60, - 0x59,0x56,0x56,0x01,0x40,0x1a, - 0x00,0x00,0x14,0x00,0x00,0x11, - 0x00,0x18,0x00,0x93,0x40,0x50, - 0x00,0x18,0x00,0x93,0x00,0x50, - 0x00,0x2d,0x36,0x01,0x40,0x3a, - 0x00,0x00,0x00,0x06,0x43,0xa9, - 0x01,0x40,0x00,0x00,0xc4,0x20, - 0x59,0x56,0x56,0x01,0x40,0x1a, - 0x00,0x00,0x14,0x00,0x00,0x11, - 0x00,0x00,0x00,0x00,0x00,0x10, - 0x00,0x00,0x00,0x00,0x00,0x10, - 0x00,0x00,0x00,0x06,0x42,0xa9, - 0x01,0x83,0x00,0x02,0x44,0x20, - 0x59,0x56,0x56,0x01,0x40,0x1a, - 0x20,0x00,0x82,0x00,0x00,0x15, - 0x00,0x00,0x15,0x20,0x00,0x11, - 0x00,0x10,0x82,0x00,0x00,0x15, - 0x00,0x00,0x15,0x20,0x00,0x11, - 0x00,0x10,0x82,0x00,0x00,0x15, - 0x00,0x00,0x15,0x20,0x00,0x11 -}; diff --git a/sys/i386/conf/GENERIC b/sys/i386/conf/GENERIC index 67032785c95f..83e346521e8f 100644 --- a/sys/i386/conf/GENERIC +++ b/sys/i386/conf/GENERIC @@ -255,7 +255,6 @@ device nfe # nVidia nForce MCP on-board Ethernet device nge # NatSemi DP83820 gigabit Ethernet device re # RealTek 8139C+/8169/8169S/8110S device rl # RealTek 8129/8139 -device sf # Adaptec AIC-6915 (``Starfire'') device sge # Silicon Integrated Systems SiS190/191 device sis # Silicon Integrated Systems SiS 900/SiS 7016 device sk # SysKonnect SK-984x & SK-982x gigabit Ethernet diff --git a/sys/modules/Makefile b/sys/modules/Makefile index aa5e5a9c612c..f8cccac8d7a6 100644 --- a/sys/modules/Makefile +++ b/sys/modules/Makefile @@ -325,7 +325,6 @@ SUBDIR= \ sdhci_pci \ sem \ send \ - ${_sf} \ ${_sfxge} \ sge \ ${_sgx} \ @@ -516,7 +515,6 @@ _pfsync= pfsync _bce= bce _fxp= fxp _ispfw= ispfw -_sf= sf _ti= ti _txp= txp diff --git a/sys/modules/sf/Makefile b/sys/modules/sf/Makefile deleted file mode 100644 index 3b5221f273c1..000000000000 --- a/sys/modules/sf/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -# $FreeBSD$ - -.PATH: ${SRCTOP}/sys/dev/sf - -KMOD= if_sf -SRCS= if_sf.c device_if.h bus_if.h pci_if.h -SRCS+= miibus_if.h - -.include <bsd.kmod.mk> diff --git a/sys/sparc64/conf/GENERIC b/sys/sparc64/conf/GENERIC index ed3e92c8ffaa..cf2edb5c7eef 100644 --- a/sys/sparc64/conf/GENERIC +++ b/sys/sparc64/conf/GENERIC @@ -203,7 +203,6 @@ device hme # Sun HME (Happy Meal Ethernet) device nge # NatSemi DP83820 gigabit Ethernet device re # RealTek 8139C+/8169/8169S/8110S device rl # RealTek 8129/8139 -device sf # Adaptec AIC-6915 (``Starfire'') device sis # Silicon Integrated Systems SiS 900/SiS 7016 device sk # SysKonnect SK-984x & SK-982x gigabit Ethernet device ste # Sundance ST201 (D-Link DFE-550TX) |