diff --git a/ObsoleteFiles.inc b/ObsoleteFiles.inc index 7477d55b8c92..3bc5a9743a89 100644 --- a/ObsoleteFiles.inc +++ b/ObsoleteFiles.inc @@ -47,6 +47,7 @@ OLD_FILES+=usr/share/man/man4/ed.4 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 # 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/man4.i386/Makefile b/share/man/man4/man4.i386/Makefile index eddf3e2e2834..6285fbc95bf0 100644 --- a/share/man/man4/man4.i386/Makefile +++ b/share/man/man4/man4.i386/Makefile @@ -8,7 +8,6 @@ MAN= apm.4 \ CPU_ELAN.4 \ ctau.4 \ cx.4 \ - fe.4 \ glxiic.4 \ glxsb.4 \ longrun.4 \ diff --git a/share/man/man4/man4.i386/fe.4 b/share/man/man4/man4.i386/fe.4 deleted file mode 100644 index 505cd2b82da0..000000000000 --- a/share/man/man4/man4.i386/fe.4 +++ /dev/null @@ -1,326 +0,0 @@ -.\" All Rights Reserved, Copyright (C) Fujitsu Limited 1995 -.\" -.\" This document may be used, modified, copied, distributed, and sold, in -.\" both source and printed form provided that the above copyright, these -.\" terms and the following disclaimer are retained. The name of the author -.\" and/or the contributor may not be used to endorse or promote products -.\" derived from this software without specific prior written permission. -.\" -.\" THIS DOCUMENT IS PROVIDED BY THE AUTHOR AND THE CONTRIBUTOR ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR THE CONTRIBUTOR 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 DOCUMENT, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" Contributed by M. Sekiguchi . -.\" for fe driver. -.\" -.\" $FreeBSD$ -.Dd October 24, 2018 -.Dt FE 4 i386 -.Os -.Sh NAME -.Nm fe -.Nd "Fujitsu MB86960A/MB86965A based Ethernet adapters" -.Sh SYNOPSIS -To compile this driver into the kernel, -place the following line in your -kernel configuration file: -.Bd -ragged -offset indent -.Cd "device fe" -.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_fe_load="YES" -.Ed -.Pp -In -.Pa /boot/device.hints : -.Cd hint.fe.0.at="isa" -.Cd hint.fe.0.port="0x300" -.Cd hint.fe.0.flags="0x0" -.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 -is a network device driver -for Ethernet adapters based on Fujitsu MB86960A, MB86965A, -or other compatible chips. -.Pp -The driver provides automatic I/O port address configuration and -automatic IRQ configuration, -when used with suitable adapter hardware. -.Pp -The driver works with program I/O data transfer technique. -It gives a fair performance. -Shared memory is never used, even if the adapter has one. -.Pp -It currently works with Fujitsu FMV-180 series for ISA, -Allied-Telesis AT1700 series and RE2000 series for ISA, -and Fujitsu MBH10302 PC card. -.Ss Parameters -In the -.Pa /boot/device.hints -file, two parameters, -.Ar port -and -.Ar irq , -must be specified to reflect adapter hardware settings. -Another parameter -.Ar flags -can be specified to provide additional configuration as an option. -.Pp -The -.Ar port -parameter specifies a base I/O port address of the adapter. -It must match with the hardware setting of the adapter. -The -.Ar port -may be left unspecified by removing -.Dl hint.fe.0.port="..." -from the file. -In that case, the driver tries to detect the hardware setting -of the I/O address automatically. -This feature may not work with some adapter hardware. -.Pp -The -.Ar irq -parameter specifies an IRQ number used by the adapter. -It must match the hardware setting of the adapter. -.Ar Irq -may be left unspecified by removing -.Dl hint.fe.0.irq="..." -from the file. -in that case, the driver tries to detect -the hardware setting of the IRQ automatically. -This feature may not work on some adapters. -.Pp -The -.Ar flags -is a numeric value which consists of a combination of various device settings. -The following flags are defined in the current version. -To specify two or more settings for a device, -use a numeric sum of each flag value. -Flag bits not specified below are reserved and must be set to 0. -Actually, each bit is either just ignored by the driver, -or tested and used to control undocumented features of the driver. -Consult the source program for undocumented features. -.Bl -tag -width 8n -.It Li 0x007F -These flag bits are used -to initialize DLCR6 register of MB86960A/MB86965A chip, -when the -.Li 0x0080 -bit of the -.Ar flags -is set. -See below for more about DLCR6 override feature. -The -.Li 0x007F -flag bits must be 0 unless the -.Li 0x0080 -bit is set, -to maintain the compatibility with future versions of the driver. -.It Li 0x0080 -This flag overrides the default setting to the DLCR6 register -of MB86960A/MB86965A chip by a user supplied value, -which is taken from the lower 7 bits of the flag value. -This is a troubleshooting flag and should not be used -without understanding of the adapter hardware. -Consult the Fujitsu manual for more information -on DLCR6 settings. -.El -.Sh HARDWARE -Controllers and cards supported by the -.Nm -driver include: -.Pp -.Bl -bullet -compact -.It -Allied Telesis RE1000, RE1000Plus, ME1500 (110-pin) -.It -CONTEC C-NET(98)P2, C-NET (9N)E (110-pin), C-NET(9N)C (ExtCard) -.It -CONTEC C-NET(PC)C PC Card Ethernet -.It -Eagle Tech NE200T -.It -Eiger Labs EPX-10BT -.It -Fujitsu FMV-J182, FMV-J182A -.It -Fujitsu MB86960A, MB86965A -.It -Fujitsu MBH10303, MBH10302 PC Card Ethernet -.It -Fujitsu Towa LA501 Ethernet -.It -HITACHI HT-4840-11 PC Card Ethernet -.It -NextCom J Link NC5310 -.It -RATOC REX-5588, REX-9822, REX-4886, and REX-R280 -.It -RATOC REX-9880/9881/9882/9883 -.It -TDK LAC-98012, LAC-98013, LAC-98025, LAC-9N011 (110-pin) -.It -TDK LAK-CD011, LAK-CD021, LAK-CD021A, LAK-CD021BX -.It -Ungermann-Bass Access/PC N98C+(PC85152, PC85142), Access/NOTE -N98(PC86132) (110-pin) -.El -.Sh FEATURES SPECIFIC TO HARDWARE MODELS -The -.Nm -driver has some features and limitations -which depend on adapter hardware models. -The following is a summary of these dependencies. -.Ss Fujitsu FMV-180 series adapters -Both automatic IRQ detection and automatic I/O port address detection -is available with these adapters. -.Pp -Automatic I/O port address detection feature of -.Nm -works mostly fine for FMV-180 series. -It works even if there are two or more FMV-180s in a system. -However, some combination of other adapters may confuse the driver. -It is recommended to explicitly specify -.Ar port -when you experience some difficulties with hardware probe. -.Pp -Automatic IRQ detection feature of -.Nm -works reliably for FMV-180 series. -It is recommended to explicitly specify -.Ar irq -always for FMV-180. -The hardware setting of IRQ is read -from the configuration EEPROM on the adapter, -even when the kernel config file specifies an IRQ value. -The driver will generate a warning message, -if the IRQ setting specified in -.Pa /boot/device.hints -does not match one stored in EEPROM. -Then, it will use the value specified in the file. -(This behavior has been changed from the previous releases.) -.Ss Allied-Telesis AT1700 series and RE2000 series adapters -Automatic I/O port address detection -is available with Allied-Telesis AT1700 series and RE2000 series, -while it is less reliable than FMV-180 series. -Using the feature with Allied-Telesis adapters -is not recommended. -.Pp -Automatic IRQ detection is also available with some limitation. -The -.Nm -driver -tries to get IRQ setting from the configuration EEPROM on the board, -if -.Ar irq -is not specified in -.Pa /boot/device.hints . -Unfortunately, -AT1700 series and RE2000 series seems to have two types of models; -One type allows IRQ selection from 3/4/5/9, -while the other from 10/11/12/15. -Identification of the models are not well known. -Hence, automatic IRQ detection with Allied-Telesis adapters -may not be reliable. -Specify an exact IRQ number if any troubles are encountered. -.Pp -Differences between AT1700 series and RE2000 series -or minor models in those series are not recognized. -.Ss Fujitsu MBH10302 PC card -The -.Nm -driver supports Fujitsu MBH10302 and compatible PC cards. -It requires the PC card (PCMCIA) support package. -.Sh SEE ALSO -.Xr netstat 1 , -.Xr ed 4 , -.Xr netintro 4 , -.Xr ng_ether 4 , -.Xr ifconfig 8 -.Sh HISTORY -The -.Nm -driver appeared in -.Fx 2.0.5 . -.Sh AUTHORS, COPYRIGHT AND DISCLAIMER -The -.Nm -driver was originally written and contributed by -.An M. Sekiguchi Aq Mt seki@sysrap.cs.fujitsu.co.jp , -following the -.Nm ed -driver written by -.An David Greenman . -PC card support in -.Nm -is written by -.An Hidetoshi Kimura Aq Mt h-kimura@tokyo.se.fujitsu.co.jp . -This manual page was written by -.An M. Sekiguchi . -.Pp -.Em "All Rights Reserved, Copyright (C) Fujitsu Limited 1995" -.Pp -This document and the associated software may be used, modified, -copied, distributed, and sold, in both source and binary form provided -that the above copyright, these terms and the following disclaimer are -retained. -The name of the author and/or the contributor may not be -used to endorse or promote products derived from this document and the -associated software without specific prior written permission. -.Pp -THIS DOCUMENT AND THE ASSOCIATED SOFTWARE IS PROVIDED BY THE AUTHOR -AND THE CONTRIBUTOR -.Dq AS IS -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE AUTHOR OR THE -CONTRIBUTOR 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 -DOCUMENT AND THE ASSOCIATED SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -.Sh BUGS -Following are major known bugs: -.Pp -Statistics on the number of collisions maintained by the -.Nm -driver is not accurate; -the -.Fl i -option of -.Xr netstat 1 -shows slightly less value than true number of collisions. -.Pp -More mbuf clusters are used than expected. -The packet receive routine has an intended violation -against the mbuf cluster allocation policy. -The unnecessarily allocated clusters are freed within short lifetime, -and it will not affect long term kernel memory usage. -.Pp -Although XNS and IPX support is included in the driver, -it has never been tested and it is expected to have a lot of bugs. diff --git a/sys/conf/NOTES b/sys/conf/NOTES index 87e17de6a262..03cda7c0882d 100644 --- a/sys/conf/NOTES +++ b/sys/conf/NOTES @@ -1937,7 +1937,6 @@ device xmphy # XaQti XMAC II # LinkSys LNE100TX, LNE100TX V2.0, Jaton XpressNet, Alfa Inc GFC2204, # KNE110TX. # em: Intel Pro/1000 Gigabit Ethernet 82542, 82543, 82544 based adapters. -# fe: Fujitsu MB86960A/MB86965A Ethernet # fxp: Intel EtherExpress Pro/100B # (hint of prefer_iomap can be done to prefer I/O instead of Mem mapping) # gem: Apple GMAC/Sun ERI/Sun GEM @@ -2040,9 +2039,6 @@ device xmphy # XaQti XMAC II # Order for ISA devices is important here -device fe -hint.fe.0.at="isa" -hint.fe.0.port="0x300" device sn hint.sn.0.at="isa" hint.sn.0.port="0x300" diff --git a/sys/conf/files b/sys/conf/files index 3dfe2bffd1f6..8a2a825b1bf2 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -1703,8 +1703,6 @@ dev/fdt/fdt_static_dtb.S optional fdt fdt_dtb_static \ dependency "${FDT_DTS_FILE:T:R}.dtb" dev/fdt/simplebus.c optional fdt dev/fdt/simple_mfd.c optional fdt -dev/fe/if_fe.c optional fe -dev/fe/if_fe_pccard.c optional fe pccard dev/filemon/filemon.c optional filemon dev/firewire/firewire.c optional firewire dev/firewire/fwcrom.c optional firewire diff --git a/sys/dev/fe/if_fe.c b/sys/dev/fe/if_fe.c deleted file mode 100644 index 633061e95281..000000000000 --- a/sys/dev/fe/if_fe.c +++ /dev/null @@ -1,2258 +0,0 @@ -/*- - * All Rights Reserved, Copyright (C) Fujitsu Limited 1995 - * - * This software may be used, modified, copied, distributed, and sold, in - * both source and binary form provided that the above copyright, these - * terms and the following disclaimer are retained. The name of the author - * and/or the contributor may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND THE CONTRIBUTOR ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR THE CONTRIBUTOR 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 -__FBSDID("$FreeBSD$"); - -/* - * - * Device driver for Fujitsu MB86960A/MB86965A based Ethernet cards. - * Contributed by M. Sekiguchi. - * - * This version is intended to be a generic template for various - * MB86960A/MB86965A based Ethernet cards. It currently supports - * Fujitsu FMV-180 series for ISA and Allied-Telesis AT1700/RE2000 - * series for ISA, as well as Fujitsu MBH10302 PC Card. - * There are some currently- - * unused hooks embedded, which are primarily intended to support - * other types of Ethernet cards, but the author is not sure whether - * they are useful. - * - * This software is a derivative work of if_ed.c version 1.56 by David - * Greenman available as a part of FreeBSD 2.0 RELEASE source distribution. - * - * The following lines are retained from the original if_ed.c: - * - * Copyright (C) 1993, David Greenman. This software may be used, modified, - * copied, distributed, and sold, in both source and binary form provided - * that the above copyright and these terms are retained. Under no - * circumstances is the author responsible for the proper functioning - * of this software, nor does the author assume any responsibility - * for damages incurred with its use. - */ - -/* - * TODO: - * o To support ISA PnP auto configuration for FMV-183/184. - * o To reconsider mbuf usage. - * o To reconsider transmission buffer usage, including - * transmission buffer size (currently 4KB x 2) and pros-and- - * cons of multiple frame transmission. - * o To test IPX codes. - * o To test new-bus frontend. - */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - -#include -#include -#include - -/* - * Transmit just one packet per a "send" command to 86960. - * This option is intended for performance test. An EXPERIMENTAL option. - */ -#ifndef FE_SINGLE_TRANSMISSION -#define FE_SINGLE_TRANSMISSION 0 -#endif - -/* - * Maximum loops when interrupt. - * This option prevents an infinite loop due to hardware failure. - * (Some laptops make an infinite loop after PC Card is ejected.) - */ -#ifndef FE_MAX_LOOP -#define FE_MAX_LOOP 0x800 -#endif - -/* - * Device configuration flags. - */ - -/* DLCR6 settings. */ -#define FE_FLAGS_DLCR6_VALUE 0x007F - -/* Force DLCR6 override. */ -#define FE_FLAGS_OVERRIDE_DLCR6 0x0080 - - -devclass_t fe_devclass; - -/* - * Special filter values. - */ -static struct fe_filter const fe_filter_nothing = { FE_FILTER_NOTHING }; -static struct fe_filter const fe_filter_all = { FE_FILTER_ALL }; - -/* Standard driver entry points. These can be static. */ -static void fe_init (void *); -static void fe_init_locked (struct fe_softc *); -static driver_intr_t fe_intr; -static int fe_ioctl (struct ifnet *, u_long, caddr_t); -static void fe_start (struct ifnet *); -static void fe_start_locked (struct ifnet *); -static void fe_watchdog (void *); -static int fe_medchange (struct ifnet *); -static void fe_medstat (struct ifnet *, struct ifmediareq *); - -/* Local functions. Order of declaration is confused. FIXME. */ -static int fe_get_packet ( struct fe_softc *, u_short ); -static void fe_tint ( struct fe_softc *, u_char ); -static void fe_rint ( struct fe_softc *, u_char ); -static void fe_xmit ( struct fe_softc * ); -static void fe_write_mbufs ( struct fe_softc *, struct mbuf * ); -static void fe_setmode ( struct fe_softc * ); -static void fe_loadmar ( struct fe_softc * ); - -#ifdef DIAGNOSTIC -static void fe_emptybuffer ( struct fe_softc * ); -#endif - -/* - * Fe driver specific constants which relate to 86960/86965. - */ - -/* Interrupt masks */ -#define FE_TMASK ( FE_D2_COLL16 | FE_D2_TXDONE ) -#define FE_RMASK ( FE_D3_OVRFLO | FE_D3_CRCERR \ - | FE_D3_ALGERR | FE_D3_SRTPKT | FE_D3_PKTRDY ) - -/* Maximum number of iterations for a receive interrupt. */ -#define FE_MAX_RECV_COUNT ( ( 65536 - 2048 * 2 ) / 64 ) - /* - * Maximum size of SRAM is 65536, - * minimum size of transmission buffer in fe is 2x2KB, - * and minimum amount of received packet including headers - * added by the chip is 64 bytes. - * Hence FE_MAX_RECV_COUNT is the upper limit for number - * of packets in the receive buffer. - */ - -/* - * Miscellaneous definitions not directly related to hardware. - */ - -/* The following line must be delete when "net/if_media.h" support it. */ -#ifndef IFM_10_FL -#define IFM_10_FL /* 13 */ IFM_10_5 -#endif - -#if 0 -/* Mapping between media bitmap (in fe_softc.mbitmap) and ifm_media. */ -static int const bit2media [] = { - IFM_HDX | IFM_ETHER | IFM_AUTO, - IFM_HDX | IFM_ETHER | IFM_MANUAL, - IFM_HDX | IFM_ETHER | IFM_10_T, - IFM_HDX | IFM_ETHER | IFM_10_2, - IFM_HDX | IFM_ETHER | IFM_10_5, - IFM_HDX | IFM_ETHER | IFM_10_FL, - IFM_FDX | IFM_ETHER | IFM_10_T, - /* More can be come here... */ - 0 -}; -#else -/* Mapping between media bitmap (in fe_softc.mbitmap) and ifm_media. */ -static int const bit2media [] = { - IFM_ETHER | IFM_AUTO, - IFM_ETHER | IFM_MANUAL, - IFM_ETHER | IFM_10_T, - IFM_ETHER | IFM_10_2, - IFM_ETHER | IFM_10_5, - IFM_ETHER | IFM_10_FL, - IFM_ETHER | IFM_10_T, - /* More can be come here... */ - 0 -}; -#endif - -/* - * Check for specific bits in specific registers have specific values. - * A common utility function called from various sub-probe routines. - */ -int -fe_simple_probe (struct fe_softc const * sc, - struct fe_simple_probe_struct const * sp) -{ - struct fe_simple_probe_struct const *p; - int8_t bits; - - for (p = sp; p->mask != 0; p++) { - bits = fe_inb(sc, p->port); - printf("port %d, mask %x, bits %x read %x\n", p->port, - p->mask, p->bits, bits); - if ((bits & p->mask) != p->bits) - return 0; - } - return 1; -} - -/* Test if a given 6 byte value is a valid Ethernet station (MAC) - address. "Vendor" is an expected vendor code (first three bytes,) - or a zero when nothing expected. */ -int -fe_valid_Ether_p (u_char const * addr, unsigned vendor) -{ -#ifdef FE_DEBUG - printf("fe?: validating %6D against %06x\n", addr, ":", vendor); -#endif - - /* All zero is not allowed as a vendor code. */ - if (addr[0] == 0 && addr[1] == 0 && addr[2] == 0) return 0; - - switch (vendor) { - case 0x000000: - /* Legal Ethernet address (stored in ROM) must have - its Group and Local bits cleared. */ - if ((addr[0] & 0x03) != 0) return 0; - break; - case 0x020000: - /* Same as above, but a local address is allowed in - this context. */ - if (ETHER_IS_MULTICAST(addr)) return 0; - break; - default: - /* Make sure the vendor part matches if one is given. */ - if ( addr[0] != ((vendor >> 16) & 0xFF) - || addr[1] != ((vendor >> 8) & 0xFF) - || addr[2] != ((vendor ) & 0xFF)) return 0; - break; - } - - /* Host part must not be all-zeros nor all-ones. */ - if (addr[3] == 0xFF && addr[4] == 0xFF && addr[5] == 0xFF) return 0; - if (addr[3] == 0x00 && addr[4] == 0x00 && addr[5] == 0x00) return 0; - - /* Given addr looks like an Ethernet address. */ - return 1; -} - -/* Fill our softc struct with default value. */ -void -fe_softc_defaults (struct fe_softc *sc) -{ - /* Prepare for typical register prototypes. We assume a - "typical" board has <32KB> of SRAM connected with a - data lines. */ - sc->proto_dlcr4 = FE_D4_LBC_DISABLE | FE_D4_CNTRL; - sc->proto_dlcr5 = 0; - sc->proto_dlcr6 = FE_D6_BUFSIZ_32KB | FE_D6_TXBSIZ_2x4KB - | FE_D6_BBW_BYTE | FE_D6_SBW_WORD | FE_D6_SRAM_100ns; - sc->proto_dlcr7 = FE_D7_BYTSWP_LH; - sc->proto_bmpr13 = 0; - - /* Assume the probe process (to be done later) is stable. */ - sc->stability = 0; - - /* A typical board needs no hooks. */ - sc->init = NULL; - sc->stop = NULL; - - /* Assume the board has no software-controllable media selection. */ - sc->mbitmap = MB_HM; - sc->defmedia = MB_HM; - sc->msel = NULL; -} - -/* Common error reporting routine used in probe routines for - "soft configured IRQ"-type boards. */ -void -fe_irq_failure (char const *name, int unit, int irq, char const *list) -{ - printf("fe%d: %s board is detected, but %s IRQ was given\n", - unit, name, (irq == NO_IRQ ? "no" : "invalid")); - if (list != NULL) { - printf("fe%d: specify an IRQ from %s in kernel config\n", - unit, list); - } -} - -/* - * Hardware (vendor) specific hooks. - */ - -/* - * Generic media selection scheme for MB86965 based boards. - */ -void -fe_msel_965 (struct fe_softc *sc) -{ - u_char b13; - - /* Find the appropriate bits for BMPR13 tranceiver control. */ - switch (IFM_SUBTYPE(sc->media.ifm_media)) { - case IFM_AUTO: b13 = FE_B13_PORT_AUTO | FE_B13_TPTYPE_UTP; break; - case IFM_10_T: b13 = FE_B13_PORT_TP | FE_B13_TPTYPE_UTP; break; - default: b13 = FE_B13_PORT_AUI; break; - } - - /* Write it into the register. It takes effect immediately. */ - fe_outb(sc, FE_BMPR13, sc->proto_bmpr13 | b13); -} - - -/* - * Fujitsu MB86965 JLI mode support routines. - */ - -/* - * Routines to read all bytes from the config EEPROM through MB86965A. - * It is a MicroWire (3-wire) serial EEPROM with 6-bit address. - * (93C06 or 93C46.) - */ -static void -fe_strobe_eeprom_jli (struct fe_softc *sc, u_short bmpr16) -{ - /* - * We must guarantee 1us (or more) interval to access slow - * EEPROMs. The following redundant code provides enough - * delay with ISA timing. (Even if the bus clock is "tuned.") - * Some modification will be needed on faster busses. - */ - fe_outb(sc, bmpr16, FE_B16_SELECT); - fe_outb(sc, bmpr16, FE_B16_SELECT | FE_B16_CLOCK); - fe_outb(sc, bmpr16, FE_B16_SELECT | FE_B16_CLOCK); - fe_outb(sc, bmpr16, FE_B16_SELECT); -} - -void -fe_read_eeprom_jli (struct fe_softc * sc, u_char * data) -{ - u_char n, val, bit; - u_char save16, save17; - - /* Save the current value of the EEPROM interface registers. */ - save16 = fe_inb(sc, FE_BMPR16); - save17 = fe_inb(sc, FE_BMPR17); - - /* Read bytes from EEPROM; two bytes per an iteration. */ - for (n = 0; n < JLI_EEPROM_SIZE / 2; n++) { - - /* Reset the EEPROM interface. */ - fe_outb(sc, FE_BMPR16, 0x00); - fe_outb(sc, FE_BMPR17, 0x00); - - /* Start EEPROM access. */ - fe_outb(sc, FE_BMPR16, FE_B16_SELECT); - fe_outb(sc, FE_BMPR17, FE_B17_DATA); - fe_strobe_eeprom_jli(sc, FE_BMPR16); - - /* Pass the iteration count as well as a READ command. */ - val = 0x80 | n; - for (bit = 0x80; bit != 0x00; bit >>= 1) { - fe_outb(sc, FE_BMPR17, (val & bit) ? FE_B17_DATA : 0); - fe_strobe_eeprom_jli(sc, FE_BMPR16); - } - fe_outb(sc, FE_BMPR17, 0x00); - - /* Read a byte. */ - val = 0; - for (bit = 0x80; bit != 0x00; bit >>= 1) { - fe_strobe_eeprom_jli(sc, FE_BMPR16); - if (fe_inb(sc, FE_BMPR17) & FE_B17_DATA) - val |= bit; - } - *data++ = val; - - /* Read one more byte. */ - val = 0; - for (bit = 0x80; bit != 0x00; bit >>= 1) { - fe_strobe_eeprom_jli(sc, FE_BMPR16); - if (fe_inb(sc, FE_BMPR17) & FE_B17_DATA) - val |= bit; - } - *data++ = val; - } - -#if 0 - /* Reset the EEPROM interface, again. */ - fe_outb(sc, FE_BMPR16, 0x00); - fe_outb(sc, FE_BMPR17, 0x00); -#else - /* Make sure to restore the original value of EEPROM interface - registers, since we are not yet sure we have MB86965A on - the address. */ - fe_outb(sc, FE_BMPR17, save17); - fe_outb(sc, FE_BMPR16, save16); -#endif - -#if 1 - /* Report what we got. */ - if (bootverbose) { - int i; - data -= JLI_EEPROM_SIZE; - for (i = 0; i < JLI_EEPROM_SIZE; i += 16) { - if_printf(sc->ifp, - "EEPROM(JLI):%3x: %16D\n", i, data + i, " "); - } - } -#endif -} - -void -fe_init_jli (struct fe_softc * sc) -{ - /* "Reset" by writing into a magic location. */ - DELAY(200); - fe_outb(sc, 0x1E, fe_inb(sc, 0x1E)); - DELAY(300); -} - - -/* - * SSi 78Q8377A support routines. - */ - -/* - * Routines to read all bytes from the config EEPROM through 78Q8377A. - * It is a MicroWire (3-wire) serial EEPROM with 8-bit address. (I.e., - * 93C56 or 93C66.) - * - * As I don't have SSi manuals, (hmm, an old song again!) I'm not exactly - * sure the following code is correct... It is just stolen from the - * C-NET(98)P2 support routine in FreeBSD(98). - */ - -void -fe_read_eeprom_ssi (struct fe_softc *sc, u_char *data) -{ - u_char val, bit; - int n; - u_char save6, save7, save12; - - /* Save the current value for the DLCR registers we are about - to destroy. */ - save6 = fe_inb(sc, FE_DLCR6); - save7 = fe_inb(sc, FE_DLCR7); - - /* Put the 78Q8377A into a state that we can access the EEPROM. */ - fe_outb(sc, FE_DLCR6, - FE_D6_BBW_WORD | FE_D6_SBW_WORD | FE_D6_DLC_DISABLE); - fe_outb(sc, FE_DLCR7, - FE_D7_BYTSWP_LH | FE_D7_RBS_BMPR | FE_D7_RDYPNS | FE_D7_POWER_UP); - - /* Save the current value for the BMPR12 register, too. */ - save12 = fe_inb(sc, FE_DLCR12); - - /* Read bytes from EEPROM; two bytes per an iteration. */ - for (n = 0; n < SSI_EEPROM_SIZE / 2; n++) { - - /* Start EEPROM access */ - fe_outb(sc, FE_DLCR12, SSI_EEP); - fe_outb(sc, FE_DLCR12, SSI_EEP | SSI_CSL); - - /* Send the following four bits to the EEPROM in the - specified order: a dummy bit, a start bit, and - command bits (10) for READ. */ - fe_outb(sc, FE_DLCR12, SSI_EEP | SSI_CSL ); - fe_outb(sc, FE_DLCR12, SSI_EEP | SSI_CSL | SSI_CLK ); /* 0 */ - fe_outb(sc, FE_DLCR12, SSI_EEP | SSI_CSL | SSI_DAT); - fe_outb(sc, FE_DLCR12, SSI_EEP | SSI_CSL | SSI_CLK | SSI_DAT); /* 1 */ - fe_outb(sc, FE_DLCR12, SSI_EEP | SSI_CSL | SSI_DAT); - fe_outb(sc, FE_DLCR12, SSI_EEP | SSI_CSL | SSI_CLK | SSI_DAT); /* 1 */ - fe_outb(sc, FE_DLCR12, SSI_EEP | SSI_CSL ); - fe_outb(sc, FE_DLCR12, SSI_EEP | SSI_CSL | SSI_CLK ); /* 0 */ - - /* Pass the iteration count to the chip. */ - for (bit = 0x80; bit != 0x00; bit >>= 1) { - val = ( n & bit ) ? SSI_DAT : 0; - fe_outb(sc, FE_DLCR12, SSI_EEP | SSI_CSL | val); - fe_outb(sc, FE_DLCR12, SSI_EEP | SSI_CSL | SSI_CLK | val); - } - - /* Read a byte. */ - val = 0; - for (bit = 0x80; bit != 0x00; bit >>= 1) { - fe_outb(sc, FE_DLCR12, SSI_EEP | SSI_CSL); - fe_outb(sc, FE_DLCR12, SSI_EEP | SSI_CSL | SSI_CLK); - if (fe_inb(sc, FE_DLCR12) & SSI_DIN) - val |= bit; - } - *data++ = val; - - /* Read one more byte. */ - val = 0; - for (bit = 0x80; bit != 0x00; bit >>= 1) { - fe_outb(sc, FE_DLCR12, SSI_EEP | SSI_CSL); - fe_outb(sc, FE_DLCR12, SSI_EEP | SSI_CSL | SSI_CLK); - if (fe_inb(sc, FE_DLCR12) & SSI_DIN) - val |= bit; - } - *data++ = val; - - fe_outb(sc, FE_DLCR12, SSI_EEP); - } - - /* Reset the EEPROM interface. (For now.) */ - fe_outb(sc, FE_DLCR12, 0x00); - - /* Restore the saved register values, for the case that we - didn't have 78Q8377A at the given address. */ - fe_outb(sc, FE_DLCR12, save12); - fe_outb(sc, FE_DLCR7, save7); - fe_outb(sc, FE_DLCR6, save6); - -#if 1 - /* Report what we got. */ - if (bootverbose) { - int i; - data -= SSI_EEPROM_SIZE; - for (i = 0; i < SSI_EEPROM_SIZE; i += 16) { - if_printf(sc->ifp, - "EEPROM(SSI):%3x: %16D\n", i, data + i, " "); - } - } -#endif -} - -/* - * TDK/LANX boards support routines. - */ - -/* It is assumed that the CLK line is low and SDA is high (float) upon entry. */ -#define LNX_PH(D,K,N) \ - ((LNX_SDA_##D | LNX_CLK_##K) << N) -#define LNX_CYCLE(D1,D2,D3,D4,K1,K2,K3,K4) \ - (LNX_PH(D1,K1,0)|LNX_PH(D2,K2,8)|LNX_PH(D3,K3,16)|LNX_PH(D4,K4,24)) - -#define LNX_CYCLE_START LNX_CYCLE(HI,LO,LO,HI, HI,HI,LO,LO) -#define LNX_CYCLE_STOP LNX_CYCLE(LO,LO,HI,HI, LO,HI,HI,LO) -#define LNX_CYCLE_HI LNX_CYCLE(HI,HI,HI,HI, LO,HI,LO,LO) -#define LNX_CYCLE_LO LNX_CYCLE(LO,LO,LO,HI, LO,HI,LO,LO) -#define LNX_CYCLE_INIT LNX_CYCLE(LO,HI,HI,HI, LO,LO,LO,LO) - -static void -fe_eeprom_cycle_lnx (struct fe_softc *sc, u_short reg20, u_long cycle) -{ - fe_outb(sc, reg20, (cycle ) & 0xFF); - DELAY(15); - fe_outb(sc, reg20, (cycle >> 8) & 0xFF); - DELAY(15); - fe_outb(sc, reg20, (cycle >> 16) & 0xFF); - DELAY(15); - fe_outb(sc, reg20, (cycle >> 24) & 0xFF); - DELAY(15); -} - -static u_char -fe_eeprom_receive_lnx (struct fe_softc *sc, u_short reg20) -{ - u_char dat; - - fe_outb(sc, reg20, LNX_CLK_HI | LNX_SDA_FL); - DELAY(15); - dat = fe_inb(sc, reg20); - fe_outb(sc, reg20, LNX_CLK_LO | LNX_SDA_FL); - DELAY(15); - return (dat & LNX_SDA_IN); -} - -void -fe_read_eeprom_lnx (struct fe_softc *sc, u_char *data) -{ - int i; - u_char n, bit, val; - u_char save20; - u_short reg20 = 0x14; - - save20 = fe_inb(sc, reg20); - - /* NOTE: DELAY() timing constants are approximately three - times longer (slower) than the required minimum. This is - to guarantee a reliable operation under some tough - conditions... Fortunately, this routine is only called - during the boot phase, so the speed is less important than - stability. */ - -#if 1 - /* Reset the X24C01's internal state machine and put it into - the IDLE state. We usually don't need this, but *if* - someone (e.g., probe routine of other driver) write some - garbage into the register at 0x14, synchronization will be - lost, and the normal EEPROM access protocol won't work. - Moreover, as there are no easy way to reset, we need a - _manoeuvre_ here. (It even lacks a reset pin, so pushing - the RESET button on the PC doesn't help!) */ - fe_eeprom_cycle_lnx(sc, reg20, LNX_CYCLE_INIT); - for (i = 0; i < 10; i++) - fe_eeprom_cycle_lnx(sc, reg20, LNX_CYCLE_START); - fe_eeprom_cycle_lnx(sc, reg20, LNX_CYCLE_STOP); - DELAY(10000); -#endif - - /* Issue a start condition. */ - fe_eeprom_cycle_lnx(sc, reg20, LNX_CYCLE_START); - - /* Send seven bits of the starting address (zero, in this - case) and a command bit for READ. */ - val = 0x01; - for (bit = 0x80; bit != 0x00; bit >>= 1) { - if (val & bit) { - fe_eeprom_cycle_lnx(sc, reg20, LNX_CYCLE_HI); - } else { - fe_eeprom_cycle_lnx(sc, reg20, LNX_CYCLE_LO); - } - } - - /* Receive an ACK bit. */ - if (fe_eeprom_receive_lnx(sc, reg20)) { - /* ACK was not received. EEPROM is not present (i.e., - this board was not a TDK/LANX) or not working - properly. */ - if (bootverbose) { - if_printf(sc->ifp, - "no ACK received from EEPROM(LNX)\n"); - } - /* Clear the given buffer to indicate we could not get - any info. and return. */ - bzero(data, LNX_EEPROM_SIZE); - goto RET; - } - - /* Read bytes from EEPROM. */ - for (n = 0; n < LNX_EEPROM_SIZE; n++) { - - /* Read a byte and store it into the buffer. */ - val = 0x00; - for (bit = 0x80; bit != 0x00; bit >>= 1) { - if (fe_eeprom_receive_lnx(sc, reg20)) - val |= bit; - } - *data++ = val; - - /* Acknowledge if we have to read more. */ - if (n < LNX_EEPROM_SIZE - 1) { - fe_eeprom_cycle_lnx(sc, reg20, LNX_CYCLE_LO); - } - } - - /* Issue a STOP condition, de-activating the clock line. - It will be safer to keep the clock line low than to leave - it high. */ - fe_eeprom_cycle_lnx(sc, reg20, LNX_CYCLE_STOP); - - RET: - fe_outb(sc, reg20, save20); - -#if 1 - /* Report what we got. */ - if (bootverbose) { - data -= LNX_EEPROM_SIZE; - for (i = 0; i < LNX_EEPROM_SIZE; i += 16) { - if_printf(sc->ifp, - "EEPROM(LNX):%3x: %16D\n", i, data + i, " "); - } - } -#endif -} - -void -fe_init_lnx (struct fe_softc * sc) -{ - /* Reset the 86960. Do we need this? FIXME. */ - fe_outb(sc, 0x12, 0x06); - DELAY(100); - fe_outb(sc, 0x12, 0x07); - DELAY(100); - - /* Setup IRQ control register on the ASIC. */ - fe_outb(sc, 0x14, sc->priv_info); -} - - -/* - * Ungermann-Bass boards support routine. - */ -void -fe_init_ubn (struct fe_softc * sc) -{ - /* Do we need this? FIXME. */ - fe_outb(sc, FE_DLCR7, - sc->proto_dlcr7 | FE_D7_RBS_BMPR | FE_D7_POWER_UP); - fe_outb(sc, 0x18, 0x00); - DELAY(200); - - /* Setup IRQ control register on the ASIC. */ - fe_outb(sc, 0x14, sc->priv_info); -} - - -/* - * Install interface into kernel networking data structures - */ -int -fe_attach (device_t dev) -{ - struct fe_softc *sc = device_get_softc(dev); - struct ifnet *ifp; - int flags = device_get_flags(dev); - int b, error; - - ifp = sc->ifp = if_alloc(IFT_ETHER); - if (ifp == NULL) { - device_printf(dev, "can not ifalloc\n"); - fe_release_resource(dev); - return (ENOSPC); - } - - mtx_init(&sc->lock, device_get_nameunit(dev), MTX_NETWORK_LOCK, - MTX_DEF); - callout_init_mtx(&sc->timer, &sc->lock, 0); - - /* - * Initialize ifnet structure - */ - ifp->if_softc = sc; - if_initname(sc->ifp, device_get_name(dev), device_get_unit(dev)); - ifp->if_start = fe_start; - ifp->if_ioctl = fe_ioctl; - ifp->if_init = fe_init; - ifp->if_linkmib = &sc->mibdata; - ifp->if_linkmiblen = sizeof (sc->mibdata); - -#if 0 /* I'm not sure... */ - sc->mibdata.dot3Compliance = DOT3COMPLIANCE_COLLS; -#endif - - /* - * Set fixed interface flags. - */ - ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; - IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen); - -#if FE_SINGLE_TRANSMISSION - /* Override txb config to allocate minimum. */ - sc->proto_dlcr6 &= ~FE_D6_TXBSIZ - sc->proto_dlcr6 |= FE_D6_TXBSIZ_2x2KB; -#endif - - /* Modify hardware config if it is requested. */ - if (flags & FE_FLAGS_OVERRIDE_DLCR6) - sc->proto_dlcr6 = flags & FE_FLAGS_DLCR6_VALUE; - - /* Find TX buffer size, based on the hardware dependent proto. */ - switch (sc->proto_dlcr6 & FE_D6_TXBSIZ) { - case FE_D6_TXBSIZ_2x2KB: sc->txb_size = 2048; break; - case FE_D6_TXBSIZ_2x4KB: sc->txb_size = 4096; break; - case FE_D6_TXBSIZ_2x8KB: sc->txb_size = 8192; break; - default: - /* Oops, we can't work with single buffer configuration. */ - if (bootverbose) { - if_printf(sc->ifp, - "strange TXBSIZ config; fixing\n"); - } - sc->proto_dlcr6 &= ~FE_D6_TXBSIZ; - sc->proto_dlcr6 |= FE_D6_TXBSIZ_2x2KB; - sc->txb_size = 2048; - break; - } - - /* Initialize the if_media interface. */ - ifmedia_init(&sc->media, 0, fe_medchange, fe_medstat); - for (b = 0; bit2media[b] != 0; b++) { - if (sc->mbitmap & (1 << b)) { - ifmedia_add(&sc->media, bit2media[b], 0, NULL); - } - } - for (b = 0; bit2media[b] != 0; b++) { - if (sc->defmedia & (1 << b)) { - ifmedia_set(&sc->media, bit2media[b]); - break; - } - } -#if 0 /* Turned off; this is called later, when the interface UPs. */ - fe_medchange(sc); -#endif - - /* Attach and stop the interface. */ - FE_LOCK(sc); - fe_stop(sc); - FE_UNLOCK(sc); - ether_ifattach(sc->ifp, sc->enaddr); - - error = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_NET | INTR_MPSAFE, - NULL, fe_intr, sc, &sc->irq_handle); - if (error) { - ether_ifdetach(ifp); - mtx_destroy(&sc->lock); - if_free(ifp); - fe_release_resource(dev); - return ENXIO; - } - - /* Print additional info when attached. */ - device_printf(dev, "type %s%s\n", sc->typestr, - (sc->proto_dlcr4 & FE_D4_DSC) ? ", full duplex" : ""); - if (bootverbose) { - int buf, txb, bbw, sbw, ram; - - buf = txb = bbw = sbw = ram = -1; - switch ( sc->proto_dlcr6 & FE_D6_BUFSIZ ) { - case FE_D6_BUFSIZ_8KB: buf = 8; break; - case FE_D6_BUFSIZ_16KB: buf = 16; break; - case FE_D6_BUFSIZ_32KB: buf = 32; break; - case FE_D6_BUFSIZ_64KB: buf = 64; break; - } - switch ( sc->proto_dlcr6 & FE_D6_TXBSIZ ) { - case FE_D6_TXBSIZ_2x2KB: txb = 2; break; - case FE_D6_TXBSIZ_2x4KB: txb = 4; break; - case FE_D6_TXBSIZ_2x8KB: txb = 8; break; - } - switch ( sc->proto_dlcr6 & FE_D6_BBW ) { - case FE_D6_BBW_BYTE: bbw = 8; break; - case FE_D6_BBW_WORD: bbw = 16; break; - } - switch ( sc->proto_dlcr6 & FE_D6_SBW ) { - case FE_D6_SBW_BYTE: sbw = 8; break; - case FE_D6_SBW_WORD: sbw = 16; break; - } - switch ( sc->proto_dlcr6 & FE_D6_SRAM ) { - case FE_D6_SRAM_100ns: ram = 100; break; - case FE_D6_SRAM_150ns: ram = 150; break; - } - device_printf(dev, "SRAM %dKB %dbit %dns, TXB %dKBx2, %dbit I/O\n", - buf, bbw, ram, txb, sbw); - } - if (sc->stability & UNSTABLE_IRQ) - device_printf(dev, "warning: IRQ number may be incorrect\n"); - if (sc->stability & UNSTABLE_MAC) - device_printf(dev, "warning: above MAC address may be incorrect\n"); - if (sc->stability & UNSTABLE_TYPE) - device_printf(dev, "warning: hardware type was not validated\n"); - - gone_by_fcp101_dev(dev); - - return 0; -} - -int -fe_alloc_port(device_t dev, int size) -{ - struct fe_softc *sc = device_get_softc(dev); - struct resource *res; - int rid; - - rid = 0; - res = bus_alloc_resource_anywhere(dev, SYS_RES_IOPORT, &rid, - size, RF_ACTIVE); - if (res) { - sc->port_used = size; - sc->port_res = res; - return (0); - } - - return (ENOENT); -} - -int -fe_alloc_irq(device_t dev, int flags) -{ - struct fe_softc *sc = device_get_softc(dev); - struct resource *res; - int rid; - - rid = 0; - res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE | flags); - if (res) { - sc->irq_res = res; - return (0); - } - - return (ENOENT); -} - -void -fe_release_resource(device_t dev) -{ - struct fe_softc *sc = device_get_softc(dev); - - if (sc->port_res) { - bus_release_resource(dev, SYS_RES_IOPORT, 0, sc->port_res); - sc->port_res = NULL; - } - if (sc->irq_res) { - bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq_res); - sc->irq_res = NULL; - } -} - -/* - * Reset interface, after some (hardware) trouble is deteced. - */ -static void -fe_reset (struct fe_softc *sc) -{ - /* Record how many packets are lost by this accident. */ - if_inc_counter(sc->ifp, IFCOUNTER_OERRORS, sc->txb_sched + sc->txb_count); - sc->mibdata.dot3StatsInternalMacTransmitErrors++; - - /* Put the interface into known initial state. */ - fe_stop(sc); - if (sc->ifp->if_flags & IFF_UP) - fe_init_locked(sc); -} - -/* - * Stop everything on the interface. - * - * All buffered packets, both transmitting and receiving, - * if any, will be lost by stopping the interface. - */ -void -fe_stop (struct fe_softc *sc) -{ - - FE_ASSERT_LOCKED(sc); - - /* Disable interrupts. */ - fe_outb(sc, FE_DLCR2, 0x00); - fe_outb(sc, FE_DLCR3, 0x00); - - /* Stop interface hardware. */ - DELAY(200); - fe_outb(sc, FE_DLCR6, sc->proto_dlcr6 | FE_D6_DLC_DISABLE); - DELAY(200); - - /* Clear all interrupt status. */ - fe_outb(sc, FE_DLCR0, 0xFF); - fe_outb(sc, FE_DLCR1, 0xFF); - - /* Put the chip in stand-by mode. */ - DELAY(200); - fe_outb(sc, FE_DLCR7, sc->proto_dlcr7 | FE_D7_POWER_DOWN); - DELAY(200); - - /* Reset transmitter variables and interface flags. */ - sc->ifp->if_drv_flags &= ~(IFF_DRV_OACTIVE | IFF_DRV_RUNNING); - sc->tx_timeout = 0; - callout_stop(&sc->timer); - sc->txb_free = sc->txb_size; - sc->txb_count = 0; - sc->txb_sched = 0; - - /* MAR loading can be delayed. */ - sc->filter_change = 0; - - /* Call a device-specific hook. */ - if (sc->stop) - sc->stop(sc); -} - -/* - * Device timeout/watchdog routine. Entered if the device neglects to - * generate an interrupt after a transmit has been started on it. - */ -static void -fe_watchdog (void *arg) -{ - struct fe_softc *sc = arg; - - FE_ASSERT_LOCKED(sc); - - if (sc->tx_timeout && --sc->tx_timeout == 0) { - struct ifnet *ifp = sc->ifp; - - /* A "debug" message. */ - if_printf(ifp, "transmission timeout (%d+%d)%s\n", - sc->txb_sched, sc->txb_count, - (ifp->if_flags & IFF_UP) ? "" : " when down"); - if (ifp->if_get_counter(ifp, IFCOUNTER_OPACKETS) == 0 && - ifp->if_get_counter(ifp, IFCOUNTER_IPACKETS) == 0) - if_printf(ifp, "wrong IRQ setting in config?\n"); - fe_reset(sc); - } - callout_reset(&sc->timer, hz, fe_watchdog, sc); -} - -/* - * Initialize device. - */ -static void -fe_init (void * xsc) -{ - struct fe_softc *sc = xsc; - - FE_LOCK(sc); - fe_init_locked(sc); - FE_UNLOCK(sc); -} - -static void -fe_init_locked (struct fe_softc *sc) -{ - - /* Start initializing 86960. */ - - /* Call a hook before we start initializing the chip. */ - if (sc->init) - sc->init(sc); - - /* - * Make sure to disable the chip, also. - * This may also help re-programming the chip after - * hot insertion of PCMCIAs. - */ - DELAY(200); - fe_outb(sc, FE_DLCR6, sc->proto_dlcr6 | FE_D6_DLC_DISABLE); - DELAY(200); - - /* Power up the chip and select register bank for DLCRs. */ - DELAY(200); - fe_outb(sc, FE_DLCR7, - sc->proto_dlcr7 | FE_D7_RBS_DLCR | FE_D7_POWER_UP); - DELAY(200); - - /* Feed the station address. */ - fe_outblk(sc, FE_DLCR8, IF_LLADDR(sc->ifp), ETHER_ADDR_LEN); - - /* Clear multicast address filter to receive nothing. */ - fe_outb(sc, FE_DLCR7, - sc->proto_dlcr7 | FE_D7_RBS_MAR | FE_D7_POWER_UP); - fe_outblk(sc, FE_MAR8, fe_filter_nothing.data, FE_FILTER_LEN); - - /* Select the BMPR bank for runtime register access. */ - fe_outb(sc, FE_DLCR7, - sc->proto_dlcr7 | FE_D7_RBS_BMPR | FE_D7_POWER_UP); - - /* Initialize registers. */ - fe_outb(sc, FE_DLCR0, 0xFF); /* Clear all bits. */ - fe_outb(sc, FE_DLCR1, 0xFF); /* ditto. */ - fe_outb(sc, FE_DLCR2, 0x00); - fe_outb(sc, FE_DLCR3, 0x00); - fe_outb(sc, FE_DLCR4, sc->proto_dlcr4); - fe_outb(sc, FE_DLCR5, sc->proto_dlcr5); - fe_outb(sc, FE_BMPR10, 0x00); - fe_outb(sc, FE_BMPR11, FE_B11_CTRL_SKIP | FE_B11_MODE1); - fe_outb(sc, FE_BMPR12, 0x00); - fe_outb(sc, FE_BMPR13, sc->proto_bmpr13); - fe_outb(sc, FE_BMPR14, 0x00); - fe_outb(sc, FE_BMPR15, 0x00); - - /* Enable interrupts. */ - fe_outb(sc, FE_DLCR2, FE_TMASK); - fe_outb(sc, FE_DLCR3, FE_RMASK); - - /* Select requested media, just before enabling DLC. */ - if (sc->msel) - sc->msel(sc); - - /* Enable transmitter and receiver. */ - DELAY(200); - fe_outb(sc, FE_DLCR6, sc->proto_dlcr6 | FE_D6_DLC_ENABLE); - DELAY(200); - -#ifdef DIAGNOSTIC - /* - * Make sure to empty the receive buffer. - * - * This may be redundant, but *if* the receive buffer were full - * at this point, then the driver would hang. I have experienced - * some strange hang-up just after UP. I hope the following - * code solve the problem. - * - * I have changed the order of hardware initialization. - * I think the receive buffer cannot have any packets at this - * point in this version. The following code *must* be - * redundant now. FIXME. - * - * I've heard a rumore that on some PC Card implementation of - * 8696x, the receive buffer can have some data at this point. - * The following message helps discovering the fact. FIXME. - */ - if (!(fe_inb(sc, FE_DLCR5) & FE_D5_BUFEMP)) { - if_printf(sc->ifp, - "receive buffer has some data after reset\n"); - fe_emptybuffer(sc); - } - - /* Do we need this here? Actually, no. I must be paranoia. */ - fe_outb(sc, FE_DLCR0, 0xFF); /* Clear all bits. */ - fe_outb(sc, FE_DLCR1, 0xFF); /* ditto. */ -#endif - - /* Set 'running' flag, because we are now running. */ - sc->ifp->if_drv_flags |= IFF_DRV_RUNNING; - callout_reset(&sc->timer, hz, fe_watchdog, sc); - - /* - * At this point, the interface is running properly, - * except that it receives *no* packets. we then call - * fe_setmode() to tell the chip what packets to be - * received, based on the if_flags and multicast group - * list. It completes the initialization process. - */ - fe_setmode(sc); - -#if 0 - /* ...and attempt to start output queued packets. */ - /* TURNED OFF, because the semi-auto media prober wants to UP - the interface keeping it idle. The upper layer will soon - start the interface anyway, and there are no significant - delay. */ - fe_start_locked(sc->ifp); -#endif -} - -/* - * This routine actually starts the transmission on the interface - */ -static void -fe_xmit (struct fe_softc *sc) -{ - /* - * Set a timer just in case we never hear from the board again. - * We use longer timeout for multiple packet transmission. - * I'm not sure this timer value is appropriate. FIXME. - */ - sc->tx_timeout = 1 + sc->txb_count; - - /* Update txb variables. */ - sc->txb_sched = sc->txb_count; - sc->txb_count = 0; - sc->txb_free = sc->txb_size; - sc->tx_excolls = 0; - - /* Start transmitter, passing packets in TX buffer. */ - fe_outb(sc, FE_BMPR10, sc->txb_sched | FE_B10_START); -} - -/* - * Start output on interface. - * We make one assumption here: - * 1) that the IFF_DRV_OACTIVE flag is checked before this code is called - * (i.e. that the output part of the interface is idle) - */ -static void -fe_start (struct ifnet *ifp) -{ - struct fe_softc *sc = ifp->if_softc; - - FE_LOCK(sc); - fe_start_locked(ifp); - FE_UNLOCK(sc); -} - -static void -fe_start_locked (struct ifnet *ifp) -{ - struct fe_softc *sc = ifp->if_softc; - struct mbuf *m; - -#ifdef DIAGNOSTIC - /* Just a sanity check. */ - if ((sc->txb_count == 0) != (sc->txb_free == sc->txb_size)) { - /* - * Txb_count and txb_free co-works to manage the - * transmission buffer. Txb_count keeps track of the - * used potion of the buffer, while txb_free does unused - * potion. So, as long as the driver runs properly, - * txb_count is zero if and only if txb_free is same - * as txb_size (which represents whole buffer.) - */ - if_printf(ifp, "inconsistent txb variables (%d, %d)\n", - sc->txb_count, sc->txb_free); - /* - * So, what should I do, then? - * - * We now know txb_count and txb_free contradicts. We - * cannot, however, tell which is wrong. More - * over, we cannot peek 86960 transmission buffer or - * reset the transmission buffer. (In fact, we can - * reset the entire interface. I don't want to do it.) - * - * If txb_count is incorrect, leaving it as-is will cause - * sending of garbage after next interrupt. We have to - * avoid it. Hence, we reset the txb_count here. If - * txb_free was incorrect, resetting txb_count just loses - * some packets. We can live with it. - */ - sc->txb_count = 0; - } -#endif - - /* - * First, see if there are buffered packets and an idle - * transmitter - should never happen at this point. - */ - if ((sc->txb_count > 0) && (sc->txb_sched == 0)) { - if_printf(ifp, "transmitter idle with %d buffered packets\n", - sc->txb_count); - fe_xmit(sc); - } - - /* - * Stop accepting more transmission packets temporarily, when - * a filter change request is delayed. Updating the MARs on - * 86960 flushes the transmission buffer, so it is delayed - * until all buffered transmission packets have been sent - * out. - */ - if (sc->filter_change) { - /* - * Filter change request is delayed only when the DLC is - * working. DLC soon raise an interrupt after finishing - * the work. - */ - goto indicate_active; - } - - for (;;) { - - /* - * See if there is room to put another packet in the buffer. - * We *could* do better job by peeking the send queue to - * know the length of the next packet. Current version just - * tests against the worst case (i.e., longest packet). FIXME. - * - * When adding the packet-peek feature, don't forget adding a - * test on txb_count against QUEUEING_MAX. - * There is a little chance the packet count exceeds - * the limit. Assume transmission buffer is 8KB (2x8KB - * configuration) and an application sends a bunch of small - * (i.e., minimum packet sized) packets rapidly. An 8KB - * buffer can hold 130 blocks of 62 bytes long... - */ - if (sc->txb_free - < ETHER_MAX_LEN - ETHER_CRC_LEN + FE_DATA_LEN_LEN) { - /* No room. */ - goto indicate_active; - } - -#if FE_SINGLE_TRANSMISSION - if (sc->txb_count > 0) { - /* Just one packet per a transmission buffer. */ - goto indicate_active; - } -#endif - - /* - * Get the next mbuf chain for a packet to send. - */ - IF_DEQUEUE(&sc->ifp->if_snd, m); - if (m == NULL) { - /* No more packets to send. */ - goto indicate_inactive; - } - - /* - * Copy the mbuf chain into the transmission buffer. - * txb_* variables are updated as necessary. - */ - fe_write_mbufs(sc, m); - - /* Start transmitter if it's idle. */ - if ((sc->txb_count > 0) && (sc->txb_sched == 0)) - fe_xmit(sc); - - /* - * Tap off here if there is a bpf listener, - * and the device is *not* in promiscuous mode. - * (86960 receives self-generated packets if - * and only if it is in "receive everything" - * mode.) - */ - if (!(sc->ifp->if_flags & IFF_PROMISC)) - BPF_MTAP(sc->ifp, m); - - m_freem(m); - } - - indicate_inactive: - /* - * We are using the !OACTIVE flag to indicate to - * the outside world that we can accept an - * additional packet rather than that the - * transmitter is _actually_ active. Indeed, the - * transmitter may be active, but if we haven't - * filled all the buffers with data then we still - * want to accept more. - */ - sc->ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - return; - - indicate_active: - /* - * The transmitter is active, and there are no room for - * more outgoing packets in the transmission buffer. - */ - sc->ifp->if_drv_flags |= IFF_DRV_OACTIVE; - return; -} - -/* - * Drop (skip) a packet from receive buffer in 86960 memory. - */ -static void -fe_droppacket (struct fe_softc * sc, int len) -{ - int i; - - /* - * 86960 manual says that we have to read 8 bytes from the buffer - * before skip the packets and that there must be more than 8 bytes - * remaining in the buffer when issue a skip command. - * Remember, we have already read 4 bytes before come here. - */ - if (len > 12) { - /* Read 4 more bytes, and skip the rest of the packet. */ - if ((sc->proto_dlcr6 & FE_D6_SBW) == FE_D6_SBW_BYTE) - { - (void) fe_inb(sc, FE_BMPR8); - (void) fe_inb(sc, FE_BMPR8); - (void) fe_inb(sc, FE_BMPR8); - (void) fe_inb(sc, FE_BMPR8); - } - else - { - (void) fe_inw(sc, FE_BMPR8); - (void) fe_inw(sc, FE_BMPR8); - } - fe_outb(sc, FE_BMPR14, FE_B14_SKIP); - } else { - /* We should not come here unless receiving RUNTs. */ - if ((sc->proto_dlcr6 & FE_D6_SBW) == FE_D6_SBW_BYTE) - { - for (i = 0; i < len; i++) - (void) fe_inb(sc, FE_BMPR8); - } - else - { - for (i = 0; i < len; i += 2) - (void) fe_inw(sc, FE_BMPR8); - } - } -} - -#ifdef DIAGNOSTIC -/* - * Empty receiving buffer. - */ -static void -fe_emptybuffer (struct fe_softc * sc) -{ - int i; - u_char saved_dlcr5; - -#ifdef FE_DEBUG - if_printf(sc->ifp, "emptying receive buffer\n"); -#endif - - /* - * Stop receiving packets, temporarily. - */ - saved_dlcr5 = fe_inb(sc, FE_DLCR5); - fe_outb(sc, FE_DLCR5, sc->proto_dlcr5); - DELAY(1300); - - /* - * When we come here, the receive buffer management may - * have been broken. So, we cannot use skip operation. - * Just discard everything in the buffer. - */ - if ((sc->proto_dlcr6 & FE_D6_SBW) == FE_D6_SBW_BYTE) - { - for (i = 0; i < 65536; i++) { - if (fe_inb(sc, FE_DLCR5) & FE_D5_BUFEMP) - break; - (void) fe_inb(sc, FE_BMPR8); - } - } - else - { - for (i = 0; i < 65536; i += 2) { - if (fe_inb(sc, FE_DLCR5) & FE_D5_BUFEMP) - break; - (void) fe_inw(sc, FE_BMPR8); - } - } - - /* - * Double check. - */ - if (fe_inb(sc, FE_DLCR5) & FE_D5_BUFEMP) { - if_printf(sc->ifp, - "could not empty receive buffer\n"); - /* Hmm. What should I do if this happens? FIXME. */ - } - - /* - * Restart receiving packets. - */ - fe_outb(sc, FE_DLCR5, saved_dlcr5); -} -#endif - -/* - * Transmission interrupt handler - * The control flow of this function looks silly. FIXME. - */ -static void -fe_tint (struct fe_softc * sc, u_char tstat) -{ - int left; - int col; - - /* - * Handle "excessive collision" interrupt. - */ - if (tstat & FE_D0_COLL16) { - - /* - * Find how many packets (including this collided one) - * are left unsent in transmission buffer. - */ - left = fe_inb(sc, FE_BMPR10); - if_printf(sc->ifp, "excessive collision (%d/%d)\n", - left, sc->txb_sched); - - /* - * Clear the collision flag (in 86960) here - * to avoid confusing statistics. - */ - fe_outb(sc, FE_DLCR0, FE_D0_COLLID); - - /* - * Restart transmitter, skipping the - * collided packet. - * - * We *must* skip the packet to keep network running - * properly. Excessive collision error is an - * indication of the network overload. If we - * tried sending the same packet after excessive - * collision, the network would be filled with - * out-of-time packets. Packets belonging - * to reliable transport (such as TCP) are resent - * by some upper layer. - */ - fe_outb(sc, FE_BMPR11, FE_B11_CTRL_SKIP | FE_B11_MODE1); - - /* Update statistics. */ - sc->tx_excolls++; - } - - /* - * Handle "transmission complete" interrupt. - */ - if (tstat & FE_D0_TXDONE) { - - /* - * Add in total number of collisions on last - * transmission. We also clear "collision occurred" flag - * here. - * - * 86960 has a design flaw on collision count on multiple - * packet transmission. When we send two or more packets - * with one start command (that's what we do when the - * transmission queue is crowded), 86960 informs us number - * of collisions occurred on the last packet on the - * transmission only. Number of collisions on previous - * packets are lost. I have told that the fact is clearly - * stated in the Fujitsu document. - * - * I considered not to mind it seriously. Collision - * count is not so important, anyway. Any comments? FIXME. - */ - - if (fe_inb(sc, FE_DLCR0) & FE_D0_COLLID) { - - /* Clear collision flag. */ - fe_outb(sc, FE_DLCR0, FE_D0_COLLID); - - /* Extract collision count from 86960. */ - col = fe_inb(sc, FE_DLCR4); - col = (col & FE_D4_COL) >> FE_D4_COL_SHIFT; - if (col == 0) { - /* - * Status register indicates collisions, - * while the collision count is zero. - * This can happen after multiple packet - * transmission, indicating that one or more - * previous packet(s) had been collided. - * - * Since the accurate number of collisions - * has been lost, we just guess it as 1; - * Am I too optimistic? FIXME. - */ - col = 1; - } - if_inc_counter(sc->ifp, IFCOUNTER_COLLISIONS, col); - if (col == 1) - sc->mibdata.dot3StatsSingleCollisionFrames++; - else - sc->mibdata.dot3StatsMultipleCollisionFrames++; - sc->mibdata.dot3StatsCollFrequencies[col-1]++; - } - - /* - * Update transmission statistics. - * Be sure to reflect number of excessive collisions. - */ - col = sc->tx_excolls; - if_inc_counter(sc->ifp, IFCOUNTER_OPACKETS, sc->txb_sched - col); - if_inc_counter(sc->ifp, IFCOUNTER_OERRORS, col); - if_inc_counter(sc->ifp, IFCOUNTER_COLLISIONS, col * 16); - sc->mibdata.dot3StatsExcessiveCollisions += col; - sc->mibdata.dot3StatsCollFrequencies[15] += col; - sc->txb_sched = 0; - - /* - * The transmitter is no more active. - * Reset output active flag and watchdog timer. - */ - sc->ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - sc->tx_timeout = 0; - - /* - * If more data is ready to transmit in the buffer, start - * transmitting them. Otherwise keep transmitter idle, - * even if more data is queued. This gives receive - * process a slight priority. - */ - if (sc->txb_count > 0) - fe_xmit(sc); - } -} - -/* - * Ethernet interface receiver interrupt. - */ -static void -fe_rint (struct fe_softc * sc, u_char rstat) -{ - u_short len; - u_char status; - int i; - - /* - * Update statistics if this interrupt is caused by an error. - * Note that, when the system was not sufficiently fast, the - * receive interrupt might not be acknowledged immediately. If - * one or more errornous frames were received before this routine - * was scheduled, they are ignored, and the following error stats - * give less than real values. - */ - if (rstat & (FE_D1_OVRFLO | FE_D1_CRCERR | FE_D1_ALGERR | FE_D1_SRTPKT)) { - if (rstat & FE_D1_OVRFLO) - sc->mibdata.dot3StatsInternalMacReceiveErrors++; - if (rstat & FE_D1_CRCERR) - sc->mibdata.dot3StatsFCSErrors++; - if (rstat & FE_D1_ALGERR) - sc->mibdata.dot3StatsAlignmentErrors++; -#if 0 - /* The reference MAC receiver defined in 802.3 - silently ignores short frames (RUNTs) without - notifying upper layer. RFC 1650 (dot3 MIB) is - based on the 802.3, and it has no stats entry for - RUNTs... */ - if (rstat & FE_D1_SRTPKT) - sc->mibdata.dot3StatsFrameTooShorts++; /* :-) */ -#endif - if_inc_counter(sc->ifp, IFCOUNTER_IERRORS, 1); - } - - /* - * MB86960 has a flag indicating "receive queue empty." - * We just loop, checking the flag, to pull out all received - * packets. - * - * We limit the number of iterations to avoid infinite-loop. - * The upper bound is set to unrealistic high value. - */ - for (i = 0; i < FE_MAX_RECV_COUNT * 2; i++) { - - /* Stop the iteration if 86960 indicates no packets. */ - if (fe_inb(sc, FE_DLCR5) & FE_D5_BUFEMP) - return; - - /* - * Extract a receive status byte. - * As our 86960 is in 16 bit bus access mode, we have to - * use inw() to get the status byte. The significant - * value is returned in lower 8 bits. - */ - if ((sc->proto_dlcr6 & FE_D6_SBW) == FE_D6_SBW_BYTE) - { - status = fe_inb(sc, FE_BMPR8); - (void) fe_inb(sc, FE_BMPR8); - } - else - { - status = (u_char) fe_inw(sc, FE_BMPR8); - } - - /* - * Extract the packet length. - * It is a sum of a header (14 bytes) and a payload. - * CRC has been stripped off by the 86960. - */ - if ((sc->proto_dlcr6 & FE_D6_SBW) == FE_D6_SBW_BYTE) - { - len = fe_inb(sc, FE_BMPR8); - len |= (fe_inb(sc, FE_BMPR8) << 8); - } - else - { - len = fe_inw(sc, FE_BMPR8); - } - - /* - * AS our 86960 is programed to ignore errored frame, - * we must not see any error indication in the - * receive buffer. So, any error condition is a - * serious error, e.g., out-of-sync of the receive - * buffer pointers. - */ - if ((status & 0xF0) != 0x20 || - len > ETHER_MAX_LEN - ETHER_CRC_LEN || - len < ETHER_MIN_LEN - ETHER_CRC_LEN) { - if_printf(sc->ifp, - "RX buffer out-of-sync\n"); - if_inc_counter(sc->ifp, IFCOUNTER_IERRORS, 1); - sc->mibdata.dot3StatsInternalMacReceiveErrors++; - fe_reset(sc); - return; - } - - /* - * Go get a packet. - */ - if (fe_get_packet(sc, len) < 0) { - /* - * Negative return from fe_get_packet() - * indicates no available mbuf. We stop - * receiving packets, even if there are more - * in the buffer. We hope we can get more - * mbuf next time. - */ - if_inc_counter(sc->ifp, IFCOUNTER_IERRORS, 1); - sc->mibdata.dot3StatsMissedFrames++; - fe_droppacket(sc, len); - return; - } - - /* Successfully received a packet. Update stat. */ - if_inc_counter(sc->ifp, IFCOUNTER_IPACKETS, 1); - } - - /* Maximum number of frames has been received. Something - strange is happening here... */ - if_printf(sc->ifp, "unusual receive flood\n"); - sc->mibdata.dot3StatsInternalMacReceiveErrors++; - fe_reset(sc); -} - -/* - * Ethernet interface interrupt processor - */ -static void -fe_intr (void *arg) -{ - struct fe_softc *sc = arg; - u_char tstat, rstat; - int loop_count = FE_MAX_LOOP; - - FE_LOCK(sc); - - /* Loop until there are no more new interrupt conditions. */ - while (loop_count-- > 0) { - /* - * Get interrupt conditions, masking unneeded flags. - */ - tstat = fe_inb(sc, FE_DLCR0) & FE_TMASK; - rstat = fe_inb(sc, FE_DLCR1) & FE_RMASK; - if (tstat == 0 && rstat == 0) { - FE_UNLOCK(sc); - return; - } - - /* - * Reset the conditions we are acknowledging. - */ - fe_outb(sc, FE_DLCR0, tstat); - fe_outb(sc, FE_DLCR1, rstat); - - /* - * Handle transmitter interrupts. - */ - if (tstat) - fe_tint(sc, tstat); - - /* - * Handle receiver interrupts - */ - if (rstat) - fe_rint(sc, rstat); - - /* - * Update the multicast address filter if it is - * needed and possible. We do it now, because - * we can make sure the transmission buffer is empty, - * and there is a good chance that the receive queue - * is empty. It will minimize the possibility of - * packet loss. - */ - if (sc->filter_change && - sc->txb_count == 0 && sc->txb_sched == 0) { - fe_loadmar(sc); - sc->ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - } - - /* - * If it looks like the transmitter can take more data, - * attempt to start output on the interface. This is done - * after handling the receiver interrupt to give the - * receive operation priority. - * - * BTW, I'm not sure in what case the OACTIVE is on at - * this point. Is the following test redundant? - * - * No. This routine polls for both transmitter and - * receiver interrupts. 86960 can raise a receiver - * interrupt when the transmission buffer is full. - */ - if ((sc->ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0) - fe_start_locked(sc->ifp); - } - FE_UNLOCK(sc); - - if_printf(sc->ifp, "too many loops\n"); -} - -/* - * Process an ioctl request. This code needs some work - it looks - * pretty ugly. - */ -static int -fe_ioctl (struct ifnet * ifp, u_long command, caddr_t data) -{ - struct fe_softc *sc = ifp->if_softc; - struct ifreq *ifr = (struct ifreq *)data; - int error = 0; - - switch (command) { - - case SIOCSIFFLAGS: - /* - * Switch interface state between "running" and - * "stopped", reflecting the UP flag. - */ - FE_LOCK(sc); - if (sc->ifp->if_flags & IFF_UP) { - if ((sc->ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) - fe_init_locked(sc); - } else { - if ((sc->ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) - fe_stop(sc); - } - - /* - * Promiscuous and/or multicast flags may have changed, - * so reprogram the multicast filter and/or receive mode. - */ - fe_setmode(sc); - FE_UNLOCK(sc); - - /* Done. */ - break; - - case SIOCADDMULTI: - case SIOCDELMULTI: - /* - * Multicast list has changed; set the hardware filter - * accordingly. - */ - FE_LOCK(sc); - fe_setmode(sc); - FE_UNLOCK(sc); - break; - - case SIOCSIFMEDIA: - case SIOCGIFMEDIA: - /* Let if_media to handle these commands and to call - us back. */ - error = ifmedia_ioctl(ifp, ifr, &sc->media, command); - break; - - default: - error = ether_ioctl(ifp, command, data); - break; - } - - return (error); -} - -/* - * Retrieve packet from receive buffer and send to the next level up via - * ether_input(). - * Returns 0 if success, -1 if error (i.e., mbuf allocation failure). - */ -static int -fe_get_packet (struct fe_softc * sc, u_short len) -{ - struct ifnet *ifp = sc->ifp; - struct ether_header *eh; - struct mbuf *m; - - FE_ASSERT_LOCKED(sc); - - /* - * NFS wants the data be aligned to the word (4 byte) - * boundary. Ethernet header has 14 bytes. There is a - * 2-byte gap. - */ -#define NFS_MAGIC_OFFSET 2 - - /* - * This function assumes that an Ethernet packet fits in an - * mbuf (with a cluster attached when necessary.) On FreeBSD - * 2.0 for x86, which is the primary target of this driver, an - * mbuf cluster has 4096 bytes, and we are happy. On ancient - * BSDs, such as vanilla 4.3 for 386, a cluster size was 1024, - * however. If the following #error message were printed upon - * compile, you need to rewrite this function. - */ -#if ( MCLBYTES < ETHER_MAX_LEN - ETHER_CRC_LEN + NFS_MAGIC_OFFSET ) -#error "Too small MCLBYTES to use fe driver." -#endif - - /* - * Our strategy has one more problem. There is a policy on - * mbuf cluster allocation. It says that we must have at - * least MINCLSIZE (208 bytes on FreeBSD 2.0 for x86) to - * allocate a cluster. For a packet of a size between - * (MHLEN - 2) to (MINCLSIZE - 2), our code violates the rule... - * On the other hand, the current code is short, simple, - * and fast, however. It does no harmful thing, just waists - * some memory. Any comments? FIXME. - */ - - /* Allocate an mbuf with packet header info. */ - MGETHDR(m, M_NOWAIT, MT_DATA); - if (m == NULL) - return -1; - - /* Attach a cluster if this packet doesn't fit in a normal mbuf. */ - if (len > MHLEN - NFS_MAGIC_OFFSET) { - if (!(MCLGET(m, M_NOWAIT))) { - m_freem(m); - return -1; - } - } - - /* Initialize packet header info. */ - m->m_pkthdr.rcvif = ifp; - m->m_pkthdr.len = len; - - /* Set the length of this packet. */ - m->m_len = len; - - /* The following silliness is to make NFS happy */ - m->m_data += NFS_MAGIC_OFFSET; - - /* Get (actually just point to) the header part. */ - eh = mtod(m, struct ether_header *); - - /* Get a packet. */ - if ((sc->proto_dlcr6 & FE_D6_SBW) == FE_D6_SBW_BYTE) - { - fe_insb(sc, FE_BMPR8, (u_int8_t *)eh, len); - } - else - { - fe_insw(sc, FE_BMPR8, (u_int16_t *)eh, (len + 1) >> 1); - } - - /* Feed the packet to upper layer. */ - FE_UNLOCK(sc); - (*ifp->if_input)(ifp, m); - FE_LOCK(sc); - return 0; -} - -/* - * Write an mbuf chain to the transmission buffer memory using 16 bit PIO. - * Returns number of bytes actually written, including length word. - * - * If an mbuf chain is too long for an Ethernet frame, it is not sent. - * Packets shorter than Ethernet minimum are legal, and we pad them - * before sending out. An exception is "partial" packets which are - * shorter than mandatory Ethernet header. - */ -static void -fe_write_mbufs (struct fe_softc *sc, struct mbuf *m) -{ - u_short length, len; - struct mbuf *mp; - u_char *data; - u_short savebyte; /* WARNING: Architecture dependent! */ -#define NO_PENDING_BYTE 0xFFFF - - static u_char padding [ETHER_MIN_LEN - ETHER_CRC_LEN - ETHER_HDR_LEN]; - -#ifdef DIAGNOSTIC - /* First, count up the total number of bytes to copy */ - length = 0; - for (mp = m; mp != NULL; mp = mp->m_next) - length += mp->m_len; - - /* Check if this matches the one in the packet header. */ - if (length != m->m_pkthdr.len) { - if_printf(sc->ifp, - "packet length mismatch? (%d/%d)\n", - length, m->m_pkthdr.len); - } -#else - /* Just use the length value in the packet header. */ - length = m->m_pkthdr.len; -#endif - -#ifdef DIAGNOSTIC - /* - * Should never send big packets. If such a packet is passed, - * it should be a bug of upper layer. We just ignore it. - * ... Partial (too short) packets, neither. - */ - if (length < ETHER_HDR_LEN || - length > ETHER_MAX_LEN - ETHER_CRC_LEN) { - if_printf(sc->ifp, - "got an out-of-spec packet (%u bytes) to send\n", length); - if_inc_counter(sc->ifp, IFCOUNTER_OERRORS, 1); - sc->mibdata.dot3StatsInternalMacTransmitErrors++; - return; - } -#endif - - /* - * Put the length word for this frame. - * Does 86960 accept odd length? -- Yes. - * Do we need to pad the length to minimum size by ourselves? - * -- Generally yes. But for (or will be) the last - * packet in the transmission buffer, we can skip the - * padding process. It may gain performance slightly. FIXME. - */ - if ((sc->proto_dlcr6 & FE_D6_SBW) == FE_D6_SBW_BYTE) - { - len = max(length, ETHER_MIN_LEN - ETHER_CRC_LEN); - fe_outb(sc, FE_BMPR8, len & 0x00ff); - fe_outb(sc, FE_BMPR8, (len & 0xff00) >> 8); - } - else - { - fe_outw(sc, FE_BMPR8, - max(length, ETHER_MIN_LEN - ETHER_CRC_LEN)); - } - - /* - * Update buffer status now. - * Truncate the length up to an even number, since we use outw(). - */ - if ((sc->proto_dlcr6 & FE_D6_SBW) != FE_D6_SBW_BYTE) - { - length = (length + 1) & ~1; - } - sc->txb_free -= FE_DATA_LEN_LEN + - max(length, ETHER_MIN_LEN - ETHER_CRC_LEN); - sc->txb_count++; - - /* - * Transfer the data from mbuf chain to the transmission buffer. - * MB86960 seems to require that data be transferred as words, and - * only words. So that we require some extra code to patch - * over odd-length mbufs. - */ - if ((sc->proto_dlcr6 & FE_D6_SBW) == FE_D6_SBW_BYTE) - { - /* 8-bit cards are easy. */ - for (mp = m; mp != NULL; mp = mp->m_next) { - if (mp->m_len) - fe_outsb(sc, FE_BMPR8, mtod(mp, caddr_t), - mp->m_len); - } - } - else - { - /* 16-bit cards are a pain. */ - savebyte = NO_PENDING_BYTE; - for (mp = m; mp != NULL; mp = mp->m_next) { - - /* Ignore empty mbuf. */ - len = mp->m_len; - if (len == 0) - continue; - - /* Find the actual data to send. */ - data = mtod(mp, caddr_t); - - /* Finish the last byte. */ - if (savebyte != NO_PENDING_BYTE) { - fe_outw(sc, FE_BMPR8, savebyte | (*data << 8)); - data++; - len--; - savebyte = NO_PENDING_BYTE; - } - - /* output contiguous words */ - if (len > 1) { - fe_outsw(sc, FE_BMPR8, (u_int16_t *)data, - len >> 1); - data += len & ~1; - len &= 1; - } - - /* Save a remaining byte, if there is one. */ - if (len > 0) - savebyte = *data; - } - - /* Spit the last byte, if the length is odd. */ - if (savebyte != NO_PENDING_BYTE) - fe_outw(sc, FE_BMPR8, savebyte); - } - - /* Pad to the Ethernet minimum length, if the packet is too short. */ - if (length < ETHER_MIN_LEN - ETHER_CRC_LEN) { - if ((sc->proto_dlcr6 & FE_D6_SBW) == FE_D6_SBW_BYTE) - { - fe_outsb(sc, FE_BMPR8, padding, - ETHER_MIN_LEN - ETHER_CRC_LEN - length); - } - else - { - fe_outsw(sc, FE_BMPR8, (u_int16_t *)padding, - (ETHER_MIN_LEN - ETHER_CRC_LEN - length) >> 1); - } - } -} - -/* - * Compute the multicast address filter from the - * list of multicast addresses we need to listen to. - */ -static struct fe_filter -fe_mcaf ( struct fe_softc *sc ) -{ - int index; - struct fe_filter filter; - struct ifmultiaddr *ifma; - - filter = fe_filter_nothing; - if_maddr_rlock(sc->ifp); - CK_STAILQ_FOREACH(ifma, &sc->ifp->if_multiaddrs, ifma_link) { - if (ifma->ifma_addr->sa_family != AF_LINK) - continue; - index = ether_crc32_le(LLADDR((struct sockaddr_dl *) - ifma->ifma_addr), ETHER_ADDR_LEN) >> 26; -#ifdef FE_DEBUG - if_printf(sc->ifp, "hash(%6D) == %d\n", - enm->enm_addrlo , ":", index); -#endif - - filter.data[index >> 3] |= 1 << (index & 7); - } - if_maddr_runlock(sc->ifp); - return ( filter ); -} - -/* - * Calculate a new "multicast packet filter" and put the 86960 - * receiver in appropriate mode. - */ -static void -fe_setmode (struct fe_softc *sc) -{ - - /* - * If the interface is not running, we postpone the update - * process for receive modes and multicast address filter - * until the interface is restarted. It reduces some - * complicated job on maintaining chip states. (Earlier versions - * of this driver had a bug on that point...) - * - * To complete the trick, fe_init() calls fe_setmode() after - * restarting the interface. - */ - if (!(sc->ifp->if_drv_flags & IFF_DRV_RUNNING)) - return; - - /* - * Promiscuous mode is handled separately. - */ - if (sc->ifp->if_flags & IFF_PROMISC) { - /* - * Program 86960 to receive all packets on the segment - * including those directed to other stations. - * Multicast filter stored in MARs are ignored - * under this setting, so we don't need to update it. - * - * Promiscuous mode in FreeBSD 2 is used solely by - * BPF, and BPF only listens to valid (no error) packets. - * So, we ignore erroneous ones even in this mode. - * (Older versions of fe driver mistook the point.) - */ - fe_outb(sc, FE_DLCR5, - sc->proto_dlcr5 | FE_D5_AFM0 | FE_D5_AFM1); - sc->filter_change = 0; - return; - } - - /* - * Turn the chip to the normal (non-promiscuous) mode. - */ - fe_outb(sc, FE_DLCR5, sc->proto_dlcr5 | FE_D5_AFM1); - - /* - * Find the new multicast filter value. - */ - if (sc->ifp->if_flags & IFF_ALLMULTI) - sc->filter = fe_filter_all; - else - sc->filter = fe_mcaf(sc); - sc->filter_change = 1; - - /* - * We have to update the multicast filter in the 86960, A.S.A.P. - * - * Note that the DLC (Data Link Control unit, i.e. transmitter - * and receiver) must be stopped when feeding the filter, and - * DLC trashes all packets in both transmission and receive - * buffers when stopped. - * - * To reduce the packet loss, we delay the filter update - * process until buffers are empty. - */ - if (sc->txb_sched == 0 && sc->txb_count == 0 && - !(fe_inb(sc, FE_DLCR1) & FE_D1_PKTRDY)) { - /* - * Buffers are (apparently) empty. Load - * the new filter value into MARs now. - */ - fe_loadmar(sc); - } else { - /* - * Buffers are not empty. Mark that we have to update - * the MARs. The new filter will be loaded by feintr() - * later. - */ - } -} - -/* - * Load a new multicast address filter into MARs. - * - * The caller must have acquired the softc lock before fe_loadmar. - * This function starts the DLC upon return. So it can be called only - * when the chip is working, i.e., from the driver's point of view, when - * a device is RUNNING. (I mistook the point in previous versions.) - */ -static void -fe_loadmar (struct fe_softc * sc) -{ - /* Stop the DLC (transmitter and receiver). */ - DELAY(200); - fe_outb(sc, FE_DLCR6, sc->proto_dlcr6 | FE_D6_DLC_DISABLE); - DELAY(200); - - /* Select register bank 1 for MARs. */ - fe_outb(sc, FE_DLCR7, sc->proto_dlcr7 | FE_D7_RBS_MAR | FE_D7_POWER_UP); - - /* Copy filter value into the registers. */ - fe_outblk(sc, FE_MAR8, sc->filter.data, FE_FILTER_LEN); - - /* Restore the bank selection for BMPRs (i.e., runtime registers). */ - fe_outb(sc, FE_DLCR7, - sc->proto_dlcr7 | FE_D7_RBS_BMPR | FE_D7_POWER_UP); - - /* Restart the DLC. */ - DELAY(200); - fe_outb(sc, FE_DLCR6, sc->proto_dlcr6 | FE_D6_DLC_ENABLE); - DELAY(200); - - /* We have just updated the filter. */ - sc->filter_change = 0; -} - -/* Change the media selection. */ -static int -fe_medchange (struct ifnet *ifp) -{ - struct fe_softc *sc = (struct fe_softc *)ifp->if_softc; - -#ifdef DIAGNOSTIC - /* If_media should not pass any request for a media which this - interface doesn't support. */ - int b; - - for (b = 0; bit2media[b] != 0; b++) { - if (bit2media[b] == sc->media.ifm_media) break; - } - if (((1 << b) & sc->mbitmap) == 0) { - if_printf(sc->ifp, - "got an unsupported media request (0x%x)\n", - sc->media.ifm_media); - return EINVAL; - } -#endif - - /* We don't actually change media when the interface is down. - fe_init() will do the job, instead. Should we also wait - until the transmission buffer being empty? Changing the - media when we are sending a frame will cause two garbages - on wires, one on old media and another on new. FIXME */ - FE_LOCK(sc); - if (sc->ifp->if_flags & IFF_UP) { - if (sc->msel) sc->msel(sc); - } - FE_UNLOCK(sc); - - return 0; -} - -/* I don't know how I can support media status callback... FIXME. */ -static void -fe_medstat (struct ifnet *ifp, struct ifmediareq *ifmr) -{ - struct fe_softc *sc = ifp->if_softc; - - ifmr->ifm_active = sc->media.ifm_media; -} diff --git a/sys/dev/fe/if_fe_isa.c b/sys/dev/fe/if_fe_isa.c deleted file mode 100644 index c30c9340fc1c..000000000000 --- a/sys/dev/fe/if_fe_isa.c +++ /dev/null @@ -1,1063 +0,0 @@ -/*- - * All Rights Reserved, Copyright (C) Fujitsu Limited 1995 - * - * This software may be used, modified, copied, distributed, and sold, in - * both source and binary form provided that the above copyright, these - * terms and the following disclaimer are retained. The name of the author - * and/or the contributor may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND THE CONTRIBUTOR ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR THE CONTRIBUTOR 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 -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include - -#include -#include - -#include -#include -#include - -#include - -/* - * ISA specific code. - */ -static int fe_isa_probe(device_t); -static int fe_isa_attach(device_t); - -static device_method_t fe_isa_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, fe_isa_probe), - DEVMETHOD(device_attach, fe_isa_attach), - - { 0, 0 } -}; - -static driver_t fe_isa_driver = { - "fe", - fe_isa_methods, - sizeof (struct fe_softc) -}; - -static int fe_probe_ssi(device_t); -static int fe_probe_jli(device_t); -static int fe_probe_fmv(device_t); -static int fe_probe_lnx(device_t); -static int fe_probe_gwy(device_t); -static int fe_probe_ubn(device_t); - -/* - * Determine if the device is present at a specified I/O address. The - * main entry to the driver. - */ -static int -fe_isa_probe(device_t dev) -{ - struct fe_softc *sc; - int error; - - /* Check isapnp ids */ - if (isa_get_vendorid(dev)) - return (ENXIO); - - /* Prepare for the softc struct. */ - sc = device_get_softc(dev); - sc->sc_unit = device_get_unit(dev); - - /* Probe for supported boards. */ - if ((error = fe_probe_ssi(dev)) == 0) - goto end; - fe_release_resource(dev); - - if ((error = fe_probe_jli(dev)) == 0) - goto end; - fe_release_resource(dev); - - if ((error = fe_probe_fmv(dev)) == 0) - goto end; - fe_release_resource(dev); - - if ((error = fe_probe_lnx(dev)) == 0) - goto end; - fe_release_resource(dev); - - if ((error = fe_probe_ubn(dev)) == 0) - goto end; - fe_release_resource(dev); - - if ((error = fe_probe_gwy(dev)) == 0) - goto end; - fe_release_resource(dev); - -end: - if (error == 0) - error = fe_alloc_irq(dev, 0); - - fe_release_resource(dev); - return (error); -} - -static int -fe_isa_attach(device_t dev) -{ - struct fe_softc *sc = device_get_softc(dev); - int error = 0; - - /* - * Note: these routines aren't expected to fail since we also call - * them in the probe routine. But coverity complains, so we'll honor - * that complaint since the intention here was never to ignore them.. - */ - if (sc->port_used) { - error = fe_alloc_port(dev, sc->port_used); - if (error != 0) - return (error); - } - error = fe_alloc_irq(dev, 0); - if (error != 0) - return (error); - - return fe_attach(dev); -} - - -/* - * Probe and initialization for Fujitsu FMV-180 series boards - */ - -static void -fe_init_fmv(struct fe_softc *sc) -{ - /* Initialize ASIC. */ - fe_outb(sc, FE_FMV3, 0); - fe_outb(sc, FE_FMV10, 0); - -#if 0 - /* "Refresh" hardware configuration. FIXME. */ - fe_outb(sc, FE_FMV2, fe_inb(sc, FE_FMV2)); -#endif - - /* Turn the "master interrupt control" flag of ASIC on. */ - fe_outb(sc, FE_FMV3, FE_FMV3_IRQENB); -} - -static void -fe_msel_fmv184(struct fe_softc *sc) -{ - u_char port; - - /* FMV-184 has a special "register" to switch between AUI/BNC. - Determine the value to write into the register, based on the - user-specified media selection. */ - port = (IFM_SUBTYPE(sc->media.ifm_media) == IFM_10_2) ? 0x00 : 0x01; - - /* The register is #5 on exntesion register bank... - (Details of the register layout is not yet discovered.) */ - fe_outb(sc, 0x1B, 0x46); /* ??? */ - fe_outb(sc, 0x1E, 0x04); /* select ex-reg #4. */ - fe_outb(sc, 0x1F, 0xC8); /* ??? */ - fe_outb(sc, 0x1E, 0x05); /* select ex-reg #5. */ - fe_outb(sc, 0x1F, port); /* Switch the media. */ - fe_outb(sc, 0x1E, 0x04); /* select ex-reg #4. */ - fe_outb(sc, 0x1F, 0x00); /* ??? */ - fe_outb(sc, 0x1B, 0x00); /* ??? */ - - /* Make sure to select "external tranceiver" on MB86964. */ - fe_outb(sc, FE_BMPR13, sc->proto_bmpr13 | FE_B13_PORT_AUI); -} - -static int -fe_probe_fmv(device_t dev) -{ - struct fe_softc *sc = device_get_softc(dev); - int n; - rman_res_t iobase, irq; - - static u_short const irqmap [ 4 ] = { 3, 7, 10, 15 }; - - static struct fe_simple_probe_struct const probe_table [] = { - { FE_DLCR2, 0x71, 0x00 }, - { FE_DLCR4, 0x08, 0x00 }, - - { FE_FMV0, 0x78, 0x50 }, /* ERRDY+PRRDY */ - { FE_FMV1, 0xB0, 0x00 }, /* FMV-183/4 has 0x48 bits. */ - { FE_FMV3, 0x7F, 0x00 }, - - { 0 } - }; - - /* Board subtypes; it lists known FMV-180 variants. */ - struct subtype { - u_short mcode; - u_short mbitmap; - u_short defmedia; - char const * str; - }; - static struct subtype const typelist [] = { - { 0x0005, MB_HA|MB_HT|MB_H5, MB_HA, "FMV-181" }, - { 0x0105, MB_HA|MB_HT|MB_H5, MB_HA, "FMV-181A" }, - { 0x0003, MB_HM, MB_HM, "FMV-182" }, - { 0x0103, MB_HM, MB_HM, "FMV-182A" }, - { 0x0804, MB_HT, MB_HT, "FMV-183" }, - { 0x0C04, MB_HT, MB_HT, "FMV-183 (on-board)" }, - { 0x0803, MB_H2|MB_H5, MB_H2, "FMV-184" }, - { 0, MB_HA, MB_HA, "unknown FMV-180 (?)" }, - }; - struct subtype const * type; - - /* Media indicator and "Hardware revision ID" */ - u_short mcode; - - /* See if the specified address is possible for FMV-180 - series. 220, 240, 260, 280, 2A0, 2C0, 300, and 340 are - allowed for all boards, and 200, 2E0, 320, 360, 380, 3A0, - 3C0, and 3E0 for PnP boards. */ - if (bus_get_resource(dev, SYS_RES_IOPORT, 0, &iobase, NULL) != 0) - return ENXIO; - if ((iobase & ~0x1E0) != 0x200) - return ENXIO; - - /* FMV-180 occupies 32 I/O addresses. */ - if (fe_alloc_port(dev, 32)) - return ENXIO; - - /* Setup an I/O address mapping table and some others. */ - fe_softc_defaults(sc); - - /* Simple probe. */ - if (!fe_simple_probe(sc, probe_table)) - return ENXIO; - - /* Get our station address from EEPROM, and make sure it is - Fujitsu's. */ - fe_inblk(sc, FE_FMV4, sc->enaddr, ETHER_ADDR_LEN); - if (!fe_valid_Ether_p(sc->enaddr, 0x00000E)) - return ENXIO; - - /* Find the supported media and "hardware revision" to know - the model identification. */ - mcode = (fe_inb(sc, FE_FMV0) & FE_FMV0_MEDIA) - | ((fe_inb(sc, FE_FMV1) & FE_FMV1_REV) << 8); - - /* Determine the card type. */ - for (type = typelist; type->mcode != 0; type++) { - if (type->mcode == mcode) - break; - } - if (type->mcode == 0) { - /* Unknown card type... Hope the driver works. */ - sc->stability |= UNSTABLE_TYPE; - if (bootverbose) { - device_printf(dev, "unknown config: %x-%x-%x-%x\n", - fe_inb(sc, FE_FMV0), - fe_inb(sc, FE_FMV1), - fe_inb(sc, FE_FMV2), - fe_inb(sc, FE_FMV3)); - } - } - - /* Setup the board type and media information. */ - sc->type = FE_TYPE_FMV; - sc->typestr = type->str; - sc->mbitmap = type->mbitmap; - sc->defmedia = type->defmedia; - sc->msel = fe_msel_965; - - if (type->mbitmap == (MB_H2 | MB_H5)) { - /* FMV184 requires a special media selection procedure. */ - sc->msel = fe_msel_fmv184; - } - - /* - * An FMV-180 has been probed. - * Determine which IRQ to be used. - * - * In this version, we give a priority to the kernel config file. - * If the EEPROM and config don't match, say it to the user for - * an attention. - */ - n = (fe_inb(sc, FE_FMV2) & FE_FMV2_IRS) >> FE_FMV2_IRS_SHIFT; - - irq = 0; - bus_get_resource(dev, SYS_RES_IRQ, 0, &irq, NULL); - if (irq == NO_IRQ) { - /* Just use the probed value. */ - bus_set_resource(dev, SYS_RES_IRQ, 0, irqmap[n], 1); - } else if (irq != irqmap[n]) { - /* Don't match. */ - sc->stability |= UNSTABLE_IRQ; - } - - /* We need an init hook to initialize ASIC before we start. */ - sc->init = fe_init_fmv; - - return 0; -} - -/* - * Fujitsu MB86965 JLI mode probe routines. - * - * 86965 has a special operating mode called JLI (mode 0), under which - * the chip interfaces with ISA bus with a software-programmable - * configuration. (The Fujitsu document calls the feature "Plug and - * play," but it is not compatible with the ISA-PnP spec. designed by - * Intel and Microsoft.) Ethernet cards designed to use JLI are - * almost same, but there are two things which require board-specific - * probe routines: EEPROM layout and IRQ pin connection. - * - * JLI provides a handy way to access EEPROM which should contains the - * chip configuration information (such as I/O port address) as well - * as Ethernet station (MAC) address. The chip configuration info. is - * stored on a fixed location. However, the station address can be - * located anywhere in the EEPROM; it is up to the board designer to - * determine the location. (The manual just says "somewhere in the - * EEPROM.") The fe driver must somehow find out the correct - * location. - * - * Another problem resides in the IRQ pin connection. JLI provides a - * user to choose an IRQ from up to four predefined IRQs. The 86965 - * chip has a register to select one out of the four possibilities. - * However, the selection is against the four IRQ pins on the chip. - * (So-called IRQ-A, -B, -C and -D.) It is (again) up to the board - * designer to determine which pin to connect which IRQ line on the - * ISA bus. We need a vendor (or model, for some vendor) specific IRQ - * mapping table. - * - * The routine fe_probe_jli() provides all probe and initialization - * processes which are common to all JLI implementation, and sub-probe - * routines supply board-specific actions. - * - * JLI sub-probe routine has the following template: - * - * u_short const * func (struct fe_softc * sc, u_char const * eeprom); - * - * where eeprom is a pointer to an array of 32 byte data read from the - * config EEPROM on the board. It returns an IRQ mapping table for the - * board, when the corresponding implementation is detected. It - * returns a NULL otherwise. - * - * Primary purpose of the functin is to analize the config EEPROM, - * determine if it matches with the pattern of that of supported card, - * and extract necessary information from it. One of the information - * expected to be extracted from EEPROM is the Ethernet station (MAC) - * address, which must be set to the softc table of the interface by - * the board-specific routine. - */ - -/* JLI sub-probe for Allied-Telesyn/Allied-Telesis AT1700/RE2000 series. */ -static u_short const * -fe_probe_jli_ati(struct fe_softc * sc, u_char const * eeprom) -{ - int i; - static u_short const irqmaps_ati [4][4] = - { - { 3, 4, 5, 9 }, - { 10, 11, 12, 15 }, - { 3, 11, 5, 15 }, - { 10, 11, 14, 15 }, - }; - - /* Make sure the EEPROM contains Allied-Telesis/Allied-Telesyn - bit pattern. */ - if (eeprom[1] != 0x00) return NULL; - for (i = 2; i < 8; i++) if (eeprom[i] != 0xFF) return NULL; - for (i = 14; i < 24; i++) if (eeprom[i] != 0xFF) return NULL; - - /* Get our station address from EEPROM, and make sure the - EEPROM contains ATI's address. */ - bcopy(eeprom + 8, sc->enaddr, ETHER_ADDR_LEN); - if (!fe_valid_Ether_p(sc->enaddr, 0x0000F4)) - return NULL; - - /* - * The following model identification codes are stolen - * from the NetBSD port of the fe driver. My reviewers - * suggested minor revision. - */ - - /* Determine the card type. */ - switch (eeprom[FE_ATI_EEP_MODEL]) { - case FE_ATI_MODEL_AT1700T: - sc->typestr = "AT-1700T/RE2001"; - sc->mbitmap = MB_HT; - sc->defmedia = MB_HT; - break; - case FE_ATI_MODEL_AT1700BT: - sc->typestr = "AT-1700BT/RE2003"; - sc->mbitmap = MB_HA | MB_HT | MB_H2; - break; - case FE_ATI_MODEL_AT1700FT: - sc->typestr = "AT-1700FT/RE2009"; - sc->mbitmap = MB_HA | MB_HT | MB_HF; - break; - case FE_ATI_MODEL_AT1700AT: - sc->typestr = "AT-1700AT/RE2005"; - sc->mbitmap = MB_HA | MB_HT | MB_H5; - break; - default: - sc->typestr = "unknown AT-1700/RE2000"; - sc->stability |= UNSTABLE_TYPE | UNSTABLE_IRQ; - break; - } - sc->type = FE_TYPE_JLI; - -#if 0 - /* Should we extract default media from eeprom? Linux driver - for AT1700 does it, although previous releases of FreeBSD - don't. FIXME. */ - /* Determine the default media selection from the config - EEPROM. The byte at offset EEP_MEDIA is believed to - contain BMPR13 value to be set. We just ignore STP bit or - squelch bit, since we don't support those. (It is - intentional.) */ - switch (eeprom[FE_ATI_EEP_MEDIA] & FE_B13_PORT) { - case FE_B13_AUTO: - sc->defmedia = MB_HA; - break; - case FE_B13_TP: - sc->defmedia = MB_HT; - break; - case FE_B13_AUI: - sc->defmedia = sc->mbitmap & (MB_H2|MB_H5|MB_H5); /*XXX*/ - break; - default: - sc->defmedia = MB_HA; - break; - } - - /* Make sure the default media is compatible with the supported - ones. */ - if ((sc->defmedia & sc->mbitmap) == 0) { - if (sc->defmedia == MB_HA) { - sc->defmedia = MB_HT; - } else { - sc->defmedia = MB_HA; - } - } -#endif - - /* - * Try to determine IRQ settings. - * Different models use different ranges of IRQs. - */ - switch ((eeprom[FE_ATI_EEP_REVISION] & 0xf0) - |(eeprom[FE_ATI_EEP_MAGIC] & 0x04)) { - case 0x30: case 0x34: return irqmaps_ati[3]; - case 0x10: case 0x14: - case 0x50: case 0x54: return irqmaps_ati[2]; - case 0x44: case 0x64: return irqmaps_ati[1]; - default: return irqmaps_ati[0]; - } -} - -/* JLI sub-probe and msel hook for ICL Ethernet. */ -static void -fe_msel_icl(struct fe_softc *sc) -{ - u_char d4; - - /* Switch between UTP and "external tranceiver" as always. */ - fe_msel_965(sc); - - /* The board needs one more bit (on DLCR4) be set appropriately. */ - if (IFM_SUBTYPE(sc->media.ifm_media) == IFM_10_5) { - d4 = sc->proto_dlcr4 | FE_D4_CNTRL; - } else { - d4 = sc->proto_dlcr4 & ~FE_D4_CNTRL; - } - fe_outb(sc, FE_DLCR4, d4); -} - -static u_short const * -fe_probe_jli_icl(struct fe_softc * sc, u_char const * eeprom) -{ - int i; - u_short defmedia; - u_char d6; - static u_short const irqmap_icl [4] = { 9, 10, 5, 15 }; - - /* Make sure the EEPROM contains ICL bit pattern. */ - for (i = 24; i < 39; i++) { - if (eeprom[i] != 0x20 && (eeprom[i] & 0xF0) != 0x30) return NULL; - } - for (i = 112; i < 122; i++) { - if (eeprom[i] != 0x20 && (eeprom[i] & 0xF0) != 0x30) return NULL; - } - - /* Make sure the EEPROM contains ICL's permanent station - address. If it isn't, probably this board is not an - ICL's. */ - if (!fe_valid_Ether_p(eeprom+122, 0x00004B)) - return NULL; - - /* Check if the "configured" Ethernet address in the EEPROM is - valid. Use it if it is, or use the "permanent" address instead. */ - if (fe_valid_Ether_p(eeprom+4, 0x020000)) { - /* The configured address is valid. Use it. */ - bcopy(eeprom+4, sc->enaddr, ETHER_ADDR_LEN); - } else { - /* The configured address is invalid. Use permanent. */ - bcopy(eeprom+122, sc->enaddr, ETHER_ADDR_LEN); - } - - /* Determine model and supported media. */ - switch (eeprom[0x5E]) { - case 0: - sc->typestr = "EtherTeam16i/COMBO"; - sc->mbitmap = MB_HA | MB_HT | MB_H5 | MB_H2; - break; - case 1: - sc->typestr = "EtherTeam16i/TP"; - sc->mbitmap = MB_HT; - break; - case 2: - sc->typestr = "EtherTeam16i/ErgoPro"; - sc->mbitmap = MB_HA | MB_HT | MB_H5; - break; - case 4: - sc->typestr = "EtherTeam16i/DUO"; - sc->mbitmap = MB_HA | MB_HT | MB_H2; - break; - default: - sc->typestr = "EtherTeam16i"; - sc->stability |= UNSTABLE_TYPE; - if (bootverbose) { - printf("fe%d: unknown model code %02x for EtherTeam16i\n", - sc->sc_unit, eeprom[0x5E]); - } - break; - } - sc->type = FE_TYPE_JLI; - - /* I'm not sure the following msel hook is required by all - models or COMBO only... FIXME. */ - sc->msel = fe_msel_icl; - - /* Make the configured media selection the default media. */ - switch (eeprom[0x28]) { - case 0: defmedia = MB_HA; break; - case 1: defmedia = MB_H5; break; - case 2: defmedia = MB_HT; break; - case 3: defmedia = MB_H2; break; - default: - if (bootverbose) { - printf("fe%d: unknown default media: %02x\n", - sc->sc_unit, eeprom[0x28]); - } - defmedia = MB_HA; - break; - } - - /* Make sure the default media is compatible with the - supported media. */ - if ((defmedia & sc->mbitmap) == 0) { - if (bootverbose) { - printf("fe%d: default media adjusted\n", sc->sc_unit); - } - defmedia = sc->mbitmap; - } - - /* Keep the determined default media. */ - sc->defmedia = defmedia; - - /* ICL has "fat" models. We have to program 86965 to properly - reflect the hardware. */ - d6 = sc->proto_dlcr6 & ~(FE_D6_BUFSIZ | FE_D6_BBW); - switch ((eeprom[0x61] << 8) | eeprom[0x60]) { - case 0x2008: d6 |= FE_D6_BUFSIZ_32KB | FE_D6_BBW_BYTE; break; - case 0x4010: d6 |= FE_D6_BUFSIZ_64KB | FE_D6_BBW_WORD; break; - default: - /* We can't support it, since we don't know which bits - to set in DLCR6. */ - printf("fe%d: unknown SRAM config for ICL\n", sc->sc_unit); - return NULL; - } - sc->proto_dlcr6 = d6; - - /* Returns the IRQ table for the ICL board. */ - return irqmap_icl; -} - -/* JLI sub-probe for RATOC REX-5586/5587. */ -static u_short const * -fe_probe_jli_rex(struct fe_softc * sc, u_char const * eeprom) -{ - int i; - static u_short const irqmap_rex [4] = { 3, 4, 5, NO_IRQ }; - - /* Make sure the EEPROM contains RATOC's config pattern. */ - if (eeprom[1] != eeprom[0]) return NULL; - for (i = 8; i < 32; i++) if (eeprom[i] != 0xFF) return NULL; - - /* Get our station address from EEPROM. Note that RATOC - stores it "byte-swapped" in each word. (I don't know why.) - So, we just can't use bcopy().*/ - sc->enaddr[0] = eeprom[3]; - sc->enaddr[1] = eeprom[2]; - sc->enaddr[2] = eeprom[5]; - sc->enaddr[3] = eeprom[4]; - sc->enaddr[4] = eeprom[7]; - sc->enaddr[5] = eeprom[6]; - - /* Make sure the EEPROM contains RATOC's station address. */ - if (!fe_valid_Ether_p(sc->enaddr, 0x00C0D0)) - return NULL; - - /* I don't know any sub-model identification. */ - sc->type = FE_TYPE_JLI; - sc->typestr = "REX-5586/5587"; - - /* Returns the IRQ for the RATOC board. */ - return irqmap_rex; -} - -/* JLI sub-probe for Unknown board. */ -static u_short const * -fe_probe_jli_unk(struct fe_softc * sc, u_char const * eeprom) -{ - int i, n, romsize; - static u_short const irqmap [4] = { NO_IRQ, NO_IRQ, NO_IRQ, NO_IRQ }; - - /* The generic JLI probe considered this board has an 86965 - in JLI mode, but any other board-specific routines could - not find the matching implementation. So, we "guess" the - location by looking for a bit pattern which looks like a - MAC address. */ - - /* Determine how large the EEPROM is. */ - for (romsize = JLI_EEPROM_SIZE/2; romsize > 16; romsize >>= 1) { - for (i = 0; i < romsize; i++) { - if (eeprom[i] != eeprom[i+romsize]) - break; - } - if (i < romsize) - break; - } - romsize <<= 1; - - /* Look for a bit pattern which looks like a MAC address. */ - for (n = 2; n <= romsize - ETHER_ADDR_LEN; n += 2) { - if (!fe_valid_Ether_p(eeprom + n, 0x000000)) - continue; - } - - /* If no reasonable address was found, we can't go further. */ - if (n > romsize - ETHER_ADDR_LEN) - return NULL; - - /* Extract our (guessed) station address. */ - bcopy(eeprom+n, sc->enaddr, ETHER_ADDR_LEN); - - /* We are not sure what type of board it is... */ - sc->type = FE_TYPE_JLI; - sc->typestr = "(unknown JLI)"; - sc->stability |= UNSTABLE_TYPE | UNSTABLE_MAC; - - /* Returns the totally unknown IRQ mapping table. */ - return irqmap; -} - -/* - * Probe and initialization for all JLI implementations. - */ - -static int -fe_probe_jli(device_t dev) -{ - struct fe_softc *sc = device_get_softc(dev); - int i, n, error, xirq; - rman_res_t iobase, irq; - u_char eeprom [JLI_EEPROM_SIZE]; - u_short const * irqmap; - - static u_short const baseaddr [8] = - { 0x260, 0x280, 0x2A0, 0x240, 0x340, 0x320, 0x380, 0x300 }; - static struct fe_simple_probe_struct const probe_table [] = { - { FE_DLCR1, 0x20, 0x00 }, - { FE_DLCR2, 0x50, 0x00 }, - { FE_DLCR4, 0x08, 0x00 }, - { FE_DLCR5, 0x80, 0x00 }, -#if 0 - { FE_BMPR16, 0x1B, 0x00 }, - { FE_BMPR17, 0x7F, 0x00 }, -#endif - { 0 } - }; - - /* - * See if the specified address is possible for MB86965A JLI mode. - */ - if (bus_get_resource(dev, SYS_RES_IOPORT, 0, &iobase, NULL) != 0) - return ENXIO; - for (i = 0; i < 8; i++) { - if (baseaddr[i] == iobase) - break; - } - if (i == 8) - return ENXIO; - - /* 86965 JLI occupies 32 I/O addresses. */ - if (fe_alloc_port(dev, 32)) - return ENXIO; - - /* Fill the softc struct with reasonable default. */ - fe_softc_defaults(sc); - - /* - * We should test if MB86965A is on the base address now. - * Unfortunately, it is very hard to probe it reliably, since - * we have no way to reset the chip under software control. - * On cold boot, we could check the "signature" bit patterns - * described in the Fujitsu document. On warm boot, however, - * we can predict almost nothing about register values. - */ - if (!fe_simple_probe(sc, probe_table)) - return ENXIO; - - /* Check if our I/O address matches config info on 86965. */ - n = (fe_inb(sc, FE_BMPR19) & FE_B19_ADDR) >> FE_B19_ADDR_SHIFT; - if (baseaddr[n] != iobase) - return ENXIO; - - /* - * We are now almost sure we have an MB86965 at the given - * address. So, read EEPROM through it. We have to write - * into LSI registers to read from EEPROM. I want to avoid it - * at this stage, but I cannot test the presence of the chip - * any further without reading EEPROM. FIXME. - */ - fe_read_eeprom_jli(sc, eeprom); - - /* Make sure that config info in EEPROM and 86965 agree. */ - if (eeprom[FE_EEPROM_CONF] != fe_inb(sc, FE_BMPR19)) - return ENXIO; - - /* Use 86965 media selection scheme, unless othewise - specified. It is "AUTO always" and "select with BMPR13." - This behaviour covers most of the 86965 based board (as - minimum requirements.) It is backward compatible with - previous versions, also. */ - sc->mbitmap = MB_HA; - sc->defmedia = MB_HA; - sc->msel = fe_msel_965; - - /* Perform board-specific probe, one by one. Note that the - order of probe is important and should not be changed - arbitrarily. */ - if ((irqmap = fe_probe_jli_ati(sc, eeprom)) == NULL - && (irqmap = fe_probe_jli_rex(sc, eeprom)) == NULL - && (irqmap = fe_probe_jli_icl(sc, eeprom)) == NULL - && (irqmap = fe_probe_jli_unk(sc, eeprom)) == NULL) - return ENXIO; - - /* Find the IRQ read from EEPROM. */ - n = (fe_inb(sc, FE_BMPR19) & FE_B19_IRQ) >> FE_B19_IRQ_SHIFT; - xirq = irqmap[n]; - - /* Try to determine IRQ setting. */ - error = bus_get_resource(dev, SYS_RES_IRQ, 0, &irq, NULL); - if (error && xirq == NO_IRQ) { - /* The device must be configured with an explicit IRQ. */ - device_printf(dev, "IRQ auto-detection does not work\n"); - return ENXIO; - } else if (error && xirq != NO_IRQ) { - /* Just use the probed IRQ value. */ - bus_set_resource(dev, SYS_RES_IRQ, 0, xirq, 1); - } else if (!error && xirq == NO_IRQ) { - /* No problem. Go ahead. */ - } else if (irq == xirq) { - /* Good. Go ahead. */ - } else { - /* User must be warned in this case. */ - sc->stability |= UNSTABLE_IRQ; - } - - /* Setup a hook, which resets te 86965 when the driver is being - initialized. This may solve a nasty bug. FIXME. */ - sc->init = fe_init_jli; - - return 0; -} - -/* Probe for TDK LAK-AX031, which is an SSi 78Q8377A based board. */ -static int -fe_probe_ssi(device_t dev) -{ - struct fe_softc *sc = device_get_softc(dev); - rman_res_t iobase, irq; - - u_char eeprom [SSI_EEPROM_SIZE]; - static struct fe_simple_probe_struct probe_table [] = { - { FE_DLCR2, 0x08, 0x00 }, - { FE_DLCR4, 0x08, 0x00 }, - { 0 } - }; - - /* See if the specified I/O address is possible for 78Q8377A. */ - if (bus_get_resource(dev, SYS_RES_IOPORT, 0, &iobase, NULL) != 0) - return ENXIO; - if ((iobase & ~0x3F0) != 0x000) - return ENXIO; - - /* We have 16 registers. */ - if (fe_alloc_port(dev, 16)) - return ENXIO; - - /* Fill the softc struct with default values. */ - fe_softc_defaults(sc); - - /* See if the card is on its address. */ - if (!fe_simple_probe(sc, probe_table)) - return ENXIO; - - /* We now have to read the config EEPROM. We should be very - careful, since doing so destroys a register. (Remember, we - are not yet sure we have a LAK-AX031 board here.) Don't - remember to select BMPRs bofore reading EEPROM, since other - register bank may be selected before the probe() is called. */ - fe_read_eeprom_ssi(sc, eeprom); - - /* Make sure the Ethernet (MAC) station address is of TDK's. */ - if (!fe_valid_Ether_p(eeprom+FE_SSI_EEP_ADDR, 0x008098)) - return ENXIO; - bcopy(eeprom + FE_SSI_EEP_ADDR, sc->enaddr, ETHER_ADDR_LEN); - - /* This looks like a TDK-AX031 board. It requires an explicit - IRQ setting in config, since we currently don't know how we - can find the IRQ value assigned by ISA PnP manager. */ - if (bus_get_resource(dev, SYS_RES_IRQ, 0, &irq, NULL) != 0) { - fe_irq_failure("LAK-AX031", sc->sc_unit, NO_IRQ, NULL); - return ENXIO; - } - - /* Fill softc struct accordingly. */ - sc->type = FE_TYPE_SSI; - sc->typestr = "LAK-AX031"; - sc->mbitmap = MB_HT; - sc->defmedia = MB_HT; - - return 0; -} - -/* - * Probe and initialization for TDK/LANX LAC-AX012/013 boards. - */ -static int -fe_probe_lnx(device_t dev) -{ - struct fe_softc *sc = device_get_softc(dev); - rman_res_t iobase, irq; - - u_char eeprom [LNX_EEPROM_SIZE]; - static struct fe_simple_probe_struct probe_table [] = { - { FE_DLCR2, 0x58, 0x00 }, - { FE_DLCR4, 0x08, 0x00 }, - { 0 } - }; - - /* See if the specified I/O address is possible for TDK/LANX boards. */ - /* 300, 320, 340, and 360 are allowed. */ - if (bus_get_resource(dev, SYS_RES_IOPORT, 0, &iobase, NULL) != 0) - return ENXIO; - if ((iobase & ~0x060) != 0x300) - return ENXIO; - - /* We have 32 registers. */ - if (fe_alloc_port(dev, 32)) - return ENXIO; - - /* Fill the softc struct with default values. */ - fe_softc_defaults(sc); - - /* See if the card is on its address. */ - if (!fe_simple_probe(sc, probe_table)) - return ENXIO; - - /* We now have to read the config EEPROM. We should be very - careful, since doing so destroys a register. (Remember, we - are not yet sure we have a LAC-AX012/AX013 board here.) */ - fe_read_eeprom_lnx(sc, eeprom); - - /* Make sure the Ethernet (MAC) station address is of TDK/LANX's. */ - if (!fe_valid_Ether_p(eeprom, 0x008098)) - return ENXIO; - bcopy(eeprom, sc->enaddr, ETHER_ADDR_LEN); - - /* This looks like a TDK/LANX board. It requires an - explicit IRQ setting in config. Make sure we have one, - determining an appropriate value for the IRQ control - register. */ - irq = 0; - bus_get_resource(dev, SYS_RES_IRQ, 0, &irq, NULL); - switch (irq) { - case 3: sc->priv_info = 0x40 | LNX_CLK_LO | LNX_SDA_HI; break; - case 4: sc->priv_info = 0x20 | LNX_CLK_LO | LNX_SDA_HI; break; - case 5: sc->priv_info = 0x10 | LNX_CLK_LO | LNX_SDA_HI; break; - case 9: sc->priv_info = 0x80 | LNX_CLK_LO | LNX_SDA_HI; break; - default: - fe_irq_failure("LAC-AX012/AX013", sc->sc_unit, irq, "3/4/5/9"); - return ENXIO; - } - - /* Fill softc struct accordingly. */ - sc->type = FE_TYPE_LNX; - sc->typestr = "LAC-AX012/AX013"; - sc->init = fe_init_lnx; - - return 0; -} - -/* - * Probe and initialization for Gateway Communications' old cards. - */ -static int -fe_probe_gwy(device_t dev) -{ - struct fe_softc *sc = device_get_softc(dev); - rman_res_t iobase, irq; - - static struct fe_simple_probe_struct probe_table [] = { - /* { FE_DLCR2, 0x70, 0x00 }, */ - { FE_DLCR2, 0x58, 0x00 }, - { FE_DLCR4, 0x08, 0x00 }, - { 0 } - }; - - /* See if the specified I/O address is possible for Gateway boards. */ - if (bus_get_resource(dev, SYS_RES_IOPORT, 0, &iobase, NULL) != 0) - return ENXIO; - if ((iobase & ~0x1E0) != 0x200) - return ENXIO; - - /* That's all. The card occupies 32 I/O addresses, as always. */ - if (fe_alloc_port(dev, 32)) - return ENXIO; - - /* Setup an I/O address mapping table and some others. */ - fe_softc_defaults(sc); - - /* See if the card is on its address. */ - if (!fe_simple_probe(sc, probe_table)) - return ENXIO; - - /* Get our station address from EEPROM. */ - fe_inblk(sc, 0x18, sc->enaddr, ETHER_ADDR_LEN); - - /* Make sure it is Gateway Communication's. */ - if (!fe_valid_Ether_p(sc->enaddr, 0x000061)) - return ENXIO; - - /* Gateway's board requires an explicit IRQ to work, since it - is not possible to probe the setting of jumpers. */ - if (bus_get_resource(dev, SYS_RES_IRQ, 0, &irq, NULL) != 0) { - fe_irq_failure("Gateway Ethernet", sc->sc_unit, NO_IRQ, NULL); - return ENXIO; - } - - /* Fill softc struct accordingly. */ - sc->type = FE_TYPE_GWY; - sc->typestr = "Gateway Ethernet (Fujitsu chipset)"; - - return 0; -} - -/* Probe and initialization for Ungermann-Bass Network - K.K. "Access/PC" boards. */ -static int -fe_probe_ubn(device_t dev) -{ - struct fe_softc *sc = device_get_softc(dev); - rman_res_t iobase, irq; -#if 0 - u_char sum; -#endif - static struct fe_simple_probe_struct const probe_table [] = { - { FE_DLCR2, 0x58, 0x00 }, - { FE_DLCR4, 0x08, 0x00 }, - { 0 } - }; - - /* See if the specified I/O address is possible for AccessPC/ISA. */ - if (bus_get_resource(dev, SYS_RES_IOPORT, 0, &iobase, NULL) != 0) - return ENXIO; - if ((iobase & ~0x0E0) != 0x300) - return ENXIO; - - /* We have 32 registers. */ - if (fe_alloc_port(dev, 32)) - return ENXIO; - - /* Setup an I/O address mapping table and some others. */ - fe_softc_defaults(sc); - - /* Simple probe. */ - if (!fe_simple_probe(sc, probe_table)) - return ENXIO; - - /* Get our station address form ID ROM and make sure it is UBN's. */ - fe_inblk(sc, 0x18, sc->enaddr, ETHER_ADDR_LEN); - if (!fe_valid_Ether_p(sc->enaddr, 0x00DD01)) - return ENXIO; -#if 0 - /* Calculate checksum. */ - sum = fe_inb(sc, 0x1e); - for (i = 0; i < ETHER_ADDR_LEN; i++) { - sum ^= sc->enaddr[i]; - } - if (sum != 0) - return ENXIO; -#endif - /* This looks like an AccessPC/ISA board. It requires an - explicit IRQ setting in config. Make sure we have one, - determining an appropriate value for the IRQ control - register. */ - irq = 0; - bus_get_resource(dev, SYS_RES_IRQ, 0, &irq, NULL); - switch (irq) { - case 3: sc->priv_info = 0x02; break; - case 4: sc->priv_info = 0x04; break; - case 5: sc->priv_info = 0x08; break; - case 10: sc->priv_info = 0x10; break; - default: - fe_irq_failure("Access/PC", sc->sc_unit, irq, "3/4/5/10"); - return ENXIO; - } - - /* Fill softc struct accordingly. */ - sc->type = FE_TYPE_UBN; - sc->typestr = "Access/PC"; - sc->init = fe_init_ubn; - - return 0; -} - -DRIVER_MODULE(fe, isa, fe_isa_driver, fe_devclass, 0, 0); diff --git a/sys/dev/fe/if_fe_pccard.c b/sys/dev/fe/if_fe_pccard.c deleted file mode 100644 index 41f7e181198c..000000000000 --- a/sys/dev/fe/if_fe_pccard.c +++ /dev/null @@ -1,361 +0,0 @@ -/*- - * All Rights Reserved, Copyright (C) Fujitsu Limited 1995 - * - * This software may be used, modified, copied, distributed, and sold, in - * both source and binary form provided that the above copyright, these - * terms and the following disclaimer are retained. The name of the author - * and/or the contributor may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND THE CONTRIBUTOR ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR THE CONTRIBUTOR 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 -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include - -#include -#include - -#include "card_if.h" -#include "pccarddevs.h" - -/* - * PC Card (PCMCIA) specific code. - */ -static int fe_pccard_probe(device_t); -static int fe_pccard_attach(device_t); -static int fe_pccard_detach(device_t); - -static const struct fe_pccard_product { - struct pccard_product mpp_product; - int mpp_flags; - int mpp_cfe; -#define MPP_MBH10302 1 -#define MPP_ANYFUNC 2 -#define MPP_SKIP_TO_CFE 4 -} fe_pccard_products[] = { - /* These need to be first */ - { PCMCIA_CARD(FUJITSU2, FMV_J181), MPP_MBH10302 }, - { PCMCIA_CARD(FUJITSU2, FMV_J182), 0 }, - { PCMCIA_CARD(FUJITSU2, FMV_J182A), 0 }, - { PCMCIA_CARD(FUJITSU2, ITCFJ182A), 0 }, - /* These need to be second */ - { PCMCIA_CARD(TDK, LAK_CD011), 0 }, - { PCMCIA_CARD(TDK, LAK_CD021BX), 0 }, - { PCMCIA_CARD(TDK, LAK_CF010), 0 }, -#if 0 /* XXX 86960-based? */ - { PCMCIA_CARD(TDK, LAK_DFL9610), 0 }, -#endif - { PCMCIA_CARD(CONTEC, CNETPC), MPP_SKIP_TO_CFE, 2 }, - { PCMCIA_CARD(FUJITSU, LA501), 0 }, - { PCMCIA_CARD(FUJITSU, LA10S), 0 }, - { PCMCIA_CARD(FUJITSU, NE200T), MPP_MBH10302 },/* Sold by Eagle */ - { PCMCIA_CARD(HITACHI, HT_4840), MPP_MBH10302 | MPP_SKIP_TO_CFE, 10 }, - { PCMCIA_CARD(RATOC, REX_R280), 0 }, - { PCMCIA_CARD(XIRCOM, CE), MPP_ANYFUNC }, - { { NULL } } -}; - -static int -fe_pccard_probe(device_t dev) -{ - int error; - uint32_t fcn = PCCARD_FUNCTION_UNSPEC; - const struct fe_pccard_product *pp; - int i; - - if ((pp = (const struct fe_pccard_product *)pccard_product_lookup(dev, - (const struct pccard_product *)fe_pccard_products, - sizeof(fe_pccard_products[0]), NULL)) != NULL) { - if (pp->mpp_product.pp_name != NULL) - device_set_desc(dev, pp->mpp_product.pp_name); - if (pp->mpp_flags & MPP_ANYFUNC) - return (0); - /* Make sure we're a network function */ - error = pccard_get_function(dev, &fcn); - if (error != 0) - return (error); - if (fcn != PCCARD_FUNCTION_NETWORK) - return (ENXIO); - if (pp->mpp_flags & MPP_SKIP_TO_CFE) { - for (i = pp->mpp_cfe; i < 32; i++) { - if (pccard_select_cfe(dev, i) == 0) - goto good; - } - device_printf(dev, - "Failed to map CFE %d or higher\n", pp->mpp_cfe); - return ENXIO; - } - good:; - return (0); - } - return (ENXIO); -} - -static device_method_t fe_pccard_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, fe_pccard_probe), - DEVMETHOD(device_attach, fe_pccard_attach), - DEVMETHOD(device_detach, fe_pccard_detach), - - { 0, 0 } -}; - -static driver_t fe_pccard_driver = { - "fe", - fe_pccard_methods, - sizeof (struct fe_softc) -}; - -DRIVER_MODULE(fe, pccard, fe_pccard_driver, fe_devclass, 0, 0); -MODULE_DEPEND(fe, pccard, 1, 1, 1); -PCCARD_PNP_INFO(fe_pccard_products); - -static int fe_probe_mbh(device_t, const struct fe_pccard_product *); -static int fe_probe_tdk(device_t, const struct fe_pccard_product *); - -static int -fe_pccard_attach(device_t dev) -{ - struct fe_softc *sc; - const struct fe_pccard_product *pp; - int error; - - /* Prepare for the device probe process. */ - sc = device_get_softc(dev); - sc->sc_unit = device_get_unit(dev); - - pp = (const struct fe_pccard_product *) pccard_product_lookup(dev, - (const struct pccard_product *)fe_pccard_products, - sizeof(fe_pccard_products[0]), NULL); - if (pp == NULL) - return (ENXIO); - - if (pp->mpp_flags & MPP_MBH10302) - error = fe_probe_mbh(dev, pp); - else - error = fe_probe_tdk(dev, pp); - if (error != 0) { - fe_release_resource(dev); - return (error); - } - error = fe_alloc_irq(dev, 0); - if (error != 0) { - fe_release_resource(dev); - return (error); - } - return (fe_attach(dev)); -} - -/* - * feunload - unload the driver and clear the table. - */ -static int -fe_pccard_detach(device_t dev) -{ - struct fe_softc *sc = device_get_softc(dev); - struct ifnet *ifp = sc->ifp; - - FE_LOCK(sc); - fe_stop(sc); - FE_UNLOCK(sc); - callout_drain(&sc->timer); - ether_ifdetach(ifp); - bus_teardown_intr(dev, sc->irq_res, sc->irq_handle); - if_free(ifp); - fe_release_resource(dev); - mtx_destroy(&sc->lock); - - return 0; -} - - -/* - * Probe and initialization for Fujitsu MBH10302 PCMCIA Ethernet interface. - * Note that this is for 10302 only; MBH10304 is handled by fe_probe_tdk(). - */ -static void -fe_init_mbh(struct fe_softc *sc) -{ - /* Minimal initialization of 86960. */ - DELAY(200); - fe_outb(sc, FE_DLCR6, sc->proto_dlcr6 | FE_D6_DLC_DISABLE); - DELAY(200); - - /* Disable all interrupts. */ - fe_outb(sc, FE_DLCR2, 0); - fe_outb(sc, FE_DLCR3, 0); - - /* Enable master interrupt flag. */ - fe_outb(sc, FE_MBH0, FE_MBH0_MAGIC | FE_MBH0_INTR_ENABLE); -} - -static int -fe_probe_mbh(device_t dev, const struct fe_pccard_product *pp) -{ - struct fe_softc *sc = device_get_softc(dev); - - static struct fe_simple_probe_struct probe_table [] = { - { FE_DLCR2, 0x58, 0x00 }, - { FE_DLCR4, 0x08, 0x00 }, - { FE_DLCR6, 0xFF, 0xB6 }, - { 0 } - }; - - /* MBH10302 occupies 32 I/O addresses. */ - if (fe_alloc_port(dev, 32)) - return ENXIO; - - /* Fill the softc struct with default values. */ - fe_softc_defaults(sc); - - /* - * See if MBH10302 is on its address. - * I'm not sure the following probe code works. FIXME. - */ - if (!fe_simple_probe(sc, probe_table)) - return ENXIO; - - /* Get our station address from EEPROM. */ - fe_inblk(sc, FE_MBH10, sc->enaddr, ETHER_ADDR_LEN); - - /* Make sure we got a valid station address. */ - if (!fe_valid_Ether_p(sc->enaddr, 0)) - return ENXIO; - - /* Determine the card type. */ - sc->type = FE_TYPE_MBH; - sc->typestr = "MBH10302 (PCMCIA)"; - - /* We seems to need our own IDENT bits... FIXME. */ - sc->proto_dlcr7 = FE_D7_BYTSWP_LH | FE_D7_IDENT_NICE; - - /* Setup hooks. We need a special initialization procedure. */ - sc->init = fe_init_mbh; - - return 0; -} - -static int -fe_pccard_xircom_mac(const struct pccard_tuple *tuple, void *argp) -{ - uint8_t *enaddr = argp; - int i; - -#if 1 - /* - * We fail to map the CIS twice, for reasons unknown. We - * may fix this in the future by loading the CIS with a sane - * CIS from userland. - */ - static uint8_t defaultmac[ETHER_ADDR_LEN] = { - 0x00, 0x80, 0xc7, 0xed, 0x16, 0x7b}; - - /* Copy the MAC ADDR and return success */ - for (i = 0; i < ETHER_ADDR_LEN; i++) - enaddr[i] = defaultmac[i]; -#else - /* FUNCE is not after FUNCID, so we gotta go find it */ - if (tuple->code != 0x22) - return (0); - - /* Make sure this is a sane node */ - if (tuple->length < ETHER_ADDR_LEN + 3) - return (0); - - /* Copy the MAC ADDR and return success */ - for (i = 0; i < ETHER_ADDR_LEN; i++) - enaddr[i] = pccard_tuple_read_1(tuple, i + 3); -#endif - return (1); -} - -/* - * Probe and initialization for TDK/CONTEC PCMCIA Ethernet interface. - * by MASUI Kenji - * - * (Contec uses TDK Ethernet chip -- hosokawa) - * - * This version of fe_probe_tdk has been rewrote to handle - * *generic* PC Card implementation of Fujitsu MB8696x family. The - * name _tdk is just for a historical reason. :-) - */ -static int -fe_probe_tdk (device_t dev, const struct fe_pccard_product *pp) -{ - struct fe_softc *sc = device_get_softc(dev); - - static struct fe_simple_probe_struct probe_table [] = { - { FE_DLCR2, 0x10, 0x00 }, - { FE_DLCR4, 0x08, 0x00 }, -/* { FE_DLCR5, 0x80, 0x00 }, Does not work well. */ - { 0 } - }; - - - /* C-NET(PC)C occupies 16 I/O addresses. */ - if (fe_alloc_port(dev, 16)) - return ENXIO; - - /* Fill the softc struct with default values. */ - fe_softc_defaults(sc); - - /* - * See if C-NET(PC)C is on its address. - */ - if (!fe_simple_probe(sc, probe_table)) - return ENXIO; - - /* Determine the card type. */ - sc->type = FE_TYPE_TDK; - sc->typestr = "Generic MB8696x/78Q837x Ethernet (PCMCIA)"; - - pccard_get_ether(dev, sc->enaddr); - - /* Make sure we got a valid station address. */ - if (!fe_valid_Ether_p(sc->enaddr, 0)) { - pccard_cis_scan(dev, fe_pccard_xircom_mac, sc->enaddr); - } - - /* Make sure we got a valid station address. */ - if (!fe_valid_Ether_p(sc->enaddr, 0)) - return ENXIO; - - return 0; -} diff --git a/sys/dev/fe/if_fereg.h b/sys/dev/fe/if_fereg.h deleted file mode 100644 index a349f77044b1..000000000000 --- a/sys/dev/fe/if_fereg.h +++ /dev/null @@ -1,158 +0,0 @@ -/*- - * Hardware specification of various 8696x based Ethernet cards. - * Contributed by M. Sekiguchi - * - * All Rights Reserved, Copyright (C) Fujitsu Limited 1995 - * - * This software may be used, modified, copied, distributed, and sold, - * in both source and binary form provided that the above copyright, - * these terms and the following disclaimer are retained. The name of - * the author and/or the contributor may not be used to endorse or - * promote products derived from this software without specific prior - * written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND THE CONTRIBUTOR ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR THE CONTRIBUTOR 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 on FMV-180 series' ISA bus interface ASIC. - * I'm not sure the following register names are appropriate. - * Doesn't it look silly, eh? FIXME. - */ - -#define FE_FMV0 16 /* Card status register #0 */ -#define FE_FMV1 17 /* Card status register #1 */ -#define FE_FMV2 18 /* Card config register #0 */ -#define FE_FMV3 19 /* Card config register #1 */ -#define FE_FMV4 20 /* Station address #1 */ -#define FE_FMV5 21 /* Station address #2 */ -#define FE_FMV6 22 /* Station address #3 */ -#define FE_FMV7 23 /* Station address #4 */ -#define FE_FMV8 24 /* Station address #5 */ -#define FE_FMV9 25 /* Station address #6 */ -#define FE_FMV10 26 /* Buffer RAM control register */ -#define FE_FMV11 27 /* Buffer RAM data register */ - -/* - * FMV-180 series' ASIC register values. - */ - -/* FMV0: Card status register #0: Misc info? */ -#define FE_FMV0_MEDIA 0x07 /* Supported physical media. */ -#define FE_FMV0_PRRDY 0x10 /* ??? */ -#define FE_FMV0_PRERR 0x20 /* ??? */ -#define FE_FMV0_ERRDY 0x40 /* ??? */ -#define FE_FMV0_IREQ 0x80 /* ??? */ - -#define FE_FMV0_MEDIUM_5 0x01 /* 10base5/Dsub */ -#define FE_FMV0_MEDIUM_2 0x02 /* 10base2/BNC */ -#define FE_FMV0_MEDIUM_T 0x04 /* 10baseT/RJ45 */ - -/* Card status register #1: Hardware revision. */ -#define FE_FMV1_REV 0x0F /* Card revision */ -#define FE_FMV1_UPPER 0xF0 /* Usage unknown */ - -/* Card config register #0: I/O port address assignment. */ -#define FE_FMV2_IOS 0x07 /* I/O selection. */ -#define FE_FMV2_MES 0x38 /* ??? boot ROM? */ -#define FE_FMV2_IRS 0xC0 /* IRQ selection. */ - -#define FE_FMV2_IOS_SHIFT 0 -#define FE_FMV2_MES_SHIFT 3 -#define FE_FMV2_IRS_SHIFT 6 - -/* Card config register #1: IRQ enable */ -#define FE_FMV3_IRQENB 0x80 /* IRQ enable. */ - - -/* - * Register(?) specific to AT1700/RE2000. - */ - -#define FE_ATI_RESET 0x1F /* Write to reset the 86965. */ - -/* EEPROM allocation (offsets) of AT1700/RE2000. */ -#define FE_ATI_EEP_ADDR 0x08 /* Station address. (8-13) */ -#define FE_ATI_EEP_MEDIA 0x18 /* Media type. */ -#define FE_ATI_EEP_MAGIC 0x19 /* XXX Magic. */ -#define FE_ATI_EEP_MODEL 0x1e /* Hardware type. */ -#define FE_ATI_EEP_REVISION 0x1f /* Hardware revision. */ - -/* Value for FE_ATI_EEP_MODEL. */ -#define FE_ATI_MODEL_AT1700T 0x00 -#define FE_ATI_MODEL_AT1700BT 0x01 -#define FE_ATI_MODEL_AT1700FT 0x02 -#define FE_ATI_MODEL_AT1700AT 0x03 - - -/* - * Registers on MBH10302. - */ - -#define FE_MBH0 0x10 /* ??? Including interrupt. */ -#define FE_MBH1 0x11 /* ??? */ -#define FE_MBH10 0x1A /* Station address. (10 - 15) */ - -/* Values to be set in MBH0 register. */ -#define FE_MBH0_MAGIC 0x0D /* Just a magic constant? */ -#define FE_MBH0_INTR 0x10 /* Master interrupt control. */ - -#define FE_MBH0_INTR_ENABLE 0x10 /* Enable interrupts. */ -#define FE_MBH0_INTR_DISABLE 0x00 /* Disable interrupts. */ - - -/* - * Fujitsu MB86965 JLI mode support routines. - */ - -/* Datasheet for 86965 explicitly states that it only supports serial - * EEPROM with 16 words (32 bytes) capacity. (I.e., 93C06.) However, - * ones with 64 words (128 bytes) are available in the marked, namely - * 93C46, and are also fully compatible with 86965. It is known that - * some boards (e.g., ICL) actually have 93C46 on them and use extra - * storage to keep various config info. */ -#define JLI_EEPROM_SIZE 128 - - -/* - * SSi 78Q8377A support routines. - */ -#define SSI_EEPROM_SIZE 512 -#define SSI_DIN 0x01 -#define SSI_DAT 0x01 -#define SSI_CSL 0x02 -#define SSI_CLK 0x04 -#define SSI_EEP 0x10 - -#define FE_SSI_EEP_IRQ 9 /* Irq ??? */ -#define FE_SSI_EEP_ADDR 16 /* Station(MAC) address */ -#define FE_SSI_EEP_DUPLEX 25 /* Duplex mode ??? */ - - -/* - * TDK/LANX boards support routines. - */ - -/* AX012/AX013 equips an X24C01 chip, which has 128 bytes of memory cells. */ -#define LNX_EEPROM_SIZE 128 - -/* Bit assignments and command definitions for the serial EEPROM - interface register in LANX ASIC. */ -#define LNX_SDA_HI 0x08 /* Drive SDA line high (logical 1.) */ -#define LNX_SDA_LO 0x00 /* Drive SDA line low (logical 0.) */ -#define LNX_SDA_FL 0x08 /* Float (don't drive) SDA line. */ -#define LNX_SDA_IN 0x01 /* Mask for reading SDA line. */ -#define LNX_CLK_HI 0x04 /* Drive clock line high (active.) */ -#define LNX_CLK_LO 0x00 /* Drive clock line low (inactive.) */ diff --git a/sys/dev/fe/if_fevar.h b/sys/dev/fe/if_fevar.h deleted file mode 100644 index 3ebfeb0f2b46..000000000000 --- a/sys/dev/fe/if_fevar.h +++ /dev/null @@ -1,183 +0,0 @@ -/*- - * All Rights Reserved, Copyright (C) Fujitsu Limited 1995 - * - * This software may be used, modified, copied, distributed, and sold, in - * both source and binary form provided that the above copyright, these - * terms and the following disclaimer are retained. The name of the author - * and/or the contributor may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND THE CONTRIBUTOR ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR THE CONTRIBUTOR 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$ - */ - -/* How many registers does an fe-supported adapter have at maximum? */ -#define MAXREGISTERS 32 - -/* Shouldn't these be defined somewhere else such as isa_device.h? */ -#define NO_IRQ 0 - -/* Flags for stability. */ -#define UNSTABLE_IRQ 0x01 /* IRQ setting may be incorrect. */ -#define UNSTABLE_MAC 0x02 /* Probed MAC address may be incorrect. */ -#define UNSTABLE_TYPE 0x04 /* Probed vendor/model may be incorrect. */ - -/* Mapping between media bitmap (in fe_softc.mbitmap) and ifm_media. */ -#define MB_HA 0x0001 -#define MB_HM 0x0002 -#define MB_HT 0x0004 -#define MB_H2 0x0008 -#define MB_H5 0x0010 -#define MB_HF 0x0020 -#define MB_FT 0x0040 - -/* Card types. */ -#define FE_TYPE_SSI 1 -#define FE_TYPE_JLI 2 -#define FE_TYPE_FMV 3 -#define FE_TYPE_LNX 4 -#define FE_TYPE_UBN 5 -#define FE_TYPE_GWY 6 -#define FE_TYPE_MBH 7 -#define FE_TYPE_TDK 8 -#define FE_TYPE_RE1000 9 -#define FE_TYPE_CNET9NE 10 -#define FE_TYPE_REX 11 - -/* - * Data type for a multicast address filter on 8696x. - */ -struct fe_filter { - u_char data [FE_FILTER_LEN]; -}; - -/* - * fe_softc: per line info and status - */ -struct fe_softc { - - /* Used by "common" codes. */ - struct ifnet *ifp; - int sc_unit; - u_char enaddr[6]; - - /* Used by config codes. */ - int type; - int port_used; - struct resource * port_res; - struct resource * irq_res; - void * irq_handle; - - /* Set by probe() and not modified in later phases. */ - char const * typestr; /* printable name of the interface. */ - u_short txb_size; /* size of TX buffer, in bytes */ - u_char proto_dlcr4; /* DLCR4 prototype. */ - u_char proto_dlcr5; /* DLCR5 prototype. */ - u_char proto_dlcr6; /* DLCR6 prototype. */ - u_char proto_dlcr7; /* DLCR7 prototype. */ - u_char proto_bmpr13; /* BMPR13 prototype. */ - u_char stability; /* How stable is this? */ - u_short priv_info; /* info specific to a vendor/model. */ - - /* Vendor/model specific hooks. */ - void (*init)(struct fe_softc *); /* Just before fe_init(). */ - void (*stop)(struct fe_softc *); /* Just after fe_stop(). */ - - /* Transmission buffer management. */ - u_short txb_free; /* free bytes in TX buffer */ - u_char txb_count; /* number of packets in TX buffer */ - u_char txb_sched; /* number of scheduled packets */ - - /* Excessive collision counter (see fe_tint() for details.) */ - u_char tx_excolls; /* # of excessive collisions. */ - - /* Multicast address filter management. */ - u_char filter_change; /* MARs must be changed ASAP. */ - struct fe_filter filter;/* new filter value. */ - - /* Network management. */ - struct ifmib_iso_8802_3 mibdata; - - /* Media information. */ - struct ifmedia media; /* used by if_media. */ - u_short mbitmap; /* bitmap for supported media; see bit2media */ - int defmedia; /* default media */ - void (* msel)(struct fe_softc *); /* media selector. */ - - struct mtx lock; - struct callout timer; - int tx_timeout; -}; - -struct fe_simple_probe_struct { - u_char port; /* Offset from the base I/O address. */ - u_char mask; /* Bits to be checked. */ - u_char bits; /* Values to be compared against. */ -}; - -#define FE_LOCK(sc) mtx_lock(&(sc)->lock) -#define FE_UNLOCK(sc) mtx_unlock(&(sc)->lock) -#define FE_ASSERT_LOCKED(sc) mtx_assert(&(sc)->lock, MA_OWNED) - -extern devclass_t fe_devclass; - -int fe_attach(device_t); -int fe_alloc_port(device_t, int); -int fe_alloc_irq(device_t, int); -void fe_release_resource(device_t); - -int fe_simple_probe(struct fe_softc const *, - struct fe_simple_probe_struct const *); -int fe_valid_Ether_p(u_char const *, unsigned); -void fe_softc_defaults(struct fe_softc *); -void fe_stop(struct fe_softc *sc); -void fe_irq_failure(char const *, int, int, char const *); -void fe_msel_965(struct fe_softc *); -void fe_read_eeprom_jli(struct fe_softc *, u_char *); -void fe_init_jli(struct fe_softc *); -void fe_read_eeprom_ssi(struct fe_softc *, u_char *); -void fe_read_eeprom_lnx(struct fe_softc *, u_char *); -void fe_init_lnx(struct fe_softc *); -void fe_init_ubn(struct fe_softc *); - - -#define fe_inb(sc, port) \ - bus_read_1((sc)->port_res, (port)) - -#define fe_outb(sc, port, value) \ - bus_write_1((sc)->port_res, (port), (value)) - -#define fe_inw(sc, port) \ - bus_read_2((sc)->port_res, (port)) - -#define fe_outw(sc, port, value) \ - bus_write_2((sc)->port_res, (port), (value)) - -#define fe_insb(sc, port, addr, count) \ - bus_read_multi_1((sc)->port_res, (port), (addr), (count)) - -#define fe_outsb(sc, port, addr, count) \ - bus_write_multi_1((sc)->port_res, (port), (addr), (count)) - -#define fe_insw(sc, port, addr, count) \ - bus_read_multi_2((sc)->port_res, (port), (addr), (count)) - -#define fe_outsw(sc, port, addr, count) \ - bus_write_multi_2((sc)->port_res, (port), (addr), (count)) - -#define fe_inblk(sc, port, addr, count) \ - bus_read_region_1((sc)->port_res, (port), (addr), (count)) - -#define fe_outblk(sc, port, addr, count) \ - bus_write_region_1((sc)->port_res, (port), (addr), (count)) diff --git a/sys/dev/fe/mb86960.h b/sys/dev/fe/mb86960.h deleted file mode 100644 index 0482783f7c52..000000000000 --- a/sys/dev/fe/mb86960.h +++ /dev/null @@ -1,340 +0,0 @@ -/*- - * All Rights Reserved, Copyright (C) Fujitsu Limited 1995 - * - * This software may be used, modified, copied, distributed, and sold, in - * both source and binary form provided that the above copyright, these - * terms and the following disclaimer are retained. The name of the author - * and/or the contributor may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND THE CONTRIBUTOR ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR THE CONTRIBUTOR 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 of Fujitsu MB86960A/MB86965A series Ethernet controllers. - * Written and contributed by M.S. - */ - -/* - * Notes on register naming: - * - * Fujitsu documents for MB86960A/MB86965A uses no mnemorable names - * for their registers. They defined only three names for 32 - * registers and appended numbers to distinguish registers of - * same name. Surprisingly, the numbers represent I/O address - * offsets of the registers from the base addresses, and their - * names correspond to the "bank" the registers are allocated. - * All this means that, for example, to say "read DLCR8" has no more - * than to say "read a register at offset 8 on bank DLCR." - * - * The following definitions may look silly, but that's what Fujitsu - * did, and it is necessary to know these names to read Fujitsu - * documents.. - */ - -/* Data Link Control Registers, on invaliant port addresses. */ -#define FE_DLCR0 0 -#define FE_DLCR1 1 -#define FE_DLCR2 2 -#define FE_DLCR3 3 -#define FE_DLCR4 4 -#define FE_DLCR5 5 -#define FE_DLCR6 6 -#define FE_DLCR7 7 - -/* More DLCRs, on register bank #0. */ -#define FE_DLCR8 8 -#define FE_DLCR9 9 -#define FE_DLCR10 10 -#define FE_DLCR11 11 -#define FE_DLCR12 12 -#define FE_DLCR13 13 -#define FE_DLCR14 14 -#define FE_DLCR15 15 - -/* Malticast Address Registers. On register bank #1. */ -#define FE_MAR8 8 -#define FE_MAR9 9 -#define FE_MAR10 10 -#define FE_MAR11 11 -#define FE_MAR12 12 -#define FE_MAR13 13 -#define FE_MAR14 14 -#define FE_MAR15 15 - -/* Buffer Memory Port Registers. On register back #2. */ -#define FE_BMPR8 8 -#define FE_BMPR9 9 -#define FE_BMPR10 10 -#define FE_BMPR11 11 -#define FE_BMPR12 12 -#define FE_BMPR13 13 -#define FE_BMPR14 14 -#define FE_BMPR15 15 - -/* More BMPRs, only on 86965, accessible only when JLI mode. */ -#define FE_BMPR16 16 -#define FE_BMPR17 17 -#define FE_BMPR18 18 -#define FE_BMPR19 19 - -/* - * Definitions of registers. - * I don't have Fujitsu documents of MB86960A/MB86965A, so I don't - * know the official names for each flags and fields. The following - * names are assigned by me (the author of this file,) since I cannot - * mnemorize hexadecimal constants for all of these functions. - * Comments? - * - * I've got documents from Fujitsu web site, recently. However, it's - * too late. Names for some fields (bits) are kept different from - * those used in the Fujitsu documents... - */ - -/* DLCR0 -- transmitter status */ -#define FE_D0_BUSERR 0x01 /* Bus write error? */ -#define FE_D0_COLL16 0x02 /* Collision limit (16) encountered */ -#define FE_D0_COLLID 0x04 /* Collision on last transmission */ -#define FE_D0_JABBER 0x08 /* Jabber */ -#define FE_D0_CRLOST 0x10 /* Carrier lost on last transmission */ -#define FE_D0_PKTRCD 0x20 /* Last packet looped back correctly */ -#define FE_D0_NETBSY 0x40 /* Network Busy (Carrier Detected) */ -#define FE_D0_TXDONE 0x80 /* Transmission complete */ - -/* DLCR1 -- receiver status */ -#define FE_D1_OVRFLO 0x01 /* Receiver buffer overflow */ -#define FE_D1_CRCERR 0x02 /* CRC error on last packet */ -#define FE_D1_ALGERR 0x04 /* Alignment error on last packet */ -#define FE_D1_SRTPKT 0x08 /* Short (RUNT) packet is received */ -#define FE_D1_RMTRST 0x10 /* Remote reset packet (type = 0x0900) */ -#define FE_D1_DMAEOP 0x20 /* Host asserted End of DMA OPeration */ -#define FE_D1_BUSERR 0x40 /* Bus read error */ -#define FE_D1_PKTRDY 0x80 /* Packet(s) ready on receive buffer */ - -/* DLCR2 -- transmitter interrupt control; same layout as DLCR0 */ -#define FE_D2_BUSERR FE_D0_BUSERR -#define FE_D2_COLL16 FE_D0_COLL16 -#define FE_D2_COLLID FE_D0_COLLID -#define FE_D2_JABBER FE_D0_JABBER -#define FE_D2_TXDONE FE_D0_TXDONE - -#define FE_D2_RESERVED 0x70 - -/* DLCR3 -- receiver interrupt control; same layout as DLCR1 */ -#define FE_D3_OVRFLO FE_D1_OVRFLO -#define FE_D3_CRCERR FE_D1_CRCERR -#define FE_D3_ALGERR FE_D1_ALGERR -#define FE_D3_SRTPKT FE_D1_SRTPKT -#define FE_D3_RMTRST FE_D1_RMTRST -#define FE_D3_DMAEOP FE_D1_DMAEOP -#define FE_D3_BUSERR FE_D1_BUSERR -#define FE_D3_PKTRDY FE_D1_PKTRDY - -/* DLCR4 -- transmitter operation mode */ -#define FE_D4_DSC 0x01 /* Disable carrier sense on trans. */ -#define FE_D4_LBC 0x02 /* Loop back test control */ -#define FE_D4_CNTRL 0x04 /* - tied to CNTRL pin of the chip */ -#define FE_D4_TEST1 0x08 /* Test output #1 */ -#define FE_D4_COL 0xF0 /* Collision counter */ - -#define FE_D4_LBC_ENABLE 0x00 /* Perform loop back test */ -#define FE_D4_LBC_DISABLE 0x02 /* Normal operation */ - -#define FE_D4_COL_SHIFT 4 - -/* DLCR5 -- receiver operation mode */ -#define FE_D5_AFM0 0x01 /* Receive packets for other stations */ -#define FE_D5_AFM1 0x02 /* Receive packets for this station */ -#define FE_D5_RMTRST 0x04 /* Enable remote reset operation */ -#define FE_D5_SRTPKT 0x08 /* Accept short (RUNT) packets */ -#define FE_D5_SRTADR 0x10 /* Short (16 bits?) MAC address */ -#define FE_D5_BADPKT 0x20 /* Accept packets with error */ -#define FE_D5_BUFEMP 0x40 /* Receive buffer is empty */ -#define FE_D5_TEST2 0x80 /* Test output #2 */ - -/* DLCR6 -- hardware configuration #0 */ -#define FE_D6_BUFSIZ 0x03 /* Size of NIC buffer SRAM */ -#define FE_D6_TXBSIZ 0x0C /* Size (and config)of trans. buffer */ -#define FE_D6_BBW 0x10 /* Buffer SRAM bus width */ -#define FE_D6_SBW 0x20 /* System bus width */ -#define FE_D6_SRAM 0x40 /* Buffer SRAM access time */ -#define FE_D6_DLC 0x80 /* Disable DLC (recever/transmitter) */ - -#define FE_D6_BUFSIZ_8KB 0x00 /* The board has 8KB SRAM */ -#define FE_D6_BUFSIZ_16KB 0x01 /* The board has 16KB SRAM */ -#define FE_D6_BUFSIZ_32KB 0x02 /* The board has 32KB SRAM */ -#define FE_D6_BUFSIZ_64KB 0x03 /* The board has 64KB SRAM */ - -#define FE_D6_TXBSIZ_1x2KB 0x00 /* Single 2KB buffer for trans. */ -#define FE_D6_TXBSIZ_2x2KB 0x04 /* Double 2KB buffers */ -#define FE_D6_TXBSIZ_2x4KB 0x08 /* Double 4KB buffers */ -#define FE_D6_TXBSIZ_2x8KB 0x0C /* Double 8KB buffers */ - -#define FE_D6_BBW_WORD 0x00 /* SRAM has 16 bit data line */ -#define FE_D6_BBW_BYTE 0x10 /* SRAM has 8 bit data line */ - -#define FE_D6_SBW_WORD 0x00 /* Access with 16 bit (AT) bus */ -#define FE_D6_SBW_BYTE 0x20 /* Access with 8 bit (XT) bus */ - -#define FE_D6_SRAM_150ns 0x00 /* The board has slow SRAM */ -#define FE_D6_SRAM_100ns 0x40 /* The board has fast SRAM */ - -#define FE_D6_DLC_ENABLE 0x00 /* Normal operation */ -#define FE_D6_DLC_DISABLE 0x80 /* Stop sending/receiving */ - -/* DLC7 -- hardware configuration #1 */ -#define FE_D7_BYTSWP 0x01 /* Host byte order control */ -#define FE_D7_EOPPOL 0x02 /* Polarity of DMA EOP signal */ -#define FE_D7_RBS 0x0C /* Register bank select */ -#define FE_D7_RDYPNS 0x10 /* Senses RDYPNSEL input signal */ -#define FE_D7_POWER 0x20 /* Stand-by (power down) mode control */ -#define FE_D7_IDENT 0xC0 /* Chip identification */ - -#define FE_D7_BYTSWP_LH 0x00 /* DEC/Intel byte order */ -#define FE_D7_BYTSWP_HL 0x01 /* IBM/Motorolla byte order */ - -#define FE_D7_RBS_DLCR 0x00 /* Select DLCR8-15 */ -#define FE_D7_RBS_MAR 0x04 /* Select MAR8-15 */ -#define FE_D7_RBS_BMPR 0x08 /* Select BMPR8-15 */ - -#define FE_D7_POWER_DOWN 0x00 /* Power down (stand-by) mode */ -#define FE_D7_POWER_UP 0x20 /* Normal operation */ - -#define FE_D7_IDENT_TDK 0x00 /* TDK chips? */ -#define FE_D7_IDENT_NICE 0x80 /* Fujitsu NICE (86960) */ -#define FE_D7_IDENT_EC 0xC0 /* Fujitsu EtherCoupler (86965) */ - -/* DLCR8 thru DLCR13 are for Ethernet station address. */ - -/* DLCR14 and DLCR15 are for TDR. (TDR is used for cable diagnostic.) */ - -/* MAR8 thru MAR15 are for Multicast address filter. */ - -/* BMPR8 and BMPR9 are for packet data. */ - -/* BMPR10 -- transmitter start trigger */ -#define FE_B10_START 0x80 /* Start transmitter */ -#define FE_B10_COUNT 0x7F /* Packet count */ - -/* BMPR11 -- 16 collisions control */ -#define FE_B11_CTRL 0x01 /* Skip or resend errored packets */ -#define FE_B11_MODE1 0x02 /* Restart transmitter after COLL16 */ -#define FE_B11_MODE2 0x04 /* Automatic restart enable */ - -#define FE_B11_CTRL_RESEND 0x00 /* Re-send the collided packet */ -#define FE_B11_CTRL_SKIP 0x01 /* Skip the collided packet */ - -/* BMPR12 -- DMA enable */ -#define FE_B12_TXDMA 0x01 /* Enable transmitter DMA */ -#define FE_B12_RXDMA 0x02 /* Enable receiver DMA */ - -/* BMPR13 -- DMA control */ -#define FE_B13_BSTCTL 0x03 /* DMA burst mode control */ -#define FE_B13_TPTYPE 0x04 /* Twisted pair cable impedance */ -#define FE_B13_PORT 0x18 /* Port (TP/AUI) selection */ -#define FE_B13_LNKTST 0x20 /* Link test enable */ -#define FE_B13_SQTHLD 0x40 /* Lower squelch threshold */ -#define FE_B13_IOUNLK 0x80 /* Change I/O base address, on JLI mode */ - -#define FE_B13_BSTCTL_1 0x00 -#define FE_B13_BSTCTL_4 0x01 -#define FE_B13_BSTCTL_8 0x02 -#define FE_B13_BSTCLT_12 0x03 - -#define FE_B13_TPTYPE_UTP 0x00 /* Unshielded (standard) cable */ -#define FE_B13_TPTYPE_STP 0x04 /* Shielded (IBM) cable */ - -#define FE_B13_PORT_AUTO 0x00 /* Auto detected */ -#define FE_B13_PORT_TP 0x08 /* Force TP */ -#define FE_B13_PORT_AUI 0x18 /* Force AUI */ - -/* BMPR14 -- More receiver control and more transmission interrupts */ -#define FE_B14_FILTER 0x01 /* Filter out self-originated packets */ -#define FE_B14_SQE 0x02 /* SQE interrupt enable */ -#define FE_B14_SKIP 0x04 /* Skip a received packet */ -#define FE_B14_RJAB 0x20 /* RJAB interrupt enable */ -#define FE_B14_LLD 0x40 /* Local-link-down interrupt enable */ -#define FE_B14_RLD 0x80 /* Remote-link-down interrupt enable */ - -/* BMPR15 -- More transmitter status; basically same layout as BMPR14 */ -#define FE_B15_SQE FE_B14_SQE -#define FE_B15_RCVPOL 0x08 /* Reversed receive line polarity */ -#define FE_B15_RMTPRT 0x10 /* ??? */ -#define FE_B15_RAJB FE_B14_RJAB -#define FE_B15_LLD FE_B14_LLD -#define FE_B15_RLD FE_B14_RLD - -/* BMPR16 -- EEPROM control */ -#define FE_B16_DOUT 0x04 /* EEPROM Data in (CPU to EEPROM) */ -#define FE_B16_SELECT 0x20 /* EEPROM chip select */ -#define FE_B16_CLOCK 0x40 /* EEPROM shift clock */ -#define FE_B16_DIN 0x80 /* EEPROM data out (EEPROM to CPU) */ - -/* BMPR17 -- EEPROM data */ -#define FE_B17_DATA 0x80 /* EEPROM data bit */ - -/* BMPR18 -- cycle I/O address setting in JLI mode */ - -/* BMPR19 -- ISA interface configuration in JLI mode */ -#define FE_B19_IRQ 0xC0 -#define FE_B19_IRQ_SHIFT 6 - -#define FE_B19_ROM 0x38 -#define FE_B19_ROM_SHIFT 3 - -#define FE_B19_ADDR 0x07 -#define FE_B19_ADDR_SHIFT 0 - -/* - * An extra I/O port address to reset 86965. This location is called - * "ID ROM area" by Fujitsu document. - */ - -/* - * Flags in Receive Packet Header... Basically same layout as DLCR1. - */ -#define FE_RPH_OVRFLO FE_D1_OVRFLO -#define FE_RPH_CRCERR FE_D1_CRCERR -#define FE_RPH_ALGERR FE_D1_ALGERR -#define FE_RPH_SRTPKT FE_D1_SRTPKT -#define FE_RPH_RMTRST FE_D1_RMTRST -#define FE_RPH_GOOD 0x20 /* Good packet follows */ - -/* - * EEPROM specification (of JLI mode). - */ - -/* Number of bytes in an EEPROM accessible through 86965. */ -#define FE_EEPROM_SIZE 32 - -/* Offset for JLI config; automatically copied into BMPR19 at startup. */ -#define FE_EEPROM_CONF 0 - -/* - * Some 8696x specific constants. - */ - -/* Length (in bytes) of a Multicast Address Filter. */ -#define FE_FILTER_LEN 8 - -/* How many packets we can put in the transmission buffer on NIC memory. */ -#define FE_QUEUEING_MAX 127 - -/* Length (in bytes) of a "packet length" word in transmission buffer. */ -#define FE_DATA_LEN_LEN 2 - -/* Special Multicast Address Filter value. */ -#define FE_FILTER_NOTHING { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } -#define FE_FILTER_ALL { 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF } diff --git a/sys/i386/conf/GENERIC b/sys/i386/conf/GENERIC index a1447dcdf5d5..4e7e2d5fc4f1 100644 --- a/sys/i386/conf/GENERIC +++ b/sys/i386/conf/GENERIC @@ -271,7 +271,6 @@ device wb # Winbond W89C840F device xl # 3Com 3c90x (``Boomerang'', ``Cyclone'') # ISA Ethernet NICs. pccard NICs included. -device fe # Fujitsu MB8696x based cards device sn # SMC's 9000 series of Ethernet chips device xe # Xircom pccard Ethernet diff --git a/sys/modules/Makefile b/sys/modules/Makefile index ad1a1abdf45a..c7edeb4022f5 100644 --- a/sys/modules/Makefile +++ b/sys/modules/Makefile @@ -118,7 +118,6 @@ SUBDIR= \ ext2fs \ fdc \ fdescfs \ - ${_fe} \ ${_ffec} \ filemon \ firewire \ @@ -599,7 +598,6 @@ _dpms= dpms _em= em _et= et _exca= exca -_fe= fe _if_ndis= if_ndis _io= io _ix= ix diff --git a/sys/modules/fe/Makefile b/sys/modules/fe/Makefile deleted file mode 100644 index 3137bf2ed440..000000000000 --- a/sys/modules/fe/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -# $FreeBSD$ - -.PATH: ${SRCTOP}/sys/dev/fe - -KMOD= if_fe -SRCS= if_fe.c if_fe_isa.c if_fe_pccard.c - -SRCS+= bus_if.h card_if.h device_if.h isa_if.h pccarddevs.h - -.include