diff options
author | Brooks Davis <brooks@FreeBSD.org> | 2019-05-17 15:23:34 +0000 |
---|---|---|
committer | Brooks Davis <brooks@FreeBSD.org> | 2019-05-17 15:23:34 +0000 |
commit | 607790d10fdb97d25cdc0bbe9ed6eaae67383ae1 (patch) | |
tree | e7b745359a5dbe0c98b2687ad4c7dd8d75d42952 | |
parent | dd262716a1e0eae81d2232d6d5b3083ed868ff8b (diff) |
FCP-101: Remove pcn(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=347915
-rw-r--r-- | ObsoleteFiles.inc | 2 | ||||
-rw-r--r-- | share/man/man4/Makefile | 2 | ||||
-rw-r--r-- | share/man/man4/pcn.4 | 199 | ||||
-rw-r--r-- | sys/amd64/conf/GENERIC | 1 | ||||
-rw-r--r-- | sys/conf/NOTES | 7 | ||||
-rw-r--r-- | sys/conf/files | 1 | ||||
-rw-r--r-- | sys/dev/pcn/if_pcn.c | 1524 | ||||
-rw-r--r-- | sys/dev/pcn/if_pcnreg.h | 533 | ||||
-rw-r--r-- | sys/i386/conf/GENERIC | 1 | ||||
-rw-r--r-- | sys/modules/Makefile | 1 | ||||
-rw-r--r-- | sys/modules/pcn/Makefile | 9 | ||||
-rw-r--r-- | sys/sparc64/conf/GENERIC | 1 |
12 files changed, 2 insertions, 2279 deletions
diff --git a/ObsoleteFiles.inc b/ObsoleteFiles.inc index 3bc5a9743a89..3e14d903413d 100644 --- a/ObsoleteFiles.inc +++ b/ObsoleteFiles.inc @@ -48,6 +48,8 @@ OLD_FILES+=usr/share/man/man4/if_ed.4 OLD_FILES+=usr/share/man/man4/ep.4 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 # 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 d09526d60a82..798cc67cdd38 100644 --- a/share/man/man4/Makefile +++ b/share/man/man4/Makefile @@ -401,7 +401,6 @@ MAN= aac.4 \ pcib.4 \ pcic.4 \ pcm.4 \ - pcn.4 \ ${_pf.4} \ ${_pflog.4} \ ${_pfsync.4} \ @@ -692,7 +691,6 @@ MLINKS+=ow.4 onewire.4 MLINKS+=pccbb.4 cbb.4 MLINKS+=pcm.4 snd.4 \ pcm.4 sound.4 -MLINKS+=pcn.4 if_pcn.4 MLINKS+=pms.4 pmspcv.4 MLINKS+=ral.4 if_ral.4 MLINKS+=re.4 if_re.4 diff --git a/share/man/man4/pcn.4 b/share/man/man4/pcn.4 deleted file mode 100644 index 2d2281c2059a..000000000000 --- a/share/man/man4/pcn.4 +++ /dev/null @@ -1,199 +0,0 @@ -.\" Copyright (c) Berkeley Software Design, Inc. -.\" Copyright (c) 1997, 1998, 1999, 2000 -.\" Bill Paul <wpaul@osd.bsdi.com>. 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 PCN 4 -.Os -.Sh NAME -.Nm pcn -.Nd "AMD PCnet/PCI Fast Ethernet device 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 pcn" -.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_pcn_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 PCI Ethernet adapters and embedded -controllers based on the AMD PCnet/FAST, PCnet/FAST+, PCnet/FAST III, -PCnet/PRO and PCnet/Home Ethernet controller chips. -Supported NIC's include the Allied Telesyn AT-2700 family. -.Pp -The PCnet/PCI chips include a 100Mbps Ethernet MAC and support -both a serial and MII-compliant transceiver interface. -They use a bus master DMA and a scatter/gather descriptor scheme. -The AMD chips provide a mechanism for zero-copy receive, -providing good performance in server environments. -Receive address filtering is provided using a single perfect filter entry -for the station address and a 64-bit multicast hash table. -.Pp -The -.Nm -driver supports the following media types: -.Bl -tag -width 10baseTXUTP -.It autoselect -Enable autoselection of the media type and options. -The user can manually override -the autoselected mode by adding media options to -.Xr rc.conf 5 . -.It 10baseT/UTP -Set 10Mbps operation. -The -.Xr ifconfig 8 -.Cm mediaopt -option can also be used to select either -.Sq full-duplex -or -.Sq half-duplex -modes. -.It 100baseTX -Set 100Mbps (Fast Ethernet) operation. -The -.Xr ifconfig 8 -.Cm mediaopt -option can also be used to select either -.Sq full-duplex -or -.Sq half-duplex -modes. -.El -.Pp -The -.Nm -driver supports the following media options: -.Bl -tag -width full-duplex -.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 -The -.Nm -driver supports adapters and embedded controllers based on the AMD PCnet/FAST, -PCnet/FAST+, PCnet/FAST III, PCnet/PRO and PCnet/Home Fast Ethernet chips: -.Pp -.Bl -bullet -compact -.It -AMD Am79C971 PCnet-FAST -.It -AMD Am79C972 PCnet-FAST+ -.It -AMD Am79C973/Am79C975 PCnet-FAST III -.It -AMD Am79C976 PCnet-PRO -.It -AMD Am79C978 PCnet-Home -.It -Allied-Telesis LA-PCI -.El -.Sh DIAGNOSTICS -.Bl -diag -.It "pcn%d: couldn't map ports/memory" -A fatal initialization error has occurred. -.It "pcn%d: couldn't map interrupt" -A fatal initialization error has occurred. -.It "pcn%d: watchdog timeout" -The device has stopped responding to the network, or there is a problem with -the network connection (e.g.\& a cable fault). -.It "pcn%d: no memory for rx list" -The driver failed to allocate an mbuf for the receiver ring. -.It "pcn%d: no memory for tx list" -The driver failed to allocate an mbuf for the transmitter ring when -allocating a pad buffer or collapsing an mbuf chain into a cluster. -.It "pcn%d: chip is in D3 power state -- setting to D0" -This message applies only to adapters which support power -management. -Some operating systems place the controller in low power -mode when shutting down, and some PCI BIOSes fail to bring the chip -out of this state before configuring it. -The controller loses all of -its PCI configuration in the D3 state, so if the BIOS does not set -it back to full power mode in time, it will not be able to configure it -correctly. -The driver tries to detect this condition and bring -the adapter back to the D0 (full power) state, but this may not be -enough to return the driver to a fully operational condition. -If -you see this message at boot time and the driver fails to attach -the device as a network interface, you will have to perform a -warm boot to have the device properly configured. -.Pp -Note that this condition only occurs when warm booting from another -operating system. -If you power down your system prior to booting -.Fx , -the card should be configured correctly. -.El -.Sh SEE ALSO -.Xr arp 4 , -.Xr miibus 4 , -.Xr netintro 4 , -.Xr ng_ether 4 , -.Xr ifconfig 8 -.Rs -.%T AMD PCnet/FAST, PCnet/FAST+ and PCnet/Home datasheets -.%U http://www.amd.com -.Re -.Sh HISTORY -The -.Nm -device driver first appeared in -.Fx 4.3 . -.Sh AUTHORS -The -.Nm -driver was written by -.An Bill Paul Aq Mt wpaul@osd.bsdi.com . diff --git a/sys/amd64/conf/GENERIC b/sys/amd64/conf/GENERIC index 5849165cae87..42f67f5aa90f 100644 --- a/sys/amd64/conf/GENERIC +++ b/sys/amd64/conf/GENERIC @@ -271,7 +271,6 @@ device lge # Level 1 LXT1001 gigabit Ethernet device msk # Marvell/SysKonnect Yukon II Gigabit Ethernet device nfe # nVidia nForce MCP on-board Ethernet device nge # NatSemi DP83820 gigabit Ethernet -device pcn # AMD Am79C97x PCI 10/100 (precedence over 'le') device re # RealTek 8139C+/8169/8169S/8110S device rl # RealTek 8129/8139 device sf # Adaptec AIC-6915 (``Starfire'') diff --git a/sys/conf/NOTES b/sys/conf/NOTES index 03cda7c0882d..2bf8bea40938 100644 --- a/sys/conf/NOTES +++ b/sys/conf/NOTES @@ -1965,12 +1965,6 @@ device xmphy # XaQti XMAC II # GigaNIX 1000TA and 1000TPC, the Addtron AEG320T, the Surecom # EP-320G-TX and the Netgear GA622T. # oce: Emulex 10 Gbit adapters (OneConnect Ethernet) -# pcn: Support for PCI fast ethernet adapters based on the AMD Am79c97x -# PCnet-FAST, PCnet-FAST+, PCnet-FAST III, PCnet-PRO and PCnet-Home -# chipsets. These can also be handled by the le(4) driver if the -# pcn(4) driver is left out of the kernel. The le(4) driver does not -# support the additional features like the MII bus and burst mode of -# the PCnet-FAST and greater chipsets though. # ral: Ralink Technology IEEE 802.11 wireless adapter # re: RealTek 8139C+/8169/816xS/811xS/8101E PCI/PCIe Ethernet adapter # rl: Support for PCI fast ethernet adapters based on the RealTek 8129/8139 @@ -2072,7 +2066,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 pcn # AMD Am79C97x PCI 10/100 NICs device sf # Adaptec AIC-6915 (``Starfire'') device sge # Silicon Integrated Systems SiS190/191 device sis # Silicon Integrated Systems SiS 900/SiS 7016 diff --git a/sys/conf/files b/sys/conf/files index 8a2a825b1bf2..5a573611a988 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -2563,7 +2563,6 @@ dev/pci/pci_user.c optional pci dev/pci/pcib_if.m standard dev/pci/pcib_support.c standard dev/pci/vga_pci.c optional pci -dev/pcn/if_pcn.c optional pcn pci dev/pms/freebsd/driver/ini/src/agtiapi.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/sallsdk/spc/sadisc.c optional pmspcv \ diff --git a/sys/dev/pcn/if_pcn.c b/sys/dev/pcn/if_pcn.c deleted file mode 100644 index 87fea8f9fe0b..000000000000 --- a/sys/dev/pcn/if_pcn.c +++ /dev/null @@ -1,1524 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-4-Clause - * - * Copyright (c) 2000 Berkeley Software Design, Inc. - * Copyright (c) 1997, 1998, 1999, 2000 - * Bill Paul <wpaul@osd.bsdi.com>. 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$"); - -/* - * AMD Am79c972 fast ethernet PCI NIC driver. Datasheets are available - * from http://www.amd.com. - * - * The AMD PCnet/PCI controllers are more advanced and functional - * versions of the venerable 7990 LANCE. The PCnet/PCI chips retain - * backwards compatibility with the LANCE and thus can be made - * to work with older LANCE drivers. This is in fact how the - * PCnet/PCI chips were supported in FreeBSD originally. The trouble - * is that the PCnet/PCI devices offer several performance enhancements - * which can't be exploited in LANCE compatibility mode. Chief among - * these enhancements is the ability to perform PCI DMA operations - * using 32-bit addressing (which eliminates the need for ISA - * bounce-buffering), and special receive buffer alignment (which - * allows the receive handler to pass packets to the upper protocol - * layers without copying on both the x86 and alpha platforms). - */ - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/sockio.h> -#include <sys/mbuf.h> -#include <sys/malloc.h> -#include <sys/kernel.h> -#include <sys/module.h> -#include <sys/socket.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/bpf.h> - -#include <vm/vm.h> /* for vtophys */ -#include <vm/pmap.h> /* for vtophys */ -#include <machine/bus.h> -#include <machine/resource.h> -#include <sys/bus.h> -#include <sys/rman.h> - -#include <dev/mii/mii.h> -#include <dev/mii/miivar.h> - -#include <dev/pci/pcireg.h> -#include <dev/pci/pcivar.h> - -#define PCN_USEIOSPACE - -#include <dev/pcn/if_pcnreg.h> - -MODULE_DEPEND(pcn, pci, 1, 1, 1); -MODULE_DEPEND(pcn, ether, 1, 1, 1); -MODULE_DEPEND(pcn, miibus, 1, 1, 1); - -/* "device miibus" required. See GENERIC if you get errors here. */ -#include "miibus_if.h" - -/* - * Various supported device vendors/types and their names. - */ -static const struct pcn_type pcn_devs[] = { - { PCN_VENDORID, PCN_DEVICEID_PCNET, "AMD PCnet/PCI 10/100BaseTX" }, - { PCN_VENDORID, PCN_DEVICEID_HOME, "AMD PCnet/Home HomePNA" }, - { 0, 0, NULL } -}; - -static const struct pcn_chipid { - u_int32_t id; - const char *name; -} pcn_chipid[] = { - { Am79C971, "Am79C971" }, - { Am79C972, "Am79C972" }, - { Am79C973, "Am79C973" }, - { Am79C978, "Am79C978" }, - { Am79C975, "Am79C975" }, - { Am79C976, "Am79C976" }, - { 0, NULL }, -}; - -static const char *pcn_chipid_name(u_int32_t); -static u_int32_t pcn_chip_id(device_t); -static const struct pcn_type *pcn_match(u_int16_t, u_int16_t); - -static u_int32_t pcn_csr_read(struct pcn_softc *, int); -static u_int16_t pcn_csr_read16(struct pcn_softc *, int); -static u_int16_t pcn_bcr_read16(struct pcn_softc *, int); -static void pcn_csr_write(struct pcn_softc *, int, int); -static u_int32_t pcn_bcr_read(struct pcn_softc *, int); -static void pcn_bcr_write(struct pcn_softc *, int, int); - -static int pcn_probe(device_t); -static int pcn_attach(device_t); -static int pcn_detach(device_t); - -static int pcn_newbuf(struct pcn_softc *, int, struct mbuf *); -static int pcn_encap(struct pcn_softc *, struct mbuf *, u_int32_t *); -static void pcn_rxeof(struct pcn_softc *); -static void pcn_txeof(struct pcn_softc *); -static void pcn_intr(void *); -static void pcn_tick(void *); -static void pcn_start(struct ifnet *); -static void pcn_start_locked(struct ifnet *); -static int pcn_ioctl(struct ifnet *, u_long, caddr_t); -static void pcn_init(void *); -static void pcn_init_locked(struct pcn_softc *); -static void pcn_stop(struct pcn_softc *); -static void pcn_watchdog(struct pcn_softc *); -static int pcn_shutdown(device_t); -static int pcn_ifmedia_upd(struct ifnet *); -static void pcn_ifmedia_sts(struct ifnet *, struct ifmediareq *); - -static int pcn_miibus_readreg(device_t, int, int); -static int pcn_miibus_writereg(device_t, int, int, int); -static void pcn_miibus_statchg(device_t); - -static void pcn_setfilt(struct ifnet *); -static void pcn_setmulti(struct pcn_softc *); -static void pcn_reset(struct pcn_softc *); -static int pcn_list_rx_init(struct pcn_softc *); -static int pcn_list_tx_init(struct pcn_softc *); - -#ifdef PCN_USEIOSPACE -#define PCN_RES SYS_RES_IOPORT -#define PCN_RID PCN_PCI_LOIO -#else -#define PCN_RES SYS_RES_MEMORY -#define PCN_RID PCN_PCI_LOMEM -#endif - -static device_method_t pcn_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, pcn_probe), - DEVMETHOD(device_attach, pcn_attach), - DEVMETHOD(device_detach, pcn_detach), - DEVMETHOD(device_shutdown, pcn_shutdown), - - /* MII interface */ - DEVMETHOD(miibus_readreg, pcn_miibus_readreg), - DEVMETHOD(miibus_writereg, pcn_miibus_writereg), - DEVMETHOD(miibus_statchg, pcn_miibus_statchg), - - DEVMETHOD_END -}; - -static driver_t pcn_driver = { - "pcn", - pcn_methods, - sizeof(struct pcn_softc) -}; - -static devclass_t pcn_devclass; - -DRIVER_MODULE(pcn, pci, pcn_driver, pcn_devclass, 0, 0); -MODULE_PNP_INFO("U16:vendor;U16:device", pci, pcn, pcn_devs, - nitems(pcn_devs) - 1); -DRIVER_MODULE(miibus, pcn, miibus_driver, miibus_devclass, 0, 0); - -#define PCN_CSR_SETBIT(sc, reg, x) \ - pcn_csr_write(sc, reg, pcn_csr_read(sc, reg) | (x)) - -#define PCN_CSR_CLRBIT(sc, reg, x) \ - pcn_csr_write(sc, reg, pcn_csr_read(sc, reg) & ~(x)) - -#define PCN_BCR_SETBIT(sc, reg, x) \ - pcn_bcr_write(sc, reg, pcn_bcr_read(sc, reg) | (x)) - -#define PCN_BCR_CLRBIT(sc, reg, x) \ - pcn_bcr_write(sc, reg, pcn_bcr_read(sc, reg) & ~(x)) - -static u_int32_t -pcn_csr_read(sc, reg) - struct pcn_softc *sc; - int reg; -{ - CSR_WRITE_4(sc, PCN_IO32_RAP, reg); - return(CSR_READ_4(sc, PCN_IO32_RDP)); -} - -static u_int16_t -pcn_csr_read16(sc, reg) - struct pcn_softc *sc; - int reg; -{ - CSR_WRITE_2(sc, PCN_IO16_RAP, reg); - return(CSR_READ_2(sc, PCN_IO16_RDP)); -} - -static void -pcn_csr_write(sc, reg, val) - struct pcn_softc *sc; - int reg; - int val; -{ - CSR_WRITE_4(sc, PCN_IO32_RAP, reg); - CSR_WRITE_4(sc, PCN_IO32_RDP, val); - return; -} - -static u_int32_t -pcn_bcr_read(sc, reg) - struct pcn_softc *sc; - int reg; -{ - CSR_WRITE_4(sc, PCN_IO32_RAP, reg); - return(CSR_READ_4(sc, PCN_IO32_BDP)); -} - -static u_int16_t -pcn_bcr_read16(sc, reg) - struct pcn_softc *sc; - int reg; -{ - CSR_WRITE_2(sc, PCN_IO16_RAP, reg); - return(CSR_READ_2(sc, PCN_IO16_BDP)); -} - -static void -pcn_bcr_write(sc, reg, val) - struct pcn_softc *sc; - int reg; - int val; -{ - CSR_WRITE_4(sc, PCN_IO32_RAP, reg); - CSR_WRITE_4(sc, PCN_IO32_BDP, val); - return; -} - -static int -pcn_miibus_readreg(dev, phy, reg) - device_t dev; - int phy, reg; -{ - struct pcn_softc *sc; - int val; - - sc = device_get_softc(dev); - - /* - * At least Am79C971 with DP83840A wedge when isolating the - * external PHY so we can't allow multiple external PHYs. - * There are cards that use Am79C971 with both the internal - * and an external PHY though. - * For internal PHYs it doesn't really matter whether we can - * isolate the remaining internal and the external ones in - * the PHY drivers as the internal PHYs have to be enabled - * individually in PCN_BCR_PHYSEL, PCN_CSR_MODE, etc. - * With Am79C97{3,5,8} we don't support switching beetween - * the internal and external PHYs, yet, so we can't allow - * multiple PHYs with these either. - * Am79C97{2,6} actually only support external PHYs (not - * connectable internal ones respond at the usual addresses, - * which don't hurt if we let them show up on the bus) and - * isolating them works. - */ - if (((sc->pcn_type == Am79C971 && phy != PCN_PHYAD_10BT) || - sc->pcn_type == Am79C973 || sc->pcn_type == Am79C975 || - sc->pcn_type == Am79C978) && sc->pcn_extphyaddr != -1 && - phy != sc->pcn_extphyaddr) - return(0); - - pcn_bcr_write(sc, PCN_BCR_MIIADDR, reg | (phy << 5)); - val = pcn_bcr_read(sc, PCN_BCR_MIIDATA) & 0xFFFF; - if (val == 0xFFFF) - return(0); - - if (((sc->pcn_type == Am79C971 && phy != PCN_PHYAD_10BT) || - sc->pcn_type == Am79C973 || sc->pcn_type == Am79C975 || - sc->pcn_type == Am79C978) && sc->pcn_extphyaddr == -1) - sc->pcn_extphyaddr = phy; - - return(val); -} - -static int -pcn_miibus_writereg(dev, phy, reg, data) - device_t dev; - int phy, reg, data; -{ - struct pcn_softc *sc; - - sc = device_get_softc(dev); - - pcn_bcr_write(sc, PCN_BCR_MIIADDR, reg | (phy << 5)); - pcn_bcr_write(sc, PCN_BCR_MIIDATA, data); - - return(0); -} - -static void -pcn_miibus_statchg(dev) - device_t dev; -{ - struct pcn_softc *sc; - struct mii_data *mii; - - sc = device_get_softc(dev); - mii = device_get_softc(sc->pcn_miibus); - - if ((mii->mii_media_active & IFM_GMASK) == IFM_FDX) { - PCN_BCR_SETBIT(sc, PCN_BCR_DUPLEX, PCN_DUPLEX_FDEN); - } else { - PCN_BCR_CLRBIT(sc, PCN_BCR_DUPLEX, PCN_DUPLEX_FDEN); - } - - return; -} - -static void -pcn_setmulti(sc) - struct pcn_softc *sc; -{ - struct ifnet *ifp; - struct ifmultiaddr *ifma; - u_int32_t h, i; - u_int16_t hashes[4] = { 0, 0, 0, 0 }; - - ifp = sc->pcn_ifp; - - PCN_CSR_SETBIT(sc, PCN_CSR_EXTCTL1, PCN_EXTCTL1_SPND); - - if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) { - for (i = 0; i < 4; i++) - pcn_csr_write(sc, PCN_CSR_MAR0 + i, 0xFFFF); - PCN_CSR_CLRBIT(sc, PCN_CSR_EXTCTL1, PCN_EXTCTL1_SPND); - return; - } - - /* first, zot all the existing hash bits */ - for (i = 0; i < 4; i++) - pcn_csr_write(sc, PCN_CSR_MAR0 + i, 0); - - /* now program new ones */ - if_maddr_rlock(ifp); - CK_STAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { - if (ifma->ifma_addr->sa_family != AF_LINK) - continue; - h = ether_crc32_le(LLADDR((struct sockaddr_dl *) - ifma->ifma_addr), ETHER_ADDR_LEN) >> 26; - hashes[h >> 4] |= 1 << (h & 0xF); - } - if_maddr_runlock(ifp); - - for (i = 0; i < 4; i++) - pcn_csr_write(sc, PCN_CSR_MAR0 + i, hashes[i]); - - PCN_CSR_CLRBIT(sc, PCN_CSR_EXTCTL1, PCN_EXTCTL1_SPND); - - return; -} - -static void -pcn_reset(sc) - struct pcn_softc *sc; -{ - /* - * Issue a reset by reading from the RESET register. - * Note that we don't know if the chip is operating in - * 16-bit or 32-bit mode at this point, so we attempt - * to reset the chip both ways. If one fails, the other - * will succeed. - */ - CSR_READ_2(sc, PCN_IO16_RESET); - CSR_READ_4(sc, PCN_IO32_RESET); - - /* Wait a little while for the chip to get its brains in order. */ - DELAY(1000); - - /* Select 32-bit (DWIO) mode */ - CSR_WRITE_4(sc, PCN_IO32_RDP, 0); - - /* Select software style 3. */ - pcn_bcr_write(sc, PCN_BCR_SSTYLE, PCN_SWSTYLE_PCNETPCI_BURST); - - return; -} - -static const char * -pcn_chipid_name(u_int32_t id) -{ - const struct pcn_chipid *p; - - p = pcn_chipid; - while (p->name) { - if (id == p->id) - return (p->name); - p++; - } - return ("Unknown"); -} - -static u_int32_t -pcn_chip_id(device_t dev) -{ - struct pcn_softc *sc; - u_int32_t chip_id; - - sc = device_get_softc(dev); - /* - * Note: we can *NOT* put the chip into - * 32-bit mode yet. The le(4) driver will only - * work in 16-bit mode, and once the chip - * goes into 32-bit mode, the only way to - * get it out again is with a hardware reset. - * So if pcn_probe() is called before the - * le(4) driver's probe routine, the chip will - * be locked into 32-bit operation and the - * le(4) driver will be unable to attach to it. - * Note II: if the chip happens to already - * be in 32-bit mode, we still need to check - * the chip ID, but first we have to detect - * 32-bit mode using only 16-bit operations. - * The safest way to do this is to read the - * PCI subsystem ID from BCR23/24 and compare - * that with the value read from PCI config - * space. - */ - chip_id = pcn_bcr_read16(sc, PCN_BCR_PCISUBSYSID); - chip_id <<= 16; - chip_id |= pcn_bcr_read16(sc, PCN_BCR_PCISUBVENID); - /* - * Note III: the test for 0x10001000 is a hack to - * pacify VMware, who's pseudo-PCnet interface is - * broken. Reading the subsystem register from PCI - * config space yields 0x00000000 while reading the - * same value from I/O space yields 0x10001000. It's - * not supposed to be that way. - */ - if (chip_id == pci_read_config(dev, - PCIR_SUBVEND_0, 4) || chip_id == 0x10001000) { - /* We're in 16-bit mode. */ - chip_id = pcn_csr_read16(sc, PCN_CSR_CHIPID1); - chip_id <<= 16; - chip_id |= pcn_csr_read16(sc, PCN_CSR_CHIPID0); - } else { - /* We're in 32-bit mode. */ - chip_id = pcn_csr_read(sc, PCN_CSR_CHIPID1); - chip_id <<= 16; - chip_id |= pcn_csr_read(sc, PCN_CSR_CHIPID0); - } - - return (chip_id); -} - -static const struct pcn_type * -pcn_match(u_int16_t vid, u_int16_t did) -{ - const struct pcn_type *t; - - t = pcn_devs; - while (t->pcn_name != NULL) { - if ((vid == t->pcn_vid) && (did == t->pcn_did)) - return (t); - t++; - } - return (NULL); -} - -/* - * Probe for an AMD chip. Check the PCI vendor and device - * IDs against our list and return a device name if we find a match. - */ -static int -pcn_probe(dev) - device_t dev; -{ - const struct pcn_type *t; - struct pcn_softc *sc; - int rid; - u_int32_t chip_id; - - t = pcn_match(pci_get_vendor(dev), pci_get_device(dev)); - if (t == NULL) - return (ENXIO); - sc = device_get_softc(dev); - - /* - * Temporarily map the I/O space so we can read the chip ID register. - */ - rid = PCN_RID; - sc->pcn_res = bus_alloc_resource_any(dev, PCN_RES, &rid, RF_ACTIVE); - if (sc->pcn_res == NULL) { - device_printf(dev, "couldn't map ports/memory\n"); - return(ENXIO); - } - sc->pcn_btag = rman_get_bustag(sc->pcn_res); - sc->pcn_bhandle = rman_get_bushandle(sc->pcn_res); - - chip_id = pcn_chip_id(dev); - - bus_release_resource(dev, PCN_RES, PCN_RID, sc->pcn_res); - - switch((chip_id >> 12) & PART_MASK) { - case Am79C971: - case Am79C972: - case Am79C973: - case Am79C975: - case Am79C976: - case Am79C978: - break; - default: - return(ENXIO); - } - device_set_desc(dev, t->pcn_name); - return(BUS_PROBE_DEFAULT); -} - -/* - * Attach the interface. Allocate softc structures, do ifmedia - * setup and ethernet/BPF attach. - */ -static int -pcn_attach(dev) - device_t dev; -{ - u_int32_t eaddr[2]; - struct pcn_softc *sc; - struct mii_data *mii; - struct mii_softc *miisc; - struct ifnet *ifp; - int error = 0, rid; - - sc = device_get_softc(dev); - - /* Initialize our mutex. */ - mtx_init(&sc->pcn_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK, - MTX_DEF); - /* - * Map control/status registers. - */ - pci_enable_busmaster(dev); - - /* Retrieve the chip ID */ - sc->pcn_type = (pcn_chip_id(dev) >> 12) & PART_MASK; - device_printf(dev, "Chip ID %04x (%s)\n", - sc->pcn_type, pcn_chipid_name(sc->pcn_type)); - - rid = PCN_RID; - sc->pcn_res = bus_alloc_resource_any(dev, PCN_RES, &rid, RF_ACTIVE); - - if (sc->pcn_res == NULL) { - device_printf(dev, "couldn't map ports/memory\n"); - error = ENXIO; - goto fail; - } - - sc->pcn_btag = rman_get_bustag(sc->pcn_res); - sc->pcn_bhandle = rman_get_bushandle(sc->pcn_res); - - /* Allocate interrupt */ - rid = 0; - sc->pcn_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, - RF_SHAREABLE | RF_ACTIVE); - - if (sc->pcn_irq == NULL) { - device_printf(dev, "couldn't map interrupt\n"); - error = ENXIO; - goto fail; - } - - /* Reset the adapter. */ - pcn_reset(sc); - - /* - * Get station address from the EEPROM. - */ - eaddr[0] = CSR_READ_4(sc, PCN_IO32_APROM00); - eaddr[1] = CSR_READ_4(sc, PCN_IO32_APROM01); - - callout_init_mtx(&sc->pcn_stat_callout, &sc->pcn_mtx, 0); - - sc->pcn_ldata = contigmalloc(sizeof(struct pcn_list_data), M_DEVBUF, - M_NOWAIT, 0, 0xffffffff, PAGE_SIZE, 0); - - if (sc->pcn_ldata == NULL) { - device_printf(dev, "no memory for list buffers!\n"); - error = ENXIO; - goto fail; - } - bzero(sc->pcn_ldata, sizeof(struct pcn_list_data)); - - ifp = sc->pcn_ifp = if_alloc(IFT_ETHER); - if (ifp == NULL) { - device_printf(dev, "can not if_alloc()\n"); - error = ENOSPC; - 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 = pcn_ioctl; - ifp->if_start = pcn_start; - ifp->if_init = pcn_init; - ifp->if_snd.ifq_maxlen = PCN_TX_LIST_CNT - 1; - - /* - * Do MII setup. - * See the comment in pcn_miibus_readreg() for why we can't - * universally pass MIIF_NOISOLATE here. - */ - sc->pcn_extphyaddr = -1; - error = mii_attach(dev, &sc->pcn_miibus, ifp, pcn_ifmedia_upd, - pcn_ifmedia_sts, BMSR_DEFCAPMASK, MII_PHY_ANY, MII_OFFSET_ANY, 0); - if (error != 0) { - device_printf(dev, "attaching PHYs failed\n"); - goto fail; - } - /* - * Record the media instances of internal PHYs, which map the - * built-in interfaces to the MII, so we can set the active - * PHY/port based on the currently selected media. - */ - sc->pcn_inst_10bt = -1; - mii = device_get_softc(sc->pcn_miibus); - LIST_FOREACH(miisc, &mii->mii_phys, mii_list) { - switch (miisc->mii_phy) { - case PCN_PHYAD_10BT: - sc->pcn_inst_10bt = miisc->mii_inst; - break; - /* - * XXX deal with the Am79C97{3,5} internal 100baseT - * and the Am79C978 internal HomePNA PHYs. - */ - } - } - - /* - * Call MI attach routine. - */ - ether_ifattach(ifp, (u_int8_t *) eaddr); - - /* Hook interrupt last to avoid having to lock softc */ - error = bus_setup_intr(dev, sc->pcn_irq, INTR_TYPE_NET | INTR_MPSAFE, - NULL, pcn_intr, sc, &sc->pcn_intrhand); - - if (error) { - device_printf(dev, "couldn't set up irq\n"); - ether_ifdetach(ifp); - goto fail; - } - -fail: - if (error) - pcn_detach(dev); - - gone_by_fcp101_dev(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 -pcn_detach(dev) - device_t dev; -{ - struct pcn_softc *sc; - struct ifnet *ifp; - - sc = device_get_softc(dev); - ifp = sc->pcn_ifp; - - KASSERT(mtx_initialized(&sc->pcn_mtx), ("pcn mutex not initialized")); - - /* These should only be active if attach succeeded */ - if (device_is_attached(dev)) { - PCN_LOCK(sc); - pcn_reset(sc); - pcn_stop(sc); - PCN_UNLOCK(sc); - callout_drain(&sc->pcn_stat_callout); - ether_ifdetach(ifp); - } - if (sc->pcn_miibus) - device_delete_child(dev, sc->pcn_miibus); - bus_generic_detach(dev); - - if (sc->pcn_intrhand) - bus_teardown_intr(dev, sc->pcn_irq, sc->pcn_intrhand); - if (sc->pcn_irq) - bus_release_resource(dev, SYS_RES_IRQ, 0, sc->pcn_irq); - if (sc->pcn_res) - bus_release_resource(dev, PCN_RES, PCN_RID, sc->pcn_res); - - if (ifp) - if_free(ifp); - - if (sc->pcn_ldata) { - contigfree(sc->pcn_ldata, sizeof(struct pcn_list_data), - M_DEVBUF); - } - - mtx_destroy(&sc->pcn_mtx); - - return(0); -} - -/* - * Initialize the transmit descriptors. - */ -static int -pcn_list_tx_init(sc) - struct pcn_softc *sc; -{ - struct pcn_list_data *ld; - struct pcn_ring_data *cd; - int i; - - cd = &sc->pcn_cdata; - ld = sc->pcn_ldata; - - for (i = 0; i < PCN_TX_LIST_CNT; i++) { - cd->pcn_tx_chain[i] = NULL; - ld->pcn_tx_list[i].pcn_tbaddr = 0; - ld->pcn_tx_list[i].pcn_txctl = 0; - ld->pcn_tx_list[i].pcn_txstat = 0; - } - - cd->pcn_tx_prod = cd->pcn_tx_cons = cd->pcn_tx_cnt = 0; - - return(0); -} - - -/* - * Initialize the RX descriptors and allocate mbufs for them. - */ -static int -pcn_list_rx_init(sc) - struct pcn_softc *sc; -{ - struct pcn_ring_data *cd; - int i; - - cd = &sc->pcn_cdata; - - for (i = 0; i < PCN_RX_LIST_CNT; i++) { - if (pcn_newbuf(sc, i, NULL) == ENOBUFS) - return(ENOBUFS); - } - - cd->pcn_rx_prod = 0; - - return(0); -} - -/* - * Initialize an RX descriptor and attach an MBUF cluster. - */ -static int -pcn_newbuf(sc, idx, m) - struct pcn_softc *sc; - int idx; - struct mbuf *m; -{ - struct mbuf *m_new = NULL; - struct pcn_rx_desc *c; - - c = &sc->pcn_ldata->pcn_rx_list[idx]; - - if (m == NULL) { - MGETHDR(m_new, M_NOWAIT, MT_DATA); - if (m_new == NULL) - return(ENOBUFS); - - if (!(MCLGET(m_new, M_NOWAIT))) { - m_freem(m_new); - return(ENOBUFS); - } - m_new->m_len = m_new->m_pkthdr.len = MCLBYTES; - } else { - m_new = m; - m_new->m_len = m_new->m_pkthdr.len = MCLBYTES; - m_new->m_data = m_new->m_ext.ext_buf; - } - - m_adj(m_new, ETHER_ALIGN); - - sc->pcn_cdata.pcn_rx_chain[idx] = m_new; - c->pcn_rbaddr = vtophys(mtod(m_new, caddr_t)); - c->pcn_bufsz = (~(PCN_RXLEN) + 1) & PCN_RXLEN_BUFSZ; - c->pcn_bufsz |= PCN_RXLEN_MBO; - c->pcn_rxstat = PCN_RXSTAT_STP|PCN_RXSTAT_ENP|PCN_RXSTAT_OWN; - - return(0); -} - -/* - * A frame has been uploaded: pass the resulting mbuf chain up to - * the higher level protocols. - */ -static void -pcn_rxeof(sc) - struct pcn_softc *sc; -{ - struct mbuf *m; - struct ifnet *ifp; - struct pcn_rx_desc *cur_rx; - int i; - - PCN_LOCK_ASSERT(sc); - - ifp = sc->pcn_ifp; - i = sc->pcn_cdata.pcn_rx_prod; - - while(PCN_OWN_RXDESC(&sc->pcn_ldata->pcn_rx_list[i])) { - cur_rx = &sc->pcn_ldata->pcn_rx_list[i]; - m = sc->pcn_cdata.pcn_rx_chain[i]; - sc->pcn_cdata.pcn_rx_chain[i] = NULL; - - /* - * If an error occurs, update stats, clear the - * status word and leave the mbuf cluster in place: - * it should simply get re-used next time this descriptor - * comes up in the ring. - */ - if (cur_rx->pcn_rxstat & PCN_RXSTAT_ERR) { - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); - pcn_newbuf(sc, i, m); - PCN_INC(i, PCN_RX_LIST_CNT); - continue; - } - - if (pcn_newbuf(sc, i, NULL)) { - /* Ran out of mbufs; recycle this one. */ - pcn_newbuf(sc, i, m); - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); - PCN_INC(i, PCN_RX_LIST_CNT); - continue; - } - - PCN_INC(i, PCN_RX_LIST_CNT); - - /* No errors; receive the packet. */ - if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1); - m->m_len = m->m_pkthdr.len = - cur_rx->pcn_rxlen - ETHER_CRC_LEN; - m->m_pkthdr.rcvif = ifp; - - PCN_UNLOCK(sc); - (*ifp->if_input)(ifp, m); - PCN_LOCK(sc); - } - - sc->pcn_cdata.pcn_rx_prod = i; - - return; -} - -/* - * A frame was downloaded to the chip. It's safe for us to clean up - * the list buffers. - */ - -static void -pcn_txeof(sc) - struct pcn_softc *sc; -{ - struct pcn_tx_desc *cur_tx = NULL; - struct ifnet *ifp; - u_int32_t idx; - - ifp = sc->pcn_ifp; - - /* - * Go through our tx list and free mbufs for those - * frames that have been transmitted. - */ - idx = sc->pcn_cdata.pcn_tx_cons; - while (idx != sc->pcn_cdata.pcn_tx_prod) { - cur_tx = &sc->pcn_ldata->pcn_tx_list[idx]; - - if (!PCN_OWN_TXDESC(cur_tx)) - break; - - if (!(cur_tx->pcn_txctl & PCN_TXCTL_ENP)) { - sc->pcn_cdata.pcn_tx_cnt--; - PCN_INC(idx, PCN_TX_LIST_CNT); - continue; - } - - if (cur_tx->pcn_txctl & PCN_TXCTL_ERR) { - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); - if (cur_tx->pcn_txstat & PCN_TXSTAT_EXDEF) - if_inc_counter(ifp, IFCOUNTER_COLLISIONS, 1); - if (cur_tx->pcn_txstat & PCN_TXSTAT_RTRY) - if_inc_counter(ifp, IFCOUNTER_COLLISIONS, 1); - } - - if_inc_counter(ifp, IFCOUNTER_COLLISIONS, - cur_tx->pcn_txstat & PCN_TXSTAT_TRC); - - if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); - if (sc->pcn_cdata.pcn_tx_chain[idx] != NULL) { - m_freem(sc->pcn_cdata.pcn_tx_chain[idx]); - sc->pcn_cdata.pcn_tx_chain[idx] = NULL; - } - - sc->pcn_cdata.pcn_tx_cnt--; - PCN_INC(idx, PCN_TX_LIST_CNT); - } - - if (idx != sc->pcn_cdata.pcn_tx_cons) { - /* Some buffers have been freed. */ - sc->pcn_cdata.pcn_tx_cons = idx; - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - } - sc->pcn_timer = (sc->pcn_cdata.pcn_tx_cnt == 0) ? 0 : 5; - - return; -} - -static void -pcn_tick(xsc) - void *xsc; -{ - struct pcn_softc *sc; - struct mii_data *mii; - struct ifnet *ifp; - - sc = xsc; - ifp = sc->pcn_ifp; - PCN_LOCK_ASSERT(sc); - - mii = device_get_softc(sc->pcn_miibus); - mii_tick(mii); - - /* link just died */ - if (sc->pcn_link && !(mii->mii_media_status & IFM_ACTIVE)) - sc->pcn_link = 0; - - /* link just came up, restart */ - if (!sc->pcn_link && mii->mii_media_status & IFM_ACTIVE && - IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) { - sc->pcn_link++; - if (ifp->if_snd.ifq_head != NULL) - pcn_start_locked(ifp); - } - - if (sc->pcn_timer > 0 && --sc->pcn_timer == 0) - pcn_watchdog(sc); - callout_reset(&sc->pcn_stat_callout, hz, pcn_tick, sc); - - return; -} - -static void -pcn_intr(arg) - void *arg; -{ - struct pcn_softc *sc; - struct ifnet *ifp; - u_int32_t status; - - sc = arg; - ifp = sc->pcn_ifp; - - PCN_LOCK(sc); - - /* Suppress unwanted interrupts */ - if (!(ifp->if_flags & IFF_UP)) { - pcn_stop(sc); - PCN_UNLOCK(sc); - return; - } - - CSR_WRITE_4(sc, PCN_IO32_RAP, PCN_CSR_CSR); - - while ((status = CSR_READ_4(sc, PCN_IO32_RDP)) & PCN_CSR_INTR) { - CSR_WRITE_4(sc, PCN_IO32_RDP, status); - - if (status & PCN_CSR_RINT) - pcn_rxeof(sc); - - if (status & PCN_CSR_TINT) - pcn_txeof(sc); - - if (status & PCN_CSR_ERR) { - pcn_init_locked(sc); - break; - } - } - - if (ifp->if_snd.ifq_head != NULL) - pcn_start_locked(ifp); - - PCN_UNLOCK(sc); - return; -} - -/* - * Encapsulate an mbuf chain in a descriptor by coupling the mbuf data - * pointers to the fragment pointers. - */ -static int -pcn_encap(sc, m_head, txidx) - struct pcn_softc *sc; - struct mbuf *m_head; - u_int32_t *txidx; -{ - struct pcn_tx_desc *f = NULL; - struct mbuf *m; - int frag, cur, cnt = 0; - - /* - * Start packing the mbufs in this chain into - * the fragment pointers. Stop when we run out - * of fragments or hit the end of the mbuf chain. - */ - m = m_head; - cur = frag = *txidx; - - for (m = m_head; m != NULL; m = m->m_next) { - if (m->m_len == 0) - continue; - - if ((PCN_TX_LIST_CNT - (sc->pcn_cdata.pcn_tx_cnt + cnt)) < 2) - return(ENOBUFS); - f = &sc->pcn_ldata->pcn_tx_list[frag]; - f->pcn_txctl = (~(m->m_len) + 1) & PCN_TXCTL_BUFSZ; - f->pcn_txctl |= PCN_TXCTL_MBO; - f->pcn_tbaddr = vtophys(mtod(m, vm_offset_t)); - if (cnt == 0) - f->pcn_txctl |= PCN_TXCTL_STP; - else - f->pcn_txctl |= PCN_TXCTL_OWN; - cur = frag; - PCN_INC(frag, PCN_TX_LIST_CNT); - cnt++; - } - - if (m != NULL) - return(ENOBUFS); - - sc->pcn_cdata.pcn_tx_chain[cur] = m_head; - sc->pcn_ldata->pcn_tx_list[cur].pcn_txctl |= - PCN_TXCTL_ENP|PCN_TXCTL_ADD_FCS|PCN_TXCTL_MORE_LTINT; - sc->pcn_ldata->pcn_tx_list[*txidx].pcn_txctl |= PCN_TXCTL_OWN; - sc->pcn_cdata.pcn_tx_cnt += cnt; - *txidx = frag; - - return(0); -} - -/* - * Main transmit routine. To avoid having to do mbuf copies, we put pointers - * to the mbuf data regions directly in the transmit lists. We also save a - * copy of the pointers since the transmit list fragment pointers are - * physical addresses. - */ -static void -pcn_start(ifp) - struct ifnet *ifp; -{ - struct pcn_softc *sc; - - sc = ifp->if_softc; - PCN_LOCK(sc); - pcn_start_locked(ifp); - PCN_UNLOCK(sc); -} - -static void -pcn_start_locked(ifp) - struct ifnet *ifp; -{ - struct pcn_softc *sc; - struct mbuf *m_head = NULL; - u_int32_t idx; - - sc = ifp->if_softc; - - PCN_LOCK_ASSERT(sc); - - if (!sc->pcn_link) - return; - - idx = sc->pcn_cdata.pcn_tx_prod; - - if (ifp->if_drv_flags & IFF_DRV_OACTIVE) - return; - - while(sc->pcn_cdata.pcn_tx_chain[idx] == NULL) { - IF_DEQUEUE(&ifp->if_snd, m_head); - if (m_head == NULL) - break; - - if (pcn_encap(sc, m_head, &idx)) { - IF_PREPEND(&ifp->if_snd, m_head); - ifp->if_drv_flags |= IFF_DRV_OACTIVE; - break; - } - - /* - * If there's a BPF listener, bounce a copy of this frame - * to him. - */ - BPF_MTAP(ifp, m_head); - - } - - /* Transmit */ - sc->pcn_cdata.pcn_tx_prod = idx; - pcn_csr_write(sc, PCN_CSR_CSR, PCN_CSR_TX|PCN_CSR_INTEN); - - /* - * Set a timeout in case the chip goes out to lunch. - */ - sc->pcn_timer = 5; - - return; -} - -static void -pcn_setfilt(ifp) - struct ifnet *ifp; -{ - struct pcn_softc *sc; - - sc = ifp->if_softc; - - /* If we want promiscuous mode, set the allframes bit. */ - if (ifp->if_flags & IFF_PROMISC) { - PCN_CSR_SETBIT(sc, PCN_CSR_MODE, PCN_MODE_PROMISC); - } else { - PCN_CSR_CLRBIT(sc, PCN_CSR_MODE, PCN_MODE_PROMISC); - } - - /* Set the capture broadcast bit to capture broadcast frames. */ - if (ifp->if_flags & IFF_BROADCAST) { - PCN_CSR_CLRBIT(sc, PCN_CSR_MODE, PCN_MODE_RXNOBROAD); - } else { - PCN_CSR_SETBIT(sc, PCN_CSR_MODE, PCN_MODE_RXNOBROAD); - } - - return; -} - -static void -pcn_init(xsc) - void *xsc; -{ - struct pcn_softc *sc = xsc; - - PCN_LOCK(sc); - pcn_init_locked(sc); - PCN_UNLOCK(sc); -} - -static void -pcn_init_locked(sc) - struct pcn_softc *sc; -{ - struct ifnet *ifp = sc->pcn_ifp; - struct mii_data *mii = NULL; - struct ifmedia_entry *ife; - - PCN_LOCK_ASSERT(sc); - - /* - * Cancel pending I/O and free all RX/TX buffers. - */ - pcn_stop(sc); - pcn_reset(sc); - - mii = device_get_softc(sc->pcn_miibus); - ife = mii->mii_media.ifm_cur; - - /* Set MAC address */ - pcn_csr_write(sc, PCN_CSR_PAR0, - ((u_int16_t *)IF_LLADDR(sc->pcn_ifp))[0]); - pcn_csr_write(sc, PCN_CSR_PAR1, - ((u_int16_t *)IF_LLADDR(sc->pcn_ifp))[1]); - pcn_csr_write(sc, PCN_CSR_PAR2, - ((u_int16_t *)IF_LLADDR(sc->pcn_ifp))[2]); - - /* Init circular RX list. */ - if (pcn_list_rx_init(sc) == ENOBUFS) { - if_printf(ifp, "initialization failed: no " - "memory for rx buffers\n"); - pcn_stop(sc); - return; - } - - /* - * Init tx descriptors. - */ - pcn_list_tx_init(sc); - - /* Clear PCN_MISC_ASEL so we can set the port via PCN_CSR_MODE. */ - PCN_BCR_CLRBIT(sc, PCN_BCR_MISCCFG, PCN_MISC_ASEL); - - /* - * Set up the port based on the currently selected media. - * For Am79C978 we've to unconditionally set PCN_PORT_MII and - * set the PHY in PCN_BCR_PHYSEL instead. - */ - if (sc->pcn_type != Am79C978 && - IFM_INST(ife->ifm_media) == sc->pcn_inst_10bt) - pcn_csr_write(sc, PCN_CSR_MODE, PCN_PORT_10BASET); - else - pcn_csr_write(sc, PCN_CSR_MODE, PCN_PORT_MII); - - /* Set up RX filter. */ - pcn_setfilt(ifp); - - /* - * Load the multicast filter. - */ - pcn_setmulti(sc); - - /* - * Load the addresses of the RX and TX lists. - */ - pcn_csr_write(sc, PCN_CSR_RXADDR0, - vtophys(&sc->pcn_ldata->pcn_rx_list[0]) & 0xFFFF); - pcn_csr_write(sc, PCN_CSR_RXADDR1, - (vtophys(&sc->pcn_ldata->pcn_rx_list[0]) >> 16) & 0xFFFF); - pcn_csr_write(sc, PCN_CSR_TXADDR0, - vtophys(&sc->pcn_ldata->pcn_tx_list[0]) & 0xFFFF); - pcn_csr_write(sc, PCN_CSR_TXADDR1, - (vtophys(&sc->pcn_ldata->pcn_tx_list[0]) >> 16) & 0xFFFF); - - /* Set the RX and TX ring sizes. */ - pcn_csr_write(sc, PCN_CSR_RXRINGLEN, (~PCN_RX_LIST_CNT) + 1); - pcn_csr_write(sc, PCN_CSR_TXRINGLEN, (~PCN_TX_LIST_CNT) + 1); - - /* We're not using the initialization block. */ - pcn_csr_write(sc, PCN_CSR_IAB1, 0); - - /* Enable fast suspend mode. */ - PCN_CSR_SETBIT(sc, PCN_CSR_EXTCTL2, PCN_EXTCTL2_FASTSPNDE); - - /* - * Enable burst read and write. Also set the no underflow - * bit. This will avoid transmit underruns in certain - * conditions while still providing decent performance. - */ - PCN_BCR_SETBIT(sc, PCN_BCR_BUSCTL, PCN_BUSCTL_NOUFLOW| - PCN_BUSCTL_BREAD|PCN_BUSCTL_BWRITE); - - /* Enable graceful recovery from underflow. */ - PCN_CSR_SETBIT(sc, PCN_CSR_IMR, PCN_IMR_DXSUFLO); - - /* Enable auto-padding of short TX frames. */ - PCN_CSR_SETBIT(sc, PCN_CSR_TFEAT, PCN_TFEAT_PAD_TX); - - /* Disable MII autoneg (we handle this ourselves). */ - PCN_BCR_SETBIT(sc, PCN_BCR_MIICTL, PCN_MIICTL_DANAS); - - if (sc->pcn_type == Am79C978) - /* XXX support other PHYs? */ - pcn_bcr_write(sc, PCN_BCR_PHYSEL, - PCN_PHYSEL_PCNET|PCN_PHY_HOMEPNA); - - /* Enable interrupts and start the controller running. */ - pcn_csr_write(sc, PCN_CSR_CSR, PCN_CSR_INTEN|PCN_CSR_START); - - mii_mediachg(mii); - - ifp->if_drv_flags |= IFF_DRV_RUNNING; - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - - callout_reset(&sc->pcn_stat_callout, hz, pcn_tick, sc); - - return; -} - -/* - * Set media options. - */ -static int -pcn_ifmedia_upd(ifp) - struct ifnet *ifp; -{ - struct pcn_softc *sc; - - sc = ifp->if_softc; - - PCN_LOCK(sc); - - /* - * At least Am79C971 with DP83840A can wedge when switching - * from the internal 10baseT PHY to the external PHY without - * issuing pcn_reset(). For setting the port in PCN_CSR_MODE - * the PCnet chip has to be powered down or stopped anyway - * and although documented otherwise it doesn't take effect - * until the next initialization. - */ - sc->pcn_link = 0; - pcn_stop(sc); - pcn_reset(sc); - pcn_init_locked(sc); - if (ifp->if_snd.ifq_head != NULL) - pcn_start_locked(ifp); - - PCN_UNLOCK(sc); - - return(0); -} - -/* - * Report current media status. - */ -static void -pcn_ifmedia_sts(ifp, ifmr) - struct ifnet *ifp; - struct ifmediareq *ifmr; -{ - struct pcn_softc *sc; - struct mii_data *mii; - - sc = ifp->if_softc; - - mii = device_get_softc(sc->pcn_miibus); - PCN_LOCK(sc); - mii_pollstat(mii); - ifmr->ifm_active = mii->mii_media_active; - ifmr->ifm_status = mii->mii_media_status; - PCN_UNLOCK(sc); - - return; -} - -static int -pcn_ioctl(ifp, command, data) - struct ifnet *ifp; - u_long command; - caddr_t data; -{ - struct pcn_softc *sc = ifp->if_softc; - struct ifreq *ifr = (struct ifreq *) data; - struct mii_data *mii = NULL; - int error = 0; - - switch(command) { - case SIOCSIFFLAGS: - PCN_LOCK(sc); - if (ifp->if_flags & IFF_UP) { - if (ifp->if_drv_flags & IFF_DRV_RUNNING && - ifp->if_flags & IFF_PROMISC && - !(sc->pcn_if_flags & IFF_PROMISC)) { - PCN_CSR_SETBIT(sc, PCN_CSR_EXTCTL1, - PCN_EXTCTL1_SPND); - pcn_setfilt(ifp); - PCN_CSR_CLRBIT(sc, PCN_CSR_EXTCTL1, - PCN_EXTCTL1_SPND); - pcn_csr_write(sc, PCN_CSR_CSR, - PCN_CSR_INTEN|PCN_CSR_START); - } else if (ifp->if_drv_flags & IFF_DRV_RUNNING && - !(ifp->if_flags & IFF_PROMISC) && - sc->pcn_if_flags & IFF_PROMISC) { - PCN_CSR_SETBIT(sc, PCN_CSR_EXTCTL1, - PCN_EXTCTL1_SPND); - pcn_setfilt(ifp); - PCN_CSR_CLRBIT(sc, PCN_CSR_EXTCTL1, - PCN_EXTCTL1_SPND); - pcn_csr_write(sc, PCN_CSR_CSR, - PCN_CSR_INTEN|PCN_CSR_START); - } else if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) - pcn_init_locked(sc); - } else { - if (ifp->if_drv_flags & IFF_DRV_RUNNING) - pcn_stop(sc); - } - sc->pcn_if_flags = ifp->if_flags; - PCN_UNLOCK(sc); - error = 0; - break; - case SIOCADDMULTI: - case SIOCDELMULTI: - PCN_LOCK(sc); - pcn_setmulti(sc); - PCN_UNLOCK(sc); - error = 0; - break; - case SIOCGIFMEDIA: - case SIOCSIFMEDIA: - mii = device_get_softc(sc->pcn_miibus); - error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, command); - break; - default: - error = ether_ioctl(ifp, command, data); - break; - } - - return(error); -} - -static void -pcn_watchdog(struct pcn_softc *sc) -{ - struct ifnet *ifp; - - PCN_LOCK_ASSERT(sc); - ifp = sc->pcn_ifp; - - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); - if_printf(ifp, "watchdog timeout\n"); - - pcn_stop(sc); - pcn_reset(sc); - pcn_init_locked(sc); - - if (ifp->if_snd.ifq_head != NULL) - pcn_start_locked(ifp); -} - -/* - * Stop the adapter and free any mbufs allocated to the - * RX and TX lists. - */ -static void -pcn_stop(struct pcn_softc *sc) -{ - int i; - struct ifnet *ifp; - - PCN_LOCK_ASSERT(sc); - ifp = sc->pcn_ifp; - sc->pcn_timer = 0; - - callout_stop(&sc->pcn_stat_callout); - - /* Turn off interrupts */ - PCN_CSR_CLRBIT(sc, PCN_CSR_CSR, PCN_CSR_INTEN); - /* Stop adapter */ - PCN_CSR_SETBIT(sc, PCN_CSR_CSR, PCN_CSR_STOP); - sc->pcn_link = 0; - - /* - * Free data in the RX lists. - */ - for (i = 0; i < PCN_RX_LIST_CNT; i++) { - if (sc->pcn_cdata.pcn_rx_chain[i] != NULL) { - m_freem(sc->pcn_cdata.pcn_rx_chain[i]); - sc->pcn_cdata.pcn_rx_chain[i] = NULL; - } - } - bzero((char *)&sc->pcn_ldata->pcn_rx_list, - sizeof(sc->pcn_ldata->pcn_rx_list)); - - /* - * Free the TX list buffers. - */ - for (i = 0; i < PCN_TX_LIST_CNT; i++) { - if (sc->pcn_cdata.pcn_tx_chain[i] != NULL) { - m_freem(sc->pcn_cdata.pcn_tx_chain[i]); - sc->pcn_cdata.pcn_tx_chain[i] = NULL; - } - } - - bzero((char *)&sc->pcn_ldata->pcn_tx_list, - sizeof(sc->pcn_ldata->pcn_tx_list)); - - ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); - - return; -} - -/* - * Stop all chip I/O so that the kernel's probe routines don't - * get confused by errant DMAs when rebooting. - */ -static int -pcn_shutdown(device_t dev) -{ - struct pcn_softc *sc; - - sc = device_get_softc(dev); - - PCN_LOCK(sc); - pcn_reset(sc); - pcn_stop(sc); - PCN_UNLOCK(sc); - - return 0; -} diff --git a/sys/dev/pcn/if_pcnreg.h b/sys/dev/pcn/if_pcnreg.h deleted file mode 100644 index 95cf0ec8f847..000000000000 --- a/sys/dev/pcn/if_pcnreg.h +++ /dev/null @@ -1,533 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-4-Clause - * - * Copyright (c) 2000 Berkeley Software Design, Inc. - * Copyright (c) 1997, 1998, 1999, 2000 - * Bill Paul <wpaul@ee.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$ - */ - -/* - * I/O map in 16-bit mode. To switch to 32-bit mode, - * you need to perform a 32-bit write to the RDP register - * (writing a 0 is recommended). - */ -#define PCN_IO16_APROM00 0x00 -#define PCN_IO16_APROM01 0x02 -#define PCN_IO16_APROM02 0x04 -#define PCN_IO16_APROM03 0x06 -#define PCN_IO16_APROM04 0x08 -#define PCN_IO16_APROM05 0x0A -#define PCN_IO16_APROM06 0x0C -#define PCN_IO16_APROM07 0x0E -#define PCN_IO16_RDP 0x10 -#define PCN_IO16_RAP 0x12 -#define PCN_IO16_RESET 0x14 -#define PCN_IO16_BDP 0x16 - -/* - * I/O map in 32-bit mode. - */ -#define PCN_IO32_APROM00 0x00 -#define PCN_IO32_APROM01 0x04 -#define PCN_IO32_APROM02 0x08 -#define PCN_IO32_APROM03 0x0C -#define PCN_IO32_RDP 0x10 -#define PCN_IO32_RAP 0x14 -#define PCN_IO32_RESET 0x18 -#define PCN_IO32_BDP 0x1C - -/* - * CSR registers - */ -#define PCN_CSR_CSR 0x00 -#define PCN_CSR_IAB0 0x01 -#define PCN_CSR_IAB1 0x02 -#define PCN_CSR_IMR 0x03 -#define PCN_CSR_TFEAT 0x04 -#define PCN_CSR_EXTCTL1 0x05 -#define PCN_CSR_DTBLLEN 0x06 -#define PCN_CSR_EXTCTL2 0x07 -#define PCN_CSR_MAR0 0x08 -#define PCN_CSR_MAR1 0x09 -#define PCN_CSR_MAR2 0x0A -#define PCN_CSR_MAR3 0x0B -#define PCN_CSR_PAR0 0x0C -#define PCN_CSR_PAR1 0x0D -#define PCN_CSR_PAR2 0x0E -#define PCN_CSR_MODE 0x0F -#define PCN_CSR_RXADDR0 0x18 -#define PCN_CSR_RXADDR1 0x19 -#define PCN_CSR_TXADDR0 0x1E -#define PCN_CSR_TXADDR1 0x1F -#define PCN_CSR_TXPOLL 0x2F -#define PCN_CSR_RXPOLL 0x31 -#define PCN_CSR_RXRINGLEN 0x4C -#define PCN_CSR_TXRINGLEN 0x4E -#define PCN_CSR_DMACTL 0x50 -#define PCN_CSR_BUSTIMER 0x52 -#define PCN_CSR_MEMERRTIMEO 0x64 -#define PCN_CSR_ONNOWMISC 0x74 -#define PCN_CSR_ADVFEAT 0x7A -#define PCN_CSR_MACCFG 0x7D -#define PCN_CSR_CHIPID0 0x58 -#define PCN_CSR_CHIPID1 0x59 - -/* - * Control and status register (CSR0) - */ -#define PCN_CSR_INIT 0x0001 -#define PCN_CSR_START 0x0002 -#define PCN_CSR_STOP 0x0004 -#define PCN_CSR_TX 0x0008 -#define PCN_CSR_TXON 0x0010 -#define PCN_CSR_RXON 0x0020 -#define PCN_CSR_INTEN 0x0040 -#define PCN_CSR_INTR 0x0080 -#define PCN_CSR_IDONE 0x0100 -#define PCN_CSR_TINT 0x0200 -#define PCN_CSR_RINT 0x0400 -#define PCN_CSR_MERR 0x0800 -#define PCN_CSR_MISS 0x1000 -#define PCN_CSR_CERR 0x2000 -#define PCN_CSR_ERR 0x8000 - -/* - * Interrupt masks and deferral control (CSR3) - */ -#define PCN_IMR_BSWAP 0x0004 -#define PCN_IMR_ENMBA 0x0008 /* enable modified backoff alg */ -#define PCN_IMR_DXMT2PD 0x0010 -#define PCN_IMR_LAPPEN 0x0020 /* lookahead packet processing enb */ -#define PCN_IMR_DXSUFLO 0x0040 /* disable TX stop on underflow */ -#define PCN_IMR_IDONE 0x0100 -#define PCN_IMR_TINT 0x0200 -#define PCN_IMR_RINT 0x0400 -#define PCN_IMR_MERR 0x0800 -#define PCN_IMR_MISS 0x1000 - -/* - * Test and features control (CSR4) - */ -#define PCN_TFEAT_TXSTRTMASK 0x0004 -#define PCN_TFEAT_TXSTRT 0x0008 -#define PCN_TFEAT_RXCCOFLOWM 0x0010 /* Rx collision counter oflow */ -#define PCN_TFEAT_RXCCOFLOW 0x0020 -#define PCN_TFEAT_UINT 0x0040 -#define PCN_TFEAT_UINTREQ 0x0080 -#define PCN_TFEAT_MISSOFLOWM 0x0100 -#define PCN_TFEAT_MISSOFLOW 0x0200 -#define PCN_TFEAT_STRIP_FCS 0x0400 -#define PCN_TFEAT_PAD_TX 0x0800 -#define PCN_TFEAT_TXDPOLL 0x1000 -#define PCN_TFEAT_DMAPLUS 0x4000 - -/* - * Extended control and interrupt 1 (CSR5) - */ -#define PCN_EXTCTL1_SPND 0x0001 /* suspend */ -#define PCN_EXTCTL1_MPMODE 0x0002 /* magic packet mode */ -#define PCN_EXTCTL1_MPENB 0x0004 /* magic packet enable */ -#define PCN_EXTCTL1_MPINTEN 0x0008 /* magic packet interrupt enable */ -#define PCN_EXTCTL1_MPINT 0x0010 /* magic packet interrupt */ -#define PCN_EXTCTL1_MPPLBA 0x0020 /* magic packet phys. logical bcast */ -#define PCN_EXTCTL1_EXDEFEN 0x0040 /* excessive deferral interrupt enb. */ -#define PCN_EXTCTL1_EXDEF 0x0080 /* excessive deferral interrupt */ -#define PCN_EXTCTL1_SINTEN 0x0400 /* system interrupt enable */ -#define PCN_EXTCTL1_SINT 0x0800 /* system interrupt */ -#define PCN_EXTCTL1_LTINTEN 0x4000 /* last TX interrupt enb */ -#define PCN_EXTCTL1_TXOKINTD 0x8000 /* TX OK interrupt disable */ - -/* - * RX/TX descriptor len (CSR6) - */ -#define PCN_DTBLLEN_RLEN 0x0F00 -#define PCN_DTBLLEN_TLEN 0xF000 - -/* - * Extended control and interrupt 2 (CSR7) - */ -#define PCN_EXTCTL2_MIIPDTINTE 0x0001 -#define PCN_EXTCTL2_MIIPDTINT 0x0002 -#define PCN_EXTCTL2_MCCIINTE 0x0004 -#define PCN_EXTCTL2_MCCIINT 0x0008 -#define PCN_EXTCTL2_MCCINTE 0x0010 -#define PCN_EXTCTL2_MCCINT 0x0020 -#define PCN_EXTCTL2_MAPINTE 0x0040 -#define PCN_EXTCTL2_MAPINT 0x0080 -#define PCN_EXTCTL2_MREINTE 0x0100 -#define PCN_EXTCTL2_MREINT 0x0200 -#define PCN_EXTCTL2_STINTE 0x0400 -#define PCN_EXTCTL2_STINT 0x0800 -#define PCN_EXTCTL2_RXDPOLL 0x1000 -#define PCN_EXTCTL2_RDMD 0x2000 -#define PCN_EXTCTL2_RXFRTG 0x4000 -#define PCN_EXTCTL2_FASTSPNDE 0x8000 - - -/* - * Mode (CSR15) - */ -#define PCN_MODE_RXD 0x0001 /* RX disable */ -#define PCN_MODE_TXD 0x0002 /* TX disable */ -#define PCN_MODE_LOOP 0x0004 /* loopback enable */ -#define PCN_MODE_TXCRCD 0x0008 -#define PCN_MODE_FORCECOLL 0x0010 -#define PCN_MODE_RETRYD 0x0020 -#define PCN_MODE_INTLOOP 0x0040 -#define PCN_MODE_PORTSEL 0x0180 -#define PCN_MODE_RXVPAD 0x2000 -#define PCN_MODE_RXNOBROAD 0x4000 -#define PCN_MODE_PROMISC 0x8000 - -/* Settings for PCN_MODE_PORTSEL when ASEL (BCR2[1]) is 0 */ -#define PCN_PORT_AUI 0x0000 -#define PCN_PORT_10BASET 0x0080 -#define PCN_PORT_GPSI 0x0100 -#define PCN_PORT_MII 0x0180 - -/* - * Chip ID values. - */ -/* CSR88-89: Chip ID masks */ -#define AMD_MASK 0x003 -#define PART_MASK 0xffff -#define Am79C971 0x2623 -#define Am79C972 0x2624 -#define Am79C973 0x2625 -#define Am79C978 0x2626 -#define Am79C975 0x2627 -#define Am79C976 0x2628 - -/* - * Advanced feature control (CSR122) - */ -#define PCN_AFC_RXALIGN 0x0001 - -/* - * BCR (bus control) registers - */ -#define PCN_BCR_MMRA 0x00 /* Master Mode Read Active */ -#define PCN_BCR_MMW 0x01 /* Master Mode Write Active */ -#define PCN_BCR_MISCCFG 0x02 -#define PCN_BCR_LED0 0x04 -#define PCN_BCR_LED1 0x05 -#define PCN_BCR_LED2 0x06 -#define PCN_BCR_LED3 0x07 -#define PCN_BCR_DUPLEX 0x09 -#define PCN_BCR_BUSCTL 0x12 -#define PCN_BCR_EECTL 0x13 -#define PCN_BCR_SSTYLE 0x14 -#define PCN_BCR_PCILAT 0x16 -#define PCN_BCR_PCISUBVENID 0x17 -#define PCN_BCR_PCISUBSYSID 0x18 -#define PCN_BCR_SRAMSIZE 0x19 -#define PCN_BCR_SRAMBOUND 0x1A -#define PCN_BCR_SRAMCTL 0x1B -#define PCN_BCR_MIICTL 0x20 -#define PCN_BCR_MIIADDR 0x21 -#define PCN_BCR_MIIDATA 0x22 -#define PCN_BCR_PCIVENID 0x23 -#define PCN_BCR_PCIPCAP 0x24 -#define PCN_BCR_DATA0 0x25 -#define PCN_BCR_DATA1 0x26 -#define PCN_BCR_DATA2 0x27 -#define PCN_BCR_DATA3 0x28 -#define PCN_BCR_DATA4 0x29 -#define PCN_BCR_DATA5 0x2A -#define PCN_BCR_DATA6 0x2B -#define PCN_BCR_DATA7 0x2C -#define PCN_BCR_ONNOWPAT0 0x2D -#define PCN_BCR_ONNOWPAT1 0x2E -#define PCN_BCR_ONNOWPAT2 0x2F -#define PCN_BCR_PHYSEL 0x31 - -/* - * Miscellaneous Configuration (BCR2) - */ -#define PCN_MISC_TMAULOOP 1<<14 /* T-MAU Loopback packet enable. */ -#define PCN_MISC_LEDPE 1<<12 /* LED Program Enable */ -#define PCN_MISC_APROMWE 1<<8 /* Address PROM Write Enable */ -#define PCN_MISC_INTLEVEL 1<<7 /* Interrupt level */ -#define PCN_MISC_EADISEL 1<<3 /* EADI Select */ -#define PCN_MISC_AWAKE 1<<2 /* Power saving mode select */ -#define PCN_MISC_ASEL 1<<1 /* Auto Select */ -#define PCN_MISC_XMAUSEL 1<<0 /* Reserved. */ - -/* - * Full duplex control (BCR9) - */ -#define PCN_DUPLEX_FDEN 0x0001 /* Full-duplex enable */ -#define PCN_DUPLEX_AUI 0x0002 /* AUI full-duplex */ -#define PCN_DUPLEX_FDRPAD 0x0004 /* Full-duplex runt pkt accept dis. */ - -/* - * Burst and bus control register (BCR18) - */ -#define PCN_BUSCTL_BWRITE 0x0020 -#define PCN_BUSCTL_BREAD 0x0040 -#define PCN_BUSCTL_DWIO 0x0080 -#define PCN_BUSCTL_EXTREQ 0x0100 -#define PCN_BUSCTL_MEMCMD 0x0200 -#define PCN_BUSCTL_NOUFLOW 0x0800 -#define PCN_BUSCTL_ROMTMG 0xF000 - -/* - * EEPROM control (BCR19) - */ -#define PCN_EECTL_EDATA 0x0001 -#define PCN_EECTL_ECLK 0x0002 -#define PCN_EECTL_EECS 0x0004 -#define PCN_EECTL_EEN 0x0100 -#define PCN_EECTL_EEDET 0x2000 -#define PCN_EECTL_PREAD 0x4000 -#define PCN_EECTL_PVALID 0x8000 - -/* - * Software style (BCR20) - */ -#define PCN_SSTYLE_APERREN 0x0400 /* advanced parity error checking */ -#define PCN_SSTYLE_SSIZE32 0x0100 -#define PCN_SSTYLE_SWSTYLE 0x00FF - -#define PCN_SWSTYLE_LANCE 0x0000 -#define PCN_SWSTYLE_PCNETPCI 0x0102 -#define PCN_SWSTYLE_PCNETPCI_BURST 0x0103 - -/* - * MII control and status (BCR32) - */ -#define PCN_MIICTL_MIILP 0x0002 /* MII internal loopback */ -#define PCN_MIICTL_XPHYSP 0x0008 /* external PHY speed */ -#define PCN_MIICTL_XPHYFD 0x0010 /* external PHY full duplex */ -#define PCN_MIICTL_XPHYANE 0x0020 /* external phy auto-neg enable */ -#define PCN_MIICTL_XPHYRST 0x0040 /* external PHY reset */ -#define PCN_MIICTL_DANAS 0x0080 /* disable auto-neg auto-setup */ -#define PCN_MIICTL_APDW 0x0700 /* auto-poll dwell time */ -#define PCN_MIICTL_APEP 0x0100 /* auto-poll external PHY */ -#define PCN_MIICTL_FMDC 0x3000 /* data clock speed */ -#define PCN_MIICTL_MIIPD 0x4000 /* PHY detect */ -#define PCN_MIICTL_ANTST 0x8000 /* Manufacturing test */ - -/* - * MII address register (BCR33) - */ -#define PCN_MIIADDR_REGAD 0x001F -#define PCN_MIIADDR_PHYAD 0x03E0 - -/* addresses of internal PHYs */ -#define PCN_PHYAD_100BTX 30 -#define PCN_PHYAD_10BT 31 - -/* - * MII data register (BCR34) - */ -#define PCN_MIIDATA_MIIMD 0xFFFF - -/* - * PHY selection (BCR49) (HomePNA NIC only) - */ -#define PCN_PHYSEL_PHYSEL 0x0003 -#define PCN_PHYSEL_DEFAULT 0x0300 -#define PCN_PHYSEL_PCNET 0x8000 - -#define PCN_PHY_10BT 0x0000 -#define PCN_PHY_HOMEPNA 0x0001 -#define PCN_PHY_EXTERNAL 0x0002 - -struct pcn_rx_desc { - u_int16_t pcn_rxlen; - u_int16_t pcn_rsvd0; - u_int16_t pcn_bufsz; - u_int16_t pcn_rxstat; - u_int32_t pcn_rbaddr; - u_int32_t pcn_uspace; -}; - -#define PCN_RXSTAT_BPE 0x0080 /* bus parity error */ -#define PCN_RXSTAT_ENP 0x0100 /* end of packet */ -#define PCN_RXSTAT_STP 0x0200 /* start of packet */ -#define PCN_RXSTAT_BUFF 0x0400 /* buffer error */ -#define PCN_RXSTAT_CRC 0x0800 /* CRC error */ -#define PCN_RXSTAT_OFLOW 0x1000 /* rx overrun */ -#define PCN_RXSTAT_FRAM 0x2000 /* framing error */ -#define PCN_RXSTAT_ERR 0x4000 /* error summary */ -#define PCN_RXSTAT_OWN 0x8000 - -#define PCN_RXLEN_MBO 0xF000 -#define PCN_RXLEN_BUFSZ 0x0FFF - -#define PCN_OWN_RXDESC(x) (((x)->pcn_rxstat & PCN_RXSTAT_OWN) == 0) - -struct pcn_tx_desc { - u_int32_t pcn_txstat; - u_int32_t pcn_txctl; - u_int32_t pcn_tbaddr; - u_int32_t pcn_uspace; -}; - -#define PCN_TXSTAT_TRC 0x0000000F /* transmit retries */ -#define PCN_TXSTAT_RTRY 0x04000000 /* retry */ -#define PCN_TXSTAT_LCAR 0x08000000 /* lost carrier */ -#define PCN_TXSTAT_LCOL 0x10000000 /* late collision */ -#define PCN_TXSTAT_EXDEF 0x20000000 /* excessive deferrals */ -#define PCN_TXSTAT_UFLOW 0x40000000 /* transmit underrun */ -#define PCN_TXSTAT_BUFF 0x80000000 /* buffer error */ - -#define PCN_TXCTL_OWN 0x80000000 -#define PCN_TXCTL_ERR 0x40000000 /* error summary */ -#define PCN_TXCTL_ADD_FCS 0x20000000 /* add FCS to pkt */ -#define PCN_TXCTL_MORE_LTINT 0x10000000 -#define PCN_TXCTL_ONE 0x08000000 -#define PCN_TXCTL_DEF 0x04000000 -#define PCN_TXCTL_STP 0x02000000 -#define PCN_TXCTL_ENP 0x01000000 -#define PCN_TXCTL_BPE 0x00800000 -#define PCN_TXCTL_MBO 0x0000F000 -#define PCN_TXCTL_BUFSZ 0x00000FFF - -#define PCN_OWN_TXDESC(x) (((x)->pcn_txctl & PCN_TXCTL_OWN) == 0) - -#define PCN_RX_LIST_CNT 64 -#define PCN_TX_LIST_CNT 256 - -struct pcn_list_data { - struct pcn_rx_desc pcn_rx_list[PCN_RX_LIST_CNT]; - struct pcn_tx_desc pcn_tx_list[PCN_TX_LIST_CNT]; -}; - -struct pcn_ring_data { - struct mbuf *pcn_rx_chain[PCN_RX_LIST_CNT]; - struct mbuf *pcn_tx_chain[PCN_TX_LIST_CNT]; - int pcn_rx_prod; - int pcn_tx_prod; - int pcn_tx_cons; - int pcn_tx_cnt; -}; - -/* - * AMD PCI vendor ID. - */ -#define PCN_VENDORID 0x1022 - -/* - * AMD PCnet/PCI device IDs - */ -#define PCN_DEVICEID_PCNET 0x2000 -#define PCN_DEVICEID_HOME 0x2001 - -struct pcn_type { - u_int16_t pcn_vid; - u_int16_t pcn_did; - const char *pcn_name; -}; - -struct pcn_softc { - struct ifnet *pcn_ifp; - bus_space_handle_t pcn_bhandle; - bus_space_tag_t pcn_btag; - struct resource *pcn_res; - struct resource *pcn_irq; - void *pcn_intrhand; - device_t pcn_miibus; - u_int8_t pcn_link; - int8_t pcn_extphyaddr; - int8_t pcn_inst_10bt; - int pcn_if_flags; - int pcn_type; - struct pcn_list_data *pcn_ldata; - struct pcn_ring_data pcn_cdata; - struct callout pcn_stat_callout; - struct mtx pcn_mtx; - int pcn_timer; -}; - -#define PCN_LOCK(_sc) mtx_lock(&(_sc)->pcn_mtx) -#define PCN_UNLOCK(_sc) mtx_unlock(&(_sc)->pcn_mtx) -#define PCN_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->pcn_mtx, MA_OWNED) - -/* - * register space access macros - */ -#define CSR_WRITE_4(sc, reg, val) \ - bus_space_write_4(sc->pcn_btag, sc->pcn_bhandle, reg, val) - -#define CSR_READ_4(sc, reg) \ - bus_space_read_4(sc->pcn_btag, sc->pcn_bhandle, reg) - -#define CSR_WRITE_2(sc, reg, val) \ - bus_space_write_2(sc->pcn_btag, sc->pcn_bhandle, reg, val) - -#define CSR_READ_2(sc, reg) \ - bus_space_read_2(sc->pcn_btag, sc->pcn_bhandle, reg) - -#define PCN_TIMEOUT 1000 -#define ETHER_ALIGN 2 -#define PCN_RXLEN 1536 -#define PCN_MIN_FRAMELEN 60 -#define PCN_INC(x, y) (x) = (x + 1) % y -/* - * PCI low memory base and low I/O base register, and - * other PCI registers. - */ - -#define PCN_PCI_VENDOR_ID 0x00 -#define PCN_PCI_DEVICE_ID 0x02 -#define PCN_PCI_COMMAND 0x04 -#define PCN_PCI_STATUS 0x06 -#define PCN_PCI_REVID 0x08 -#define PCN_PCI_CLASSCODE 0x09 -#define PCN_PCI_CACHELEN 0x0C -#define PCN_PCI_LATENCY_TIMER 0x0D -#define PCN_PCI_HEADER_TYPE 0x0E -#define PCN_PCI_LOIO 0x10 -#define PCN_PCI_LOMEM 0x14 -#define PCN_PCI_BIOSROM 0x30 -#define PCN_PCI_INTLINE 0x3C -#define PCN_PCI_INTPIN 0x3D -#define PCN_PCI_MINGNT 0x3E -#define PCN_PCI_MINLAT 0x3F -#define PCN_PCI_RESETOPT 0x48 -#define PCN_PCI_EEPROM_DATA 0x4C - -/* power management registers */ -#define PCN_PCI_CAPID 0x50 /* 8 bits */ -#define PCN_PCI_NEXTPTR 0x51 /* 8 bits */ -#define PCN_PCI_PWRMGMTCAP 0x52 /* 16 bits */ -#define PCN_PCI_PWRMGMTCTRL 0x54 /* 16 bits */ - -#define PCN_PSTATE_MASK 0x0003 -#define PCN_PSTATE_D0 0x0000 -#define PCN_PSTATE_D1 0x0001 -#define PCN_PSTATE_D2 0x0002 -#define PCN_PSTATE_D3 0x0003 -#define PCN_PME_EN 0x0010 -#define PCN_PME_STATUS 0x8000 diff --git a/sys/i386/conf/GENERIC b/sys/i386/conf/GENERIC index 4e7e2d5fc4f1..67032785c95f 100644 --- a/sys/i386/conf/GENERIC +++ b/sys/i386/conf/GENERIC @@ -253,7 +253,6 @@ device lge # Level 1 LXT1001 gigabit Ethernet device msk # Marvell/SysKonnect Yukon II Gigabit Ethernet device nfe # nVidia nForce MCP on-board Ethernet device nge # NatSemi DP83820 gigabit Ethernet -device pcn # AMD Am79C97x PCI 10/100 (precedence over 'le') device re # RealTek 8139C+/8169/8169S/8110S device rl # RealTek 8129/8139 device sf # Adaptec AIC-6915 (``Starfire'') diff --git a/sys/modules/Makefile b/sys/modules/Makefile index c7edeb4022f5..aa5e5a9c612c 100644 --- a/sys/modules/Makefile +++ b/sys/modules/Makefile @@ -283,7 +283,6 @@ SUBDIR= \ ${_padlock_rng} \ ${_pccard} \ ${_pcfclock} \ - pcn \ ${_pf} \ ${_pflog} \ ${_pfsync} \ diff --git a/sys/modules/pcn/Makefile b/sys/modules/pcn/Makefile deleted file mode 100644 index aa772f235896..000000000000 --- a/sys/modules/pcn/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -# $FreeBSD$ - -.PATH: ${SRCTOP}/sys/dev/pcn - -KMOD= if_pcn -SRCS= if_pcn.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 6480d0200f84..ed3e92c8ffaa 100644 --- a/sys/sparc64/conf/GENERIC +++ b/sys/sparc64/conf/GENERIC @@ -201,7 +201,6 @@ device fxp # Intel EtherExpress PRO/100B (82557, 82558) device gem # Sun GEM/Sun ERI/Apple GMAC device hme # Sun HME (Happy Meal Ethernet) device nge # NatSemi DP83820 gigabit Ethernet -#device pcn # AMD Am79C97x PCI 10/100 (precedence over 'le') device re # RealTek 8139C+/8169/8169S/8110S device rl # RealTek 8129/8139 device sf # Adaptec AIC-6915 (``Starfire'') |